summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2018-03-17 05:03:12 -0300
committerGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>2018-04-25 23:33:41 -0300
commit20176d0395294b9eeb7f0e28f1a1a35705fa0888 (patch)
tree5612322d0bd94720eb03351f9c109c861a19eb2b
parent762a3f89a99c42fff1022c5cbea9b1a5af42c646 (diff)
downloadmutter-20176d0395294b9eeb7f0e28f1a1a35705fa0888.tar.gz
wayland: Check if state and size changed before calling move_resize()
The current implementation of the XdgSurface v6 protocol does not check if the window changed before calling meta_window_wayland_move_resize(). The problem with this approach is that calling this function is a costly operation since we enter the compositor side. In GNOME Shell case, it is in JavaScript, which triggers a GJS trampoline. Calling this function on every mouse movement is naturally as terrible as it could be - and is exactly what happens now. This commit adds the necessary checks to only call move_resize() when the window actually changed, or when it needs to be updated. https://bugzilla.gnome.org/show_bug.cgi?id=780292 Issue: #78
-rw-r--r--src/wayland/meta-wayland-legacy-xdg-shell.c18
-rw-r--r--src/wayland/meta-wayland-xdg-shell.c18
2 files changed, 34 insertions, 2 deletions
diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.c b/src/wayland/meta-wayland-legacy-xdg-shell.c
index c43bcff3e..cfc0dfedd 100644
--- a/src/wayland/meta-wayland-legacy-xdg-shell.c
+++ b/src/wayland/meta-wayland-legacy-xdg-shell.c
@@ -585,6 +585,17 @@ is_new_size_hints_valid (MetaWindow *window,
(new_max_height == 0 || new_min_height <= new_max_height));
}
+static inline gboolean
+did_geometry_change (MetaWaylandZxdgSurfaceV6 *xdg_surface,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandZxdgSurfaceV6Private *priv =
+ meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
+
+ return pending->has_new_geometry &&
+ !meta_rectangle_equal (&priv->geometry, &pending->new_geometry);
+}
+
static void
meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
@@ -600,6 +611,11 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window = surface->window;
MetaRectangle window_geometry;
+ gboolean geometry_changed;
+
+ /* This check must happen before chaining up, otherwise the new geometry
+ * is applied and it'll always return FALSE. */
+ geometry_changed = did_geometry_change (xdg_surface, pending);
surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
@@ -618,7 +634,7 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
if (!window)
return;
- if (pending->has_new_geometry)
+ if (geometry_changed || meta_window_wayland_needs_move_resize (window))
{
window_geometry =
meta_wayland_zxdg_surface_v6_get_window_geometry (xdg_surface);
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
index c750d3f66..a08520d31 100644
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ b/src/wayland/meta-wayland-xdg-shell.c
@@ -608,6 +608,17 @@ is_new_size_hints_valid (MetaWindow *window,
(new_max_height == 0 || new_min_height <= new_max_height));
}
+static inline gboolean
+did_geometry_change (MetaWaylandXdgSurface *xdg_surface,
+ MetaWaylandPendingState *pending)
+{
+ MetaWaylandXdgSurfacePrivate *priv =
+ meta_wayland_xdg_surface_get_instance_private (xdg_surface);
+
+ return pending->has_new_geometry &&
+ !meta_rectangle_equal (&priv->geometry, &pending->new_geometry);
+}
+
static void
meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
MetaWaylandPendingState *pending)
@@ -621,6 +632,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window;
MetaRectangle window_geometry;
+ gboolean geometry_changed;
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
{
@@ -630,6 +642,10 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
window = surface->window;
+ /* This check must happen before chaining up, otherwise the new geometry
+ * is applied and it'll always return FALSE. */
+ geometry_changed = did_geometry_change (xdg_surface, pending);
+
surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
surface_role_class->commit (surface_role, pending);
@@ -643,7 +659,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
if (!pending->newly_attached)
return;
- if (pending->has_new_geometry)
+ if (geometry_changed || meta_window_wayland_needs_move_resize (window))
{
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
meta_window_wayland_move_resize (window,