wayland/xdg-shell: Scale positioner coordinates
authorJonas Ådahl <jadahl@gmail.com>
Thu, 13 Oct 2016 05:56:00 +0000 (13:56 +0800)
committerPeter Michael Green <plugwash@raspbian.org>
Fri, 21 Oct 2016 23:24:13 +0000 (23:24 +0000)
When the monitor is scaled (i.e. HiDPI scaling) the placement coordinates
ere still in unscaled xdg_surface window geometry coordinate space when
used to place the window. Fix this by scaling the coordinates by the
monitor scale of the parent toplevel window before using them.

https://bugzilla.gnome.org/show_bug.cgi?id=771841

Gbp-Pq: Name wayland-xdg-shell-Scale-positioner-coordinates.patch

src/wayland/meta-wayland-xdg-shell.c

index 4e572dcd9d155693d42104e8ffcfd6c5c41ffb27..005e753d0c466ba1e3e60126bf5fadb49e9b634c 100644 (file)
@@ -109,6 +109,11 @@ struct _MetaWaylandXdgPopup
 
   struct {
     MetaWaylandSurface *parent_surface;
+
+    /*
+     * The coordinates/dimensions in the placement rule are in logical pixel
+     * coordinate space, i.e. not scaled given what monitor the popup is on.
+     */
     MetaPlacementRule placement_rule;
 
     MetaWaylandSeat *grab_seat;
@@ -757,6 +762,22 @@ meta_wayland_xdg_toplevel_class_init (MetaWaylandXdgToplevelClass *klass)
     xdg_toplevel_role_shell_client_destroyed;
 }
 
+static void
+scale_placement_rule (MetaPlacementRule  *placement_rule,
+                      MetaWaylandSurface *surface)
+{
+  int monitor_scale = surface->window->monitor->scale;
+
+  placement_rule->anchor_rect.x *= monitor_scale;
+  placement_rule->anchor_rect.y *= monitor_scale;
+  placement_rule->anchor_rect.width *= monitor_scale;
+  placement_rule->anchor_rect.height *= monitor_scale;
+  placement_rule->offset_x *= monitor_scale;
+  placement_rule->offset_y *= monitor_scale;
+  placement_rule->width *= monitor_scale;
+  placement_rule->height *= monitor_scale;
+}
+
 static void
 finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
 {
@@ -764,14 +785,13 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
   MetaWaylandSurface *surface =
     meta_wayland_surface_role_get_surface (surface_role);
   MetaWaylandSurface *parent_surface;
-  MetaPlacementRule placement_rule;
+  MetaPlacementRule scaled_placement_rule;
   MetaWaylandSeat *seat;
   uint32_t serial;
   MetaDisplay *display = meta_get_display ();
   MetaWindow *window;
 
   parent_surface = xdg_popup->setup.parent_surface;
-  placement_rule = xdg_popup->setup.placement_rule;
   seat = xdg_popup->setup.grab_seat;
   serial = xdg_popup->setup.grab_serial;
 
@@ -795,7 +815,10 @@ finish_popup_setup (MetaWaylandXdgPopup *xdg_popup)
   window = meta_window_wayland_new (display, surface);
   meta_wayland_surface_set_window (surface, window);
   meta_window_update_monitor (window, FALSE);
-  meta_window_place_with_placement_rule (window, &placement_rule);
+
+  scaled_placement_rule = xdg_popup->setup.placement_rule;
+  scale_placement_rule (&scaled_placement_rule, surface);
+  meta_window_place_with_placement_rule (window, &scaled_placement_rule);
 
   if (seat)
     {