mirror of
https://github.com/brl/mutter.git
synced 2024-12-27 05:12:15 +00:00
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
This commit is contained in:
parent
1c00cd5ca3
commit
2872bb1f2a
@ -585,6 +585,17 @@ is_new_size_hints_valid (MetaWindow *window,
|
|||||||
(new_max_height == 0 || new_min_height <= new_max_height));
|
(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
|
static void
|
||||||
meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandPendingState *pending)
|
MetaWaylandPendingState *pending)
|
||||||
@ -600,6 +611,11 @@ meta_wayland_zxdg_toplevel_v6_commit (MetaWaylandSurfaceRole *surface_role,
|
|||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWindow *window = surface->window;
|
MetaWindow *window = surface->window;
|
||||||
MetaRectangle window_geometry;
|
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 =
|
surface_role_class =
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_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)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pending->has_new_geometry)
|
if (geometry_changed || meta_window_wayland_needs_move_resize (window))
|
||||||
{
|
{
|
||||||
window_geometry =
|
window_geometry =
|
||||||
meta_wayland_zxdg_surface_v6_get_window_geometry (xdg_surface);
|
meta_wayland_zxdg_surface_v6_get_window_geometry (xdg_surface);
|
||||||
|
@ -608,6 +608,17 @@ is_new_size_hints_valid (MetaWindow *window,
|
|||||||
(new_max_height == 0 || new_min_height <= new_max_height));
|
(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
|
static void
|
||||||
meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
||||||
MetaWaylandPendingState *pending)
|
MetaWaylandPendingState *pending)
|
||||||
@ -621,6 +632,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
|||||||
meta_wayland_surface_role_get_surface (surface_role);
|
meta_wayland_surface_role_get_surface (surface_role);
|
||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaRectangle window_geometry;
|
MetaRectangle window_geometry;
|
||||||
|
gboolean geometry_changed;
|
||||||
|
|
||||||
if (!surface->buffer_ref.buffer && xdg_surface_priv->first_buffer_attached)
|
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;
|
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 =
|
surface_role_class =
|
||||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
|
||||||
surface_role_class->commit (surface_role, pending);
|
surface_role_class->commit (surface_role, pending);
|
||||||
@ -643,7 +659,7 @@ meta_wayland_xdg_toplevel_commit (MetaWaylandSurfaceRole *surface_role,
|
|||||||
if (!pending->newly_attached)
|
if (!pending->newly_attached)
|
||||||
return;
|
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);
|
window_geometry = meta_wayland_xdg_surface_get_window_geometry (xdg_surface);
|
||||||
meta_window_wayland_move_resize (window,
|
meta_window_wayland_move_resize (window,
|
||||||
|
Loading…
Reference in New Issue
Block a user