From ca31e4dc147997cae5abb75bf630acaaa30d2a8b Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Fri, 5 May 2017 13:55:51 +0200 Subject: wayland: Make sure we have a pending geometry If the client doesn't set a geometry using xdg_shell, we'll compute its geometry based on its surface and subsurfaces. Yet, we translate that as a window (re)size only when there is a pending geometry, that we don't have when we computed the geometry by ourself. Make sure we set the pending new geometry flag when computing the geometry when it actually changed. https://bugzilla.gnome.org/show_bug.cgi?id=782213 --- src/wayland/meta-wayland-xdg-shell.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index 5d3b97b..9791b9f 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -1272,11 +1272,19 @@ xdg_surface_role_commit (MetaWaylandSurfaceRole *surface_role, } else if (!priv->has_set_geometry) { + MetaRectangle new_geometry = { 0 }; + /* If the surface has never set any geometry, calculate * a default one unioning the surface and all subsurfaces together. */ + meta_wayland_surface_calculate_window_geometry (surface, - &priv->geometry, + &new_geometry, 0, 0); + if (!meta_rectangle_equal (&new_geometry, &priv->geometry)) + { + pending->has_new_geometry = TRUE; + priv->geometry = new_geometry; + } } } -- cgit v0.12 From 7f0f880fba6c1b066cfa3d36aa113cc0d46fadad Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Wed, 10 May 2017 08:59:53 +0200 Subject: wayland: Apply size hints regardless of geometry Previously we would bail out early in xdg_toplevel_role_commit() if no geometry change was set, ignoring the possible min/max size hints changes. But setting a min/max size hint without changing the geometry is perfectly valid, so we ought to apply the min/max changes regardless of a geometry change. https://bugzilla.gnome.org/show_bug.cgi?id=782213 --- src/wayland/meta-wayland-xdg-shell.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index 9791b9f..e840365 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -624,20 +624,18 @@ xdg_toplevel_role_commit (MetaWaylandSurfaceRole *surface_role, if (!window) return; - if (!pending->has_new_geometry) + if (pending->has_new_geometry) { - if (pending->dx != 0 || pending->dx != 0) - { - g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now."); - } - return; + window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface); + meta_window_wayland_move_resize (window, + &xdg_surface_priv->acked_configure_serial, + window_geometry, + pending->dx, pending->dy); + } + else if (pending->dx != 0 || pending->dx != 0) + { + g_warning ("XXX: Attach-initiated move without a new geometry. This is unimplemented right now."); } - - window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface); - meta_window_wayland_move_resize (window, - &xdg_surface_priv->acked_configure_serial, - window_geometry, - pending->dx, pending->dy); /* When we get to this point, we ought to have valid size hints */ if (pending->has_new_min_size || pending->has_new_max_size) -- cgit v0.12 From 7801df7ef6c721c403f472056eec13a5e7566888 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Wed, 10 May 2017 11:32:29 +0200 Subject: wayland: place window if maximized before placement If a client changes the state of a surface to issue a set_maximize, this causes apply_pending_state() to be called before mutter has placed the window. If the monitor on which the window is to be shown initially is different from the one where the pointer is placed, this causes the effect to be played at the wrong location before the window eventually reaches its location on another monitor. Force the window to be placed prior to change its state to maximized in xdg-shell so that mutter won't relocate the window afterwards. This also avoids sending an xdg_toplevel.configure with a size of 0x0 which would cause the client to initially draw its surface with some arbitrary size. https://bugzilla.gnome.org/show_bug.cgi?id=782183 https://bugzilla.gnome.org/show_bug.cgi?id=781353 --- src/wayland/meta-wayland-xdg-shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c index e840365..afe9546 100644 --- a/src/wayland/meta-wayland-xdg-shell.c +++ b/src/wayland/meta-wayland-xdg-shell.c @@ -348,6 +348,7 @@ xdg_toplevel_set_maximized (struct wl_client *client, { MetaWaylandSurface *surface = surface_from_xdg_toplevel_resource (resource); + meta_window_force_placement (surface->window); meta_window_maximize (surface->window, META_MAXIMIZE_BOTH); } -- cgit v0.12 From a8ceceed1a6d381cffc6b52f6d1422381ad34672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Fri, 21 Apr 2017 17:40:25 +0800 Subject: window/wayland: Don't try to resize window on tear down When terminating mutter running as a display server, don't try to resize maximized windows when unmanaging, as at this point, they will have no MetaWaylandSurface. Originally this was done instead of setting the net_wm_state to not mess with future window managers, but when we're a Wayland compositor, this does not matter. https://bugzilla.gnome.org/show_bug.cgi?id=782156 --- src/core/window.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/window.c b/src/core/window.c index e35ed08..f15392d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2957,7 +2957,11 @@ unmaximize_window_before_freeing (MetaWindow *window) window->rect = window->saved_rect; set_net_wm_state (window); } - else if (window->screen->closing) /* See bug #358042 */ + else if (window->screen->closing /* See bug #358042 */ +#ifdef HAVE_WAYLAND + && !meta_is_wayland_compositor () +#endif + ) { /* Do NOT update net_wm_state: this screen is closing, * it likely will be managed by another window manager -- cgit v0.12 From bbed0d80453a680711358bdfb55235bfac3057e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 31 May 2017 17:24:07 +0800 Subject: wayland/pointer: Use glib signals tracking focus surface Use the "destroy" MetaWaylandSurface signal instead of the wl_resource destroy signal for tracking the lifetime of the surface with pointer focus. As unsetting the focus may have side effects due to handlers of the "focus-surface-changed" signal, connect the signal after the default handler to make sure other clean up facilities have the chance deal with the surface destruction before we try to unset the focus. https://bugzilla.gnome.org/show_bug.cgi?id=783113 --- src/wayland/meta-wayland-pointer.c | 28 +++++++++++++++------------- src/wayland/meta-wayland-pointer.h | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 4578f3e..7c05912 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -247,14 +247,6 @@ sync_focus_surface (MetaWaylandPointer *pointer) } static void -pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) -{ - MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); - - meta_wayland_pointer_set_focus (pointer, NULL); -} - -static void meta_wayland_pointer_send_frame (MetaWaylandPointer *pointer, struct wl_resource *resource) { @@ -488,8 +480,6 @@ meta_wayland_pointer_enable (MetaWaylandPointer *pointer) g_hash_table_new_full (NULL, NULL, NULL, (GDestroyNotify) meta_wayland_pointer_client_free); - pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy; - pointer->cursor_surface = NULL; manager = clutter_device_manager_get_default (); @@ -815,6 +805,13 @@ meta_wayland_pointer_broadcast_leave (MetaWaylandPointer *pointer, meta_wayland_pointer_broadcast_frame (pointer); } +static void +focus_surface_destroyed (MetaWaylandSurface *surface, + MetaWaylandPointer *pointer) +{ + meta_wayland_pointer_set_focus (pointer, NULL); +} + void meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, MetaWaylandSurface *surface) @@ -838,7 +835,9 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, pointer->focus_client = NULL; } - wl_list_remove (&pointer->focus_surface_listener.link); + g_signal_handler_disconnect (pointer->focus_surface, + pointer->focus_surface_destroyed_handler_id); + pointer->focus_surface_destroyed_handler_id = 0; pointer->focus_surface = NULL; } @@ -848,8 +847,11 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, ClutterPoint pos; pointer->focus_surface = surface; - wl_resource_add_destroy_listener (pointer->focus_surface->resource, - &pointer->focus_surface_listener); + + pointer->focus_surface_destroyed_handler_id = + g_signal_connect_after (pointer->focus_surface, "destroy", + G_CALLBACK (focus_surface_destroyed), + pointer); clutter_input_device_get_coords (pointer->device, NULL, &pos); diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 547cd56..9f55590 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -71,7 +71,7 @@ struct _MetaWaylandPointer GHashTable *pointer_clients; MetaWaylandSurface *focus_surface; - struct wl_listener focus_surface_listener; + gulong focus_surface_destroyed_handler_id; guint32 focus_serial; guint32 click_serial; -- cgit v0.12 From 0f7c3f3678d3fa0a770daec34b522fc4a7346a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Wed, 31 May 2017 17:27:52 +0800 Subject: wayland/pointer: Track lifetime of current surface Clear the pointer->current when the surface is destroyed. https://bugzilla.gnome.org/show_bug.cgi?id=783113 --- src/wayland/meta-wayland-pointer.c | 48 +++++++++++++++++++++++++++++++++++--- src/wayland/meta-wayland-pointer.h | 1 + 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 7c05912..0cd2883 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -87,6 +87,10 @@ G_DEFINE_TYPE (MetaWaylandPointer, meta_wayland_pointer, META_TYPE_WAYLAND_INPUT_DEVICE) static void +meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface); + +static void meta_wayland_pointer_reset_grab (MetaWaylandPointer *pointer); static void @@ -510,6 +514,7 @@ meta_wayland_pointer_disable (MetaWaylandPointer *pointer) meta_wayland_pointer_cancel_grab (pointer); meta_wayland_pointer_reset_grab (pointer); meta_wayland_pointer_set_focus (pointer, NULL); + meta_wayland_pointer_set_current (pointer, NULL); g_clear_pointer (&pointer->pointer_clients, g_hash_table_unref); pointer->cursor_surface = NULL; @@ -538,10 +543,39 @@ count_buttons (const ClutterEvent *event) } static void +current_surface_destroyed (MetaWaylandSurface *surface, + MetaWaylandPointer *pointer) +{ + meta_wayland_pointer_set_current (pointer, NULL); +} + +static void +meta_wayland_pointer_set_current (MetaWaylandPointer *pointer, + MetaWaylandSurface *surface) +{ + if (pointer->current) + { + g_signal_handler_disconnect (pointer->current, + pointer->current_surface_destroyed_handler_id); + pointer->current = NULL; + } + + if (surface) + { + pointer->current = surface; + pointer->current_surface_destroyed_handler_id = + g_signal_connect (surface, "destroy", + G_CALLBACK (current_surface_destroyed), + pointer); + } +} + +static void repick_for_event (MetaWaylandPointer *pointer, const ClutterEvent *for_event) { ClutterActor *actor; + MetaWaylandSurface *surface; if (for_event) actor = clutter_event_get_source (for_event); @@ -549,10 +583,18 @@ repick_for_event (MetaWaylandPointer *pointer, actor = clutter_input_device_get_pointer_actor (pointer->device); if (META_IS_SURFACE_ACTOR_WAYLAND (actor)) - pointer->current = - meta_surface_actor_wayland_get_surface (META_SURFACE_ACTOR_WAYLAND (actor)); + { + MetaSurfaceActorWayland *actor_wayland = + META_SURFACE_ACTOR_WAYLAND (actor); + + surface = meta_surface_actor_wayland_get_surface (actor_wayland); + } else - pointer->current = NULL; + { + surface = NULL; + } + + meta_wayland_pointer_set_current (pointer, surface); sync_focus_surface (pointer); meta_wayland_pointer_update_cursor_surface (pointer); diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index 9f55590..87bc8c7 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -87,6 +87,7 @@ struct _MetaWaylandPointer ClutterInputDevice *device; MetaWaylandSurface *current; + gulong current_surface_destroyed_handler_id; guint32 button_count; }; -- cgit v0.12