Skip to content
Permalink
Browse files

Scale monitor geometries down to device pixels to support multiple mo…

…nitors in HiDPI
  • Loading branch information...
vkareh committed Feb 24, 2018
1 parent b08bc13 commit 87a376956154563d72192f74608b46622aaa753a
Showing with 44 additions and 26 deletions.
  1. +27 −6 mate-panel/panel-multiscreen.c
  2. +1 −3 mate-panel/panel-run-dialog.c
  3. +11 −4 mate-panel/panel-struts.c
  4. +5 −13 mate-panel/panel-toplevel.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;
@@ -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);
@@ -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 *
@@ -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;

0 comments on commit 87a3769

Please sign in to comment.
You can’t perform that action at this time.