diff options
| author | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2014-08-05 23:21:39 +0200 |
|---|---|---|
| committer | Marco Trevisan (Treviño) <mail@3v1n0.net> | 2014-08-05 23:21:39 +0200 |
| commit | 0ab956e7d678e588455a5e3cdbd1dc7524c600c6 (patch) | |
| tree | ced5f2fa99f35886fca18f5ad21cfbf162108084 /services | |
| parent | 306bc106319317664e11d6d85a0d54978708040b (diff) | |
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 to attach the menu Fixes LP: #1351591 (bzr r3844.5.1)
Diffstat (limited to 'services')
| -rw-r--r-- | services/panel-service.c | 50 |
1 files changed, 44 insertions, 6 deletions
diff --git a/services/panel-service.c b/services/panel-service.c index a161cacbd..03e35c3ff 100644 --- a/services/panel-service.c +++ b/services/panel-service.c @@ -276,6 +276,15 @@ panel_service_class_init (PanelServiceClass *klass) g_type_class_add_private (obj_class, sizeof (PanelServicePrivate)); } +static gboolean +is_point_in_rect (gint x, gint y, GdkRectangle* rect) +{ + g_return_val_if_fail (rect, FALSE); + + return (x >= rect->x && x <= (rect->x + rect->width) && + y >= rect->y && y <= (rect->y + rect->height)); +} + IndicatorObjectEntry * get_entry_at (PanelService *self, gint x, gint y) { @@ -293,8 +302,7 @@ get_entry_at (PanelService *self, gint x, gint y) IndicatorObjectEntry *entry = k; GdkRectangle *geo = v; - if (x >= geo->x && x <= (geo->x + geo->width) && - y >= geo->y && y <= (geo->y + geo->height)) + if (is_point_in_rect (x, y, geo)) { return entry; } @@ -1624,11 +1632,41 @@ indicator_object_to_variant (IndicatorObject *object, const gchar *indicator_id, } static int -get_monitor_scale_at (gint x, gint y) +get_monitor_at (gint x, gint y) { + gint i; + gdouble scale; GdkScreen *screen = gdk_screen_get_default (); - int monitor = gdk_screen_get_monitor_at_point (screen, x, y); - return gdk_screen_get_monitor_scale_factor (screen, monitor); + gint monitors = gdk_screen_get_n_monitors (screen); + + for (i = 0; i < monitors; ++i) + { + GdkRectangle rect = { 0 }; + gdk_screen_get_monitor_geometry (screen, i, &rect); + scale = gdk_screen_get_monitor_scale_factor (screen, i); + + if (scale != 1.0) + { + rect.x *= scale; + rect.y *= scale; + rect.width *= scale; + rect.height *= scale; + } + + if (is_point_in_rect (x, y, &rect)) + { + return i; + } + } + + return gdk_screen_get_monitor_at_point (screen, x, y); +} + +static int +get_monitor_scale_at (gint x, gint y) +{ + gint monitor = get_monitor_at (x, y); + return gdk_screen_get_monitor_scale_factor (gdk_screen_get_default (), monitor); } static void @@ -1642,7 +1680,7 @@ positon_menu (GtkMenu *menu, PanelServicePrivate *priv = self->priv; GdkScreen *screen = gdk_screen_get_default (); - gint monitor = gdk_screen_get_monitor_at_point (screen, priv->last_x, priv->last_y); + gint monitor = get_monitor_at (priv->last_x, priv->last_y); gtk_menu_set_monitor (menu, monitor); gint scale = gdk_screen_get_monitor_scale_factor (screen, monitor); |
