From 87a376956154563d72192f74608b46622aaa753a Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Sat, 24 Feb 2018 11:02:15 -0500 Subject: Scale monitor geometries down to device pixels to support multiple monitors in HiDPI --- mate-panel/panel-multiscreen.c | 33 +++++++++++++++++++++++++++------ mate-panel/panel-run-dialog.c | 4 +--- mate-panel/panel-struts.c | 15 +++++++++++---- mate-panel/panel-toplevel.c | 18 +++++------------- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/mate-panel/panel-multiscreen.c b/mate-panel/panel-multiscreen.c index d2e43862..4aabe77d 100644 --- a/mate-panel/panel-multiscreen.c +++ b/mate-panel/panel-multiscreen.c @@ -88,11 +88,14 @@ panel_multiscreen_get_randr_monitors_for_screen (GdkScreen *screen, GdkRectangle **geometries_ret) { #ifdef HAVE_RANDR + GdkDisplay *display; + GdkMonitor *monitor; Display *xdisplay; Window xroot; XRRScreenResources *resources; RROutput primary; GArray *geometries; + int scale; int i; if (!have_randr) @@ -138,6 +141,11 @@ panel_multiscreen_get_randr_monitors_for_screen (GdkScreen *screen, return FALSE; primary = XRRGetOutputPrimary (xdisplay, xroot); + display = gdk_screen_get_display (screen); + monitor = gdk_display_get_primary_monitor (display); + + /* Use scale factor to bring geometries down to device pixels to support HiDPI displays */ + scale = gdk_monitor_get_scale_factor (monitor); geometries = g_array_sized_new (FALSE, FALSE, sizeof (GdkRectangle), @@ -157,10 +165,10 @@ panel_multiscreen_get_randr_monitors_for_screen (GdkScreen *screen, crtc = XRRGetCrtcInfo (xdisplay, resources, output->crtc); - rect.x = crtc->x; - rect.y = crtc->y; - rect.width = crtc->width; - rect.height = crtc->height; + rect.x = crtc->x / scale; + rect.y = crtc->y / scale; + rect.width = crtc->width / scale; + rect.height = crtc->height / scale; XRRFreeCrtcInfo (crtc); @@ -211,8 +219,21 @@ panel_multiscreen_get_gdk_monitors_for_screen (GdkScreen *screen, num_monitors = gdk_display_get_n_monitors (display); geometries = g_new (GdkRectangle, num_monitors); - for (i = 0; i < num_monitors; i++) - gdk_monitor_get_geometry (gdk_display_get_monitor (display, i), &(geometries[i])); + for (i = 0; i < num_monitors; i++) { + GdkMonitor *monitor; + int scale; + + monitor = gdk_display_get_monitor (display, i); + scale = gdk_monitor_get_scale_factor (monitor); + + gdk_monitor_get_geometry (monitor, &(geometries[i])); + + /* Scale geometries down to device pixels to support HiDPI displays */ + geometries[i].x /= scale; + geometries[i].y /= scale; + geometries[i].width /= scale; + geometries[i].height /= scale; + } *monitors_ret = num_monitors; *geometries_ret = geometries; diff --git a/mate-panel/panel-run-dialog.c b/mate-panel/panel-run-dialog.c index 50098cb1..38edf5e0 100644 --- a/mate-panel/panel-run-dialog.c +++ b/mate-panel/panel-run-dialog.c @@ -1708,7 +1708,6 @@ panel_run_dialog_setup_entry (PanelRunDialog *dialog, GdkScreen *screen; int width_request; GtkWidget *entry; - gint scale; dialog->combobox = PANEL_GTK_BUILDER_GET (gui, "comboboxentry"); @@ -1721,10 +1720,9 @@ panel_run_dialog_setup_entry (PanelRunDialog *dialog, (GTK_COMBO_BOX (dialog->combobox), 0); screen = gtk_window_get_screen (GTK_WINDOW (dialog->run_dialog)); - scale = gtk_widget_get_scale_factor (GTK_WIDGET (dialog->run_dialog)); /* 1/4 the width of the first monitor should be a good value */ - width_request = panel_multiscreen_width (screen, 0) / (4 * scale); + width_request = panel_multiscreen_width (screen, 0) / 4; g_object_set (G_OBJECT (dialog->combobox), "width_request", width_request, NULL); diff --git a/mate-panel/panel-struts.c b/mate-panel/panel-struts.c index d59587e5..f702f565 100644 --- a/mate-panel/panel-struts.c +++ b/mate-panel/panel-struts.c @@ -75,10 +75,17 @@ panel_struts_get_monitor_geometry (GdkScreen *screen, int *width, int *height) { - *x = panel_multiscreen_x (screen, monitor); - *y = panel_multiscreen_y (screen, monitor); - *width = panel_multiscreen_width (screen, monitor); - *height = panel_multiscreen_height (screen, monitor); + GdkDisplay *display; + int scale; + + /* Use scale factor to bring strut dimensions up to application pixels to support HiDPI displays */ + display = gdk_screen_get_display (screen); + scale = gdk_monitor_get_scale_factor (gdk_display_get_monitor (display, monitor)); + + *x = panel_multiscreen_x (screen, monitor) * scale; + *y = panel_multiscreen_y (screen, monitor) * scale; + *width = panel_multiscreen_width (screen, monitor) * scale; + *height = panel_multiscreen_height (screen, monitor) * scale; } static PanelStrut * diff --git a/mate-panel/panel-toplevel.c b/mate-panel/panel-toplevel.c index 19d14b3c..1737b381 100644 --- a/mate-panel/panel-toplevel.c +++ b/mate-panel/panel-toplevel.c @@ -290,8 +290,7 @@ static GdkScreen* panel_toplevel_get_screen_geometry(PanelToplevel* toplevel, in * sorts of awful misalignments and pretend it's all good. Or we can just * make this thing think that the screen is scaled down, and because GTK+ * already scaled everything up without the panel knowing about it, the whole - * thing somehow works well... sigh. - * @see panel_toplevel_get_monitor_geometry() */ + * thing somehow works well... sigh. */ *width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) / toplevel->priv->scale; *height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) / toplevel->priv->scale; @@ -307,24 +306,17 @@ static GdkScreen* panel_toplevel_get_monitor_geometry(PanelToplevel* toplevel, i screen = gtk_window_get_screen(GTK_WINDOW(toplevel)); - if (x) *x = panel_multiscreen_x(screen, toplevel->priv->monitor) / toplevel->priv->scale; - if (y) *y = panel_multiscreen_y(screen, toplevel->priv->monitor) / toplevel->priv->scale; + if (x) *x = panel_multiscreen_x(screen, toplevel->priv->monitor); + if (y) *y = panel_multiscreen_y(screen, toplevel->priv->monitor); - /* To scale the panels up for HiDPI displays, we can either multiply a lot of - * toplevel geometry attributes by the scale factor, then correct for all - * sorts of awful misalignments and pretend it's all good. Or we can just - * make this thing think that the screen is scaled down, and because GTK+ - * already scaled everything up without the panel knowing about it, the whole - * thing somehow works well... sigh. - * @see panel_toplevel_get_screen_geometry() */ if (width) { - *width = panel_multiscreen_width(screen, toplevel->priv->monitor) / toplevel->priv->scale; + *width = panel_multiscreen_width(screen, toplevel->priv->monitor); } if (height) { - *height = panel_multiscreen_height(screen, toplevel->priv->monitor) / toplevel->priv->scale; + *height = panel_multiscreen_height(screen, toplevel->priv->monitor); } return screen; -- cgit v1.2.1