summaryrefslogtreecommitdiff
path: root/libmetacity/meta-theme-metacity.c
diff options
context:
space:
mode:
Diffstat (limited to 'libmetacity/meta-theme-metacity.c')
-rw-r--r--libmetacity/meta-theme-metacity.c146
1 files changed, 93 insertions, 53 deletions
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);