The xwm used to automatically send to Xwayland the position of X windows
when that changed, using the x,y of the primary view of the surface.
This works fine for the desktop shell but less so for others.
This patch adds a 'send_position' vfunc to the weston_shell_client that
the shell will call when it wants to let Xwayland know what the position
of a window is.
The logic used by the desktop-shell for that is exactly the same the xwm
used to have.
---

v3: rebased, no actual change

 desktop-shell/shell.c     | 40 +++++++++++++++++++-------
 desktop-shell/shell.h     |  1 +
 src/compositor.h          |  4 +--
 xwayland/window-manager.c | 72 +++++++++++++++++++++--------------------------
 xwayland/xwayland.h       |  1 -
 5 files changed, 64 insertions(+), 54 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index 780902d..85664c6 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -1813,7 +1813,8 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
 }
 
 static const struct weston_shell_client shell_client = {
-       send_configure
+       send_configure,
+       NULL
 };
 
 static void
@@ -3704,12 +3705,6 @@ create_shell_surface(void *shell, struct weston_surface 
*surface,
        return create_common_surface(NULL, shell, surface, client);
 }
 
-static struct weston_view *
-get_primary_view(void *shell, struct shell_surface *shsurf)
-{
-       return shsurf->view;
-}
-
 static void
 shell_get_shell_surface(struct wl_client *client,
                        struct wl_resource *resource,
@@ -3995,7 +3990,8 @@ xdg_send_configure(struct weston_surface *surface,
 }
 
 static const struct weston_shell_client xdg_client = {
-       xdg_send_configure
+       xdg_send_configure,
+       NULL
 };
 
 static void
@@ -4119,7 +4115,8 @@ xdg_popup_send_configure(struct weston_surface *surface,
 }
 
 static const struct weston_shell_client xdg_popup_client = {
-       xdg_popup_send_configure
+       xdg_popup_send_configure,
+       NULL
 };
 
 static struct shell_surface *
@@ -5412,6 +5409,27 @@ wake_handler(struct wl_listener *listener, void *data)
 }
 
 static void
