window-actor: Handle geometry scale
Geometry scale is applied to each surface individually, using Clutter scales, and not only this breaks subsurfaces, it also pollutes the toolkit and makes the actor tree slightly too fragile. If GNOME Shell mistakenly tries to set the actor scale of any of these surfaces, for example, various artifacts might happen. Move geometry scale handling to MetaWindowActor. It is applied as a child transform operation, so that the Clutter-managed scale properties are left untouched. In the future where the entirety of the window is managed by a ClutterContent itself, the geometry scale will be applied directly into the transform matrix of MetaWindowActor. However, doing that now would break the various ClutterClones used by GNOME Shell, so the child transform is an acceptable compromise during this transition. https://gitlab.gnome.org/GNOME/mutter/merge_requests/409
This commit is contained in:
parent
c747be84d9
commit
fb9e8768a3
6 changed files with 78 additions and 22 deletions
|
@ -22,6 +22,7 @@
|
|||
#include "clutter/clutter.h"
|
||||
#include "compositor/meta-cullable.h"
|
||||
#include "compositor/meta-shaped-texture-private.h"
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
#include "compositor/region-utils.h"
|
||||
#include "meta/meta-shaped-texture.h"
|
||||
|
||||
|
@ -76,7 +77,6 @@ effective_unobscured_region (MetaSurfaceActor *surface_actor)
|
|||
return priv->unobscured_region;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
set_unobscured_region (MetaSurfaceActor *surface_actor,
|
||||
cairo_region_t *unobscured_region)
|
||||
|
@ -250,18 +250,21 @@ meta_surface_actor_cull_out (MetaCullable *cullable,
|
|||
|
||||
if (opacity == 0xff)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
cairo_region_t *scaled_opaque_region;
|
||||
cairo_region_t *opaque_region;
|
||||
double geometry_scale;
|
||||
int geometry_scale = 1;
|
||||
|
||||
opaque_region = meta_shaped_texture_get_opaque_region (priv->texture);
|
||||
|
||||
if (!opaque_region)
|
||||
return;
|
||||
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (surface_actor),
|
||||
&geometry_scale,
|
||||
NULL);
|
||||
window_actor =
|
||||
meta_window_actor_from_actor (CLUTTER_ACTOR (surface_actor));
|
||||
if (window_actor)
|
||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||
|
||||
scaled_opaque_region = meta_region_scale (opaque_region, geometry_scale);
|
||||
|
||||
if (unobscured_region)
|
||||
|
|
|
@ -88,4 +88,9 @@ void meta_window_actor_assign_surface_actor (MetaWindowActor *self,
|
|||
MetaWindowActor *meta_window_actor_from_window (MetaWindow *window);
|
||||
MetaWindowActor *meta_window_actor_from_actor (ClutterActor *actor);
|
||||
|
||||
void meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
|
||||
int geometry_scale);
|
||||
|
||||
int meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor);
|
||||
|
||||
#endif /* META_WINDOW_ACTOR_PRIVATE_H */
|
||||
|
|
|
@ -81,6 +81,8 @@ typedef struct _MetaWindowActorPrivate
|
|||
|
||||
MetaShadowMode shadow_mode;
|
||||
|
||||
int geometry_scale;
|
||||
|
||||
guint size_changed_id;
|
||||
|
||||
/*
|
||||
|
@ -252,6 +254,10 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
|
|||
static void
|
||||
meta_window_actor_init (MetaWindowActor *self)
|
||||
{
|
||||
MetaWindowActorPrivate *priv =
|
||||
meta_window_actor_get_instance_private (self);
|
||||
|
||||
priv->geometry_scale = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1891,6 +1897,34 @@ meta_window_actor_from_window (MetaWindow *window)
|
|||
return META_WINDOW_ACTOR (meta_window_get_compositor_private (window));
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_actor_set_geometry_scale (MetaWindowActor *window_actor,
|
||||
int geometry_scale)
|
||||
{
|
||||
MetaWindowActorPrivate *priv =
|
||||
meta_window_actor_get_instance_private (window_actor);
|
||||
CoglMatrix child_transform;
|
||||
|
||||
if (priv->geometry_scale == geometry_scale)
|
||||
return;
|
||||
|
||||
priv->geometry_scale = geometry_scale;
|
||||
|
||||
cogl_matrix_init_identity (&child_transform);
|
||||
cogl_matrix_scale (&child_transform, geometry_scale, geometry_scale, 1);
|
||||
clutter_actor_set_child_transform (CLUTTER_ACTOR (window_actor),
|
||||
&child_transform);
|
||||
}
|
||||
|
||||
int
|
||||
meta_window_actor_get_geometry_scale (MetaWindowActor *window_actor)
|
||||
{
|
||||
MetaWindowActorPrivate *priv =
|
||||
meta_window_actor_get_instance_private (window_actor);
|
||||
|
||||
return priv->geometry_scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_get_frame_bounds (MetaScreenCastWindow *screen_cast_window,
|
||||
MetaRectangle *bounds)
|
||||
|
|
|
@ -149,10 +149,6 @@ meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor
|
|||
|
||||
/* Wayland surface coordinate space -> stage coordinate space */
|
||||
geometry_scale = meta_wayland_actor_surface_get_geometry_scale (actor_surface);
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (surface_actor),
|
||||
geometry_scale,
|
||||
geometry_scale);
|
||||
|
||||
surface_rect = (cairo_rectangle_int_t) {
|
||||
.width = meta_wayland_surface_get_width (surface) * geometry_scale,
|
||||
.height = meta_wayland_surface_get_height (surface) * geometry_scale,
|
||||
|
|
|
@ -56,7 +56,6 @@ sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
|||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
|
||||
MetaWindow *toplevel_window;
|
||||
int geometry_scale;
|
||||
int x, y;
|
||||
|
||||
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
|
@ -66,9 +65,8 @@ sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
|||
if (toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
return;
|
||||
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (toplevel_window);
|
||||
x = (surface->offset_x + surface->sub.x) * geometry_scale;
|
||||
y = (surface->offset_y + surface->sub.y) * geometry_scale;
|
||||
x = surface->offset_x + surface->sub.x;
|
||||
y = surface->offset_y + surface->sub.y;
|
||||
|
||||
clutter_actor_set_position (actor, x, y);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-private.h"
|
||||
#include "core/boxes-private.h"
|
||||
#include "core/stack-tracker.h"
|
||||
#include "core/window-private.h"
|
||||
|
@ -69,6 +70,19 @@ struct _MetaWindowWaylandClass
|
|||
|
||||
G_DEFINE_TYPE (MetaWindowWayland, meta_window_wayland, META_TYPE_WINDOW)
|
||||
|
||||
static void
|
||||
set_geometry_scale_for_window (MetaWindowWayland *wl_window,
|
||||
int geometry_scale)
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
|
||||
wl_window->geometry_scale = geometry_scale;
|
||||
|
||||
window_actor = meta_window_actor_from_window (META_WINDOW (wl_window));
|
||||
if (window_actor)
|
||||
meta_window_actor_set_geometry_scale (window_actor, geometry_scale);
|
||||
}
|
||||
|
||||
static int
|
||||
get_window_geometry_scale_for_logical_monitor (MetaLogicalMonitor *logical_monitor)
|
||||
{
|
||||
|
@ -526,8 +540,7 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
|||
meta_wayland_actor_surface_sync_actor_state (actor_surface);
|
||||
}
|
||||
|
||||
wl_window->geometry_scale = geometry_scale;
|
||||
|
||||
set_geometry_scale_for_window (wl_window, geometry_scale);
|
||||
meta_window_emit_size_changed (window);
|
||||
}
|
||||
|
||||
|
@ -663,6 +676,8 @@ meta_window_wayland_new (MetaDisplay *display,
|
|||
MetaWaylandSurface *surface)
|
||||
{
|
||||
XWindowAttributes attrs = { 0 };
|
||||
MetaWindowWayland *wl_window;
|
||||
MetaWindow *window;
|
||||
|
||||
/*
|
||||
* Set attributes used by _meta_window_shared_new, don't bother trying to fake
|
||||
|
@ -677,13 +692,18 @@ meta_window_wayland_new (MetaDisplay *display,
|
|||
attrs.map_state = IsUnmapped;
|
||||
attrs.override_redirect = False;
|
||||
|
||||
return _meta_window_shared_new (display,
|
||||
META_WINDOW_CLIENT_TYPE_WAYLAND,
|
||||
surface,
|
||||
None,
|
||||
WithdrawnState,
|
||||
META_COMP_EFFECT_CREATE,
|
||||
&attrs);
|
||||
window = _meta_window_shared_new (display,
|
||||
META_WINDOW_CLIENT_TYPE_WAYLAND,
|
||||
surface,
|
||||
None,
|
||||
WithdrawnState,
|
||||
META_COMP_EFFECT_CREATE,
|
||||
&attrs);
|
||||
|
||||
wl_window = META_WINDOW_WAYLAND (window);
|
||||
set_geometry_scale_for_window (wl_window, wl_window->geometry_scale);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
Loading…
Add table
Reference in a new issue