Merge lp:~3v1n0/unity/monitor-scaling-pos into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Brandon Schaefer
Approved revision: no longer in the source branch.
Merged at revision: 3854
Proposed branch: lp:~3v1n0/unity/monitor-scaling-pos
Merge into: lp:unity
Diff against target: 152 lines (+69/-18)
2 files modified
services/panel-service.c (+44/-6)
unity-shared/UScreen.cpp (+25/-12)
To merge this branch: bzr merge lp:~3v1n0/unity/monitor-scaling-pos
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Brandon Schaefer (community) Approve
Review via email: mp+229693@code.launchpad.net

Commit message

UScreen, PanelService: get monitor at position, ignoring pre-multipled Gdk scale factor

Get monitor position based on absolute coordinates, ignoring the pre-multipled
scaling factor that Gdk applies to all the monitor sizes.

In this way we get the proper monitor index for absolute coordinates,
independently from the scaling factor.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'services/panel-service.c'
2--- services/panel-service.c 2014-04-29 18:48:45 +0000
3+++ services/panel-service.c 2014-08-05 21:27:47 +0000
4@@ -276,6 +276,15 @@
5 g_type_class_add_private (obj_class, sizeof (PanelServicePrivate));
6 }
7
8+static gboolean
9+is_point_in_rect (gint x, gint y, GdkRectangle* rect)
10+{
11+ g_return_val_if_fail (rect, FALSE);
12+
13+ return (x >= rect->x && x <= (rect->x + rect->width) &&
14+ y >= rect->y && y <= (rect->y + rect->height));
15+}
16+
17 IndicatorObjectEntry *
18 get_entry_at (PanelService *self, gint x, gint y)
19 {
20@@ -293,8 +302,7 @@
21 IndicatorObjectEntry *entry = k;
22 GdkRectangle *geo = v;
23
24- if (x >= geo->x && x <= (geo->x + geo->width) &&
25- y >= geo->y && y <= (geo->y + geo->height))
26+ if (is_point_in_rect (x, y, geo))
27 {
28 return entry;
29 }
30@@ -1624,11 +1632,41 @@
31 }
32
33 static int
34+get_monitor_at (gint x, gint y)
35+{
36+ gint i;
37+ gdouble scale;
38+ GdkScreen *screen = gdk_screen_get_default ();
39+ gint monitors = gdk_screen_get_n_monitors (screen);
40+
41+ for (i = 0; i < monitors; ++i)
42+ {
43+ GdkRectangle rect = { 0 };
44+ gdk_screen_get_monitor_geometry (screen, i, &rect);
45+ scale = gdk_screen_get_monitor_scale_factor (screen, i);
46+
47+ if (scale != 1.0)
48+ {
49+ rect.x *= scale;
50+ rect.y *= scale;
51+ rect.width *= scale;
52+ rect.height *= scale;
53+ }
54+
55+ if (is_point_in_rect (x, y, &rect))
56+ {
57+ return i;
58+ }
59+ }
60+
61+ return gdk_screen_get_monitor_at_point (screen, x, y);
62+}
63+
64+static int
65 get_monitor_scale_at (gint x, gint y)
66 {
67- GdkScreen *screen = gdk_screen_get_default ();
68- int monitor = gdk_screen_get_monitor_at_point (screen, x, y);
69- return gdk_screen_get_monitor_scale_factor (screen, monitor);
70+ gint monitor = get_monitor_at (x, y);
71+ return gdk_screen_get_monitor_scale_factor (gdk_screen_get_default (), monitor);
72 }
73
74 static void
75@@ -1642,7 +1680,7 @@
76 PanelServicePrivate *priv = self->priv;
77
78 GdkScreen *screen = gdk_screen_get_default ();
79- gint monitor = gdk_screen_get_monitor_at_point (screen, priv->last_x, priv->last_y);
80+ gint monitor = get_monitor_at (priv->last_x, priv->last_y);
81 gtk_menu_set_monitor (menu, monitor);
82
83 gint scale = gdk_screen_get_monitor_scale_factor (screen, monitor);
84
85=== modified file 'unity-shared/UScreen.cpp'
86--- unity-shared/UScreen.cpp 2014-04-08 16:29:49 +0000
87+++ unity-shared/UScreen.cpp 2014-08-05 21:27:47 +0000
88@@ -18,6 +18,8 @@
89
90 #include "UScreen.h"
91 #include <NuxCore/Logger.h>
92+#include <NuxCore/NuxCore.h>
93+#include <NuxGraphics/GraphicsDisplay.h>
94
95 namespace unity
96 {
97@@ -60,17 +62,8 @@
98
99 int UScreen::GetMonitorWithMouse() const
100 {
101- GdkDevice* device;
102- GdkDisplay *display;
103- int x;
104- int y;
105-
106- display = gdk_display_get_default();
107- device = gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(display));
108-
109- gdk_device_get_position(device, nullptr, &x, &y);
110-
111- return GetMonitorAtPosition(x, y);
112+ auto const& mouse = nux::GetGraphicsDisplay()->GetMouseScreenCoord();
113+ return GetMonitorAtPosition(mouse.x, mouse.y);
114 }
115
116 int UScreen::GetPrimaryMonitor() const
117@@ -80,6 +73,23 @@
118
119 int UScreen::GetMonitorAtPosition(int x, int y) const
120 {
121+ int monitors = gdk_screen_get_n_monitors(screen_);
122+
123+ for (int i = 0; i < monitors; ++i)
124+ {
125+ GdkRectangle rect = { 0 };
126+ gdk_screen_get_monitor_geometry(screen_, i, &rect);
127+
128+ float scale = gdk_screen_get_monitor_scale_factor(screen_, i);
129+ nux::Geometry geo(rect.x, rect.y, rect.width, rect.height);
130+
131+ if (scale != 1.0)
132+ geo = geo * scale;
133+
134+ if (geo.IsPointInside(x, y))
135+ return i;
136+ }
137+
138 return gdk_screen_get_monitor_at_point(screen_, x, y);
139 }
140
141@@ -151,7 +161,10 @@
142 gdk_screen_get_monitor_geometry(screen_, i, &rect);
143
144 float scale = gdk_screen_get_monitor_scale_factor(screen_, i);
145- nux::Geometry geo(rect.x*scale, rect.y*scale, rect.width*scale, rect.height*scale);
146+ nux::Geometry geo(rect.x, rect.y, rect.width, rect.height);
147+
148+ if (scale != 1.0)
149+ geo = geo * scale;
150
151 // Check for mirrored displays
152 if (geo == last_geo)