+transform_handler(struct wl_listener *listener, void *data)
+{
+       struct weston_surface *surface = data;
+       struct shell_surface *shsurf = get_shell_surface(surface);
+       struct weston_view *view;;
+       int x, y;
+
+       if (!shsurf || !shsurf->client->send_position)
+               return;
+
+       view = shsurf->view;
+       if (!view || !weston_view_is_mapped(view))
+               return;
+
+       x = view->geometry.x;
+       y = view->geometry.y;
+
+       shsurf->client->send_position(surface, x, y);
+}
+
+static void
 center_on_output(struct weston_view *view, struct weston_output *output)
 {
        int32_t surf_x, surf_y, width, height;
@@ -6379,6 +6397,7 @@ shell_destroy(struct wl_listener *listener, void *data)
 
        wl_list_remove(&shell->idle_listener.link);
        wl_list_remove(&shell->wake_listener.link);
+       wl_list_remove(&shell->transform_listener.link);
 
        text_backend_destroy(shell->text_backend);
        input_panel_destroy(shell);
@@ -6520,10 +6539,11 @@ module_init(struct weston_compositor *ec,
        wl_signal_add(&ec->idle_signal, &shell->idle_listener);
        shell->wake_listener.notify = wake_handler;
        wl_signal_add(&ec->wake_signal, &shell->wake_listener);
+       shell->transform_listener.notify = transform_handler;
+       wl_signal_add(&ec->transform_signal, &shell->transform_listener);
 
        ec->shell_interface.shell = shell;
        ec->shell_interface.create_shell_surface = create_shell_surface;
-       ec->shell_interface.get_primary_view = get_primary_view;
        ec->shell_interface.set_toplevel = set_toplevel;
        ec->shell_interface.set_transient = set_transient;
        ec->shell_interface.set_fullscreen = shell_interface_set_fullscreen;
diff --git a/desktop-shell/shell.h b/desktop-shell/shell.h
index 2ef23f4..c55a225 100644
--- a/desktop-shell/shell.h
+++ b/desktop-shell/shell.h
@@ -121,6 +121,7 @@ struct desktop_shell {
 
        struct wl_listener idle_listener;
        struct wl_listener wake_listener;
+       struct wl_listener transform_listener;
        struct wl_listener destroy_listener;
        struct wl_listener show_input_panel_listener;
        struct wl_listener hide_input_panel_listener;
diff --git a/src/compositor.h b/src/compositor.h
index 1d04481..56713cc 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -86,6 +86,7 @@ struct weston_mode {
 
 struct weston_shell_client {
        void (*send_configure)(struct weston_surface *surface, int32_t width, 
int32_t height);
+       void (*send_position)(struct weston_surface *surface, int32_t x, 
int32_t y);
 };
 
 struct weston_shell_interface {
@@ -94,9 +95,6 @@ struct weston_shell_interface {
        struct shell_surface *(*create_shell_surface)(void *shell,
                                                      struct weston_surface 
*surface,
                                                      const struct 
weston_shell_client *client);
-       struct weston_view *(*get_primary_view)(void *shell,
-                                               struct shell_surface *shsurf);
-
        void (*set_toplevel)(struct shell_surface *shsurf);
 
        void (*set_transient)(struct shell_surface *shsurf,
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 9398d24..6ea3a88 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -145,6 +145,7 @@ struct weston_wm_window {
        xcb_atom_t type;
        int width, height;
        int x, y;
+       int pos_dirty;
        int saved_width, saved_height;
        int decorate;
        int override_redirect;
@@ -692,6 +693,8 @@ weston_wm_handle_configure_notify(struct weston_wm *wm, 
xcb_generic_event_t *eve
 
        window->x = configure_notify->x;
        window->y = configure_notify->y;
+       window->pos_dirty = 0;
+
        if (window->override_redirect) {
                window->width = configure_notify->width;
                window->height = configure_notify->height;
@@ -808,41 +811,6 @@ weston_wm_window_activate(struct wl_listener *listener, 
void *data)
 
 }
 
-static void
-weston_wm_window_transform(struct wl_listener *listener, void *data)
-{
-       struct weston_surface *surface = data;
-       struct weston_wm_window *window = get_wm_window(surface);
-       struct weston_wm *wm =
-               container_of(listener, struct weston_wm, transform_listener);
-       struct weston_view *view;
-       struct weston_shell_interface *shell_interface =
-               &wm->server->compositor->shell_interface;
-       uint32_t mask, values[2];
-
-       if (!window || !wm || !window->shsurf)
-               return;
-
-       if (!shell_interface->get_primary_view)
-               return;
-
-       view = shell_interface->get_primary_view(shell_interface->shell,
-                                                window->shsurf);
-
-       if (!view || !weston_view_is_mapped(view))
-               return;
-
-       if (window->x != view->geometry.x ||
-           window->y != view->geometry.y) {
-               values[0] = view->geometry.x;
-               values[1] = view->geometry.y;
-               mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
-
-               xcb_configure_window(wm->conn, window->frame_id, mask, values);
-               xcb_flush(wm->conn);
-       }
-}
-
 #define ICCCM_WITHDRAWN_STATE  0
 #define ICCCM_NORMAL_STATE     1
 #define ICCCM_ICONIC_STATE     3
@@ -1226,6 +1194,7 @@ weston_wm_window_create(struct weston_wm *wm,
        window->height = height;
        window->x = x;
        window->y = y;
+       window->pos_dirty = 0;
 
        geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, 
NULL);
        /* technically we should use XRender and check the visual format's
@@ -2318,9 +2287,6 @@ weston_wm_create(struct weston_xserver *wxs, int fd)
        wm->activate_listener.notify = weston_wm_window_activate;
        wl_signal_add(&wxs->compositor->activate_signal,
                      &wm->activate_listener);
-       wm->transform_listener.notify = weston_wm_window_transform;
-       wl_signal_add(&wxs->compositor->transform_signal,
-                     &wm->transform_listener);
        wm->kill_listener.notify = weston_wm_kill_client;
        wl_signal_add(&wxs->compositor->kill_signal,
                      &wm->kill_listener);
@@ -2349,7 +2315,6 @@ weston_wm_destroy(struct weston_wm *wm)
        wl_list_remove(&wm->selection_listener.link);
        wl_list_remove(&wm->activate_listener.link);
        wl_list_remove(&wm->kill_listener.link);
-       wl_list_remove(&wm->transform_listener.link);
        wl_list_remove(&wm->create_surface_listener.link);
 
        free(wm);
@@ -2440,8 +2405,35 @@ send_configure(struct weston_surface *surface, int32_t 
width, int32_t height)
                                       weston_wm_window_configure, window);
 }
 
+static void
+send_position(struct weston_surface *surface, int32_t x, int32_t y)
+{
+       struct weston_wm_window *window = get_wm_window(surface);
+       struct weston_wm *wm;
+       uint32_t mask, values[2];
+
+       if (!window || !window->wm)
+               return;
+
+       wm = window->wm;
+       /* We use pos_dirty to tell whether a configure message is in flight.
+        * This is needed in case we send two configure events in a very
+        * short time, since window->x/y is set in after a roundtrip, hence
+        * we cannot just check if the current x and y are different. */
+       if (window->x != x || window->y != y || window->pos_dirty) {
+               window->pos_dirty = 1;
+               values[0] = x;
+               values[1] = y;
+               mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
+
+               xcb_configure_window(wm->conn, window->frame_id, mask, values);
+               xcb_flush(wm->conn);
+       }
+}
+
 static const struct weston_shell_client shell_client = {
-       send_configure
+       send_configure,
+       send_position
 };
 
 static int
diff --git a/xwayland/xwayland.h b/xwayland/xwayland.h
index bace079..b1fd904 100644
--- a/xwayland/xwayland.h
+++ b/xwayland/xwayland.h
@@ -70,7 +70,6 @@ struct weston_wm {
        xcb_colormap_t colormap;
        struct wl_listener create_surface_listener;
        struct wl_listener activate_listener;
-       struct wl_listener transform_listener;
        struct wl_listener kill_listener;
        struct wl_list unpaired_window_list;
 
-- 
2.6.2

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to