mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05:00
wayland: Fix subsurface positioning on HiDPI
Keep the active position state in its original coordinate space, and synchronize the surface actor with it when it changes and when synchronizing the rest of the surface state, in case the surface scale had changed. https://bugzilla.gnome.org/show_bug.cgi?id=745655
This commit is contained in:
parent
117f57f74c
commit
3b993131e8
@ -102,6 +102,45 @@ meta_surface_actor_wayland_get_scale (MetaSurfaceActorWayland *actor)
|
|||||||
return (double)output_scale / (double)priv->surface->scale;
|
return (double)output_scale / (double)priv->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 monitor_scale = 1;
|
||||||
|
|
||||||
|
toplevel_window = meta_wayland_surface_get_toplevel_window (surface);
|
||||||
|
if (toplevel_window)
|
||||||
|
monitor_scale = meta_window_wayland_get_main_monitor_scale (toplevel_window);
|
||||||
|
|
||||||
|
*x = *x * monitor_scale;
|
||||||
|
*y = *y * monitor_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;
|
||||||
|
|
||||||
|
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
|
void
|
||||||
meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
||||||
{
|
{
|
||||||
@ -148,16 +187,21 @@ meta_surface_actor_wayland_sync_state (MetaSurfaceActorWayland *self)
|
|||||||
scaled_opaque_region);
|
scaled_opaque_region);
|
||||||
cairo_region_destroy (scaled_opaque_region);
|
cairo_region_destroy (scaled_opaque_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_surface_actor_wayland_sync_subsurface_state (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
|
meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
MetaWaylandSurface *surface = meta_surface_actor_wayland_get_surface (self);
|
||||||
|
MetaWindow *window = meta_wayland_surface_get_toplevel_window (surface);
|
||||||
GList *iter;
|
GList *iter;
|
||||||
|
|
||||||
meta_surface_actor_wayland_sync_state (self);
|
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)
|
for (iter = surface->subsurfaces; iter != NULL; iter = iter->next)
|
||||||
{
|
{
|
||||||
MetaWaylandSurface *subsurf = iter->data;
|
MetaWaylandSurface *subsurf = iter->data;
|
||||||
@ -165,6 +209,7 @@ meta_surface_actor_wayland_sync_state_recursive (MetaSurfaceActorWayland *self)
|
|||||||
meta_surface_actor_wayland_sync_state_recursive (
|
meta_surface_actor_wayland_sync_state_recursive (
|
||||||
META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
|
META_SURFACE_ACTOR_WAYLAND (subsurf->surface_actor));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -70,6 +70,8 @@ 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_state_recursive (MetaSurfaceActorWayland *self);
|
||||||
|
|
||||||
|
void meta_surface_actor_wayland_sync_subsurface_state (MetaSurfaceActorWayland *self);
|
||||||
|
|
||||||
gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
|
gboolean meta_surface_actor_wayland_is_on_monitor (MetaSurfaceActorWayland *self,
|
||||||
MetaMonitorInfo *monitor);
|
MetaMonitorInfo *monitor);
|
||||||
|
|
||||||
|
@ -382,18 +382,13 @@ static void
|
|||||||
subsurface_surface_commit (MetaWaylandSurface *surface,
|
subsurface_surface_commit (MetaWaylandSurface *surface,
|
||||||
MetaWaylandPendingState *pending)
|
MetaWaylandPendingState *pending)
|
||||||
{
|
{
|
||||||
MetaSurfaceActor *surface_actor = surface->surface_actor;
|
MetaSurfaceActorWayland *surface_actor =
|
||||||
float x, y;
|
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor);
|
||||||
|
|
||||||
if (surface->buffer != NULL)
|
if (surface->buffer != NULL)
|
||||||
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
clutter_actor_show (CLUTTER_ACTOR (surface_actor));
|
||||||
else
|
else
|
||||||
clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
|
clutter_actor_hide (CLUTTER_ACTOR (surface_actor));
|
||||||
|
|
||||||
clutter_actor_get_position (CLUTTER_ACTOR (surface_actor), &x, &y);
|
|
||||||
x += pending->dx;
|
|
||||||
y += pending->dy;
|
|
||||||
clutter_actor_set_position (CLUTTER_ACTOR (surface_actor), x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A non-subsurface is always desynchronized.
|
/* A non-subsurface is always desynchronized.
|
||||||
@ -427,9 +422,8 @@ parent_surface_state_applied (gpointer data, gpointer user_data)
|
|||||||
|
|
||||||
if (surface->sub.pending_pos)
|
if (surface->sub.pending_pos)
|
||||||
{
|
{
|
||||||
clutter_actor_set_position (CLUTTER_ACTOR (surface->surface_actor),
|
surface->sub.x = surface->sub.pending_x;
|
||||||
surface->sub.pending_x,
|
surface->sub.y = surface->sub.pending_y;
|
||||||
surface->sub.pending_y);
|
|
||||||
surface->sub.pending_pos = FALSE;
|
surface->sub.pending_pos = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,6 +471,9 @@ parent_surface_state_applied (gpointer data, gpointer user_data)
|
|||||||
|
|
||||||
if (is_surface_effectively_synchronized (surface))
|
if (is_surface_effectively_synchronized (surface))
|
||||||
apply_pending_state (surface, &surface->sub.pending);
|
apply_pending_state (surface, &surface->sub.pending);
|
||||||
|
|
||||||
|
meta_surface_actor_wayland_sync_subsurface_state (
|
||||||
|
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -522,9 +519,6 @@ apply_pending_state (MetaWaylandSurface *surface,
|
|||||||
surface->input_region = cairo_region_reference (pending->input_region);
|
surface->input_region = cairo_region_reference (pending->input_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
meta_surface_actor_wayland_sync_state (
|
|
||||||
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
|
|
||||||
|
|
||||||
/* wl_surface.frame */
|
/* wl_surface.frame */
|
||||||
wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
|
wl_list_insert_list (&compositor->frame_callbacks, &pending->frame_callback_list);
|
||||||
wl_list_init (&pending->frame_callback_list);
|
wl_list_init (&pending->frame_callback_list);
|
||||||
@ -549,6 +543,9 @@ apply_pending_state (MetaWaylandSurface *surface,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta_surface_actor_wayland_sync_state (
|
||||||
|
META_SURFACE_ACTOR_WAYLAND (surface->surface_actor));
|
||||||
|
|
||||||
pending_state_reset (pending);
|
pending_state_reset (pending);
|
||||||
|
|
||||||
g_list_foreach (surface->subsurfaces, parent_surface_state_applied, NULL);
|
g_list_foreach (surface->subsurfaces, parent_surface_state_applied, NULL);
|
||||||
|
@ -136,6 +136,9 @@ struct _MetaWaylandSurface
|
|||||||
MetaWaylandSurface *parent;
|
MetaWaylandSurface *parent;
|
||||||
struct wl_listener parent_destroy_listener;
|
struct wl_listener parent_destroy_listener;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
/* When the surface is synchronous, its state will be applied
|
/* When the surface is synchronous, its state will be applied
|
||||||
* when the parent is committed. This is done by moving the
|
* when the parent is committed. This is done by moving the
|
||||||
* "real" pending state below to here when this surface is
|
* "real" pending state below to here when this surface is
|
||||||
|
Loading…
Reference in New Issue
Block a user