[PATCH v4] xwm: let the shells decide the position of X windows
Derek Foreman
derekf at osg.samsung.com
Fri Dec 18 09:51:24 PST 2015
On 11/12/15 12:57 PM, Giulio Camuffo wrote:
> 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.
> Reviewed-by: Derek Foreman <derekf at osg.samsung.com>
Pushed
Thanks,
Derek
> ---
> v4: changed pos_dirty to bool instead of int
>
> 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 8a5aa91..a427088 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 dd873df..f6f92bd 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;
> + bool 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 = false;
> +
> 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 = false;
>
> geometry_reply = xcb_get_geometry_reply(wm->conn, geometry_cookie, NULL);
> /* technically we should use XRender and check the visual format's
> @@ -2316,9 +2285,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);
> @@ -2347,7 +2313,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);
> @@ -2438,8 +2403,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 = true;
> + 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;
>
>
More information about the wayland-devel
mailing list