From f9db65f47f7e3cfa050d3373d1a2b3615c574040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 20 Jan 2016 18:01:41 +0100 Subject: [PATCH] theme: Take invisible borders required by the theme into account GTK+ paints some elements like box shadows (which Adwaita likes to (ab)use for borders) outside the rectangle passed to gtk_render_*. This is not an issue if our own invisible frame border is big enough, but in case of non-resizable windows we end up clipping away part of the decoration. Use the newly added gtk_render_background_get_clip() to make sure we always use a mask that is large enough to contain all decorations. https://bugzilla.gnome.org/show_bug.cgi?id=752794 --- configure.ac | 2 +- src/ui/theme-private.h | 2 ++ src/ui/theme.c | 20 ++++++++++++++++---- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 3ad43df3b..8731079da 100644 --- a/configure.ac +++ b/configure.ac @@ -59,7 +59,7 @@ CANBERRA_GTK_VERSION=0.26 CLUTTER_PACKAGE=clutter-1.0 MUTTER_PC_MODULES=" - gtk+-3.0 >= 3.19.7 + gtk+-3.0 >= 3.19.8 gio-unix-2.0 >= 2.35.1 pango >= 1.2.0 cairo >= 1.10.0 diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h index 3ebe06b2e..eaee95d10 100644 --- a/src/ui/theme-private.h +++ b/src/ui/theme-private.h @@ -53,6 +53,8 @@ typedef struct _MetaFrameGeometry MetaFrameGeometry; **/ struct _MetaFrameLayout { + /** Invisible border required by the theme */ + GtkBorder invisible_border; /** Border/padding of the entire frame */ GtkBorder frame_border; /** Border/padding of the titlebar region */ diff --git a/src/ui/theme.c b/src/ui/theme.c index 71ddf456f..0dbfdf6e0 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -94,23 +94,28 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout, borders->visible.right = layout->frame_border.right; borders->visible.bottom = layout->frame_border.bottom; + borders->invisible = layout->invisible_border; + draggable_borders = meta_prefs_get_draggable_border_width (); if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) { - borders->invisible.left = MAX (0, draggable_borders - borders->visible.left); - borders->invisible.right = MAX (0, draggable_borders - borders->visible.right); + borders->invisible.left = MAX (borders->invisible.left, + draggable_borders - borders->visible.left); + borders->invisible.right = MAX (borders->invisible.right, + draggable_borders - borders->visible.right); } if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) { - borders->invisible.bottom = MAX (0, draggable_borders - borders->visible.bottom); + borders->invisible.bottom = MAX (borders->invisible.bottom, + draggable_borders - borders->visible.bottom); /* borders.visible.top is the height of the *title bar*. We can't do the same * algorithm here, titlebars are expectedly much bigger. Just subtract a couple * pixels to get a proper feel. */ if (type != META_FRAME_TYPE_ATTACHED) - borders->invisible.top = MAX (0, draggable_borders - 2); + borders->invisible.top = MAX (borders->invisible.top, draggable_borders - 2); } borders->total.left = borders->invisible.left + borders->visible.left; @@ -266,6 +271,7 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout, GtkStyleContext *style; GtkBorder border; GtkRequisition requisition; + GdkRectangle clip_rect; int border_radius, max_radius; meta_style_info_set_flags (style_info, flags); @@ -274,6 +280,12 @@ meta_frame_layout_sync_with_style (MetaFrameLayout *layout, get_padding_and_border (style, &layout->frame_border); scale_border (&layout->frame_border, layout->title_scale); + gtk_render_background_get_clip (style, 0, 0, 0, 0, &clip_rect); + layout->invisible_border.left = -clip_rect.x; + layout->invisible_border.right = clip_rect.width + clip_rect.x; + layout->invisible_border.top = -clip_rect.y; + layout->invisible_border.bottom = clip_rect.height + clip_rect.y; + if (layout->hide_buttons) layout->icon_size = 0;