[PATCH weston v2 05/24] shell: implement set_xwayland_position

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


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

Store the initial xwayland position explicitly in struct shell_surface.
New variables are needed, because e.g. saved_x, saved_y are the view
position, and to compute that we need the window geometry, which is not
available before the first commit, so it's not available at
set_xwayland_position() time.

Regression: kcachegrind (Qt 4, X11), the first menu invocation will
slightly misplace the menu if the window has not been manually moved.

Problem: geometry is not taken into account due to a race between XWM
drawing decorations and Xwayland committing the first buffer.

Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
Reviewed-by: Quentin Glidic <sardemff7+git at sardemff7.net>
---
 desktop-shell/shell.c | 37 +++++++++++++++++++++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 3913f95..9b39933 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -134,6 +134,12 @@ struct shell_surface {
 		bool lowered;
 	} state;
 
+	struct {
+		bool is_set;
+		int32_t x;
+		int32_t y;
+	} xwayland;
+
 	int focus_count;
 
 	bool destroying;
@@ -2385,6 +2391,22 @@ set_maximized_position(struct desktop_shell *shell,
 }
 
 static void
+set_position_from_xwayland(struct shell_surface *shsurf)
+{
+	struct weston_geometry geometry;
+	float x;
+	float y;
+
+	assert(shsurf->xwayland.is_set);
+
+	geometry = weston_desktop_surface_get_geometry(shsurf->desktop_surface);
+	x = shsurf->xwayland.x - geometry.x;
+	y = shsurf->xwayland.y - geometry.y;
+
+	weston_view_set_position(shsurf->view, x, y);
+}
+
+static void
 map(struct desktop_shell *shell, struct shell_surface *shsurf,
     int32_t sx, int32_t sy)
 {
@@ -2399,6 +2421,8 @@ map(struct desktop_shell *shell, struct shell_surface *shsurf,
 		shell_map_fullscreen(shsurf);
 	} else if (shsurf->state.maximized) {
 		set_maximized_position(shell, shsurf);
+	} else if (shsurf->xwayland.is_set) {
+		set_position_from_xwayland(shsurf);
 	} else {
 		weston_view_set_initial_position(shsurf->view, shell);
 	}
@@ -2783,6 +2807,18 @@ desktop_surface_pong(struct weston_desktop_client *desktop_client,
 	end_busy_cursor(shell->compositor, desktop_client);
 }
 
+static void
+desktop_surface_set_xwayland_position(struct weston_desktop_surface *surface,
+				      int32_t x, int32_t y, void *shell_)
+{
+	struct shell_surface *shsurf =
+		weston_desktop_surface_get_user_data(surface);
+
+	shsurf->xwayland.x = x;
+	shsurf->xwayland.y = y;
+	shsurf->xwayland.is_set = true;
+}
+
 static const struct weston_desktop_api shell_desktop_api = {
 	.struct_size = sizeof(struct weston_desktop_api),
 	.surface_added = desktop_surface_added,
@@ -2795,6 +2831,7 @@ static const struct weston_desktop_api shell_desktop_api = {
 	.minimized_requested = desktop_surface_minimized_requested,
 	.ping_timeout = desktop_surface_ping_timeout,
 	.pong = desktop_surface_pong,
+	.set_xwayland_position = desktop_surface_set_xwayland_position,
 };
 
 /* ************************ *
-- 
2.10.2



More information about the wayland-devel mailing list