summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2013-11-15 17:37:50 -0500
committerOwen W. Taylor <otaylor@fishsoup.net>2013-11-19 14:04:16 -0500
commita4a8f1f863640262b7f3491be0205b272b455f5a (patch)
treea014f9aeb53130b824a678e3e505609eb19bce36
parentf36a62733098d8ef416d627c20f50c64bc7f0a4b (diff)
downloadmutter-a4a8f1f863640262b7f3491be0205b272b455f5a.tar.gz
MetaFrame: Cache borders
Cache the computed border size so we can fetch the border size at any time without worrying that we'll be spending too much time in the theme code (in some cases we might allocate a PangoFontDescription or do other significant work.) The main effort here is clearing the cache when various bits of window state change that could potentially affect the computed borders. https://bugzilla.gnome.org/show_bug.cgi?id=707194
-rw-r--r--src/core/core.c1
-rw-r--r--src/core/display.c1
-rw-r--r--src/core/frame.c21
-rw-r--r--src/core/frame.h5
-rw-r--r--src/core/window-private.h3
-rw-r--r--src/core/window.c15
6 files changed, 43 insertions, 3 deletions
diff --git a/src/core/core.c b/src/core/core.c
index 3a96cde43..b1ba70dc1 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -172,6 +172,7 @@ meta_core_queue_frame_resize (Display *xdisplay,
MetaWindow *window = get_window (xdisplay, frame_xwindow);
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
+ meta_window_frame_size_changed (window);
}
void
diff --git a/src/core/display.c b/src/core/display.c
index 525f9bd04..2915c3aa2 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -4564,6 +4564,7 @@ meta_display_queue_retheme_all_windows (MetaDisplay *display)
MetaWindow *window = tmp->data;
meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
+ meta_window_frame_size_changed (window);
if (window->frame)
{
meta_frame_queue_draw (window->frame);
diff --git a/src/core/frame.c b/src/core/frame.c
index d7e254ecf..a2a4fbf63 100644
--- a/src/core/frame.c
+++ b/src/core/frame.c
@@ -69,6 +69,7 @@ meta_window_ensure_frame (MetaWindow *window)
frame->mapped = FALSE;
frame->is_flashing = FALSE;
+ frame->borders_cached = FALSE;
meta_verbose ("Framing window %s: visual %s default, depth %d default depth %d\n",
window->desc,
@@ -334,9 +335,23 @@ meta_frame_calc_borders (MetaFrame *frame,
if (frame == NULL)
meta_frame_borders_clear (borders);
else
- meta_ui_get_frame_borders (frame->window->screen->ui,
- frame->xwindow,
- borders);
+ {
+ 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;
}
gboolean
diff --git a/src/core/frame.h b/src/core/frame.h
index cff9cb25c..d633adc25 100644
--- a/src/core/frame.h
+++ b/src/core/frame.h
@@ -41,6 +41,8 @@ struct _MetaFrame
*/
MetaRectangle rect;
+ MetaFrameBorders cached_borders; /* valid if borders_cached is set */
+
/* position of client, size of frame */
int child_x;
int child_y;
@@ -50,6 +52,7 @@ struct _MetaFrame
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);
@@ -68,6 +71,8 @@ gboolean meta_frame_sync_to_window (MetaFrame *frame,
gboolean need_move,
gboolean need_resize);
+void meta_frame_clear_cached_borders (MetaFrame *frame);
+
cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame);
void meta_frame_get_mask (MetaFrame *frame,
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 1a428030c..cc2faa424 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -533,6 +533,7 @@ void meta_window_update_fullscreen_monitors (MetaWindow *window,
unsigned long left,
unsigned long right);
+
/* args to move are window pos, not frame pos */
void meta_window_move (MetaWindow *window,
gboolean user_op,
@@ -683,6 +684,8 @@ void meta_window_recalc_features (MetaWindow *window);
void meta_window_recalc_window_type (MetaWindow *window);
void meta_window_type_changed (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 c993d2df2..f7b62841e 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -4213,6 +4213,7 @@ meta_window_set_above (MetaWindow *window,
window->wm_state_above = new_value;
meta_window_update_layer (window);
set_net_wm_state (window);
+ meta_window_frame_size_changed (window);
g_object_notify (G_OBJECT (window), "above");
}
@@ -4352,6 +4353,7 @@ meta_window_shade (MetaWindow *window,
window->shaded = TRUE;
meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
+ meta_window_frame_size_changed (window);
/* After queuing the calc showing, since _focus flushes it,
* and we need to focus the frame
@@ -4377,6 +4379,7 @@ meta_window_unshade (MetaWindow *window,
{
window->shaded = FALSE;
meta_window_queue(window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
+ meta_window_frame_size_changed (window);
/* focus the window */
meta_topic (META_DEBUG_FOCUS,
@@ -6378,6 +6381,7 @@ window_stick_impl (MetaWindow *window)
* toggled back off.
*/
window->on_all_workspaces_requested = TRUE;
+ meta_window_frame_size_changed (window);
meta_window_update_on_all_workspaces (window);
meta_window_queue(window, META_QUEUE_CALC_SHOWING);
@@ -6392,6 +6396,7 @@ window_unstick_impl (MetaWindow *window)
/* Revert to window->workspaces */
window->on_all_workspaces_requested = FALSE;
+ meta_window_frame_size_changed (window);
meta_window_update_on_all_workspaces (window);
/* We change ourselves to the active workspace, since otherwise you'd get
@@ -7467,6 +7472,7 @@ static void
meta_window_appears_focused_changed (MetaWindow *window)
{
set_net_wm_state (window);
+ meta_window_frame_size_changed (window);
g_object_notify (G_OBJECT (window), "appears-focused");
@@ -8643,6 +8649,13 @@ meta_window_type_changed (MetaWindow *window)
g_object_thaw_notify (object);
}
+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)
{
@@ -8943,6 +8956,8 @@ recalc_window_features (MetaWindow *window)
if (window->has_resize_func != old_has_resize_func)
g_object_notify (G_OBJECT (window), "resizeable");
+ meta_window_frame_size_changed (window);
+
/* FIXME perhaps should ensure if we don't have a shade func,
* we aren't shaded, etc.
*/