[mutter] wayland/dnd-surface: Apply surface offset



commit 5cfea4fee322508563844d8e7761719b1c3083eb
Author: Robert Mader <robert mader posteo de>
Date:   Mon Jul 15 13:46:00 2019 +0200

    wayland/dnd-surface: Apply surface offset
    
    The surface offset allows an application to move itself in relative
    coordinates to its previous position. It is rather ill defined and
    partly incompatible with other functionality, which is why we ignore
    it generally.
    
    For dnd-surfaces though, it is the de-facto standard for applications
    to properly position the dnd-icon below the cursor. Therefore apply
    the offset on actor sync by setting the feedback actor anchor.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/684

 src/wayland/meta-wayland-dnd-surface.c | 51 ++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)
---
diff --git a/src/wayland/meta-wayland-dnd-surface.c b/src/wayland/meta-wayland-dnd-surface.c
index ae60f53e8..c83bb0c52 100644
--- a/src/wayland/meta-wayland-dnd-surface.c
+++ b/src/wayland/meta-wayland-dnd-surface.c
@@ -21,9 +21,13 @@
 
 #include "wayland/meta-wayland-dnd-surface.h"
 
+#include "compositor/meta-feedback-actor-private.h"
+
 struct _MetaWaylandSurfaceRoleDND
 {
   MetaWaylandActorSurface parent;
+  int32_t pending_offset_x;
+  int32_t pending_offset_y;
 };
 
 G_DEFINE_TYPE (MetaWaylandSurfaceRoleDND,
@@ -45,14 +49,57 @@ dnd_surface_commit (MetaWaylandSurfaceRole  *surface_role,
 {
   MetaWaylandSurface *surface =
     meta_wayland_surface_role_get_surface (surface_role);
+  MetaWaylandSurfaceRoleDND *surface_role_dnd =
+    META_WAYLAND_SURFACE_ROLE_DND (surface_role);
   MetaWaylandSurfaceRoleClass *surface_role_class =
     META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_surface_role_dnd_parent_class);
 
   meta_wayland_surface_queue_pending_state_frame_callbacks (surface, pending);
 
+  surface_role_dnd->pending_offset_x = pending->dx;
+  surface_role_dnd->pending_offset_y = pending->dy;
+
   surface_role_class->commit (surface_role, pending);
 }
 
+static void
+dnd_subsurface_sync_actor_state (MetaWaylandActorSurface *actor_surface)
+{
+  MetaSurfaceActor *surface_actor =
+    meta_wayland_actor_surface_get_actor (actor_surface);
+  MetaFeedbackActor *feedback_actor =
+    META_FEEDBACK_ACTOR (clutter_actor_get_parent (CLUTTER_ACTOR (surface_actor)));
+  MetaWaylandSurfaceRole *surface_role =
+    META_WAYLAND_SURFACE_ROLE (actor_surface);
+  MetaWaylandSurfaceRoleDND *surface_role_dnd =
+    META_WAYLAND_SURFACE_ROLE_DND (surface_role);
+  MetaWaylandSurface *surface =
+    meta_wayland_surface_role_get_surface (surface_role);
+  MetaWaylandActorSurfaceClass *actor_surface_class =
+    META_WAYLAND_ACTOR_SURFACE_CLASS (meta_wayland_surface_role_dnd_parent_class);
+  float geometry_scale;
+  float actor_scale;
+  float anchor_x;
+  float anchor_y;
+  float new_anchor_x;
+  float new_anchor_y;
+
+  g_return_if_fail (META_IS_FEEDBACK_ACTOR (feedback_actor));
+
+  geometry_scale =
+    meta_wayland_actor_surface_get_geometry_scale (actor_surface);
+  actor_scale = geometry_scale / surface->scale;
+
+  meta_feedback_actor_get_anchor (feedback_actor, &anchor_x, &anchor_y);
+  new_anchor_x = anchor_x - surface_role_dnd->pending_offset_x / actor_scale;
+  new_anchor_y = anchor_y - surface_role_dnd->pending_offset_y / actor_scale;
+  meta_feedback_actor_set_anchor (feedback_actor,
+                                  new_anchor_x,
+                                  new_anchor_y);
+
+  actor_surface_class->sync_actor_state (actor_surface);
+}
+
 static void
 meta_wayland_surface_role_dnd_init (MetaWaylandSurfaceRoleDND *role)
 {
@@ -63,7 +110,11 @@ meta_wayland_surface_role_dnd_class_init (MetaWaylandSurfaceRoleDNDClass *klass)
 {
   MetaWaylandSurfaceRoleClass *surface_role_class =
     META_WAYLAND_SURFACE_ROLE_CLASS (klass);
+  MetaWaylandActorSurfaceClass *actor_surface_class =
+    META_WAYLAND_ACTOR_SURFACE_CLASS (klass);
 
   surface_role_class->assigned = dnd_surface_assigned;
   surface_role_class->commit = dnd_surface_commit;
+
+  actor_surface_class->sync_actor_state = dnd_subsurface_sync_actor_state;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]