From 7f99492c269f541c81e4f36742ecc3f0b4ebac04 Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Wed, 20 Dec 2017 14:03:18 -0500 Subject: Support panel auto-scaling for HiDPI displays *Fix scaling of panel widgets, buttons, and the menu bar *Draw grab handles at the ends of the panel *Fix size of _almost_ all included applets *Fix panel snapping coordinates *Down-scale monitor coordinates to support multi-monitors Author: Victor Kareh Date: Wed Dec 20 14:03:18 2017 -0500 --- mate-panel/main.c | 3 --- mate-panel/panel-run-dialog.c | 4 +++- mate-panel/panel-struts.c | 11 ++++++----- mate-panel/panel-struts.h | 3 ++- mate-panel/panel-toplevel.c | 41 ++++++++++++++++++++++++++++++++--------- mate-panel/panel-widget.c | 18 ++++++++++++------ 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/mate-panel/main.c b/mate-panel/main.c index 06fdc2f4..4289c158 100644 --- a/mate-panel/main.c +++ b/mate-panel/main.c @@ -85,9 +85,6 @@ main (int argc, char **argv) gtk_init (&argc, &argv); - /* FIXME: High dpi scaling does not work... */ - gdk_x11_display_set_window_scale (gdk_display_get_default (), 1); - error = NULL; if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("%s\n", error->message); diff --git a/mate-panel/panel-run-dialog.c b/mate-panel/panel-run-dialog.c index e00d0c51..a696138e 100644 --- a/mate-panel/panel-run-dialog.c +++ b/mate-panel/panel-run-dialog.c @@ -1695,6 +1695,7 @@ panel_run_dialog_setup_entry (PanelRunDialog *dialog, GdkScreen *screen; int width_request; GtkWidget *entry; + gint scale; dialog->combobox = PANEL_GTK_BUILDER_GET (gui, "comboboxentry"); @@ -1707,9 +1708,10 @@ 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_WINDOW (dialog->run_dialog)); /* 1/4 the width of the first monitor should be a good value */ - width_request = panel_multiscreen_width (screen, 0) / 4; + width_request = panel_multiscreen_width (screen, 0) / (4 * scale); 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 644dafb0..d59587e5 100644 --- a/mate-panel/panel-struts.c +++ b/mate-panel/panel-struts.c @@ -404,7 +404,8 @@ panel_struts_register_strut (PanelToplevel *toplevel, PanelOrientation orientation, int strut_size, int strut_start, - int strut_end) + int strut_end, + gint scale) { PanelStrut *strut; gboolean new_strut = FALSE; @@ -440,24 +441,24 @@ panel_struts_register_strut (PanelToplevel *toplevel, strut->geometry.x = strut->strut_start; strut->geometry.y = monitor_y; strut->geometry.width = strut->strut_end - strut->strut_start + 1; - strut->geometry.height = strut->strut_size; + strut->geometry.height = strut->strut_size / scale; break; case PANEL_ORIENTATION_BOTTOM: strut->geometry.x = strut->strut_start; strut->geometry.y = monitor_y + monitor_height - strut->strut_size; strut->geometry.width = strut->strut_end - strut->strut_start + 1; - strut->geometry.height = strut->strut_size; + strut->geometry.height = strut->strut_size / scale; break; case PANEL_ORIENTATION_LEFT: strut->geometry.x = monitor_x; strut->geometry.y = strut->strut_start; - strut->geometry.width = strut->strut_size; + strut->geometry.width = strut->strut_size / scale; strut->geometry.height = strut->strut_end - strut->strut_start + 1; break; case PANEL_ORIENTATION_RIGHT: strut->geometry.x = monitor_x + monitor_width - strut->strut_size; strut->geometry.y = strut->strut_start; - strut->geometry.width = strut->strut_size; + strut->geometry.width = strut->strut_size / scale; strut->geometry.height = strut->strut_end - strut->strut_start + 1; break; } diff --git a/mate-panel/panel-struts.h b/mate-panel/panel-struts.h index b96b93e6..e7d8185f 100644 --- a/mate-panel/panel-struts.h +++ b/mate-panel/panel-struts.h @@ -36,7 +36,8 @@ gboolean panel_struts_register_strut (PanelToplevel *toplevel, PanelOrientation orientation, int strut_size, int strut_start, - int strut_end); + int strut_end, + gint scale); void panel_struts_unregister_strut (PanelToplevel *toplevel); diff --git a/mate-panel/panel-toplevel.c b/mate-panel/panel-toplevel.c index 7aa61e42..42b09d35 100644 --- a/mate-panel/panel-toplevel.c +++ b/mate-panel/panel-toplevel.c @@ -83,6 +83,7 @@ struct _PanelToplevelPrivate { gboolean expand; PanelOrientation orientation; int size; + gint scale; /* relative to the monitor origin */ int x; @@ -284,8 +285,15 @@ static GdkScreen* panel_toplevel_get_screen_geometry(PanelToplevel* toplevel, in screen = gtk_window_get_screen(GTK_WINDOW(toplevel)); - *width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen)); - *height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen)); + /* 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_monitor_geometry() */ + *width = WidthOfScreen (gdk_x11_screen_get_xscreen (screen)) / toplevel->priv->scale; + *height = HeightOfScreen (gdk_x11_screen_get_xscreen (screen)) / toplevel->priv->scale; return screen; } @@ -299,17 +307,24 @@ 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); - if (y) *y = panel_multiscreen_y(screen, toplevel->priv->monitor); + 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; + /* 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); + *width = panel_multiscreen_width(screen, toplevel->priv->monitor) / toplevel->priv->scale; } if (height) { - *height = panel_multiscreen_height(screen, toplevel->priv->monitor); + *height = panel_multiscreen_height(screen, toplevel->priv->monitor) / toplevel->priv->scale; } return screen; @@ -1504,6 +1519,10 @@ static gboolean panel_toplevel_update_struts(PanelToplevel* toplevel, gboolean e } } + /* Adjust strut size based on scale factor */ + if (strut > 0) + strut += toplevel->priv->size * (toplevel->priv->scale - 1); + if (orientation != toplevel->priv->orientation) { toplevel->priv->orientation = orientation; g_object_notify (G_OBJECT (toplevel), "orientation"); @@ -1519,7 +1538,8 @@ static gboolean panel_toplevel_update_struts(PanelToplevel* toplevel, gboolean e orientation, strut, strut_start, - strut_end); + strut_end, + toplevel->priv->scale); else panel_struts_unregister_strut (toplevel); @@ -2336,7 +2356,8 @@ panel_toplevel_update_size_from_hints (PanelToplevel *toplevel, int total_size; int full_hints; - total_size = non_panel_widget_size + requisition_size; + /* Scale down the size so that the panel only takes what it needs for the applets it has. */ + total_size = non_panel_widget_size + (requisition_size / toplevel->priv->scale); nb_size_hints = toplevel->priv->panel_widget->nb_applets_size_hints; if (nb_size_hints <= 0) @@ -4317,7 +4338,7 @@ panel_toplevel_class_init (PanelToplevelClass *klass) widget_class->button_press_event = panel_toplevel_button_press_event; widget_class->button_release_event = panel_toplevel_button_release_event; #if GTK_CHECK_VERSION (3, 18, 0) - widget_class->configure_event = panel_toplevel_configure_event; + widget_class->configure_event = panel_toplevel_configure_event; #endif widget_class->key_press_event = panel_toplevel_key_press_event; widget_class->motion_notify_event = panel_toplevel_motion_notify_event; @@ -4752,6 +4773,7 @@ panel_toplevel_init (PanelToplevel *toplevel) toplevel->priv->expand = TRUE; toplevel->priv->orientation = PANEL_ORIENTATION_BOTTOM; toplevel->priv->size = DEFAULT_SIZE; + toplevel->priv->scale = gtk_widget_get_scale_factor (GTK_WIDGET (toplevel)); toplevel->priv->x = 0; toplevel->priv->y = 0; toplevel->priv->x_right = -1; @@ -4826,6 +4848,7 @@ panel_toplevel_init (PanelToplevel *toplevel) toplevel->priv->attach_hidden = FALSE; toplevel->priv->updated_geometry_initial = FALSE; toplevel->priv->initial_animation_done = FALSE; + #if GTK_CHECK_VERSION (3, 18, 0) widget = GTK_WIDGET (toplevel); gtk_widget_add_events (widget, diff --git a/mate-panel/panel-widget.c b/mate-panel/panel-widget.c index cedcbb21..ce9d88b0 100644 --- a/mate-panel/panel-widget.c +++ b/mate-panel/panel-widget.c @@ -1214,6 +1214,7 @@ panel_widget_get_preferred_size(GtkWidget *widget, GList *list; GList *ad_with_hints; gboolean dont_fill; + gint scale; g_return_if_fail(PANEL_IS_WIDGET(widget)); g_return_if_fail(minimum_size != NULL); @@ -1231,6 +1232,7 @@ panel_widget_get_preferred_size(GtkWidget *widget, natural_size->height = minimum_size->height; ad_with_hints = NULL; + scale = gtk_widget_get_scale_factor(widget); for (list = panel->applet_list; list!=NULL; list = g_list_next(list)) { AppletData *ad = list->data; @@ -1254,8 +1256,10 @@ panel_widget_get_preferred_size(GtkWidget *widget, else if (panel->packed) { - minimum_size->width += child_min_size.width; - natural_size->width += child_natural_size.width; + /* Just because everything is bigger when scaled up doesn't mean + * that the applets need any less room when the panel is packed. */ + minimum_size->width += child_min_size.width * scale; + natural_size->width += child_natural_size.width * scale; } } else { if (minimum_size->width < child_min_size.width && @@ -1271,8 +1275,10 @@ panel_widget_get_preferred_size(GtkWidget *widget, else if (panel->packed) { - minimum_size->height += child_min_size.height; - natural_size->height += child_natural_size.height; + /* Just because everything is bigger when scaled up doesn't mean + * that the applets need any less room when the panel is packed. */ + minimum_size->height += child_min_size.height * scale; + natural_size->height += child_natural_size.height * scale; } } } @@ -1409,9 +1415,9 @@ panel_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocation) gtk_widget_set_allocation (widget, allocation); if (gtk_widget_get_realized (widget)) gdk_window_move_resize (gtk_widget_get_window (widget), - allocation->x, + allocation->x, allocation->y, - allocation->width, + allocation->width, allocation->height); if(panel->orient == GTK_ORIENTATION_HORIZONTAL) -- cgit v1.2.1