window-actor/wayland: Draw black background for fullscreen windows
Fullscreen Wayland toplevel surfaces don't need to respect the configured size in which case it should be shown centered on the monitor with a black background. The black background becomes part of the window geometry. The surface container is responsible for correctly culling the surfaces and making sure the surface actors are removed from the actor tree to avoid destroying them. The window actor culling implementation assumes all surfaces to be direct children of said actor. The introduction of the surface_container actor broke that assumption. This implements the culling interface in MetaWindowActorWayland which is aware of the actor surface_container and fullscreen state. v2: Fix forwarding culling to surface even if there is a background. v2: Don't alter passed geometry. v2: Update window geometry code documentation to reflect these changes. v2: Only use constrained rect if we're acked fullscreen. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2338>
This commit is contained in:
parent
0034b54877
commit
909616b208
@ -34,6 +34,8 @@ struct _MetaWindowActorClass
|
||||
void (*update_regions) (MetaWindowActor *actor);
|
||||
gboolean (*can_freeze_commits) (MetaWindowActor *actor);
|
||||
|
||||
void (*sync_geometry) (MetaWindowActor *actor,
|
||||
const MetaRectangle *actor_rect);
|
||||
gboolean (*is_single_surface_actor) (MetaWindowActor *actor);
|
||||
};
|
||||
|
||||
|
@ -22,15 +22,35 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "compositor/clutter-utils.h"
|
||||
#include "compositor/meta-cullable.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/meta-window-actor-wayland.h"
|
||||
#include "compositor/region-utils.h"
|
||||
#include "meta/meta-window-actor.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
struct _MetaSurfaceContainerActorWayland
|
||||
{
|
||||
ClutterActor parent;
|
||||
|
||||
MetaWindowActor *window_actor;
|
||||
};
|
||||
|
||||
static void surface_container_cullable_iface_init (MetaCullableInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (MetaSurfaceContainerActorWayland,
|
||||
meta_surface_container_actor_wayland,
|
||||
CLUTTER_TYPE_ACTOR,
|
||||
G_IMPLEMENT_INTERFACE (META_TYPE_CULLABLE,
|
||||
surface_container_cullable_iface_init))
|
||||
|
||||
struct _MetaWindowActorWayland
|
||||
{
|
||||
MetaWindowActor parent;
|
||||
ClutterActor *background;
|
||||
MetaSurfaceContainerActorWayland *surface_container;
|
||||
};
|
||||
|
||||
static void cullable_iface_init (MetaCullableInterface *iface);
|
||||
@ -42,10 +62,90 @@ G_DEFINE_TYPE_WITH_CODE (MetaWindowActorWayland, meta_window_actor_wayland,
|
||||
|
||||
typedef struct _SurfaceTreeTraverseData
|
||||
{
|
||||
MetaWindowActor *window_actor;
|
||||
ClutterActor *surface_container;
|
||||
int index;
|
||||
} SurfaceTreeTraverseData;
|
||||
|
||||
static MetaSurfaceContainerActorWayland *
|
||||
surface_container_new (MetaWindowActor *window_actor)
|
||||
{
|
||||
MetaSurfaceContainerActorWayland *surface_container;
|
||||
|
||||
surface_container = g_object_new (META_TYPE_SURFACE_CONTAINER_ACTOR_WAYLAND,
|
||||
NULL);
|
||||
surface_container->window_actor = window_actor;
|
||||
|
||||
return surface_container;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_container_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
meta_cullable_cull_out_children (cullable, unobscured_region, clip_region);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
surface_container_is_untransformed (MetaCullable *cullable)
|
||||
{
|
||||
MetaSurfaceContainerActorWayland *surface_container =
|
||||
META_SURFACE_CONTAINER_ACTOR_WAYLAND (cullable);
|
||||
ClutterActor *actor = CLUTTER_ACTOR (cullable);
|
||||
MetaWindowActor *window_actor;
|
||||
float width, height;
|
||||
graphene_point3d_t verts[4];
|
||||
int geometry_scale;
|
||||
|
||||
clutter_actor_get_size (actor, &width, &height);
|
||||
clutter_actor_get_abs_allocation_vertices (actor, verts);
|
||||
|
||||
window_actor = surface_container->window_actor;
|
||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||
|
||||
return meta_actor_vertices_are_untransformed (verts,
|
||||
width * geometry_scale,
|
||||
height * geometry_scale,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_container_reset_culling (MetaCullable *cullable)
|
||||
{
|
||||
meta_cullable_reset_culling_children (cullable);
|
||||
}
|
||||
|
||||
static void
|
||||
surface_container_cullable_iface_init (MetaCullableInterface *iface)
|
||||
{
|
||||
iface->cull_out = surface_container_cull_out;
|
||||
iface->is_untransformed = surface_container_is_untransformed;
|
||||
iface->reset_culling = surface_container_reset_culling;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_container_dispose (GObject *object)
|
||||
{
|
||||
MetaSurfaceContainerActorWayland *self = META_SURFACE_CONTAINER_ACTOR_WAYLAND (object);
|
||||
|
||||
clutter_actor_remove_all_children (CLUTTER_ACTOR (self));
|
||||
|
||||
G_OBJECT_CLASS (meta_surface_container_actor_wayland_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_container_actor_wayland_class_init (MetaSurfaceContainerActorWaylandClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = surface_container_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_surface_container_actor_wayland_init (MetaSurfaceContainerActorWayland *self)
|
||||
{
|
||||
}
|
||||
|
||||
static gboolean
|
||||
get_surface_actor_list (GNode *node,
|
||||
gpointer data)
|
||||
@ -64,23 +164,23 @@ set_surface_actor_index (GNode *node,
|
||||
{
|
||||
MetaWaylandSurface *surface = node->data;
|
||||
SurfaceTreeTraverseData *traverse_data = data;
|
||||
ClutterActor *window_actor = CLUTTER_ACTOR (traverse_data->window_actor);
|
||||
ClutterActor *container = traverse_data->surface_container;
|
||||
ClutterActor *surface_actor =
|
||||
CLUTTER_ACTOR (meta_wayland_surface_get_actor (surface));
|
||||
|
||||
if (clutter_actor_contains (window_actor, surface_actor))
|
||||
if (clutter_actor_contains (container, surface_actor))
|
||||
{
|
||||
if (clutter_actor_get_child_at_index (window_actor, traverse_data->index) !=
|
||||
if (clutter_actor_get_child_at_index (container, traverse_data->index) !=
|
||||
surface_actor)
|
||||
{
|
||||
clutter_actor_set_child_at_index (window_actor,
|
||||
clutter_actor_set_child_at_index (container,
|
||||
surface_actor,
|
||||
traverse_data->index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clutter_actor_insert_child_at_index (window_actor,
|
||||
clutter_actor_insert_child_at_index (container,
|
||||
surface_actor,
|
||||
traverse_data->index);
|
||||
}
|
||||
@ -92,6 +192,7 @@ set_surface_actor_index (GNode *node,
|
||||
void
|
||||
meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
|
||||
{
|
||||
MetaWindowActorWayland *self = META_WINDOW_ACTOR_WAYLAND (actor);
|
||||
MetaSurfaceActor *surface_actor =
|
||||
meta_window_actor_get_surface (actor);
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (
|
||||
@ -109,18 +210,21 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
|
||||
get_surface_actor_list,
|
||||
&surface_actors);
|
||||
|
||||
children = clutter_actor_get_children (CLUTTER_ACTOR (actor));
|
||||
children =
|
||||
clutter_actor_get_children (CLUTTER_ACTOR (self->surface_container));
|
||||
for (l = children; l; l = l->next)
|
||||
{
|
||||
ClutterActor *child_actor = l->data;
|
||||
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (child_actor) &&
|
||||
!g_list_find (surface_actors, child_actor))
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (actor), child_actor);
|
||||
if (!g_list_find (surface_actors, child_actor))
|
||||
{
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (self->surface_container),
|
||||
child_actor);
|
||||
}
|
||||
}
|
||||
|
||||
traverse_data = (SurfaceTreeTraverseData) {
|
||||
.window_actor = actor,
|
||||
.surface_container = CLUTTER_ACTOR (self->surface_container),
|
||||
.index = 0,
|
||||
};
|
||||
g_node_traverse (root_node,
|
||||
@ -131,14 +235,48 @@ meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor)
|
||||
&traverse_data);
|
||||
}
|
||||
|
||||
static cairo_region_t *
|
||||
calculate_background_cull_region (MetaWindowActorWayland *self)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (self);
|
||||
int geometry_scale;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||
rect = (cairo_rectangle_int_t) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = clutter_actor_get_width (self->background) * geometry_scale,
|
||||
.height = clutter_actor_get_height (self->background) * geometry_scale,
|
||||
};
|
||||
|
||||
return cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_cull_out (MetaCullable *cullable,
|
||||
cairo_region_t *unobscured_region,
|
||||
cairo_region_t *clip_region)
|
||||
{
|
||||
meta_cullable_cull_out_children (cullable,
|
||||
MetaWindowActorWayland *self =
|
||||
META_WINDOW_ACTOR_WAYLAND (cullable);
|
||||
|
||||
meta_cullable_cull_out_children (META_CULLABLE (self),
|
||||
unobscured_region,
|
||||
clip_region);
|
||||
if (self->background)
|
||||
{
|
||||
cairo_region_t *background_cull_region;
|
||||
|
||||
background_cull_region = calculate_background_cull_region (self);
|
||||
|
||||
if (unobscured_region)
|
||||
cairo_region_subtract (unobscured_region, background_cull_region);
|
||||
if (clip_region)
|
||||
cairo_region_subtract (clip_region, background_cull_region);
|
||||
|
||||
cairo_region_destroy (background_cull_region);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -157,19 +295,25 @@ cullable_iface_init (MetaCullableInterface *iface)
|
||||
static MetaSurfaceActor *
|
||||
meta_window_actor_wayland_get_scanout_candidate (MetaWindowActor *actor)
|
||||
{
|
||||
MetaWindowActorWayland *self = META_WINDOW_ACTOR_WAYLAND (actor);
|
||||
ClutterActor *surface_container = CLUTTER_ACTOR (self->surface_container);
|
||||
ClutterActor *child_actor;
|
||||
MetaSurfaceActor *topmost_surface_actor;
|
||||
MetaWindow *window;
|
||||
|
||||
child_actor = clutter_actor_get_last_child (CLUTTER_ACTOR (actor));
|
||||
if (!child_actor || !META_IS_SURFACE_ACTOR_WAYLAND (child_actor))
|
||||
if (clutter_actor_get_last_child (CLUTTER_ACTOR (self)) != surface_container)
|
||||
return NULL;
|
||||
|
||||
child_actor = clutter_actor_get_last_child (surface_container);
|
||||
if (!child_actor)
|
||||
return NULL;
|
||||
|
||||
topmost_surface_actor = META_SURFACE_ACTOR (child_actor);
|
||||
|
||||
window = meta_window_actor_get_meta_window (actor);
|
||||
if (!meta_window_is_fullscreen (window) &&
|
||||
!meta_surface_actor_is_opaque (topmost_surface_actor))
|
||||
if (!meta_surface_actor_is_opaque (topmost_surface_actor) &&
|
||||
!(meta_window_is_fullscreen (window) &&
|
||||
clutter_actor_get_n_children (surface_container) == 1))
|
||||
return NULL;
|
||||
|
||||
return topmost_surface_actor;
|
||||
@ -223,6 +367,13 @@ static void
|
||||
meta_window_actor_wayland_set_frozen (MetaWindowActor *actor,
|
||||
gboolean frozen)
|
||||
{
|
||||
MetaWindowActorWayland *self = META_WINDOW_ACTOR_WAYLAND (actor);
|
||||
ClutterActor *child;
|
||||
ClutterActorIter iter;
|
||||
|
||||
clutter_actor_iter_init (&iter, CLUTTER_ACTOR (self->surface_container));
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
meta_surface_actor_set_frozen (META_SURFACE_ACTOR (child), frozen);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -239,36 +390,122 @@ meta_window_actor_wayland_can_freeze_commits (MetaWindowActor *actor)
|
||||
static gboolean
|
||||
meta_window_actor_wayland_is_single_surface_actor (MetaWindowActor *actor)
|
||||
{
|
||||
return clutter_actor_get_n_children (CLUTTER_ACTOR (actor)) == 1;
|
||||
MetaWindowActorWayland *self = META_WINDOW_ACTOR_WAYLAND (actor);
|
||||
ClutterActor *surface_container = CLUTTER_ACTOR (self->surface_container);
|
||||
|
||||
return clutter_actor_get_n_children (surface_container) == 1 &&
|
||||
!self->background;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
maybe_configure_black_background (MetaWindowActorWayland *self,
|
||||
float *surfaces_width,
|
||||
float *surfaces_height,
|
||||
float *background_width,
|
||||
float *background_height)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (self);
|
||||
MetaWindow *window = meta_window_actor_get_meta_window (window_actor);
|
||||
MetaLogicalMonitor *logical_monitor;
|
||||
int geometry_scale;
|
||||
MetaRectangle fullscreen_layout;
|
||||
ClutterActor *child;
|
||||
ClutterActorIter iter;
|
||||
float max_width = 0;
|
||||
float max_height = 0;
|
||||
|
||||
if (!meta_window_wayland_is_acked_fullscreen (META_WINDOW_WAYLAND (window)))
|
||||
return FALSE;
|
||||
|
||||
geometry_scale = meta_window_actor_get_geometry_scale (window_actor);
|
||||
|
||||
logical_monitor = meta_window_get_main_logical_monitor (window);
|
||||
fullscreen_layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||
|
||||
clutter_actor_iter_init (&iter, CLUTTER_ACTOR (self->surface_container));
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
float child_width, child_height;
|
||||
|
||||
clutter_actor_get_size (child, &child_width, &child_height);
|
||||
|
||||
if (META_IS_SURFACE_ACTOR (child) &&
|
||||
meta_surface_actor_is_opaque (META_SURFACE_ACTOR (child)) &&
|
||||
G_APPROX_VALUE (clutter_actor_get_x (child), 0,
|
||||
CLUTTER_COORDINATE_EPSILON) &&
|
||||
G_APPROX_VALUE (clutter_actor_get_y (child), 0,
|
||||
CLUTTER_COORDINATE_EPSILON) &&
|
||||
G_APPROX_VALUE (child_width, fullscreen_layout.width,
|
||||
CLUTTER_COORDINATE_EPSILON) &&
|
||||
G_APPROX_VALUE (child_height, fullscreen_layout.height,
|
||||
CLUTTER_COORDINATE_EPSILON))
|
||||
return FALSE;
|
||||
|
||||
max_width = MAX (max_width, child_width);
|
||||
max_height = MAX (max_height, child_height);
|
||||
}
|
||||
|
||||
*surfaces_width = max_width;
|
||||
*surfaces_height = max_height;
|
||||
*background_width = window->rect.width / geometry_scale;
|
||||
*background_height = window->rect.height / geometry_scale;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_dispose (GObject *object)
|
||||
meta_window_actor_wayland_sync_geometry (MetaWindowActor *actor,
|
||||
const MetaRectangle *actor_rect)
|
||||
{
|
||||
MetaWindowActor *window_actor = META_WINDOW_ACTOR (object);
|
||||
MetaSurfaceActor *surface_actor =
|
||||
meta_window_actor_get_surface (window_actor);
|
||||
g_autoptr (GList) children = NULL;
|
||||
GList *l;
|
||||
MetaWindowActorWayland *self = META_WINDOW_ACTOR_WAYLAND (actor);
|
||||
ClutterActor *surface_container = CLUTTER_ACTOR (self->surface_container);
|
||||
MetaWindow *window;
|
||||
float surfaces_width, surfaces_height;
|
||||
float background_width, background_height;
|
||||
|
||||
children = clutter_actor_get_children (CLUTTER_ACTOR (window_actor));
|
||||
for (l = children; l; l = l->next)
|
||||
window = meta_window_actor_get_meta_window (actor);
|
||||
if (window->unmanaging)
|
||||
return;
|
||||
|
||||
if (maybe_configure_black_background (self,
|
||||
&surfaces_width, &surfaces_height,
|
||||
&background_width, &background_height))
|
||||
{
|
||||
ClutterActor *child_actor = l->data;
|
||||
int geometry_scale;
|
||||
int child_actor_width, child_actor_height;
|
||||
|
||||
if (META_IS_SURFACE_ACTOR_WAYLAND (child_actor) &&
|
||||
child_actor != CLUTTER_ACTOR (surface_actor))
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (window_actor), child_actor);
|
||||
if (!self->background)
|
||||
{
|
||||
self->background = clutter_actor_new ();
|
||||
clutter_actor_set_background_color (self->background,
|
||||
CLUTTER_COLOR_Black);
|
||||
clutter_actor_set_reactive (self->background, TRUE);
|
||||
clutter_actor_insert_child_below (CLUTTER_ACTOR (self),
|
||||
self->background,
|
||||
NULL);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_window_actor_wayland_parent_class)->dispose (object);
|
||||
geometry_scale =
|
||||
meta_window_actor_get_geometry_scale (actor);
|
||||
child_actor_width = actor_rect->width / geometry_scale;
|
||||
child_actor_height = actor_rect->height / geometry_scale;
|
||||
|
||||
clutter_actor_set_size (self->background,
|
||||
background_width, background_height);
|
||||
clutter_actor_set_position (surface_container,
|
||||
(child_actor_width - surfaces_width) / 2,
|
||||
(child_actor_height - surfaces_height) / 2);
|
||||
}
|
||||
else if (self->background)
|
||||
{
|
||||
clutter_actor_set_position (surface_container, 0, 0);
|
||||
g_clear_pointer (&self->background, clutter_actor_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
|
||||
{
|
||||
MetaWindowActorClass *window_actor_class = META_WINDOW_ACTOR_CLASS (klass);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
window_actor_class->get_scanout_candidate = meta_window_actor_wayland_get_scanout_candidate;
|
||||
window_actor_class->assign_surface_actor = meta_window_actor_wayland_assign_surface_actor;
|
||||
@ -280,12 +517,15 @@ meta_window_actor_wayland_class_init (MetaWindowActorWaylandClass *klass)
|
||||
window_actor_class->set_frozen = meta_window_actor_wayland_set_frozen;
|
||||
window_actor_class->update_regions = meta_window_actor_wayland_update_regions;
|
||||
window_actor_class->can_freeze_commits = meta_window_actor_wayland_can_freeze_commits;
|
||||
window_actor_class->sync_geometry = meta_window_actor_wayland_sync_geometry;
|
||||
window_actor_class->is_single_surface_actor = meta_window_actor_wayland_is_single_surface_actor;
|
||||
|
||||
object_class->dispose = meta_window_actor_wayland_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_wayland_init (MetaWindowActorWayland *self)
|
||||
{
|
||||
self->surface_container = surface_container_new (META_WINDOW_ACTOR (self));
|
||||
|
||||
clutter_actor_add_child (CLUTTER_ACTOR (self),
|
||||
CLUTTER_ACTOR (self->surface_container));
|
||||
}
|
||||
|
@ -31,6 +31,12 @@ G_DECLARE_FINAL_TYPE (MetaWindowActorWayland,
|
||||
META, WINDOW_ACTOR_WAYLAND,
|
||||
MetaWindowActor)
|
||||
|
||||
#define META_TYPE_SURFACE_CONTAINER_ACTOR_WAYLAND (meta_surface_container_actor_wayland_get_type())
|
||||
G_DECLARE_FINAL_TYPE (MetaSurfaceContainerActorWayland,
|
||||
meta_surface_container_actor_wayland,
|
||||
META, SURFACE_CONTAINER_ACTOR_WAYLAND,
|
||||
ClutterActor)
|
||||
|
||||
void meta_window_actor_wayland_rebuild_surface_tree (MetaWindowActor *actor);
|
||||
|
||||
#endif /*META_WINDOW_ACTOR_WAYLAND_H */
|
||||
|
@ -1511,6 +1511,7 @@ meta_window_actor_x11_set_frozen (MetaWindowActor *actor,
|
||||
return;
|
||||
|
||||
actor_x11->is_frozen = frozen;
|
||||
meta_surface_actor_set_frozen (meta_window_actor_get_surface (actor), frozen);
|
||||
|
||||
if (frozen)
|
||||
meta_window_x11_freeze_commits (window);
|
||||
@ -1538,6 +1539,12 @@ meta_window_actor_x11_is_single_surface_actor (MetaWindowActor *actor)
|
||||
return clutter_actor_get_n_children (CLUTTER_ACTOR (actor)) == 1;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_x11_sync_geometry (MetaWindowActor *actor,
|
||||
const MetaRectangle *actor_rect)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_actor_x11_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -1672,6 +1679,9 @@ meta_window_actor_x11_dispose (GObject *object)
|
||||
{
|
||||
g_clear_signal_handler (&actor_x11->repaint_scheduled_id, surface_actor);
|
||||
g_clear_signal_handler (&actor_x11->size_changed_id, surface_actor);
|
||||
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (object),
|
||||
CLUTTER_ACTOR (surface_actor));
|
||||
}
|
||||
|
||||
g_clear_pointer (&actor_x11->shape_region, cairo_region_destroy);
|
||||
@ -1714,6 +1724,7 @@ meta_window_actor_x11_class_init (MetaWindowActorX11Class *klass)
|
||||
window_actor_class->set_frozen = meta_window_actor_x11_set_frozen;
|
||||
window_actor_class->update_regions = meta_window_actor_x11_update_regions;
|
||||
window_actor_class->can_freeze_commits = meta_window_actor_x11_can_freeze_commits;
|
||||
window_actor_class->sync_geometry = meta_window_actor_x11_sync_geometry;
|
||||
window_actor_class->is_single_surface_actor = meta_window_actor_x11_is_single_surface_actor;
|
||||
|
||||
actor_class->paint = meta_window_actor_x11_paint;
|
||||
|
@ -270,16 +270,6 @@ static void
|
||||
meta_window_actor_set_frozen (MetaWindowActor *self,
|
||||
gboolean frozen)
|
||||
{
|
||||
ClutterActor *child;
|
||||
ClutterActorIter iter;
|
||||
|
||||
clutter_actor_iter_init (&iter, CLUTTER_ACTOR (self));
|
||||
while (clutter_actor_iter_next (&iter, &child))
|
||||
{
|
||||
if (META_IS_SURFACE_ACTOR (child))
|
||||
meta_surface_actor_set_frozen (META_SURFACE_ACTOR (child), frozen);
|
||||
}
|
||||
|
||||
META_WINDOW_ACTOR_GET_CLASS (self)->set_frozen (self, frozen);
|
||||
}
|
||||
|
||||
@ -464,12 +454,7 @@ meta_window_actor_dispose (GObject *object)
|
||||
|
||||
g_clear_object (&priv->window);
|
||||
|
||||
if (priv->surface)
|
||||
{
|
||||
clutter_actor_remove_child (CLUTTER_ACTOR (self),
|
||||
CLUTTER_ACTOR (priv->surface));
|
||||
g_clear_object (&priv->surface);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_window_actor_parent_class)->dispose (object);
|
||||
}
|
||||
@ -861,6 +846,8 @@ meta_window_actor_sync_actor_geometry (MetaWindowActor *self,
|
||||
if (meta_window_actor_is_frozen (self) && !did_placement)
|
||||
return META_WINDOW_ACTOR_CHANGE_POSITION | META_WINDOW_ACTOR_CHANGE_SIZE;
|
||||
|
||||
META_WINDOW_ACTOR_GET_CLASS (self)->sync_geometry (self, &actor_rect);
|
||||
|
||||
if (clutter_actor_has_allocation (actor))
|
||||
{
|
||||
ClutterActorBox box;
|
||||
|
@ -267,14 +267,13 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
configured_rect.width = constrained_rect.width;
|
||||
configured_rect.height = constrained_rect.height;
|
||||
|
||||
/* For wayland clients, the size is completely determined by the client,
|
||||
* and while this allows to avoid some trickery with frames and the resulting
|
||||
* lagging, we also need to insist a bit when the constraints would apply
|
||||
* a different size than the client decides.
|
||||
/* The size is determined by the client, except when the client is explicitly
|
||||
* fullscreen, in which case the compositor compensates for the size
|
||||
* difference between what surface configuration the client provided, and the
|
||||
* size of the area a fullscreen window state is expected to fill.
|
||||
*
|
||||
* Note that this is not generally a problem for normal toplevel windows (the
|
||||
* constraints don't see the size hints, or just change the position), but
|
||||
* it can be for maximized or fullscreen.
|
||||
* For non-explicit-fullscreen states, since the size is always determined by
|
||||
* the client, the we cannot use the size calculated by the constraints.
|
||||
*/
|
||||
|
||||
if (flags & META_MOVE_RESIZE_FORCE_MOVE)
|
||||
@ -283,16 +282,26 @@ meta_window_wayland_move_resize_internal (MetaWindow *window,
|
||||
}
|
||||
else if (flags & META_MOVE_RESIZE_WAYLAND_FINISH_MOVE_RESIZE)
|
||||
{
|
||||
/* This is a call to wl_surface_commit(), ignore the constrained_rect and
|
||||
* update the real client size to match the buffer size.
|
||||
*/
|
||||
MetaWaylandWindowConfiguration *configuration;
|
||||
int new_width, new_height;
|
||||
|
||||
if (window->rect.width != unconstrained_rect.width ||
|
||||
window->rect.height != unconstrained_rect.height)
|
||||
configuration = wl_window->last_acked_configuration;
|
||||
if (configuration && configuration->is_fullscreen)
|
||||
{
|
||||
new_width = constrained_rect.width;
|
||||
new_height = constrained_rect.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_width = unconstrained_rect.width;
|
||||
new_height = unconstrained_rect.height;
|
||||
}
|
||||
if (window->rect.width != new_width ||
|
||||
window->rect.height != new_height)
|
||||
{
|
||||
*result |= META_MOVE_RESIZE_RESULT_RESIZED;
|
||||
window->rect.width = unconstrained_rect.width;
|
||||
window->rect.height = unconstrained_rect.height;
|
||||
window->rect.width = new_width;
|
||||
window->rect.height = new_height;
|
||||
}
|
||||
|
||||
window->buffer_rect.width =
|
||||
@ -1290,3 +1299,10 @@ meta_window_wayland_get_max_size (MetaWindow *window,
|
||||
scale = 1.0 / (float) meta_window_wayland_get_geometry_scale (window);
|
||||
scale_size (width, height, scale);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_window_wayland_is_acked_fullscreen (MetaWindowWayland *wl_window)
|
||||
{
|
||||
return (wl_window->last_acked_configuration &&
|
||||
wl_window->last_acked_configuration->is_fullscreen);
|
||||
}
|
||||
|
@ -81,4 +81,6 @@ gboolean meta_window_wayland_is_resize (MetaWindowWayland *wl_window,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
gboolean meta_window_wayland_is_acked_fullscreen (MetaWindowWayland *wl_window);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user