summaryrefslogtreecommitdiff
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/display_server_x11.cpp43
-rw-r--r--platform/linuxbsd/display_server_x11.h5
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;