[PATCH weston] xwayland: Forward global position to X
Kristian Høgsberg
hoegsberg at gmail.com
Fri Jun 14 12:42:39 PDT 2013
On Wed, Jun 12, 2013 at 03:43:21PM -0300, Tiago Vignatti wrote:
> xeyes works as expected now. subwindows are popped also as expected. This
> patch should fix the following:
>
> https://bugs.freedesktop.org/show_bug.cgi?id=59983
>
> Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
> ---
>
> Hey guys,
>
> This fix the problem mentioned above but exposes something that was already
> buggy before: XWM (and probably all X clients) is getting wrong EnterNotify,
> setting wrong cursor. This happens sometimes only.
Thanks Tiago, that patch looks good. I applied it with one change: I
renamed position_signal to transform_signal and emit it from the
bottom of weston_surface_update_transform(). This way, all weston
surfaces will emit this signal whenever they update their transform.
> To check the problem, I've added a printf in weston_wm_handle_enter and set
> WAYLAND_DEBUG=1. You will see that the coordinates wl_pointer_enter comes to
> XWayland vary from what it sends along to the X clients. It's not all the
> time as I said, so probably there's a race between the two protocols. Another
> way to check is clobber one window with another, leaving the cursor right on
> the decoration border where it should change the icon if you alternate the
> windows with ctrl+tab:
>
> http://i.troll.ws/4c2cbb1b.png
>
> Grab cursor not being set all the times is another way to see the bug.
>
> I hope this help someone else find the problem. I'm not continuing the
> investigations here in principle.
Ok. I see the problem - you can also try to put xev below a wayland
surface and then alt-tab to xev. xev gets the correct enter event,
but it then gets a spurious leave event. It doesn't seem like it's
something that this patch introduces though.
Kristian
> Tiago
>
>
> src/compositor.c | 1 +
> src/compositor.h | 5 +++
> src/shell.c | 30 ++++++++++++++++-
> src/xwayland/window-manager.c | 73 ++++++++++++++++++++++++++---------------
> src/xwayland/xwayland.h | 2 +-
> 5 files changed, 83 insertions(+), 28 deletions(-)
>
> diff --git a/src/compositor.c b/src/compositor.c
> index 099600d..f019441 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -2777,6 +2777,7 @@ weston_compositor_init(struct weston_compositor *ec,
> ec->wl_display = display;
> wl_signal_init(&ec->destroy_signal);
> wl_signal_init(&ec->activate_signal);
> + wl_signal_init(&ec->position_signal);
> wl_signal_init(&ec->kill_signal);
> wl_signal_init(&ec->idle_signal);
> wl_signal_init(&ec->wake_signal);
> diff --git a/src/compositor.h b/src/compositor.h
> index 22700b7..bcca468 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -94,6 +94,8 @@ struct weston_shell_interface {
> uint32_t method,
> uint32_t framerate,
> struct weston_output *output);
> + void (*set_xwayland)(struct shell_surface *shsurf,
> + int x, int y, uint32_t flags);
> int (*move)(struct shell_surface *shsurf, struct weston_seat *ws);
> int (*resize)(struct shell_surface *shsurf,
> struct weston_seat *ws, uint32_t edges);
> @@ -502,7 +504,10 @@ struct weston_compositor {
> struct weston_shell_interface shell_interface;
> struct weston_config *config;
>
> + /* xwayland */
> struct wl_signal activate_signal;
> + struct wl_signal position_signal;
> +
> struct wl_signal kill_signal;
> struct wl_signal idle_signal;
> struct wl_signal wake_signal;
> diff --git a/src/shell.c b/src/shell.c
> index 3d10eef..d9038b2 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -171,7 +171,8 @@ enum shell_surface_type {
> SHELL_SURFACE_TRANSIENT,
> SHELL_SURFACE_FULLSCREEN,
> SHELL_SURFACE_MAXIMIZED,
> - SHELL_SURFACE_POPUP
> + SHELL_SURFACE_POPUP,
> + SHELL_SURFACE_XWAYLAND
> };
>
> struct ping_timer {
> @@ -340,9 +341,13 @@ shell_grab_start(struct shell_grab *grab,
> static void
> shell_grab_end(struct shell_grab *grab)
> {
> + struct weston_compositor *compositor =
> + grab->shsurf->surface->compositor;
> +
> if (grab->shsurf)
> wl_list_remove(&grab->shsurf_destroy_listener.link);
>
> + wl_signal_emit(&compositor->position_signal, grab->shsurf->surface);
> weston_pointer_end_grab(grab->pointer);
> }
>
> @@ -1581,6 +1586,7 @@ reset_shell_surface_type(struct shell_surface *surface)
> case SHELL_SURFACE_TOPLEVEL:
> case SHELL_SURFACE_TRANSIENT:
> case SHELL_SURFACE_POPUP:
> + case SHELL_SURFACE_XWAYLAND:
> break;
> }
>
> @@ -1622,6 +1628,11 @@ set_surface_type(struct shell_surface *shsurf)
> }
> break;
>
> + case SHELL_SURFACE_XWAYLAND:
> + weston_surface_set_position(surface, shsurf->transient.x,
> + shsurf->transient.y);
> + break;
> +
> default:
> break;
> }
> @@ -1925,6 +1936,16 @@ shell_surface_set_fullscreen(struct wl_client *client,
> set_fullscreen(shsurf, method, framerate, output);
> }
>
> +static void
> +set_xwayland(struct shell_surface *shsurf, int x, int y, uint32_t flags)
> +{
> + /* XXX: using the same fields for transient type */
> + shsurf->transient.x = x;
> + shsurf->transient.y = y;
> + shsurf->transient.flags = flags;
> + shsurf->next_type = SHELL_SURFACE_XWAYLAND;
> +}
> +
> static const struct weston_pointer_grab_interface popup_grab_interface;
>
> static void
> @@ -3399,6 +3420,7 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
> case SHELL_SURFACE_FULLSCREEN:
> case SHELL_SURFACE_NONE:
> break;
> + case SHELL_SURFACE_XWAYLAND:
> default:
> ws = get_current_workspace(shell);
> wl_list_insert(&ws->layer.surface_list, &surface->layer_link);
> @@ -3412,6 +3434,8 @@ map(struct desktop_shell *shell, struct weston_surface *surface,
> }
>
> switch (surface_type) {
> + /* XXX: xwayland's using the same fields for transient type */
> + case SHELL_SURFACE_XWAYLAND:
> case SHELL_SURFACE_TRANSIENT:
> if (shsurf->transient.flags ==
> WL_SHELL_SURFACE_TRANSIENT_INACTIVE)
> @@ -3490,6 +3514,7 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32
> {
> struct shell_surface *shsurf = get_shell_surface(es);
> struct desktop_shell *shell = shsurf->shell;
> + struct weston_compositor *compositor = shsurf->surface->compositor;
>
> int type_changed = 0;
>
> @@ -3521,6 +3546,8 @@ shell_surface_configure(struct weston_surface *es, int32_t sx, int32_t sy, int32
> es->geometry.y + to_y - from_y,
> width, height);
> }
> +
> + wl_signal_emit(&compositor->position_signal, shsurf->surface);
> }
>
> static void launch_desktop_shell_process(void *data);
> @@ -4434,6 +4461,7 @@ module_init(struct weston_compositor *ec,
> ec->shell_interface.set_toplevel = set_toplevel;
> ec->shell_interface.set_transient = set_transient;
> ec->shell_interface.set_fullscreen = set_fullscreen;
> + ec->shell_interface.set_xwayland = set_xwayland;
> ec->shell_interface.move = surface_move;
> ec->shell_interface.resize = surface_resize;
>
> diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
> index 366f2e0..466f049 100644
> --- a/src/xwayland/window-manager.c
> +++ b/src/xwayland/window-manager.c
> @@ -584,12 +584,49 @@ weston_wm_window_activate(struct wl_listener *listener, void *data)
> if (wm->focus_window)
> weston_wm_window_schedule_repaint(wm->focus_window);
> wm->focus_window = window;
> - if (window)
> - wm->focus_latest = window;
> if (wm->focus_window)
> weston_wm_window_schedule_repaint(wm->focus_window);
> }
>
> +static void
> +weston_wm_window_position(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, position_listener);
> + struct weston_output *output = surface->output;
> + uint32_t mask, values[2];
> + float sxf, syf;
> + int sx, sy;
> + static int old_sx = -1, old_sy = -1;
> +
> + if (!window || !wm)
> + return;
> +
> + if (!weston_surface_is_mapped(surface))
> + return;
> +
> + weston_surface_to_global_float(surface, output->x, output->y,
> + &sxf, &syf);
> +
> + sx = (int) sxf;
> + sy = (int) syf;
> +
> + if (old_sx == sx && old_sy == sy)
> + return;
> +
> + values[0] = sx;
> + values[1] = sy;
> + mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y;
> +
> + xcb_configure_window(wm->conn, window->frame_id, mask, values);
> + xcb_flush(wm->conn);
> +
> + old_sx = sx;
> + old_sy = sy;
> +}
> +
> static int
> our_resource(struct weston_wm *wm, uint32_t id)
> {
> @@ -1675,6 +1712,9 @@ weston_wm_create(struct weston_xserver *wxs)
> wm->activate_listener.notify = weston_wm_window_activate;
> wl_signal_add(&wxs->compositor->activate_signal,
> &wm->activate_listener);
> + wm->position_listener.notify = weston_wm_window_position;
> + wl_signal_add(&wxs->compositor->position_signal,
> + &wm->position_listener);
> wm->kill_listener.notify = weston_wm_kill_client;
> wl_signal_add(&wxs->compositor->kill_signal,
> &wm->kill_listener);
> @@ -1799,9 +1839,7 @@ xserver_map_shell_surface(struct weston_wm *wm,
> {
> struct weston_shell_interface *shell_interface =
> &wm->server->compositor->shell_interface;
> - struct weston_wm_window *parent;
> struct theme *t = window->wm->theme;
> - int parent_id, x = 0, y = 0;
>
> if (!shell_interface->create_shell_surface)
> return;
> @@ -1819,31 +1857,14 @@ xserver_map_shell_surface(struct weston_wm *wm,
> 0, NULL);
> return;
> } else if (!window->override_redirect) {
> - /* ICCCM 4.1.1 */
> shell_interface->set_toplevel(window->shsurf);
> return;
> + } else {
> + shell_interface->set_xwayland(window->shsurf,
> + window->x + t->margin,
> + window->y + t->margin,
> + WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
> }
> -
> - /* not all non-toplevel has transient_for set. So we need this
> - * workaround to guess a parent that will determine the relative
> - * position of the transient surface */
> - if (!window->transient_for)
> - parent_id = wm->focus_latest->id;
> - else
> - parent_id = window->transient_for->id;
> -
> - parent = hash_table_lookup(wm->window_hash, parent_id);
> -
> - /* non-decorated and non-toplevel windows, e.g. sub-menus */
> - if (!parent->decorate && parent->override_redirect) {
> - x = parent->x + t->margin;
> - y = parent->y + t->margin;
> - }
> -
> - shell_interface->set_transient(window->shsurf, parent->surface,
> - window->x + t->margin - x,
> - window->y + t->margin - y,
> - WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
> }
>
> static void
> diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h
> index 9151cce..1b957ca 100644
> --- a/src/xwayland/xwayland.h
> +++ b/src/xwayland/xwayland.h
> @@ -53,7 +53,6 @@ struct weston_wm {
> struct weston_xserver *server;
> xcb_window_t wm_window;
> struct weston_wm_window *focus_window;
> - struct weston_wm_window *focus_latest;
> struct theme *theme;
> xcb_cursor_t *cursors;
> int last_cursor;
> @@ -61,6 +60,7 @@ struct weston_wm {
> xcb_visualid_t visual_id;
> xcb_colormap_t colormap;
> struct wl_listener activate_listener;
> + struct wl_listener position_listener;
> struct wl_listener kill_listener;
>
> xcb_window_t selection_window;
> --
> 1.7.9.5
>
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list