[mutter] Report a correct paint volume for shadowed windows
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] Report a correct paint volume for shadowed windows
- Date: Thu, 18 Nov 2010 14:49:16 +0000 (UTC)
commit 15f9590427650506a7098a1ba26ebc4bf8e6db6c
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Thu Nov 11 17:18:02 2010 -0500
Report a correct paint volume for shadowed windows
Since we paint shadows directly now rather than using a child actor
in the ClutterGroup, we need to implement get_paint_volume() for
Clutter 1.5.
https://bugzilla.gnome.org/show_bug.cgi?id=592382
src/compositor/meta-window-actor.c | 100 ++++++++++++++++++++++++++++++------
1 files changed, 84 insertions(+), 16 deletions(-)
---
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 35227ca..ffb0160 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -9,6 +9,7 @@
#include <X11/extensions/Xrender.h>
#include <clutter/x11/clutter-x11.h>
+#include <gdk/gdk.h> /* for gdk_rectangle_union() */
#include "display.h"
#include "errors.h"
@@ -129,6 +130,10 @@ static void meta_window_actor_get_property (GObject *object,
GParamSpec *pspec);
static void meta_window_actor_paint (ClutterActor *actor);
+#if CLUTTER_CHECK_VERSION(1, 5, 2)
+static gboolean meta_window_actor_get_paint_volume (ClutterActor *actor,
+ ClutterPaintVolume *volume);
+#endif
static void meta_window_actor_detach (MetaWindowActor *self);
static gboolean meta_window_actor_has_shadow (MetaWindowActor *self);
@@ -202,6 +207,9 @@ meta_window_actor_class_init (MetaWindowActorClass *klass)
object_class->constructed = meta_window_actor_constructed;
actor_class->paint = meta_window_actor_paint;
+#if CLUTTER_CHECK_VERSION(1, 5, 2)
+ actor_class->get_paint_volume = meta_window_actor_get_paint_volume;
+#endif
pspec = g_param_spec_object ("meta-window",
"MetaWindow",
@@ -619,10 +627,37 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
{
MetaWindowActorPrivate *priv = self->priv;
- if (priv->shaped)
+ /* We need to be defensive here because there are corner cases
+ * where getting the shape fails on a window being destroyed
+ * and similar.
+ */
+ if (priv->shaped && priv->shape_region)
cairo_region_get_extents (priv->shape_region, bounds);
- else
+ else if (priv->bounding_region)
cairo_region_get_extents (priv->bounding_region, bounds);
+ else
+ bounds->x = bounds->y = bounds->width = bounds->height = 0;
+}
+
+static void
+meta_window_actor_get_shadow_bounds (MetaWindowActor *self,
+ gboolean appears_focused,
+ cairo_rectangle_int_t *bounds)
+{
+ MetaWindowActorPrivate *priv = self->priv;
+ MetaShadow *shadow = appears_focused ? priv->focused_shadow : priv->unfocused_shadow;
+ cairo_rectangle_int_t shape_bounds;
+ MetaShadowParams params;
+
+ meta_window_actor_get_shape_bounds (self, &shape_bounds);
+ meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
+
+ meta_shadow_get_bounds (shadow,
+ params.x_offset + shape_bounds.x,
+ params.y_offset + shape_bounds.y,
+ shape_bounds.width,
+ shape_bounds.height,
+ bounds);
}
static void
@@ -656,6 +691,50 @@ meta_window_actor_paint (ClutterActor *actor)
CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (actor);
}
+#if CLUTTER_CHECK_VERSION(1, 5, 2)
+static gboolean
+meta_window_actor_get_paint_volume (ClutterActor *actor,
+ ClutterPaintVolume *volume)
+{
+ MetaWindowActor *self = META_WINDOW_ACTOR (actor);
+ MetaWindowActorPrivate *priv = self->priv;
+ cairo_rectangle_int_t bounds;
+ gboolean appears_focused = meta_window_appears_focused (priv->window);
+ ClutterVertex origin;
+
+ /* The paint volume is computed before paint functions are called
+ * so our bounds might not be updated yet. Force an update. */
+ meta_window_actor_pre_paint (self);
+
+ meta_window_actor_get_shape_bounds (self, &bounds);
+
+ if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
+ {
+ cairo_rectangle_int_t shadow_bounds;
+
+ /* We could compute an full clip region as we do for the window
+ * texture, but the shadow is relatively cheap to draw, and
+ * a little more complex to clip, so we just catch the case where
+ * the shadow is completely obscured and doesn't need to be drawn
+ * at all.
+ */
+
+ meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
+ gdk_rectangle_union (&bounds, &shadow_bounds, &bounds);
+ }
+
+ origin.x = bounds.x;
+ origin.y = bounds.y;
+ origin.z = 0.0f;
+ clutter_paint_volume_set_origin (volume, &origin);
+
+ clutter_paint_volume_set_width (volume, bounds.width);
+ clutter_paint_volume_set_height (volume, bounds.height);
+
+ return TRUE;
+}
+#endif /* CLUTTER_CHECK_VERSION */
+
static gboolean
is_shaped (MetaDisplay *display, Window xwindow)
{
@@ -1627,12 +1706,10 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
cairo_region_t *beneath_region)
{
MetaWindowActorPrivate *priv = self->priv;
+ gboolean appears_focused = meta_window_appears_focused (priv->window);
- if (priv->focused_shadow)
+ if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
{
- gboolean appears_focused = meta_window_appears_focused (priv->window);
- MetaShadowParams params;
- cairo_rectangle_int_t shape_bounds;
cairo_rectangle_int_t shadow_bounds;
cairo_region_overlap_t overlap;
@@ -1642,16 +1719,7 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
* the shadow is completely obscured and doesn't need to be drawn
* at all.
*/
- meta_window_actor_get_shape_bounds (self, &shape_bounds);
- meta_window_actor_get_shadow_params (self, appears_focused, ¶ms);
-
- meta_shadow_get_bounds (appears_focused ? priv->focused_shadow : priv->unfocused_shadow,
- params.x_offset + shape_bounds.x,
- params.y_offset + shape_bounds.y,
- shape_bounds.width,
- shape_bounds.height,
- &shadow_bounds);
-
+ meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_bounds);
overlap = cairo_region_contains_rectangle (beneath_region, &shadow_bounds);
priv->paint_shadow = overlap != CAIRO_REGION_OVERLAP_OUT;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]