[PATCH weston v2 04/24] xwayland: detect initially positioned X11 windows

Pekka Paalanen ppaalanen at gmail.com
Wed Dec 21 14:40:02 UTC 2016


From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>

X11 applications expect -geometry command line option to work for
setting the initial window position, but currently this does not work.

During map, detect X11 windows that set an explicit position. This works
by heuristics: if window position is not 0,0 then it is explicitly
positioned. Legacy fullscreen windows are also at 0,0 but these are
detected earlier.

Explicitly store the window position at map request time to detect
client-positioned windows, and use it as the suggested initial position.
weston_wm_window::x and y have been overwritten due to reparenting when
we eventually need the initial position.

This patch requires that the new set_toplevel_with_position() hook is
implemented in the shell.

Note that this patch is about positioning xwayland toplevels, not
override-redirect windows which are already handled.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Reviewed-by: Quentin Glidic <sardemff7+git at sardemff7.net>
---
 xwayland/window-manager.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 1830864..10bb390 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -35,6 +35,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <signal.h>
+#include <limits.h>
 #include <X11/Xcursor/Xcursor.h>
 #include <linux/input.h>
 
@@ -146,8 +147,11 @@ struct weston_wm_window {
 	uint32_t protocols;
 	xcb_atom_t type;
 	int width, height;
-	int x, y;
+	int x;
+	int y;
 	bool pos_dirty;
+	int map_request_x;
+	int map_request_y;
 	int saved_width, saved_height;
 	int decorate;
 	int override_redirect;
@@ -963,12 +967,16 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
 
 	weston_wm_window_read_properties(window);
 
+	window->map_request_x = window->x;
+	window->map_request_y = window->y;
+
 	if (window->frame_id == XCB_WINDOW_NONE)
 		weston_wm_window_create_frame(window);
 
 	wm_log("XCB_MAP_REQUEST (window %d, %p, frame %d, %dx%d @ %d,%d)\n",
 	       window->id, window, window->frame_id,
-	       window->width, window->height, window->x, window->y);
+	       window->width, window->height,
+	       window->map_request_x, window->map_request_y);
 
 	weston_wm_window_set_wm_state(window, ICCCM_NORMAL_STATE);
 	weston_wm_window_set_net_wm_state(window);
@@ -1206,6 +1214,8 @@ weston_wm_window_create(struct weston_wm *wm,
 	window->x = x;
 	window->y = y;
 	window->pos_dirty = false;
+	window->map_request_x = INT_MIN; /* out of range for valid positions */
+	window->map_request_y = INT_MIN; /* out of range for valid positions */
 
 	geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
 	/* technically we should use XRender and check the visual format's
@@ -2500,6 +2510,17 @@ legacy_fullscreen(struct weston_wm *wm,
 }
 
 static bool
+weston_wm_window_is_positioned(struct weston_wm_window *window)
+{
+	if (window->map_request_x == INT_MIN ||
+	    window->map_request_y == INT_MIN)
+		weston_log("XWM warning: win %d did not see map request\n",
+			   window->id);
+
+	return window->map_request_x != 0 || window->map_request_y != 0;
+}
+
+static bool
 weston_wm_window_type_inactive(struct weston_wm_window *window)
 {
 	struct weston_wm *wm = window->wm;
@@ -2592,6 +2613,10 @@ xserver_map_shell_surface(struct weston_wm_window *window,
 			xwayland_interface->set_xwayland(window->shsurf,
 							 window->x,
 							 window->y);
+		} else if (weston_wm_window_is_positioned(window)) {
+			xwayland_interface->set_toplevel_with_position(window->shsurf,
+								       window->map_request_x,
+								       window->map_request_y);
 		} else {
 			xwayland_interface->set_toplevel(window->shsurf);
 		}
-- 
2.10.2



More information about the wayland-devel mailing list