mirror of
https://github.com/brl/mutter.git
synced 2024-12-23 19:42:05 +00:00
wayland: Push actor state instead of itself pulling
Make the Wayland objects push the state relevant to their role to the MetaSurfaceActor instead of MetaSurfaceActorWayland pulling the state from the associated surface. This makes the relationship between the actor and the objects that constructs it more clear; the actor is a drawable that the protocol objects control, not the other way around. This will make it easier to "detach" a surface actor from a surface, which is necessary when unmapping a window while the underlying surface is yet to be destroyed and potentially reused. https://gitlab.gnome.org/GNOME/mutter/merge_requests/5 https://bugzilla.gnome.org/show_bug.cgi?id=791938
This commit is contained in:
parent
0162cdf8ef
commit
44624736c5
@ -90,216 +90,6 @@ meta_surface_actor_wayland_is_unredirected (MetaSurfaceActor *actor)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
double
|
||||
meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaWindow *window;
|
||||
int geometry_scale = 1;
|
||||
|
||||
g_assert (surface);
|
||||
|
||||
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
|
||||
if (!meta_is_stage_views_scaled ())
|
||||
{
|
||||
/* XXX: We do not handle x11 clients yet */
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (window);
|
||||
}
|
||||
|
||||
return (double) geometry_scale / (double) surface->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
logical_to_actor_position (MetaSurfaceActorWayland *self,
|
||||
int *x,
|
||||
int *y)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaWindow *toplevel_window;
|
||||
int geometry_scale = 1;
|
||||
|
||||
g_assert (surface);
|
||||
|
||||
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
if (toplevel_window)
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (toplevel_window);
|
||||
|
||||
*x = *x * geometry_scale;
|
||||
*y = *y * geometry_scale;
|
||||
}
|
||||
|
||||
/* Convert the current actor state to the corresponding subsurface rectangle
|
||||
* in logical pixel coordinate space. */
|
||||
void
|
||||
meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
|
||||
MetaRectangle *rect)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaWaylandBuffer *buffer = meta_wayland_surface_get_buffer (surface);
|
||||
CoglTexture *texture;
|
||||
MetaWindow *toplevel_window;
|
||||
int geometry_scale;
|
||||
float x, y;
|
||||
|
||||
g_assert (surface);
|
||||
|
||||
texture = buffer->texture;
|
||||
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
geometry_scale = meta_window_wayland_get_geometry_scale (toplevel_window);
|
||||
|
||||
clutter_actor_get_position (CLUTTER_ACTOR (self), &x, &y);
|
||||
*rect = (MetaRectangle) {
|
||||
.x = x / geometry_scale,
|
||||
.y = y / geometry_scale,
|
||||
.width = cogl_texture_get_width (texture) / surface->scale,
|
||||
.height = cogl_texture_get_height (texture) / surface->scale,
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaWindow *window;
|
||||
int x = surface->offset_x + surface->sub.x;
|
||||
int y = surface->offset_y + surface->sub.y;
|
||||
|
||||
g_assert (surface);
|
||||
|
||||
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
if (window && window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
/* Bail directly if this is part of a Xwayland window and warn
|
||||
* if there happen to be offsets anyway since that is not supposed
|
||||
* to happen. */
|
||||
g_warn_if_fail (x == 0 && y == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
logical_to_actor_position (self, &x, &y);
|
||||
clutter_actor_set_position (CLUTTER_ACTOR (self), x, y);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaShapedTexture *stex =
|
||||
meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
double texture_scale;
|
||||
|
||||
g_assert (surface);
|
||||
|
||||
/* Given the surface's window type and what output the surface actor has the
|
||||
* largest region, scale the actor with the determined scale. */
|
||||
texture_scale = meta_surface_actor_wayland_get_scale (self);
|
||||
|
||||
/* Actor scale. */
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), texture_scale, texture_scale);
|
||||
|
||||
/* Input region */
|
||||
if (surface->input_region)
|
||||
{
|
||||
cairo_region_t *scaled_input_region;
|
||||
int region_scale;
|
||||
|
||||
/* The input region from the Wayland surface is in the Wayland surface
|
||||
* coordinate space, while the surface actor input region is in the
|
||||
* physical pixel coordinate space. */
|
||||
region_scale = (int)(surface->scale * texture_scale);
|
||||
scaled_input_region = meta_region_scale (surface->input_region,
|
||||
region_scale);
|
||||
meta_surface_actor_set_input_region (META_SURFACE_ACTOR (self),
|
||||
scaled_input_region);
|
||||
cairo_region_destroy (scaled_input_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_surface_actor_set_input_region (META_SURFACE_ACTOR (self), NULL);
|
||||
}
|
||||
|
||||
/* Opaque region */
|
||||
if (surface->opaque_region)
|
||||
{
|
||||
cairo_region_t *scaled_opaque_region;
|
||||
|
||||
/* The opaque region from the Wayland surface is in Wayland surface
|
||||
* coordinate space, while the surface actor opaque region is in the
|
||||
* same coordinate space as the unscaled buffer texture. */
|
||||
scaled_opaque_region = meta_region_scale (surface->opaque_region,
|
||||
surface->scale);
|
||||
meta_surface_actor_set_opaque_region (META_SURFACE_ACTOR (self),
|
||||
scaled_opaque_region);
|
||||
cairo_region_destroy (scaled_opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_surface_actor_set_opaque_region (META_SURFACE_ACTOR (self), NULL);
|
||||
}
|
||||
|
||||
meta_surface_actor_wayland_sync_subsurface_state (self);
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
|
||||
{
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaWindow *window;
|
||||
GList *iter;
|
||||
|
||||
g_assert (surface);
|
||||
|
||||
window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
meta_surface_actor_wayland_sync_state (self);
|
||||
|
||||
if (window && window->client_type != META_WINDOW_CLIENT_TYPE_X11)
|
||||
{
|
||||
for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurf = iter->data;
|
||||
|
||||
meta_surface_actor_wayland_sync_state_recursive (
|
||||
META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
|
||||
MetaLogicalMonitor *logical_monitor)
|
||||
{
|
||||
float x, y, width, height;
|
||||
cairo_rectangle_int_t actor_rect;
|
||||
cairo_region_t *region;
|
||||
gboolean is_on_monitor;
|
||||
|
||||
clutter_actor_get_transformed_position (CLUTTER_ACTOR (self), &x, &y);
|
||||
clutter_actor_get_transformed_size (CLUTTER_ACTOR (self), &width, &height);
|
||||
|
||||
actor_rect.x = (int)roundf (x);
|
||||
actor_rect.y = (int)roundf (y);
|
||||
actor_rect.width = (int)roundf (x + width) - actor_rect.x;
|
||||
actor_rect.height = (int)roundf (y + height) - actor_rect.y;
|
||||
|
||||
/* Calculate the scaled surface actor region. */
|
||||
region = cairo_region_create_rectangle (&actor_rect);
|
||||
|
||||
cairo_region_intersect_rectangle (region,
|
||||
&((cairo_rectangle_int_t) {
|
||||
.x = logical_monitor->rect.x,
|
||||
.y = logical_monitor->rect.y,
|
||||
.width = logical_monitor->rect.width,
|
||||
.height = logical_monitor->rect.height,
|
||||
}));
|
||||
|
||||
is_on_monitor = !cairo_region_is_empty (region);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
return is_on_monitor;
|
||||
}
|
||||
|
||||
void
|
||||
meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks)
|
||||
@ -328,16 +118,11 @@ meta_surface_actor_wayland_get_preferred_width (ClutterActor *actor,
|
||||
gfloat *natural_width_p)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaShapedTexture *stex;
|
||||
double scale;
|
||||
|
||||
if (surface)
|
||||
scale = meta_surface_actor_wayland_get_scale (self);
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), &scale, NULL);
|
||||
clutter_actor_get_preferred_width (CLUTTER_ACTOR (stex),
|
||||
for_height,
|
||||
min_width_p,
|
||||
@ -357,16 +142,11 @@ meta_surface_actor_wayland_get_preferred_height (ClutterActor *actor,
|
||||
gfloat *natural_height_p)
|
||||
{
|
||||
MetaSurfaceActorWayland *self = META_SURFACE_ACTOR_WAYLAND (actor);
|
||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||
MetaShapedTexture *stex;
|
||||
double scale;
|
||||
|
||||
if (surface)
|
||||
scale = meta_surface_actor_wayland_get_scale (self);
|
||||
else
|
||||
scale = 1.0;
|
||||
|
||||
stex = meta_surface_actor_get_texture (META_SURFACE_ACTOR (self));
|
||||
clutter_actor_get_scale (CLUTTER_ACTOR (stex), NULL, &scale);
|
||||
clutter_actor_get_preferred_height (CLUTTER_ACTOR (stex),
|
||||
for_width,
|
||||
min_height_p,
|
||||
|
@ -67,15 +67,6 @@ double meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor);
|
||||
void meta_surface_actor_wayland_get_subsurface_rect (MetaSurfaceActorWayland *self,
|
||||
MetaRectangle *rect);
|
||||
|
||||
void meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self);
|
||||
|
||||
void meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self);
|
||||
|
||||
void meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self);
|
||||
|
||||
gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
|
||||
MetaLogicalMonitor *logical_monitor);
|
||||
|
||||
void meta_surface_actor_wayland_add_frame_callbacks (MetaSurfaceActorWayland *self,
|
||||
struct wl_list *frame_callbacks);
|
||||
|
||||
|
@ -23,8 +23,12 @@
|
||||
|
||||
#include "wayland/meta-wayland-actor-surface.h"
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-logical-monitor.h"
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "compositor/region-utils.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandActorSurface,
|
||||
meta_wayland_actor_surface,
|
||||
@ -55,10 +59,110 @@ queue_surface_actor_frame_callbacks (MetaWaylandSurface *surface,
|
||||
wl_list_init (&pending->frame_callback_list);
|
||||
}
|
||||
|
||||
double
|
||||
meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *actor_surface)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWindow *toplevel_window;
|
||||
int geometry_scale;
|
||||
|
||||
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
if (meta_is_stage_views_scaled ())
|
||||
{
|
||||
geometry_scale = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!toplevel_window ||
|
||||
toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
geometry_scale = 1;
|
||||
else
|
||||
geometry_scale =
|
||||
meta_window_wayland_get_geometry_scale (toplevel_window);
|
||||
}
|
||||
|
||||
return (double) geometry_scale / (double) surface->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_actor_surface_real_sync_actor_state (MetaWaylandActorSurface *actor_surface)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActor *surface_actor;
|
||||
MetaShapedTexture *stex;
|
||||
double actor_scale;
|
||||
GList *l;
|
||||
|
||||
surface_actor = surface->surface_actor;
|
||||
stex = meta_surface_actor_get_texture (surface_actor);
|
||||
|
||||
actor_scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
|
||||
clutter_actor_set_scale (CLUTTER_ACTOR (stex), actor_scale, actor_scale);
|
||||
|
||||
if (surface->input_region)
|
||||
{
|
||||
cairo_region_t *scaled_input_region;
|
||||
int region_scale;
|
||||
|
||||
/* Wayland surface coordinate space -> stage coordinate space */
|
||||
region_scale = (int) (surface->scale * actor_scale);
|
||||
scaled_input_region = meta_region_scale (surface->input_region,
|
||||
region_scale);
|
||||
meta_surface_actor_set_input_region (surface_actor, scaled_input_region);
|
||||
cairo_region_destroy (scaled_input_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_surface_actor_set_input_region (surface_actor, NULL);
|
||||
}
|
||||
|
||||
if (surface->opaque_region)
|
||||
{
|
||||
cairo_region_t *scaled_opaque_region;
|
||||
|
||||
/* Wayland surface coordinate space -> stage coordinate space */
|
||||
scaled_opaque_region = meta_region_scale (surface->opaque_region,
|
||||
surface->scale);
|
||||
meta_surface_actor_set_opaque_region (surface_actor,
|
||||
scaled_opaque_region);
|
||||
cairo_region_destroy (scaled_opaque_region);
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_surface_actor_set_opaque_region (surface_actor, NULL);
|
||||
}
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface = l->data;
|
||||
MetaWaylandActorSurface *subsurface_actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (subsurface_surface->role);
|
||||
|
||||
meta_wayland_actor_surface_sync_actor_state (subsurface_actor_surface);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_actor_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface)
|
||||
{
|
||||
MetaWaylandActorSurfaceClass *actor_surface_class =
|
||||
META_WAYLAND_ACTOR_SURFACE_GET_CLASS (actor_surface);
|
||||
|
||||
actor_surface_class->sync_actor_state (actor_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (surface_role);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandSurface *toplevel_surface;
|
||||
@ -69,8 +173,7 @@ meta_wayland_actor_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
if (!toplevel_surface || !toplevel_surface->window)
|
||||
return;
|
||||
|
||||
meta_surface_actor_wayland_sync_state (
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
|
||||
meta_wayland_actor_surface_sync_actor_state (actor_surface);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -79,10 +182,38 @@ meta_wayland_actor_surface_is_on_logical_monitor (MetaWaylandSurfaceRole *surfac
|
||||
{
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaSurfaceActorWayland *actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
float x, y, width, height;
|
||||
cairo_rectangle_int_t actor_rect;
|
||||
cairo_region_t *region;
|
||||
MetaRectangle logical_monitor_layout;
|
||||
gboolean is_on_monitor;
|
||||
|
||||
return meta_surface_actor_wayland_is_on_monitor (actor, logical_monitor);
|
||||
clutter_actor_get_transformed_position (actor, &x, &y);
|
||||
clutter_actor_get_transformed_size (actor, &width, &height);
|
||||
|
||||
actor_rect.x = (int) roundf (x);
|
||||
actor_rect.y = (int) roundf (y);
|
||||
actor_rect.width = (int) roundf (x + width) - actor_rect.x;
|
||||
actor_rect.height = (int) roundf (y + height) - actor_rect.y;
|
||||
|
||||
/* Calculate the scaled surface actor region. */
|
||||
region = cairo_region_create_rectangle (&actor_rect);
|
||||
|
||||
logical_monitor_layout = meta_logical_monitor_get_layout (logical_monitor);
|
||||
|
||||
cairo_region_intersect_rectangle (region,
|
||||
&((cairo_rectangle_int_t) {
|
||||
.x = logical_monitor_layout.x,
|
||||
.y = logical_monitor_layout.y,
|
||||
.width = logical_monitor_layout.width,
|
||||
.height = logical_monitor_layout.height,
|
||||
}));
|
||||
|
||||
is_on_monitor = !cairo_region_is_empty (region);
|
||||
cairo_region_destroy (region);
|
||||
|
||||
return is_on_monitor;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -100,4 +231,6 @@ meta_wayland_actor_surface_class_init (MetaWaylandActorSurfaceClass *klass)
|
||||
surface_role_class->commit = meta_wayland_actor_surface_commit;
|
||||
surface_role_class->is_on_logical_monitor =
|
||||
meta_wayland_actor_surface_is_on_logical_monitor;
|
||||
|
||||
klass->sync_actor_state = meta_wayland_actor_surface_real_sync_actor_state;
|
||||
}
|
||||
|
@ -32,6 +32,12 @@ G_DECLARE_DERIVABLE_TYPE (MetaWaylandActorSurface,
|
||||
struct _MetaWaylandActorSurfaceClass
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass parent_class;
|
||||
|
||||
void (* sync_actor_state) (MetaWaylandActorSurface *actor_surface);
|
||||
};
|
||||
|
||||
void meta_wayland_actor_surface_sync_actor_state (MetaWaylandActorSurface *actor_surface);
|
||||
|
||||
double meta_wayland_actor_surface_calculate_scale (MetaWaylandActorSurface *actor_surface);
|
||||
|
||||
#endif /* META_WAYLAND_ACTOR_SURFACE_H */
|
||||
|
@ -26,11 +26,53 @@
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "wayland/meta-wayland-actor-surface.h"
|
||||
#include "wayland/meta-wayland-buffer.h"
|
||||
#include "wayland/meta-wayland-subsurface.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
G_DEFINE_TYPE (MetaWaylandShellSurface,
|
||||
meta_wayland_shell_surface,
|
||||
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
||||
|
||||
void
|
||||
meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_surface,
|
||||
MetaRectangle *out_geometry)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (shell_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandBuffer *buffer;
|
||||
CoglTexture *texture;
|
||||
MetaRectangle geometry;
|
||||
GList *l;
|
||||
|
||||
buffer = surface->buffer_ref.buffer;
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
texture = meta_wayland_buffer_get_texture (buffer);
|
||||
geometry = (MetaRectangle) {
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = cogl_texture_get_width (texture) / surface->scale,
|
||||
.height = cogl_texture_get_height (texture) / surface->scale,
|
||||
};
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface = l->data;
|
||||
MetaWaylandSubsurface *subsurface =
|
||||
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
|
||||
meta_wayland_subsurface_union_geometry (subsurface,
|
||||
0, 0,
|
||||
&geometry);
|
||||
}
|
||||
|
||||
*out_geometry = geometry;
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_shell_surface_configure (MetaWaylandShellSurface *shell_surface,
|
||||
int new_x,
|
||||
@ -83,13 +125,14 @@ static void
|
||||
meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (surface_role);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWindow *window;
|
||||
MetaWaylandBuffer *buffer;
|
||||
CoglTexture *texture;
|
||||
MetaSurfaceActorWayland *surface_actor;
|
||||
double scale;
|
||||
|
||||
surface_role_class =
|
||||
@ -104,8 +147,7 @@ meta_wayland_shell_surface_surface_commit (MetaWaylandSurfaceRole *surface_role
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
surface_actor = META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
scale = meta_surface_actor_wayland_get_scale (surface_actor);
|
||||
scale = meta_wayland_actor_surface_calculate_scale (actor_surface);
|
||||
texture = meta_wayland_buffer_get_texture (buffer);
|
||||
|
||||
window->buffer_rect.width = cogl_texture_get_width (texture) * scale;
|
||||
|
@ -61,4 +61,7 @@ void meta_wayland_shell_surface_close (MetaWaylandShellSurface *shell_surface);
|
||||
void meta_wayland_shell_surface_managed (MetaWaylandShellSurface *shell_surface,
|
||||
MetaWindow *window);
|
||||
|
||||
void meta_wayland_shell_surface_calculate_geometry (MetaWaylandShellSurface *shell_surface,
|
||||
MetaRectangle *out_geometry);
|
||||
|
||||
#endif /* META_WAYLAND_SHELL_SURFACE_H */
|
||||
|
@ -24,7 +24,10 @@
|
||||
|
||||
#include "compositor/meta-surface-actor-wayland.h"
|
||||
#include "wayland/meta-wayland.h"
|
||||
#include "wayland/meta-wayland-actor-surface.h"
|
||||
#include "wayland/meta-wayland-buffer.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -48,10 +51,39 @@ G_DEFINE_TYPE (MetaWaylandSubsurface,
|
||||
meta_wayland_subsurface,
|
||||
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
||||
|
||||
static void
|
||||
sync_actor_subsurface_state (MetaWaylandSurface *surface)
|
||||
{
|
||||
ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
MetaWindow *toplevel_window;
|
||||
int geometry_scale;
|
||||
int x, y;
|
||||
|
||||
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
||||
if (!toplevel_window)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
clutter_actor_set_position (actor, x, y);
|
||||
|
||||
if (surface->buffer_ref.buffer)
|
||||
clutter_actor_show (actor);
|
||||
else
|
||||
clutter_actor_hide (actor);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (subsurface);
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (subsurface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
|
||||
@ -108,27 +140,48 @@ meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface)
|
||||
if (meta_wayland_surface_is_effectively_synchronized (surface))
|
||||
meta_wayland_surface_apply_pending_state (surface, surface->sub.pending);
|
||||
|
||||
meta_surface_actor_wayland_sync_subsurface_state (
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
|
||||
meta_wayland_actor_surface_sync_actor_state (actor_surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_subsurface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
void
|
||||
meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||
int parent_x,
|
||||
int parent_y,
|
||||
MetaRectangle *out_geometry)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurfaceRole *surface_role = META_WAYLAND_SURFACE_ROLE (subsurface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
ClutterActor *actor = CLUTTER_ACTOR (surface->surface_actor);
|
||||
MetaWaylandBuffer *buffer;
|
||||
CoglTexture *texture;
|
||||
MetaRectangle geometry;
|
||||
GList *l;
|
||||
|
||||
surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_subsurface_parent_class);
|
||||
surface_role_class->commit (surface_role, pending);
|
||||
buffer = surface->buffer_ref.buffer;
|
||||
if (!buffer)
|
||||
return;
|
||||
|
||||
if (surface->buffer_ref.buffer != NULL)
|
||||
clutter_actor_show (actor);
|
||||
else
|
||||
clutter_actor_hide (actor);
|
||||
texture = meta_wayland_buffer_get_texture (buffer);
|
||||
geometry = (MetaRectangle) {
|
||||
.x = surface->offset_x + surface->sub.x,
|
||||
.y = surface->offset_y + surface->sub.y,
|
||||
.width = cogl_texture_get_width (texture) / surface->scale,
|
||||
.height = cogl_texture_get_height (texture) / surface->scale,
|
||||
};
|
||||
|
||||
meta_rectangle_union (out_geometry, &geometry, out_geometry);
|
||||
|
||||
for (l = surface->subsurfaces; l; l = l->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurface_surface = l->data;
|
||||
MetaWaylandSubsurface *subsurface =
|
||||
META_WAYLAND_SUBSURFACE (subsurface_surface->role);
|
||||
|
||||
meta_wayland_subsurface_union_geometry (subsurface,
|
||||
parent_x + geometry.x,
|
||||
parent_y + geometry.y,
|
||||
out_geometry);
|
||||
}
|
||||
}
|
||||
|
||||
static MetaWaylandSurface *
|
||||
@ -144,6 +197,21 @@ meta_wayland_subsurface_get_toplevel (MetaWaylandSurfaceRole *surface_role)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_subsurface_sync_actor_state (MetaWaylandActorSurface *actor_surface)
|
||||
{
|
||||
MetaWaylandSurfaceRole *surface_role =
|
||||
META_WAYLAND_SURFACE_ROLE (actor_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
MetaWaylandActorSurfaceClass *actor_surface_class =
|
||||
META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_subsurface_parent_class);
|
||||
|
||||
actor_surface_class->sync_actor_state (actor_surface);
|
||||
|
||||
sync_actor_subsurface_state (surface);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_wayland_subsurface_init (MetaWaylandSubsurface *role)
|
||||
{
|
||||
@ -154,9 +222,13 @@ meta_wayland_subsurface_class_init (MetaWaylandSubsurfaceClass *klass)
|
||||
{
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class =
|
||||
META_WAYLAND_SURFACE_ROLE_CLASS (klass);
|
||||
MetaWaylandActorSurfaceClass *actor_surface_class =
|
||||
META_WAYLAND_ACTOR_SURFACE_CLASS (klass);
|
||||
|
||||
surface_role_class->commit = meta_wayland_subsurface_commit;
|
||||
surface_role_class->get_toplevel = meta_wayland_subsurface_get_toplevel;
|
||||
|
||||
actor_surface_class->sync_actor_state =
|
||||
meta_wayland_subsurface_sync_actor_state;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -355,6 +427,7 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
{
|
||||
MetaWaylandSurface *surface = wl_resource_get_user_data (surface_resource);
|
||||
MetaWaylandSurface *parent = wl_resource_get_user_data (parent_resource);
|
||||
MetaWindow *toplevel_window;
|
||||
|
||||
if (surface->wl_subsurface)
|
||||
{
|
||||
@ -374,6 +447,11 @@ wl_subcompositor_get_subsurface (struct wl_client *client,
|
||||
return;
|
||||
}
|
||||
|
||||
toplevel_window = meta_wayland_surface_get_toplevel_window (parent);
|
||||
if (toplevel_window &&
|
||||
toplevel_window->client_type == META_WINDOW_CLIENT_TYPE_X11)
|
||||
g_warning ("XWayland subsurfaces not currently supported");
|
||||
|
||||
surface->wl_subsurface =
|
||||
wl_resource_create (client,
|
||||
&wl_subsurface_interface,
|
||||
|
@ -31,6 +31,11 @@ G_DECLARE_FINAL_TYPE (MetaWaylandSubsurface,
|
||||
|
||||
void meta_wayland_subsurface_parent_state_applied (MetaWaylandSubsurface *subsurface);
|
||||
|
||||
void meta_wayland_subsurface_union_geometry (MetaWaylandSubsurface *subsurface,
|
||||
int parent_x,
|
||||
int parent_y,
|
||||
MetaRectangle *out_geometry);
|
||||
|
||||
void meta_wayland_subsurfaces_init (MetaWaylandCompositor *compositor);
|
||||
|
||||
#endif /* META_WAYLAND_SUBSURFACE_H */
|
||||
|
@ -334,45 +334,6 @@ dnd_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_calculate_window_geometry (MetaWaylandSurface *surface,
|
||||
MetaRectangle *total_geometry,
|
||||
float parent_x,
|
||||
float parent_y)
|
||||
{
|
||||
MetaSurfaceActorWayland *surface_actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
MetaRectangle subsurface_rect;
|
||||
MetaRectangle geom;
|
||||
GList *l;
|
||||
|
||||
/* Unmapped surfaces don't count. */
|
||||
if (!CLUTTER_ACTOR_IS_VISIBLE (CLUTTER_ACTOR (surface_actor)))
|
||||
return;
|
||||
|
||||
if (!surface->buffer_ref.buffer)
|
||||
return;
|
||||
|
||||
meta_surface_actor_wayland_get_subsurface_rect (surface_actor,
|
||||
&subsurface_rect);
|
||||
|
||||
geom.x = parent_x + subsurface_rect.x;
|
||||
geom.y = parent_x + subsurface_rect.y;
|
||||
geom.width = subsurface_rect.width;
|
||||
geom.height = subsurface_rect.height;
|
||||
|
||||
meta_rectangle_union (total_geometry, &geom, total_geometry);
|
||||
|
||||
for (l = surface->subsurfaces; l != NULL; l = l->next)
|
||||
{
|
||||
MetaWaylandSurface *subsurface = l->data;
|
||||
meta_wayland_surface_calculate_window_geometry (subsurface,
|
||||
total_geometry,
|
||||
subsurface_rect.x,
|
||||
subsurface_rect.y);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_wayland_surface_destroy_window (MetaWaylandSurface *surface)
|
||||
{
|
||||
|
@ -278,10 +278,6 @@ MetaWaylandSurface * meta_wayland_surface_role_get_surface (MetaWaylandSurfaceRo
|
||||
|
||||
cairo_region_t * meta_wayland_surface_calculate_input_region (MetaWaylandSurface *surface);
|
||||
|
||||
void meta_wayland_surface_calculate_window_geometry (MetaWaylandSurface *surface,
|
||||
MetaRectangle *total_geometry,
|
||||
float parent_x,
|
||||
float parent_y);
|
||||
|
||||
void meta_wayland_surface_destroy_window (MetaWaylandSurface *surface);
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "wayland/meta-wayland-popup.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-seat.h"
|
||||
#include "wayland/meta-wayland-shell-surface.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-wayland-versions.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
@ -564,6 +565,8 @@ wl_shell_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
{
|
||||
MetaWaylandWlShellSurface *wl_shell_surface =
|
||||
META_WAYLAND_WL_SHELL_SURFACE (surface_role);
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (wl_shell_surface);
|
||||
MetaWaylandSurfaceRoleClass *surface_role_class;
|
||||
MetaWaylandSurface *surface =
|
||||
meta_wayland_surface_role_get_surface (surface_role);
|
||||
@ -596,7 +599,7 @@ wl_shell_surface_role_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
if (!pending->newly_attached)
|
||||
return;
|
||||
|
||||
meta_wayland_surface_calculate_window_geometry (surface, &geom, 0, 0);
|
||||
meta_wayland_shell_surface_calculate_geometry (shell_surface, &geom);
|
||||
meta_window_wayland_move_resize (window,
|
||||
NULL,
|
||||
geom, pending->dx, pending->dy);
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "wayland/meta-wayland-popup.h"
|
||||
#include "wayland/meta-wayland-private.h"
|
||||
#include "wayland/meta-wayland-seat.h"
|
||||
#include "wayland/meta-wayland-shell-surface.h"
|
||||
#include "wayland/meta-wayland-surface.h"
|
||||
#include "wayland/meta-wayland-versions.h"
|
||||
#include "wayland/meta-window-wayland.h"
|
||||
@ -1230,6 +1231,8 @@ meta_wayland_xdg_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
MetaWaylandPendingState *pending)
|
||||
{
|
||||
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
|
||||
MetaWaylandShellSurface *shell_surface =
|
||||
META_WAYLAND_SHELL_SURFACE (xdg_surface);
|
||||
MetaWaylandXdgSurfacePrivate *priv =
|
||||
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
|
||||
MetaWaylandSurface *surface =
|
||||
@ -1283,9 +1286,8 @@ meta_wayland_xdg_surface_commit (MetaWaylandSurfaceRole *surface_role,
|
||||
/* 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,
|
||||
&new_geometry,
|
||||
0, 0);
|
||||
meta_wayland_shell_surface_calculate_geometry (shell_surface,
|
||||
&new_geometry);
|
||||
if (!meta_rectangle_equal (&new_geometry, &priv->geometry))
|
||||
{
|
||||
pending->has_new_geometry = TRUE;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "window-private.h"
|
||||
#include "boxes-private.h"
|
||||
#include "stack-tracker.h"
|
||||
#include "meta-wayland-actor-surface.h"
|
||||
#include "meta-wayland-private.h"
|
||||
#include "meta-wayland-surface.h"
|
||||
#include "meta-wayland-xdg-shell.h"
|
||||
@ -491,15 +492,13 @@ meta_window_wayland_main_monitor_changed (MetaWindow *window,
|
||||
window,
|
||||
TRUE);
|
||||
|
||||
/* The surface actor needs to update the scale recursively for itself and all
|
||||
* its subsurfaces */
|
||||
surface = window->surface;
|
||||
if (surface)
|
||||
{
|
||||
MetaSurfaceActorWayland *actor =
|
||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||
MetaWaylandActorSurface *actor_surface =
|
||||
META_WAYLAND_ACTOR_SURFACE (surface->role);
|
||||
|
||||
meta_surface_actor_wayland_sync_state_recursive (actor);
|
||||
meta_wayland_actor_surface_sync_actor_state (actor_surface);
|
||||
}
|
||||
|
||||
wl_window->geometry_scale = geometry_scale;
|
||||
|
Loading…
Reference in New Issue
Block a user