From 57c3fb46993a730f01ba8619832dde119f53c863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberts=20Muktup=C4=81vels?= Date: Thu, 24 Mar 2016 02:34:11 +0200 Subject: libmetacity: scale window decorations on HiDPI displays As we opt out of GTK+/Clutter's HiDPI handling, we need to apply the window scaling factor manually to decorations, both the geometry and when drawing. Based on mutter commit: https://git.gnome.org/browse/mutter/commit/?id=57c1078ee742d9f01e80e7fe05c88adfec4b4ac3 --- libmetacity/meta-frame-style.c | 2 +- libmetacity/meta-style-info.c | 2 + libmetacity/meta-theme-gtk.c | 130 +++++++++++++++++++++------------ libmetacity/meta-theme-metacity.c | 146 ++++++++++++++++++++++++-------------- 4 files changed, 180 insertions(+), 100 deletions(-) diff --git a/libmetacity/meta-frame-style.c b/libmetacity/meta-frame-style.c index 15bd4f5f..32ee34aa 100644 --- a/libmetacity/meta-frame-style.c +++ b/libmetacity/meta-frame-style.c @@ -303,7 +303,7 @@ meta_frame_style_apply_scale (const MetaFrameStyle *style, PangoFontDescription *font_desc) { int size = pango_font_description_get_size (font_desc); - double scale = style->layout->title_scale; + double scale = style->layout->title_scale / get_window_scaling_factor (); pango_font_description_set_size (font_desc, MAX (size * scale, 1)); } diff --git a/libmetacity/meta-style-info.c b/libmetacity/meta-style-info.c index e415b8ca..d4af8730 100644 --- a/libmetacity/meta-style-info.c +++ b/libmetacity/meta-style-info.c @@ -20,6 +20,7 @@ #include "meta-frame-enums.h" #include "meta-style-info-private.h" +#include "meta-theme-impl-private.h" static void add_toplevel_class (GtkStyleContext *style, @@ -83,6 +84,7 @@ create_style_context (GtkStyleContext *parent, context = gtk_style_context_new (); gtk_style_context_set_path (context, path); gtk_style_context_set_parent (context, parent); + gtk_style_context_set_scale (context, get_window_scaling_factor ()); gtk_widget_path_unref (path); gtk_style_context_add_provider (context, GTK_STYLE_PROVIDER (provider), diff --git a/libmetacity/meta-theme-gtk.c b/libmetacity/meta-theme-gtk.c index 11e5664a..21f093e0 100644 --- a/libmetacity/meta-theme-gtk.c +++ b/libmetacity/meta-theme-gtk.c @@ -287,6 +287,7 @@ meta_theme_gtk_get_frame_borders (MetaThemeImpl *impl, { gint buttons_height; gint content_height; + gint scale; frame_layout_sync_with_style (layout, style_info, composited, flags); @@ -344,6 +345,13 @@ meta_theme_gtk_get_frame_borders (MetaThemeImpl *impl, borders->total.right = borders->invisible.right + borders->visible.right; borders->total.bottom = borders->invisible.bottom + borders->visible.bottom; borders->total.top = borders->invisible.top + borders->visible.top; + + /* Scale geometry for HiDPI, see comment in meta_theme_gtk_draw_frame () */ + scale = get_window_scaling_factor (); + + scale_border (&borders->visible, scale); + scale_border (&borders->invisible, scale); + scale_border (&borders->total, scale); } static MetaButtonSpace * @@ -479,6 +487,7 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, int button_y; int title_right_edge; int width, height; + int scale; int content_width, content_height; int button_width, button_height; int min_size_for_rounding; @@ -507,16 +516,22 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, fgeom->width = width; fgeom->height = height; + /* Scale geometry for HiDPI, see comment in meta_theme_gtk_draw_frame () */ + scale = get_window_scaling_factor (); + content_width = width - - borders.invisible.left - layout->gtk.frame_border.left - - borders.invisible.right - layout->gtk.frame_border.right; - content_height = borders.visible.top - layout->gtk.frame_border.top; + borders.invisible.left - layout->gtk.frame_border.left * scale - + borders.invisible.right - layout->gtk.frame_border.right * scale; + content_height = borders.visible.top - layout->gtk.frame_border.top * scale; button_width = MAX ((gint) layout->gtk.icon_size, layout->gtk.button_min_size.width) + layout->button_border.left + layout->button_border.right; button_height = MAX ((gint) layout->gtk.icon_size, layout->gtk.button_min_size.height) + layout->button_border.top + layout->button_border.bottom; + button_width *= scale; + button_height *= scale; + /* FIXME all this code sort of pretends that duplicate buttons * with the same function are allowed, but that breaks the * code in frames.c, so isn't really allowed right now. @@ -571,17 +586,17 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, space_used_by_buttons = 0; - space_used_by_buttons += layout->gtk.button_margin.left /** scale*/ * n_left; + space_used_by_buttons += layout->gtk.button_margin.left * scale * n_left; space_used_by_buttons += button_width * n_left; - space_used_by_buttons += layout->gtk.button_margin.right /** scale*/ * n_left; + space_used_by_buttons += layout->gtk.button_margin.right * scale * n_left; space_used_by_buttons += (button_width * 0.75) * n_left_spacers; - space_used_by_buttons += layout->gtk.titlebar_spacing * MAX (n_left - 1, 0); + space_used_by_buttons += layout->gtk.titlebar_spacing * scale * MAX (n_left - 1, 0); - space_used_by_buttons += layout->gtk.button_margin.left /** scale*/ * n_right; + space_used_by_buttons += layout->gtk.button_margin.left * scale * n_right; space_used_by_buttons += button_width * n_right; - space_used_by_buttons += layout->gtk.button_margin.right /** scale*/ * n_right; + space_used_by_buttons += layout->gtk.button_margin.right * scale * n_right; space_used_by_buttons += (button_width * 0.75) * n_right_spacers; - space_used_by_buttons += layout->gtk.titlebar_spacing * MAX (n_right - 1, 0); + space_used_by_buttons += layout->gtk.titlebar_spacing * scale * MAX (n_right - 1, 0); if (space_used_by_buttons <= content_width) break; /* Everything fits, bail out */ @@ -647,12 +662,12 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, fgeom->n_right_buttons = n_right; /* center buttons vertically */ - button_y = borders.invisible.top + layout->gtk.frame_border.top + + button_y = borders.invisible.top + layout->gtk.frame_border.top * scale + (content_height - button_height) / 2; /* right edge of farthest-right button */ - x = width - borders.invisible.right - layout->gtk.frame_border.right - - layout->gtk.titlebar_border.right; + x = width - borders.invisible.right - layout->gtk.frame_border.right * scale - + layout->gtk.titlebar_border.right * scale; i = n_right - 1; while (i >= 0) @@ -662,7 +677,7 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, if (x < 0) /* if we go negative, leave the buttons we don't get to as 0-width */ break; - x -= layout->gtk.button_margin.right /** scale*/; + x -= layout->gtk.button_margin.right * scale; rect = right_func_rects[i]; @@ -684,16 +699,16 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, rect->clickable.height = button_height; if (i == n_right - 1) - rect->clickable.width += layout->gtk.frame_border.right + - layout->gtk.titlebar_border.right; + rect->clickable.width += layout->gtk.frame_border.right * scale + + layout->gtk.titlebar_border.right * scale; } else g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); - x = rect->visible.x - layout->gtk.button_margin.left /** scale*/; + x = rect->visible.x - layout->gtk.button_margin.left * scale; if (i > 0) - x -= layout->gtk.titlebar_spacing; + x -= layout->gtk.titlebar_spacing * scale; --i; } @@ -704,14 +719,14 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, /* Now x changes to be position from the left and we go through * the left-side buttons */ - x = borders.invisible.left + layout->gtk.frame_border.left + - layout->gtk.titlebar_border.left; + x = borders.invisible.left + layout->gtk.frame_border.left * scale + + layout->gtk.titlebar_border.left * scale; for (i = 0; i < n_left; i++) { MetaButtonSpace *rect; - x += layout->gtk.button_margin.left /** scale*/; + x += layout->gtk.button_margin.left * scale; rect = left_func_rects[i]; @@ -730,16 +745,16 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, else g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); - x = rect->visible.x + rect->visible.width + layout->gtk.button_margin.right /** scale*/; + x = rect->visible.x + rect->visible.width + layout->gtk.button_margin.right * scale; if (i < n_left - 1) - x += layout->gtk.titlebar_spacing; + x += layout->gtk.titlebar_spacing * scale; if (left_buttons_has_spacer[i]) x += (button_width * 0.75); } /* Center vertically in the available content area */ fgeom->title_rect.x = x; - fgeom->title_rect.y = borders.invisible.top + layout->gtk.frame_border.top + + fgeom->title_rect.y = borders.invisible.top + layout->gtk.frame_border.top * scale + (content_height - text_height) / 2; fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x; fgeom->title_rect.height = text_height; @@ -755,7 +770,7 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, if (flags & META_FRAME_SHADED) min_size_for_rounding = 0; else - min_size_for_rounding = 5; + min_size_for_rounding = 5 * scale; fgeom->top_left_corner_rounded_radius = 0; fgeom->top_right_corner_rounded_radius = 0; @@ -763,14 +778,14 @@ meta_theme_gtk_calc_geometry (MetaThemeImpl *impl, fgeom->bottom_right_corner_rounded_radius = 0; if (borders.visible.top + borders.visible.left >= min_size_for_rounding) - fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius; + fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius * scale; if (borders.visible.top + borders.visible.right >= min_size_for_rounding) - fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius; + fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius * scale; if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding) - fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius; + fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius * scale; if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding) - fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius; + fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius * scale; } static const char * @@ -798,6 +813,7 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, GdkPixbuf *mini_icon, GdkPixbuf *icon) { + int scale; GtkStyleContext *context; GtkStateFlags state; MetaButtonType button_type; @@ -806,12 +822,26 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, GdkRectangle button_rect; const MetaFrameBorders *borders; + /* We opt out of GTK+ HiDPI handling, so we have to do the scaling + * ourselves; the nitty-gritty is a bit confusing, so here is an overview: + * - the values in MetaFrameLayout are always as they appear in the theme, + * i.e. unscaled + * - calculated values (borders, MetaFrameGeometry) include the scale - as + * the geometry is comprised of scaled decorations and the client size + * which we must not scale, we don't have another option + * - for drawing, we scale the canvas to have GTK+ render elements (borders, + * radii, ...) at the correct scale - as a result, we have to "unscale" + * the geometry again to not apply the scaling twice + */ + scale = get_window_scaling_factor (); + cairo_scale (cr, scale, scale); + borders = &fgeom->borders; - visible_rect.x = borders->invisible.left; - visible_rect.y = borders->invisible.top; - visible_rect.width = fgeom->width - borders->invisible.left - borders->invisible.right; - visible_rect.height = fgeom->height - borders->invisible.top - borders->invisible.bottom; + visible_rect.x = borders->invisible.left / scale; + visible_rect.y = borders->invisible.top / scale; + visible_rect.width = (fgeom->width - borders->invisible.left - borders->invisible.right) / scale; + visible_rect.height = (fgeom->height - borders->invisible.top - borders->invisible.bottom) / scale; meta_style_info_set_flags (style_info, flags); @@ -826,10 +856,10 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, if (flags & META_FRAME_FULLSCREEN) return; - titlebar_rect.x = visible_rect.x + borders->visible.left; + titlebar_rect.x = visible_rect.x + borders->visible.left / scale; titlebar_rect.y = visible_rect.y + style->layout->gtk.frame_border.top; - titlebar_rect.width = visible_rect.width - borders->visible.left - borders->visible.right; - titlebar_rect.height = borders->visible.top - style->layout->gtk.frame_border.top; + titlebar_rect.width = visible_rect.width - (borders->visible.left + borders->visible.right) / scale; + titlebar_rect.height = (borders->visible.top / scale) - style->layout->gtk.frame_border.top; context = style_info->styles[META_STYLE_ELEMENT_TITLEBAR]; gtk_render_background (context, cr, @@ -847,7 +877,7 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, pango_layout_set_width (title_layout, -1); pango_layout_get_pixel_extents (title_layout, NULL, &logical); - text_width = MIN(fgeom->title_rect.width, logical.width); + text_width = MIN(fgeom->title_rect.width / scale, logical.width); if (text_width < logical.width) pango_layout_set_width (title_layout, PANGO_SCALE * text_width); @@ -856,10 +886,10 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, x = titlebar_rect.x + (titlebar_rect.width - text_width) / 2; y = titlebar_rect.y + (titlebar_rect.height - logical.height) / 2; - if (x < fgeom->title_rect.x) - x = fgeom->title_rect.x; - else if (x + text_width > fgeom->title_rect.x + fgeom->title_rect.width) - x = fgeom->title_rect.x + fgeom->title_rect.width - text_width; + if (x < fgeom->title_rect.x / scale) + x = fgeom->title_rect.x / scale; + else if (x + text_width > (fgeom->title_rect.x + fgeom->title_rect.width) / scale) + x = (fgeom->title_rect.x + fgeom->title_rect.width) / scale - text_width; context = style_info->styles[META_STYLE_ELEMENT_TITLE]; gtk_render_layout (context, cr, x, y, title_layout); @@ -879,6 +909,11 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, get_button_rect (button_type, fgeom, 0, &button_rect); + button_rect.x /= scale; + button_rect.y /= scale; + button_rect.width /= scale; + button_rect.height /= scale; + button_state = map_button_state (button_type, fgeom, 0, button_states); if (button_state == META_BUTTON_STATE_PRELIGHT) @@ -947,7 +982,10 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, GtkIconTheme *theme = gtk_icon_theme_get_default (); GtkIconInfo *info; - info = gtk_icon_theme_lookup_icon (theme, icon_name, style->layout->gtk.icon_size, 0); + info = gtk_icon_theme_lookup_icon_for_scale (theme, icon_name, + style->layout->gtk.icon_size, + scale, 0); + pixbuf = gtk_icon_info_load_symbolic_for_context (info, context, NULL, NULL); } @@ -956,17 +994,17 @@ meta_theme_gtk_draw_frame (MetaThemeImpl *impl, float width, height; int x, y; - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); + width = gdk_pixbuf_get_width (pixbuf) / scale; + height = gdk_pixbuf_get_height (pixbuf) / scale; x = button_rect.x + (button_rect.width - width) / 2; y = button_rect.y + (button_rect.height - height) / 2; cairo_translate (cr, x, y); cairo_scale (cr, - width / style->layout->gtk.icon_size, - height / style->layout->gtk.icon_size); + width / style->layout->gtk.icon_size / scale, + height / style->layout->gtk.icon_size / scale); gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_paint (cr); + cairo_paint (cr); g_object_unref (pixbuf); } diff --git a/libmetacity/meta-theme-metacity.c b/libmetacity/meta-theme-metacity.c index 92e87fd8..72a2ac54 100644 --- a/libmetacity/meta-theme-metacity.c +++ b/libmetacity/meta-theme-metacity.c @@ -4610,6 +4610,7 @@ meta_theme_metacity_get_frame_borders (MetaThemeImpl *impl, MetaFrameBorders *borders) { int buttons_height, title_height; + int scale; meta_frame_borders_clear (borders); @@ -4654,6 +4655,13 @@ meta_theme_metacity_get_frame_borders (MetaThemeImpl *impl, borders->total.right = borders->invisible.right + borders->visible.right; borders->total.bottom = borders->invisible.bottom + borders->visible.bottom; borders->total.top = borders->invisible.top + borders->visible.top; + + /* Scale geometry for HiDPI, see comment in meta_theme_metacity_draw_frame () */ + scale = get_window_scaling_factor (); + + scale_border (&borders->visible, scale); + scale_border (&borders->invisible, scale); + scale_border (&borders->total, scale); } static MetaButtonSpace * @@ -4825,6 +4833,7 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, int width, height; int button_width, button_height; int min_size_for_rounding; + int scale; /* the left/right rects in order; the max # of rects * is the number of button functions @@ -4855,15 +4864,18 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, button_width = -1; button_height = -1; + /* Scale geometry for HiDPI, see comment in meta_theme_metacity_draw_frame () */ + scale = get_window_scaling_factor (); + switch (layout->metacity.button_sizing) { case META_BUTTON_SIZING_ASPECT: - button_height = borders.visible.top - layout->button_border.top - layout->button_border.bottom; + button_height = borders.visible.top - layout->button_border.top * scale - layout->button_border.bottom * scale; button_width = button_height / layout->metacity.button_aspect; break; case META_BUTTON_SIZING_FIXED: - button_width = layout->metacity.button_width; - button_height = layout->metacity.button_height; + button_width = layout->metacity.button_width * scale; + button_height = layout->metacity.button_height * scale; break; case META_BUTTON_SIZING_LAST: default: @@ -4956,20 +4968,21 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, int space_used_by_buttons; int space_available; - space_available = fgeom->width - layout->metacity.left_titlebar_edge - - layout->metacity.right_titlebar_edge; + space_available = fgeom->width - + layout->metacity.left_titlebar_edge * scale - + layout->metacity.right_titlebar_edge * scale; space_used_by_buttons = 0; space_used_by_buttons += button_width * n_left; space_used_by_buttons += (button_width * 0.75) * n_left_spacers; - space_used_by_buttons += layout->button_border.left * n_left; - space_used_by_buttons += layout->button_border.right * n_left; + space_used_by_buttons += layout->button_border.left * scale * n_left; + space_used_by_buttons += layout->button_border.right * scale * n_left; space_used_by_buttons += button_width * n_right; space_used_by_buttons += (button_width * 0.75) * n_right_spacers; - space_used_by_buttons += layout->button_border.left * n_right; - space_used_by_buttons += layout->button_border.right * n_right; + space_used_by_buttons += layout->button_border.left * scale * n_right; + space_used_by_buttons += layout->button_border.right * scale * n_right; if (space_used_by_buttons <= space_available) break; /* Everything fits, bail out */ @@ -5052,10 +5065,10 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, /* center buttons vertically */ button_y = (borders.visible.top - - (button_height + layout->button_border.top + layout->button_border.bottom)) / 2 + layout->button_border.top + borders.invisible.top; + (button_height + layout->button_border.top * scale + layout->button_border.bottom * scale)) / 2 + layout->button_border.top * scale + borders.invisible.top; /* right edge of farthest-right button */ - x = width - layout->metacity.right_titlebar_edge - borders.invisible.right; + x = width - layout->metacity.right_titlebar_edge * scale - borders.invisible.right; i = n_right - 1; while (i >= 0) @@ -5066,7 +5079,7 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, break; rect = right_func_rects[i]; - rect->visible.x = x - layout->button_border.right - button_width; + rect->visible.x = x - layout->button_border.right * scale - button_width; if (right_buttons_has_spacer[i]) rect->visible.x -= (button_width * 0.75); @@ -5084,34 +5097,34 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, rect->clickable.height = button_height; if (i == n_right - 1) - rect->clickable.width += layout->metacity.right_titlebar_edge + - layout->metacity.right_width + - layout->button_border.right; + rect->clickable.width += layout->metacity.right_titlebar_edge * scale + + layout->metacity.right_width * scale + + layout->button_border.right * scale; } else g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); *(right_bg_rects[i]) = rect->visible; - x = rect->visible.x - layout->button_border.left; + x = rect->visible.x - layout->button_border.left * scale; --i; } /* save right edge of titlebar for later use */ - title_right_edge = x - layout->metacity.title_border.right; + title_right_edge = x - layout->metacity.title_border.right * scale; /* Now x changes to be position from the left and we go through * the left-side buttons */ - x = layout->metacity.left_titlebar_edge + borders.invisible.left; + x = layout->metacity.left_titlebar_edge * scale + borders.invisible.left; for (i = 0; i < n_left; i++) { MetaButtonSpace *rect; rect = left_func_rects[i]; - rect->visible.x = x + layout->button_border.left; + rect->visible.x = x + layout->button_border.left * scale; rect->visible.y = button_y; rect->visible.width = button_width; rect->visible.height = button_height; @@ -5126,7 +5139,7 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, else g_memmove (&(rect->clickable), &(rect->visible), sizeof(rect->clickable)); - x = rect->visible.x + rect->visible.width + layout->button_border.right; + x = rect->visible.x + rect->visible.width + layout->button_border.right * scale; if (left_buttons_has_spacer[i]) x += (button_width * 0.75); @@ -5136,12 +5149,12 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, /* We always fill as much vertical space as possible with title rect, * rather than centering it like the buttons */ - fgeom->title_rect.x = x + layout->metacity.title_border.left; - fgeom->title_rect.y = layout->metacity.title_border.top + borders.invisible.top; + fgeom->title_rect.x = x + layout->metacity.title_border.left * scale; + fgeom->title_rect.y = layout->metacity.title_border.top * scale + borders.invisible.top; fgeom->title_rect.width = title_right_edge - fgeom->title_rect.x; fgeom->title_rect.height = borders.visible.top - - layout->metacity.title_border.top - - layout->metacity.title_border.bottom; + layout->metacity.title_border.top * scale - + layout->metacity.title_border.bottom * scale; /* Nuke title if it won't fit */ if (fgeom->title_rect.width < 0 || @@ -5154,7 +5167,7 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, if (flags & META_FRAME_SHADED) min_size_for_rounding = 0; else - min_size_for_rounding = 5; + min_size_for_rounding = 5 * scale; fgeom->top_left_corner_rounded_radius = 0; fgeom->top_right_corner_rounded_radius = 0; @@ -5162,14 +5175,14 @@ meta_theme_metacity_calc_geometry (MetaThemeImpl *impl, fgeom->bottom_right_corner_rounded_radius = 0; if (borders.visible.top + borders.visible.left >= min_size_for_rounding) - fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius; + fgeom->top_left_corner_rounded_radius = layout->top_left_corner_rounded_radius * scale; if (borders.visible.top + borders.visible.right >= min_size_for_rounding) - fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius; + fgeom->top_right_corner_rounded_radius = layout->top_right_corner_rounded_radius * scale; if (borders.visible.bottom + borders.visible.left >= min_size_for_rounding) - fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius; + fgeom->bottom_left_corner_rounded_radius = layout->bottom_left_corner_rounded_radius * scale; if (borders.visible.bottom + borders.visible.right >= min_size_for_rounding) - fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius; + fgeom->bottom_right_corner_rounded_radius = layout->bottom_right_corner_rounded_radius * scale; } static void @@ -5181,6 +5194,7 @@ clip_to_rounded_corners (cairo_t *cr, gint y; gint width; gint height; + int scale; gint radius; x = rect.x; @@ -5190,10 +5204,12 @@ clip_to_rounded_corners (cairo_t *cr, cairo_new_path (cr); + scale = get_window_scaling_factor (); + if (fgeom->top_left_corner_rounded_radius != 0) { - radius = fgeom->top_left_corner_rounded_radius; - radius += sqrt(fgeom->top_left_corner_rounded_radius); + radius = fgeom->top_left_corner_rounded_radius / scale; + radius += sqrt(fgeom->top_left_corner_rounded_radius / scale); cairo_line_to (cr, x, y + radius); cairo_arc (cr, x + radius, y + radius, radius, @@ -5204,8 +5220,8 @@ clip_to_rounded_corners (cairo_t *cr, if (fgeom->top_right_corner_rounded_radius != 0) { - radius = fgeom->top_right_corner_rounded_radius; - radius += sqrt(fgeom->top_right_corner_rounded_radius); + radius = fgeom->top_right_corner_rounded_radius / scale; + radius += sqrt(fgeom->top_right_corner_rounded_radius / scale); cairo_line_to (cr, x + width - radius, y); cairo_arc (cr, x + width - radius, y + radius, radius, @@ -5216,8 +5232,8 @@ clip_to_rounded_corners (cairo_t *cr, if (fgeom->bottom_right_corner_rounded_radius != 0) { - radius = fgeom->bottom_right_corner_rounded_radius; - radius += sqrt(fgeom->bottom_right_corner_rounded_radius); + radius = fgeom->bottom_right_corner_rounded_radius / scale; + radius += sqrt(fgeom->bottom_right_corner_rounded_radius / scale); cairo_line_to (cr, x + width, y + height - radius); cairo_arc (cr, x + width - radius, y + height - radius, radius, @@ -5228,8 +5244,8 @@ clip_to_rounded_corners (cairo_t *cr, if (fgeom->bottom_left_corner_rounded_radius != 0) { - radius = fgeom->bottom_left_corner_rounded_radius; - radius += sqrt(fgeom->bottom_left_corner_rounded_radius); + radius = fgeom->bottom_left_corner_rounded_radius / scale; + radius += sqrt(fgeom->bottom_left_corner_rounded_radius / scale); cairo_line_to (cr, x + radius, y + height); cairo_arc (cr, x + radius, y + height - radius, radius, @@ -5254,6 +5270,7 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, GdkPixbuf *mini_icon, GdkPixbuf *icon) { + int scale; int i, j; GdkRectangle visible_rect; GdkRectangle titlebar_rect; @@ -5266,17 +5283,31 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, MetaDrawInfo draw_info; const MetaFrameBorders *borders; + /* We opt out of GTK+ HiDPI handling, so we have to do the scaling + * ourselves; the nitty-gritty is a bit confusing, so here is an overview: + * - the values in MetaFrameLayout are always as they appear in the theme, + * i.e. unscaled + * - calculated values (borders, MetaFrameGeometry) include the scale - as + * the geometry is comprised of scaled decorations and the client size + * which we must not scale, we don't have another option + * - for drawing, we scale the canvas to have GTK+ render elements (borders, + * radii, ...) at the correct scale - as a result, we have to "unscale" + * the geometry again to not apply the scaling twice + */ + scale = get_window_scaling_factor (); + cairo_scale (cr, scale, scale); + borders = &fgeom->borders; - visible_rect.x = borders->invisible.left; - visible_rect.y = borders->invisible.top; - visible_rect.width = fgeom->width - borders->invisible.left - borders->invisible.right; - visible_rect.height = fgeom->height - borders->invisible.top - borders->invisible.bottom; + visible_rect.x = borders->invisible.left / scale; + visible_rect.y = borders->invisible.top / scale; + visible_rect.width = (fgeom->width - borders->invisible.left - borders->invisible.right) / scale; + visible_rect.height = (fgeom->height - borders->invisible.top - borders->invisible.bottom) / scale; titlebar_rect.x = visible_rect.x; titlebar_rect.y = visible_rect.y; titlebar_rect.width = visible_rect.width; - titlebar_rect.height = borders->visible.top; + titlebar_rect.height = borders->visible.top / scale; left_titlebar_edge.x = titlebar_rect.x; left_titlebar_edge.y = titlebar_rect.y + style->layout->metacity.title_border.top; @@ -5300,19 +5331,19 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, bottom_titlebar_edge.y = titlebar_rect.y + titlebar_rect.height - bottom_titlebar_edge.height; left_edge.x = visible_rect.x; - left_edge.y = visible_rect.y + borders->visible.top; - left_edge.width = borders->visible.left; - left_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom; + left_edge.y = visible_rect.y + borders->visible.top / scale; + left_edge.width = borders->visible.left / scale; + left_edge.height = visible_rect.height - borders->visible.top / scale - borders->visible.bottom / scale; - right_edge.x = visible_rect.x + visible_rect.width - borders->visible.right; - right_edge.y = visible_rect.y + borders->visible.top; - right_edge.width = borders->visible.right; - right_edge.height = visible_rect.height - borders->visible.top - borders->visible.bottom; + right_edge.x = visible_rect.x + visible_rect.width - borders->visible.right / scale; + right_edge.y = visible_rect.y + borders->visible.top / scale; + right_edge.width = borders->visible.right / scale; + right_edge.height = visible_rect.height - borders->visible.top / scale - borders->visible.bottom / scale; bottom_edge.x = visible_rect.x; - bottom_edge.y = visible_rect.y + visible_rect.height - borders->visible.bottom; + bottom_edge.y = visible_rect.y + visible_rect.height - borders->visible.bottom / scale; bottom_edge.width = visible_rect.width; - bottom_edge.height = borders->visible.bottom; + bottom_edge.height = borders->visible.bottom / scale; if (title_layout) pango_layout_get_pixel_extents (title_layout, @@ -5366,13 +5397,17 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, case META_FRAME_PIECE_TITLEBAR_MIDDLE: rect.x = left_titlebar_edge.x + left_titlebar_edge.width; rect.y = top_titlebar_edge.y + top_titlebar_edge.height; - rect.width = titlebar_rect.width - left_titlebar_edge.width - - right_titlebar_edge.width; + rect.width = titlebar_rect.width - left_titlebar_edge.width - right_titlebar_edge.width; rect.height = titlebar_rect.height - top_titlebar_edge.height - bottom_titlebar_edge.height; break; case META_FRAME_PIECE_TITLE: rect = fgeom->title_rect; + + rect.x /= scale; + rect.y /= scale; + rect.width /= scale; + rect.height /= scale; break; case META_FRAME_PIECE_LEFT_EDGE: @@ -5441,6 +5476,11 @@ meta_theme_metacity_draw_frame (MetaThemeImpl *impl, get_button_rect (j, fgeom, middle_bg_offset, &rect); + rect.x /= scale; + rect.y /= scale; + rect.width /= scale; + rect.height /= scale; + button_state = map_button_state (j, fgeom, middle_bg_offset, button_states); op_list = meta_frame_style_get_button (style, j, button_state); -- cgit v1.2.1