diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2018-02-14 16:43:40 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-14 16:43:40 +0100 |
commit | e0f43e06785ea1b05a5d7c4be32b74a9995be8fe (patch) | |
tree | ed1ed82993d60083bf51384311fea8831035a4b8 /platform/x11 | |
parent | 2eb7a321ba321065c135f799701efaf735142593 (diff) | |
parent | 2e8c7824c0f2946f6bf33fe0a20eabb779a91763 (diff) |
Merge pull request #15564 from RandomShaper/adpod-topmost
Add new window setting: always on top
Diffstat (limited to 'platform/x11')
-rw-r--r-- | platform/x11/os_x11.cpp | 57 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 3 |
2 files changed, 57 insertions, 3 deletions
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 8f2c1812b4..2d8e32137f 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -333,6 +333,11 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a XFree(xsh); } + if (current_videomode.always_on_top) { + current_videomode.always_on_top = false; + set_window_always_on_top(true); + } + AudioDriverManager::initialize(p_audio_driver); ERR_FAIL_COND_V(!visual_server, ERR_UNAVAILABLE); @@ -725,9 +730,6 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con } void OS_X11::set_wm_fullscreen(bool p_enabled) { - if (current_videomode.fullscreen == p_enabled) - return; - if (p_enabled && !is_window_resizable()) { // Set the window as resizable to prevent window managers to ignore the fullscreen state flag. XSizeHints *xsh; @@ -788,6 +790,22 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) { } } +void OS_X11::set_wm_above(bool p_enabled) { + Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False); + Atom wm_above = XInternAtom(x11_display, "_NET_WM_STATE_ABOVE", False); + + XClientMessageEvent xev; + memset(&xev, 0, sizeof(xev)); + xev.type = ClientMessage; + xev.window = x11_window; + xev.message_type = wm_state; + xev.format = 32; + xev.data.l[0] = p_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + xev.data.l[1] = wm_above; + xev.data.l[3] = 1; + XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, (XEvent *)&xev); +} + int OS_X11::get_screen_count() const { // Using Xinerama Extension int event_base, error_base; @@ -982,7 +1000,19 @@ void OS_X11::set_window_size(const Size2 p_size) { } void OS_X11::set_window_fullscreen(bool p_enabled) { + if (current_videomode.fullscreen == p_enabled) + return; + + if (p_enabled && current_videomode.always_on_top) { + // Fullscreen + Always-on-top requires a maximized window on some window managers (Metacity) + set_window_maximized(true); + } set_wm_fullscreen(p_enabled); + if (!p_enabled && !current_videomode.always_on_top) { + // Restore + set_window_maximized(false); + } + current_videomode.fullscreen = p_enabled; } @@ -1189,6 +1219,27 @@ bool OS_X11::is_window_maximized() const { return false; } +void OS_X11::set_window_always_on_top(bool p_enabled) { + if (is_window_always_on_top() == p_enabled) + return; + + if (p_enabled && current_videomode.fullscreen) { + // Fullscreen + Always-on-top requires a maximized window on some window managers (Metacity) + set_window_maximized(true); + } + set_wm_above(p_enabled); + if (!p_enabled && !current_videomode.fullscreen) { + // Restore + set_window_maximized(false); + } + + current_videomode.always_on_top = p_enabled; +} + +bool OS_X11::is_window_always_on_top() const { + return current_videomode.always_on_top; +} + void OS_X11::set_borderless_window(bool p_borderless) { if (current_videomode.borderless_window == p_borderless) diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index b5ceea6eaf..494845bc56 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -178,6 +178,7 @@ class OS_X11 : public OS_Unix { bool maximized; //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); + void set_wm_above(bool p_enabled); typedef xrr_monitor_info *(*xrr_get_monitors_t)(Display *dpy, Window window, Bool get_active, int *nmonitors); typedef void (*xrr_free_monitors_t)(xrr_monitor_info *monitors); @@ -261,6 +262,8 @@ public: virtual bool is_window_minimized() const; virtual void set_window_maximized(bool p_enabled); virtual bool is_window_maximized() const; + virtual void set_window_always_on_top(bool p_enabled); + virtual bool is_window_always_on_top() const; virtual void request_attention(); virtual void set_borderless_window(bool p_borderless); |