Browse Source

Merge pull request #111580 from timothyqiu/x11-fullscreen

X11: Fix fullscreen exit behavior
Thaddeus Crews 1 month ago
parent
commit
685fa3281c

+ 8 - 53
platform/linuxbsd/x11/display_server_x11.cpp

@@ -2392,11 +2392,12 @@ void DisplayServerX11::_update_size_hints(WindowID p_window) {
 	XSizeHints *xsh = XAllocSizeHints();
 
 	// Always set the position and size hints - they should be synchronized with the actual values after the window is mapped anyway
-	xsh->flags |= PPosition | PSize;
+	xsh->flags |= PPosition | PSize | PWinGravity;
 	xsh->x = wd.position.x;
 	xsh->y = wd.position.y;
 	xsh->width = wd.size.width;
 	xsh->height = wd.size.height;
+	xsh->win_gravity = StaticGravity;
 
 	if (window_mode == WINDOW_MODE_FULLSCREEN || window_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN) {
 		// Do not set any other hints to prevent the window manager from ignoring the fullscreen flags
@@ -2560,29 +2561,7 @@ void DisplayServerX11::window_set_position(const Point2i &p_position, WindowID p
 	}
 
 	wd.position = p_position;
-	int x = 0;
-	int y = 0;
-	if (!window_get_flag(WINDOW_FLAG_BORDERLESS, p_window)) {
-		//exclude window decorations
-		XSync(x11_display, False);
-		Atom prop = XInternAtom(x11_display, "_NET_FRAME_EXTENTS", True);
-		if (prop != None) {
-			Atom type;
-			int format;
-			unsigned long len;
-			unsigned long remaining;
-			unsigned char *data = nullptr;
-			if (XGetWindowProperty(x11_display, wd.x11_window, prop, 0, 4, False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) {
-				if (format == 32 && len == 4 && data) {
-					long *extents = (long *)data;
-					x = extents[0];
-					y = extents[2];
-				}
-				XFree(data);
-			}
-		}
-	}
-	XMoveWindow(x11_display, wd.x11_window, p_position.x - x, p_position.y - y);
+	XMoveWindow(x11_display, wd.x11_window, p_position.x, p_position.y);
 	_update_real_mouse_position(wd);
 }
 
@@ -3098,21 +3077,12 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
 		} break;
 		case WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
 		case WINDOW_MODE_FULLSCREEN: {
-			//Remove full-screen
-			wd.fullscreen = false;
-			wd.exclusive_fullscreen = false;
-
-			_set_wm_fullscreen(p_window, false, false);
-
-			//un-maximize required for always on top
-			bool on_top = window_get_flag(WINDOW_FLAG_ALWAYS_ON_TOP, p_window);
-
-			window_set_position(wd.last_position_before_fs, p_window);
-
-			if (on_top) {
-				_set_wm_maximized(p_window, false);
+			// Only remove fullscreen when necessary.
+			if (p_mode == WINDOW_MODE_WINDOWED || p_mode == WINDOW_MODE_MAXIMIZED) {
+				wd.fullscreen = false;
+				wd.exclusive_fullscreen = false;
+				_set_wm_fullscreen(p_window, false, false);
 			}
-
 		} break;
 		case WINDOW_MODE_MAXIMIZED: {
 			// Varies between target modes, so do nothing here.
@@ -3130,8 +3100,6 @@ void DisplayServerX11::window_set_mode(WindowMode p_mode, WindowID p_window) {
 		} break;
 		case WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
 		case WINDOW_MODE_FULLSCREEN: {
-			wd.last_position_before_fs = wd.position;
-
 			if (window_get_flag(WINDOW_FLAG_ALWAYS_ON_TOP, p_window)) {
 				_set_wm_maximized(p_window, true);
 			}
@@ -4453,17 +4421,6 @@ void DisplayServerX11::_window_changed(XEvent *event) {
 		return;
 	}
 
-	// Readjusting the window position if the window is being reparented by the window manager for decoration
-	Window root, parent, *children;
-	unsigned int nchildren;
-	if (XQueryTree(x11_display, wd.x11_window, &root, &parent, &children, &nchildren) && wd.parent != parent) {
-		wd.parent = parent;
-		if (!wd.embed_parent) {
-			window_set_position(wd.position, window_id);
-		}
-	}
-	XFree(children);
-
 	{
 		//the position in xconfigure is not useful here, obtain it manually
 		int x = 0, y = 0;
@@ -6448,8 +6405,6 @@ DisplayServerX11::WindowID DisplayServerX11::_create_window(WindowMode p_mode, V
 	{
 		wd.x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo.screen), win_rect.position.x, win_rect.position.y, win_rect.size.width > 0 ? win_rect.size.width : 1, win_rect.size.height > 0 ? win_rect.size.height : 1, 0, visualInfo.depth, InputOutput, visualInfo.visual, valuemask, &windowAttributes);
 
-		wd.parent = RootWindow(x11_display, visualInfo.screen);
-
 		DEBUG_LOG_X11("CreateWindow window=%lu, parent: %lu \n", wd.x11_window, wd.parent);
 
 		if (p_parent_window) {

+ 0 - 2
platform/linuxbsd/x11/display_server_x11.h

@@ -164,7 +164,6 @@ class DisplayServerX11 : public DisplayServer {
 	struct WindowData {
 		Window x11_window;
 		Window x11_xim_window;
-		Window parent;
 		::XIC xic;
 		bool ime_active = false;
 		bool ime_in_progress = false;
@@ -201,7 +200,6 @@ class DisplayServerX11 : public DisplayServer {
 		bool resize_disabled = false;
 		bool no_min_btn = false;
 		bool no_max_btn = false;
-		Vector2i last_position_before_fs;
 		bool focused = true;
 		bool minimized = false;
 		bool maximized = false;