Add Fl_Window::maximize() and Fl_Window::un_maximize()

This commit is contained in:
ManoloFLTK
2023-11-04 11:30:45 +01:00
parent a31409f7bb
commit 0ae927a00e
15 changed files with 200 additions and 4 deletions
+1 -1
View File
@@ -180,7 +180,7 @@ protected:
IMAGE_BOUND = 1<<21, ///< binding the image to the widget will transfer ownership, so that the widget will delete the image when it is no longer needed
DEIMAGE_BOUND = 1<<22, ///< bind the inactive image to the widget, so the widget deletes the image when it is no longer needed
AUTO_DELETE_USER_DATA = 1<<23, ///< automatically call `delete` on the user_data pointer when destroying this widget; if set, user_data must point to a class derived from the class Fl_Callback_User_Data
MAXIMIZED = 1<<24, ///< a maximized Fl_Window
// Note to devs: add new FLTK core flags above this line (up to 1<<28).
// Three more flags, reserved for user code
+8
View File
@@ -92,6 +92,8 @@ private:
Fl_Window(const Fl_Window&);
Fl_Window& operator=(const Fl_Window&);
void is_maximized_(bool b);
protected:
/** Stores the last window that was made current. See current() const */
@@ -508,6 +510,12 @@ public:
\see void Fl_Window::fullscreen()
*/
void fullscreen_screens(int top, int bottom, int left, int right);
void maximize();
void un_maximize();
/** Returns whether the window is currently maximized */
unsigned int maximize_active() const { return flags() & MAXIMIZED; }
public:
/**
Iconifies the window. If you call this when shown() is false
it will show() it as an icon. If the window is already
+30
View File
@@ -922,3 +922,33 @@ bool Fl_Window::is_a_rescale() {return Fl_Window_Driver::is_a_rescale_;}
\li other platforms: 0.
*/
fl_uintptr_t Fl_Window::os_id() { return pWindowDriver->os_id();}
/**
Maximizes a top-level window to its current screen.
This function is effective only with a show()'n, resizable, top-level window.
Bordered and borderless windows can be used.
\see Fl_Window::un_maximize(), Fl_Window::maximize_active()
*/
void Fl_Window::maximize() {
if (!shown() || parent() || !resizable() || maximize_active()) return;
set_flag(MAXIMIZED);
if (border()) pWindowDriver->maximize();
else pWindowDriver->Fl_Window_Driver::maximize();
}
/**
Returns a previously maximized top-level window to its previous size.
\see Fl_Window::maximize()
*/
void Fl_Window::un_maximize() {
if (!shown() || parent() || !resizable() || !maximize_active()) return;
clear_flag(MAXIMIZED);
if (border()) pWindowDriver->un_maximize();
else pWindowDriver->Fl_Window_Driver::un_maximize();
}
void Fl_Window::is_maximized_(bool b) {
if (b) set_flag(MAXIMIZED);
else clear_flag(MAXIMIZED);
}
+8
View File
@@ -105,6 +105,10 @@ public:
int fullscreen_screen_bottom();
int fullscreen_screen_left();
int fullscreen_screen_right();
int* no_fullscreen_x() { return &pWindow->no_fullscreen_x; }
int* no_fullscreen_y() { return &pWindow->no_fullscreen_y; }
int* no_fullscreen_w() { return &pWindow->no_fullscreen_w; }
int* no_fullscreen_h() { return &pWindow->no_fullscreen_h; }
int force_position();
void force_position(int c);
void x(int X);
@@ -154,6 +158,10 @@ public:
virtual void unmap() {}
virtual void fullscreen_on() {}
virtual void fullscreen_off(int /*X*/, int /*Y*/, int /*W*/, int /*H*/) {}
virtual void maximize();
virtual void un_maximize();
virtual bool maximize_needs_hide() { return false; }
void is_maximized(bool b) { pWindow->is_maximized_(b); }
virtual void use_border();
virtual void size_range();
virtual void iconize() {}
+28
View File
@@ -286,6 +286,34 @@ Fl_Window *Fl_Window_Driver::find(fl_uintptr_t xid) {
return 0;
}
void Fl_Window_Driver::maximize() {
*no_fullscreen_x() = x();
*no_fullscreen_y() = y();
*no_fullscreen_w() = w();
*no_fullscreen_h() = h();
int X,Y,W,H;
Fl::screen_work_area(X, Y, W, H, screen_num());
int width = decorated_w();
int height = decorated_h();
int dw = (width - w());
int dh = (height - h() - dw);
bool need_hide_show = maximize_needs_hide();
if (need_hide_show) hide(); // pb may occur in subwindow without this
resize(X + dw/2, Y + dh + dw/2, W - dw, H - dh - dw);
if (need_hide_show) show();
}
void Fl_Window_Driver::un_maximize() {
resize(*no_fullscreen_x(), *no_fullscreen_y(),
*no_fullscreen_w(), *no_fullscreen_h());
*no_fullscreen_x() = 0;
*no_fullscreen_y() = 0;
*no_fullscreen_w() = 0;
*no_fullscreen_h() = 0;
}
/**
\}
\endcond
+14
View File
@@ -1351,6 +1351,9 @@ static FLWindowDelegate *flwindowdelegate_instance = nil;
window->redraw();
}
#endif
if (!window->parent()) {
Fl_Cocoa_Window_Driver::driver(window)->is_maximized([nsw isZoomed]);
}
fl_unlock_function();
}
- (void)windowDidResignKey:(NSNotification *)notif
@@ -3236,6 +3239,17 @@ void Fl_Cocoa_Window_Driver::fullscreen_on() {
Fl::handle(FL_FULLSCREEN, pWindow);
}
void Fl_Cocoa_Window_Driver::maximize() {
[fl_xid(pWindow) performZoom:nil];
}
void Fl_Cocoa_Window_Driver::un_maximize() {
[fl_xid(pWindow) performZoom:nil];
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
static NSUInteger calc_win_style(Fl_Window *win) {
NSUInteger winstyle;
+1
View File
@@ -1572,6 +1572,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_SIZE:
if (!window->parent()) {
Fl_Window_Driver::driver(window)->is_maximized(wParam == SIZE_MAXIMIZED);
if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) {
Fl::handle(FL_HIDE, window);
} else {
+44
View File
@@ -200,6 +200,8 @@ static Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
static Atom fl_NET_SUPPORTING_WM_CHECK;
static Atom fl_NET_WM_STATE;
static Atom fl_NET_WM_STATE_FULLSCREEN;
static Atom fl_NET_WM_STATE_MAXIMIZED_VERT;
static Atom fl_NET_WM_STATE_MAXIMIZED_HORZ;
static Atom fl_NET_WM_FULLSCREEN_MONITORS;
Atom fl_NET_WORKAREA;
static Atom fl_NET_WM_ICON;
@@ -590,6 +592,8 @@ void open_display_i(Display* d) {
fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0);
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
fl_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(d, "_NET_WM_STATE_MAXIMIZED_VERT", 0);
fl_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(d, "_NET_WM_STATE_MAXIMIZED_HORZ", 0);
fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0);
@@ -1947,6 +1951,7 @@ int fl_handle(const XEvent& thisevent)
case PropertyNotify:
if (xevent.xproperty.atom == fl_NET_WM_STATE) {
int fullscreen_state = 0;
int maximize_state = 0;
if (xevent.xproperty.state != PropertyDelete) {
unsigned long nitems;
unsigned long *words = 0;
@@ -1955,10 +1960,14 @@ int fl_handle(const XEvent& thisevent)
if (words[item] == fl_NET_WM_STATE_FULLSCREEN) {
fullscreen_state = 1;
}
if (words[item] == fl_NET_WM_STATE_MAXIMIZED_HORZ) {
maximize_state = 1;
}
}
}
if ( words ) { XFree(words); words = 0; }
}
Fl_Window_Driver::driver(window)->is_maximized(maximize_state);
if (window->fullscreen_active() && !fullscreen_state) {
window->_clear_fullscreen();
event = FL_FULLSCREEN;
@@ -2318,6 +2327,41 @@ void Fl_X11_Window_Driver::fullscreen_off(int X, int Y, int W, int H) {
}
}
void Fl_X11_Window_Driver::maximize() {
if (Fl_X11_Screen_Driver::ewmh_supported()) {
send_wm_event(fl_xid(pWindow), fl_NET_WM_STATE, _NET_WM_STATE_ADD,
fl_NET_WM_STATE_MAXIMIZED_VERT, fl_NET_WM_STATE_MAXIMIZED_HORZ);
} else {
*no_fullscreen_x() = x();
*no_fullscreen_y() = y();
*no_fullscreen_w() = w();
*no_fullscreen_h() = h();
int X,Y,W,H;
Fl::screen_work_area(X, Y, W, H, screen_num());
int width, height;
decorated_win_size(width, height);
int dw = (width - w());
int dh = (height - h() - dw);
resize(X + dw/2, Y + dh + dw/2, W - dw, H - dh - dw);
}
}
void Fl_X11_Window_Driver::un_maximize() {
if (Fl_X11_Screen_Driver::ewmh_supported()) {
send_wm_event(fl_xid(pWindow), fl_NET_WM_STATE, _NET_WM_STATE_REMOVE,
fl_NET_WM_STATE_MAXIMIZED_VERT, fl_NET_WM_STATE_MAXIMIZED_HORZ);
} else {
resize(*no_fullscreen_x(), *no_fullscreen_y(),
*no_fullscreen_w(), *no_fullscreen_h());
*no_fullscreen_x() = 0;
*no_fullscreen_y() = 0;
*no_fullscreen_w() = 0;
*no_fullscreen_h() = 0;
}
}
////////////////////////////////////////////////////////////////
// A subclass of Fl_Window may call this to associate an X window it
@@ -130,6 +130,8 @@ public:
void unmap() FL_OVERRIDE;
void fullscreen_on() FL_OVERRIDE;
void fullscreen_off(int X, int Y, int W, int H) FL_OVERRIDE;
void maximize() FL_OVERRIDE;
void un_maximize() FL_OVERRIDE;
void use_border() FL_OVERRIDE;
void size_range() FL_OVERRIDE;
void iconize() FL_OVERRIDE;
@@ -114,6 +114,8 @@ public:
void unmap() FL_OVERRIDE;
void fullscreen_on() FL_OVERRIDE;
void fullscreen_off(int X, int Y, int W, int H) FL_OVERRIDE;
void maximize() FL_OVERRIDE;
void un_maximize() FL_OVERRIDE;
void use_border() FL_OVERRIDE;
void size_range() FL_OVERRIDE;
void iconize() FL_OVERRIDE;
@@ -941,6 +941,8 @@ static void handle_configure(struct libdecor_frame *frame,
}
}
if (window->fl_win->border())
driver->is_maximized(window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED);
if (window_state & LIBDECOR_WINDOW_STATE_MAXIMIZED) state = libdecor_state_new(width,
height);
else state = libdecor_state_new(int(ceil(width/f)*f), int(ceil(height/f)*f));
@@ -2135,3 +2137,15 @@ Fl_Wayland_Plugin *Fl_Wayland_Window_Driver::gl_plugin() {
}
return plugin;
}
void Fl_Wayland_Window_Driver::maximize() {
struct wld_window *xid = (struct wld_window *)Fl_X::flx(pWindow)->xid;
if (xid->kind == DECORATED) libdecor_frame_set_maximized(xid->frame);
}
void Fl_Wayland_Window_Driver::un_maximize() {
struct wld_window *xid = (struct wld_window *)Fl_X::flx(pWindow)->xid;
if (xid->kind == DECORATED) libdecor_frame_unset_maximized(xid->frame);
}
@@ -101,6 +101,9 @@ public:
void unmap() FL_OVERRIDE;
void fullscreen_on() FL_OVERRIDE;
void fullscreen_off(int X, int Y, int W, int H) FL_OVERRIDE;
void maximize() FL_OVERRIDE;
void un_maximize() FL_OVERRIDE;
virtual bool maximize_needs_hide() FL_OVERRIDE { return true; }
void iconize() FL_OVERRIDE;
void decoration_sizes(int *top, int *left, int *right, int *bottom) FL_OVERRIDE;
// --- window cursor stuff
@@ -616,6 +616,15 @@ void Fl_WinAPI_Window_Driver::fullscreen_off(int X, int Y, int W, int H) {
}
void Fl_WinAPI_Window_Driver::maximize() {
ShowWindow(fl_xid(pWindow), SW_SHOWMAXIMIZED);
}
void Fl_WinAPI_Window_Driver::un_maximize() {
ShowWindow(fl_xid(pWindow), SW_SHOWNORMAL);
}
void Fl_WinAPI_Window_Driver::iconize() {
ShowWindow(fl_xid(pWindow), SW_SHOWMINNOACTIVE);
}
+2
View File
@@ -113,6 +113,8 @@ public:
void unmap() FL_OVERRIDE;
void fullscreen_on() FL_OVERRIDE;
void fullscreen_off(int X, int Y, int W, int H) FL_OVERRIDE;
void maximize() FL_OVERRIDE;
void un_maximize() FL_OVERRIDE;
void use_border() FL_OVERRIDE;
void size_range() FL_OVERRIDE;
void iconize() FL_OVERRIDE;
+34 -3
View File
@@ -1,7 +1,6 @@
//
//
// Copyright 1998-2010 by Bill Spitzak and others.
// Copyright 1998-2023 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -124,6 +123,8 @@ class fullscreen_window : public Fl_Single_Window {
public:
fullscreen_window(int W, int H, const char *t=0);
int handle (int e) FL_OVERRIDE;
void resize(int x, int y, int w, int h) FL_OVERRIDE;
Fl_Toggle_Light_Button *b3_maxi;
Fl_Toggle_Light_Button *b3;
Fl_Toggle_Light_Button *b4;
};
@@ -132,6 +133,19 @@ fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Wi
}
void after_resize(void *data) {
Fl::remove_check(after_resize, data);
fullscreen_window *win = (fullscreen_window*)data;
if (win->maximize_active()) win->b3_maxi->set();
else win->b3_maxi->clear();
win->b3_maxi->redraw();
}
void fullscreen_window::resize(int x, int y, int w, int h) {
Fl_Single_Window::resize(x,y,w,h);
Fl::add_check(after_resize, this);
};
int fullscreen_window::handle(int e) {
if (e == FL_FULLSCREEN) {
// fprintf(stderr, "Received FL_FULLSCREEN event\n");
@@ -163,6 +177,19 @@ void border_cb(Fl_Widget *o, void *p) {
w->border(d);
}
void maximize_cb(Fl_Widget *o, void *p) {
Fl_Window *w = (Fl_Window *)p;
if (w->maximize_active()) {
w->un_maximize();
//((Fl_Button*)o)->set();
} else {
w->maximize();
//((Fl_Button*)o)->clear();
}
}
Fl_Button *border_button;
void fullscreen_cb(Fl_Widget *o, void *p) {
Fl_Window *w = (Fl_Window *)p;
@@ -250,7 +277,7 @@ void exit_cb(Fl_Widget *, void *) {
exit(0);
}
#define NUMB 8
#define NUMB 9
int twowindow = 0;
int initfull = 0;
@@ -315,6 +342,10 @@ int main(int argc, char **argv) {
window.b3 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"FullScreen");
window.b3->callback(fullscreen_cb,w);
y+=30;
window.b3_maxi = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"Maximize");
window.b3_maxi->callback(maximize_cb,w);
y+=30;
window.b4 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"All Screens");
window.b4->callback(allscreens_cb,w);