diff options
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r-- | platform/linuxbsd/display_server_x11.cpp | 43 | ||||
-rw-r--r-- | platform/linuxbsd/display_server_x11.h | 5 |
2 files changed, 48 insertions, 0 deletions
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index b68b766ddd..3e6d244dc6 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -640,6 +640,14 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) { WindowData &wd = windows[p_id]; + while (wd.transient_children.size()) { + window_set_transient(wd.transient_children.front()->get(), INVALID_WINDOW_ID); + } + + if (wd.transient_parent != INVALID_WINDOW_ID) { + window_set_transient(p_id, INVALID_WINDOW_ID); + } + #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { context_vulkan->window_destroy(p_id); @@ -733,6 +741,40 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window } } +void DisplayServerX11::window_set_transient(WindowID p_window, WindowID p_parent) { + + ERR_FAIL_COND(p_window == p_parent); + + ERR_FAIL_COND(!windows.has(p_window)); + WindowData &wd_window = windows[p_window]; + + ERR_FAIL_COND(wd_window.transient_parent == p_parent); + + ERR_FAIL_COND_MSG(wd_window.on_top, "Windows with the 'on top' can't become transient."); + if (p_parent == INVALID_WINDOW_ID) { + //remove transient + + ERR_FAIL_COND(wd_window.transient_parent == INVALID_WINDOW_ID); + ERR_FAIL_COND(!windows.has(wd_window.transient_parent)); + + WindowData &wd_parent = windows[wd_window.transient_parent]; + + wd_window.transient_parent = INVALID_WINDOW_ID; + wd_parent.transient_children.erase(p_window); + + XSetTransientForHint(x11_display, wd_window.x11_window, None); + } else { + ERR_FAIL_COND(!windows.has(p_parent)); + ERR_FAIL_COND_MSG(wd_window.transient_parent != INVALID_WINDOW_ID, "Window already has a transient parent"); + WindowData &wd_parent = windows[p_parent]; + + wd_window.transient_parent = p_parent; + wd_parent.transient_children.insert(p_window); + + XSetTransientForHint(x11_display, wd_window.x11_window, wd_parent.x11_window); + } +} + Point2i DisplayServerX11::window_get_position(WindowID p_window) const { ERR_FAIL_COND_V(!windows.has(p_window), Point2i()); const WindowData &wd = windows[p_window]; @@ -1353,6 +1395,7 @@ void DisplayServerX11::window_set_flag(WindowFlags p_flag, bool p_enabled, Windo } break; case WINDOW_FLAG_ALWAYS_ON_TOP: { + ERR_FAIL_COND_MSG(wd.transient_parent != INVALID_WINDOW_ID, "Can't make a window transient if the 'on top' flag is active."); if (p_enabled && wd.fullscreen) { _set_wm_maximized(p_window, true); } diff --git a/platform/linuxbsd/display_server_x11.h b/platform/linuxbsd/display_server_x11.h index e17078c5ca..85d6dbf972 100644 --- a/platform/linuxbsd/display_server_x11.h +++ b/platform/linuxbsd/display_server_x11.h @@ -125,6 +125,9 @@ class DisplayServerX11 : public DisplayServer { Callable input_text_callback; Callable drop_files_callback; + WindowID transient_parent = INVALID_WINDOW_ID; + Set<WindowID> transient_children; + //better to guess on the fly, given WM can change it //WindowMode mode; bool fullscreen = false; //OS can't exit from this mode @@ -278,6 +281,8 @@ public: virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID); virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const; + virtual void window_set_transient(WindowID p_window, WindowID p_parent); + virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID); virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const; |