Browse Source

DisplayServer: separate window showing into another function

When creating a window, Godot would first register it to the WM(show it) and then set its flags.
This works fine on a floating WM, but on tiling WMs as soon as a window gets registered
the WM immediately acts on the window by scaling it up and treating it as a generic window,
being registered without any special flags.

This commit separates the showing of the window into another function and calls it after the most important flags are set,
making windows with special flags(eg. all popups) work again on tiling WMs.

Fixes #37930
Lorenzo Cerqua 5 years ago
parent
commit
d670a49612

+ 10 - 2
platform/linuxbsd/display_server_x11.cpp

@@ -685,6 +685,14 @@ DisplayServer::WindowID DisplayServerX11::create_sub_window(WindowMode p_mode, u
 	return id;
 }
 
+void DisplayServerX11::show_window(WindowID p_id) {
+	_THREAD_SAFE_METHOD_
+
+	WindowData &wd = windows[p_id];
+
+	XMapWindow(x11_display, wd.x11_window);
+}
+
 void DisplayServerX11::delete_sub_window(WindowID p_id) {
 	_THREAD_SAFE_METHOD_
 
@@ -3218,8 +3226,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
 		WindowData wd;
 		wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), p_rect.position.x, p_rect.position.y, p_rect.size.width > 0 ? p_rect.size.width : 1, p_rect.size.height > 0 ? p_rect.size.height : 1, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes);
 
-		XMapWindow(x11_display, wd.x11_window);
-
 		//associate PID
 		// make PID known to X11
 		{
@@ -3414,6 +3420,7 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, u
 	if (cursors[current_cursor] != None) {
 		XDefineCursor(x11_display, wd.x11_window, cursors[current_cursor]);
 	}
+
 	return id;
 }
 
@@ -3653,6 +3660,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode
 			window_set_flag(WindowFlags(i), true, main_window);
 		}
 	}
+	show_window(main_window);
 
 //create RenderingDevice if used
 #if defined(VULKAN_ENABLED)

+ 1 - 0
platform/linuxbsd/display_server_x11.h

@@ -276,6 +276,7 @@ public:
 	virtual Vector<DisplayServer::WindowID> get_window_list() const;
 
 	virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+	virtual void show_window(WindowID p_id);
 	virtual void delete_sub_window(WindowID p_id);
 
 	virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;

+ 1 - 0
platform/osx/display_server_osx.h

@@ -230,6 +230,7 @@ public:
 	virtual Vector<int> get_window_list() const override;
 
 	virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i()) override;
+	virtual void show_window(WindowID p_id) override;
 	virtual void delete_sub_window(WindowID p_id) override;
 
 	virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;

+ 8 - 3
platform/osx/display_server_osx.mm

@@ -2311,18 +2311,23 @@ DisplayServer::WindowID DisplayServerOSX::create_sub_window(WindowMode p_mode, u
 	_THREAD_SAFE_METHOD_
 
 	WindowID id = _create_window(p_mode, p_rect);
-	WindowData &wd = windows[id];
 	for (int i = 0; i < WINDOW_FLAG_MAX; i++) {
 		if (p_flags & (1 << i)) {
 			window_set_flag(WindowFlags(i), true, id);
 		}
 	}
+
+	return id;
+}
+
+void DisplayServerOSX::show_window(WindowID p_id) {
+	WindowData &wd = windows[p_id];
+
 	if (wd.no_focus) {
 		[wd.window_object orderFront:nil];
 	} else {
 		[wd.window_object makeKeyAndOrderFront:nil];
 	}
-	return id;
 }
 
 void DisplayServerOSX::_send_window_event(const WindowData &wd, WindowEvent p_event) {
@@ -3755,7 +3760,7 @@ DisplayServerOSX::DisplayServerOSX(const String &p_rendering_driver, WindowMode
 			window_set_flag(WindowFlags(i), true, main_window);
 		}
 	}
-	[windows[main_window].window_object makeKeyAndOrderFront:nil];
+	show_window(MAIN_WINDOW_ID);
 
 #if defined(OPENGL_ENABLED)
 	if (rendering_driver == "opengl_es") {

+ 9 - 7
platform/windows/display_server_windows.cpp

@@ -495,13 +495,17 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod
 
 	_update_window_style(window_id);
 
-	ShowWindow(wd.hWnd, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
-	if (!(p_flags & WINDOW_FLAG_NO_FOCUS_BIT)) {
+	return window_id;
+}
+
+void DisplayServerWindows::show_window(WindowID p_id) {
+	WindowData &wd = windows[p_id];
+
+	ShowWindow(wd.hWnd, wd.no_focus ? SW_SHOWNOACTIVATE : SW_SHOW); // Show The Window
+	if (!wd.no_focus) {
 		SetForegroundWindow(wd.hWnd); // Slightly Higher Priority
 		SetFocus(wd.hWnd); // Sets Keyboard Focus To
 	}
-
-	return window_id;
 }
 
 void DisplayServerWindows::delete_sub_window(WindowID p_window) {
@@ -3121,9 +3125,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
 		}
 	}
 
-	ShowWindow(windows[MAIN_WINDOW_ID].hWnd, SW_SHOW); // Show The Window
-	SetForegroundWindow(windows[MAIN_WINDOW_ID].hWnd); // Slightly Higher Priority
-	SetFocus(windows[MAIN_WINDOW_ID].hWnd); // Sets Keyboard Focus To
+	show_window(MAIN_WINDOW_ID);
 
 #if defined(VULKAN_ENABLED)
 

+ 1 - 0
platform/windows/display_server_windows.h

@@ -460,6 +460,7 @@ public:
 	virtual Vector<DisplayServer::WindowID> get_window_list() const;
 
 	virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+	virtual void show_window(WindowID p_window);
 	virtual void delete_sub_window(WindowID p_window);
 
 	virtual WindowID get_window_at_screen_position(const Point2i &p_position) const;

+ 1 - 0
scene/main/window.cpp

@@ -247,6 +247,7 @@ void Window::_make_window() {
 	}
 
 	RS::get_singleton()->viewport_set_update_mode(get_viewport_rid(), RS::VIEWPORT_UPDATE_WHEN_VISIBLE);
+	DisplayServer::get_singleton()->show_window(window_id);
 }
 
 void Window::_update_from_window() {

+ 4 - 0
servers/display_server.cpp

@@ -185,6 +185,10 @@ DisplayServer::WindowID DisplayServer::create_sub_window(WindowMode p_mode, uint
 	ERR_FAIL_V_MSG(INVALID_WINDOW_ID, "Sub-windows not supported by this display server.");
 }
 
+void DisplayServer::show_window(WindowID p_id) {
+	ERR_FAIL_MSG("Sub-windows not supported by this display server.");
+}
+
 void DisplayServer::delete_sub_window(WindowID p_id) {
 	ERR_FAIL_MSG("Sub-windows not supported by this display server.");
 }

+ 1 - 0
servers/display_server.h

@@ -220,6 +220,7 @@ public:
 	};
 
 	virtual WindowID create_sub_window(WindowMode p_mode, uint32_t p_flags, const Rect2i &p_rect = Rect2i());
+	virtual void show_window(WindowID p_id);
 	virtual void delete_sub_window(WindowID p_id);
 
 	virtual WindowID get_window_at_screen_position(const Point2i &p_position) const = 0;