diff options
| -rw-r--r-- | src/core/frame-private.h | 4 | ||||
| -rw-r--r-- | src/core/frame.c | 46 | ||||
| -rw-r--r-- | src/core/window-private.h | 2 | ||||
| -rw-r--r-- | src/core/window.c | 36 | ||||
| -rw-r--r-- | src/include/common.h | 14 | ||||
| -rw-r--r-- | src/include/frame.h | 1 | ||||
| -rw-r--r-- | src/ui/theme.c | 50 | ||||
| -rw-r--r-- | src/ui/theme.h | 4 |
8 files changed, 126 insertions, 31 deletions
diff --git a/src/core/frame-private.h b/src/core/frame-private.h index 8c2a2eeb..77216420 100644 --- a/src/core/frame-private.h +++ b/src/core/frame-private.h @@ -48,9 +48,13 @@ struct _MetaFrame int right_width; int bottom_height; + /* valid if borders_cached is set */ + MetaFrameBorders cached_borders; + guint mapped : 1; guint need_reapply_frame_shape : 1; guint is_flashing : 1; /* used by the visual bell flash */ + guint borders_cached : 1; }; void meta_window_ensure_frame (MetaWindow *window); diff --git a/src/core/frame.c b/src/core/frame.c index e1eec2a4..a8ba65c0 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -85,6 +85,7 @@ meta_window_ensure_frame (MetaWindow *window) frame->mapped = FALSE; frame->need_reapply_frame_shape = TRUE; frame->is_flashing = FALSE; + frame->borders_cached = FALSE; meta_verbose ("Frame geometry %d,%d %dx%d\n", frame->rect.x, frame->rect.y, @@ -302,22 +303,51 @@ meta_frame_get_flags (MetaFrame *frame) return flags; } +static void +clear_border (GtkBorder *border) +{ + border->left = 0; + border->right = 0; + border->top = 0; + border->bottom = 0; +} + void -meta_frame_borders_clear (MetaFrameBorders *self) +meta_frame_borders_clear (MetaFrameBorders *borders) { - self->visible.top = self->invisible.top = self->total.top = 0; - self->visible.bottom = self->invisible.bottom = self->total.bottom = 0; - self->visible.left = self->invisible.left = self->total.left = 0; - self->visible.right = self->invisible.right = self->total.right = 0; + clear_border (&borders->visible); + clear_border (&borders->shadow); + clear_border (&borders->resize); + clear_border (&borders->invisible); + clear_border (&borders->total); } void meta_frame_calc_borders (MetaFrame *frame, MetaFrameBorders *borders) { - meta_ui_get_frame_borders (frame->window->screen->ui, - frame->xwindow, - borders); + if (frame == NULL) + { + meta_frame_borders_clear (borders); + } + else + { + if (!frame->borders_cached) + { + meta_ui_get_frame_borders (frame->window->screen->ui, + frame->xwindow, + &frame->cached_borders); + frame->borders_cached = TRUE; + } + + *borders = frame->cached_borders; + } +} + +void +meta_frame_clear_cached_borders (MetaFrame *frame) +{ + frame->borders_cached = FALSE; } static gboolean diff --git a/src/core/window-private.h b/src/core/window-private.h index 52864a86..06d4fd65 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -687,6 +687,8 @@ const char* meta_window_get_startup_id (MetaWindow *window); void meta_window_recalc_features (MetaWindow *window); void meta_window_recalc_window_type (MetaWindow *window); +void meta_window_frame_size_changed (MetaWindow *window); + void meta_window_stack_just_below (MetaWindow *window, MetaWindow *below_this_one); diff --git a/src/core/window.c b/src/core/window.c index 050c89f8..ae0fa791 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2593,6 +2593,8 @@ meta_window_maximize_internal (MetaWindow *window, window->maximized_vertically = window->maximized_vertically || maximize_vertically; + meta_window_frame_size_changed (window); + /* Fix for #336850: If the frame shape isn't reapplied, it is * possible that the frame will retains its rounded corners. That * happens if the client's size when maximized equals the unmaximized @@ -2725,6 +2727,13 @@ meta_window_tile (MetaWindow *window) */ meta_window_queue (window, META_QUEUE_MOVE_RESIZE); + /* Clear cached frame bounds that depend on invisible border calculations */ + if (window->frame_bounds) + { + cairo_region_destroy (window->frame_bounds); + window->frame_bounds = NULL; + } + set_allowed_actions_hint (window); } @@ -2808,6 +2817,8 @@ meta_window_unmaximize (MetaWindow *window, window->maximized_vertically = window->maximized_vertically && !unmaximize_vertically; + meta_window_frame_size_changed (window); + /* Unmaximize to the saved_rect position in the direction(s) * being unmaximized. */ @@ -2932,6 +2943,8 @@ meta_window_make_above (MetaWindow *window) meta_window_update_layer (window); meta_window_raise (window); set_net_wm_state (window); + + meta_window_frame_size_changed (window); } void @@ -2941,6 +2954,8 @@ meta_window_unmake_above (MetaWindow *window) meta_window_raise (window); meta_window_update_layer (window); set_net_wm_state (window); + + meta_window_frame_size_changed (window); } void @@ -3071,7 +3086,8 @@ meta_window_shade (MetaWindow *window, { window->shaded = TRUE; - meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + meta_window_frame_size_changed (window); set_allowed_actions_hint (window); @@ -3096,7 +3112,9 @@ meta_window_unshade (MetaWindow *window, if (window->shaded) { window->shaded = FALSE; - meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + + meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); + meta_window_frame_size_changed (window); set_allowed_actions_hint (window); @@ -4531,6 +4549,8 @@ window_stick_impl (MetaWindow *window) */ window->on_all_workspaces = TRUE; + meta_window_frame_size_changed (window); + /* We do, however, change the MRU lists of all the workspaces */ tmp = window->screen->workspaces; @@ -4561,6 +4581,8 @@ window_unstick_impl (MetaWindow *window) window->on_all_workspaces = FALSE; + meta_window_frame_size_changed (window); + /* Remove window from MRU lists that it doesn't belong in */ tmp = window->screen->workspaces; while (tmp) @@ -5587,6 +5609,7 @@ static void meta_window_appears_focused_changed (MetaWindow *window) { set_net_wm_state (window); + meta_window_frame_size_changed (window); if (window->frame) meta_frame_queue_draw (window->frame); @@ -6583,6 +6606,13 @@ recalc_window_type (MetaWindow *window) } } +void +meta_window_frame_size_changed (MetaWindow *window) +{ + if (window->frame) + meta_frame_clear_cached_borders (window->frame); +} + static void set_allowed_actions_hint (MetaWindow *window) { @@ -6877,6 +6907,8 @@ recalc_window_features (MetaWindow *window) old_always_sticky != window->always_sticky) set_allowed_actions_hint (window); + meta_window_frame_size_changed (window); + /* FIXME perhaps should ensure if we don't have a shade func, * we aren't shaded, etc. */ diff --git a/src/include/common.h b/src/include/common.h index 031274f6..a0dfb69c 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -310,15 +310,11 @@ struct _MetaButtonLayout typedef struct _MetaFrameBorders MetaFrameBorders; struct _MetaFrameBorders { - /* The frame border is made up of two pieces - an inner visible portion - * and an outer portion that is invisible but responds to events. - */ - GtkBorder visible; - GtkBorder invisible; - - /* For convenience, we have a "total" border which is equal to the sum - * of the two borders above. */ - GtkBorder total; + GtkBorder visible; /* Visible window frame decoration */ + GtkBorder shadow; /* Extra size needed for shadow */ + GtkBorder resize; /* Extra size used for resize cursor area */ + GtkBorder invisible; /* Max of shadow and resize borders */ + GtkBorder total; /* Sum of visible and invisible borders */ }; /* sets all dimensions to zero */ diff --git a/src/include/frame.h b/src/include/frame.h index 97314d4b..2deba88b 100644 --- a/src/include/frame.h +++ b/src/include/frame.h @@ -30,5 +30,6 @@ Window meta_frame_get_xwindow (MetaFrame *frame); void meta_frame_calc_borders (MetaFrame *frame, MetaFrameBorders *borders); +void meta_frame_clear_cached_borders (MetaFrame *frame); #endif diff --git a/src/ui/theme.c b/src/ui/theme.c index dadc9ab8..8bd144f2 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -328,10 +328,10 @@ meta_frame_layout_new (void) layout->right_width = -1; layout->bottom_height = -1; - layout->invisible_border.left = 10; - layout->invisible_border.right = 10; - layout->invisible_border.bottom = 10; - layout->invisible_border.top = 10; + layout->invisible_resize_border.left = 10; + layout->invisible_resize_border.right = 10; + layout->invisible_resize_border.bottom = 10; + layout->invisible_resize_border.top = 10; init_border (&layout->title_border); @@ -514,6 +514,7 @@ void meta_frame_layout_get_borders (const MetaFrameLayout *layout, int text_height, MetaFrameFlags flags, + MetaFrameType type, MetaFrameBorders *borders) { int buttons_height, title_height; @@ -540,25 +541,52 @@ meta_frame_layout_get_borders (const MetaFrameLayout *layout, borders->visible.right = layout->right_width; borders->visible.bottom = layout->bottom_height; + borders->shadow.top = 0; + borders->shadow.left = 0; + borders->shadow.right = 0; + borders->shadow.bottom = 0; + if (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) { - borders->invisible.left = layout->invisible_border.left; - borders->invisible.right = layout->invisible_border.right; + borders->resize.left = layout->invisible_resize_border.left; + borders->resize.right = layout->invisible_resize_border.right; } if (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) { - borders->invisible.bottom = layout->invisible_border.bottom; - borders->invisible.top = layout->invisible_border.top; + borders->resize.bottom = layout->invisible_resize_border.bottom; + + if (type != META_FRAME_TYPE_ATTACHED) + borders->resize.top = layout->invisible_resize_border.top; } - if (flags & META_FRAME_SHADED) - borders->visible.bottom = borders->invisible.bottom = 0; + borders->invisible.left = MAX (borders->shadow.left, borders->resize.left); + borders->invisible.right = MAX (borders->shadow.right, borders->resize.right); + borders->invisible.bottom = MAX (borders->shadow.bottom, borders->resize.bottom); + borders->invisible.top = MAX (borders->shadow.top, borders->resize.top); + + /* Maximized and tiled windows should not have invisible borders on the sides + * that touch the screen edges */ + if (flags & (META_FRAME_MAXIMIZED | META_FRAME_TILED_LEFT | META_FRAME_TILED_RIGHT)) + { + borders->invisible.top = 0; + borders->invisible.bottom = 0; + } + if (flags & (META_FRAME_MAXIMIZED | META_FRAME_TILED_LEFT)) + borders->invisible.left = 0; + if (flags & (META_FRAME_MAXIMIZED | META_FRAME_TILED_RIGHT)) + borders->invisible.right = 0; + + if (type == META_FRAME_TYPE_ATTACHED) + borders->invisible.top = 0; borders->total.left = borders->invisible.left + borders->visible.left; 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; + + if (flags & META_FRAME_SHADED) + borders->visible.bottom = borders->invisible.bottom = 0; } static MetaButtonType @@ -758,6 +786,7 @@ meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, meta_frame_layout_get_borders (layout, text_height, flags, + META_FRAME_TYPE_NORMAL, /* Will be updated when type parameter is passed down */ &borders); fgeom->borders = borders; @@ -5947,6 +5976,7 @@ meta_theme_get_frame_borders (MetaTheme *theme, meta_frame_layout_get_borders (style->layout, text_height, flags, + type, borders); } diff --git a/src/ui/theme.h b/src/ui/theme.h index b32690f1..c3c10810 100644 --- a/src/ui/theme.h +++ b/src/ui/theme.h @@ -92,8 +92,7 @@ struct _MetaFrameLayout /** Size of bottom side */ int bottom_height; - /** Invisible border */ - GtkBorder invisible_border; + GtkBorder invisible_resize_border; /** Border of blue title region * \bug (blue?!) @@ -874,6 +873,7 @@ void meta_frame_layout_unref (MetaFrameLayout *layout) void meta_frame_layout_get_borders (const MetaFrameLayout *layout, int text_height, MetaFrameFlags flags, + MetaFrameType type, MetaFrameBorders *borders); void meta_frame_layout_calc_geometry (const MetaFrameLayout *layout, int text_height, |
