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
This commit is contained in:
parent
21a246eb42
commit
15f9590427
@ -9,6 +9,7 @@
|
|||||||
#include <X11/extensions/Xrender.h>
|
#include <X11/extensions/Xrender.h>
|
||||||
|
|
||||||
#include <clutter/x11/clutter-x11.h>
|
#include <clutter/x11/clutter-x11.h>
|
||||||
|
#include <gdk/gdk.h> /* for gdk_rectangle_union() */
|
||||||
|
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
@ -129,6 +130,10 @@ static void meta_window_actor_get_property (GObject *object,
|
|||||||
GParamSpec *pspec);
|
GParamSpec *pspec);
|
||||||
|
|
||||||
static void meta_window_actor_paint (ClutterActor *actor);
|
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 void meta_window_actor_detach (MetaWindowActor *self);
|
||||||
static gboolean meta_window_actor_has_shadow (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;
|
object_class->constructed = meta_window_actor_constructed;
|
||||||
|
|
||||||
actor_class->paint = meta_window_actor_paint;
|
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",
|
pspec = g_param_spec_object ("meta-window",
|
||||||
"MetaWindow",
|
"MetaWindow",
|
||||||
@ -619,10 +627,37 @@ meta_window_actor_get_shape_bounds (MetaWindowActor *self,
|
|||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
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);
|
cairo_region_get_extents (priv->shape_region, bounds);
|
||||||
else
|
else if (priv->bounding_region)
|
||||||
cairo_region_get_extents (priv->bounding_region, bounds);
|
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
|
static void
|
||||||
@ -656,6 +691,50 @@ meta_window_actor_paint (ClutterActor *actor)
|
|||||||
CLUTTER_ACTOR_CLASS (meta_window_actor_parent_class)->paint (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
|
static gboolean
|
||||||
is_shaped (MetaDisplay *display, Window xwindow)
|
is_shaped (MetaDisplay *display, Window xwindow)
|
||||||
{
|
{
|
||||||
@ -1627,12 +1706,10 @@ meta_window_actor_set_visible_region_beneath (MetaWindowActor *self,
|
|||||||
cairo_region_t *beneath_region)
|
cairo_region_t *beneath_region)
|
||||||
{
|
{
|
||||||
MetaWindowActorPrivate *priv = self->priv;
|
MetaWindowActorPrivate *priv = self->priv;
|
||||||
|
|
||||||
if (priv->focused_shadow)
|
|
||||||
{
|
|
||||||
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
gboolean appears_focused = meta_window_appears_focused (priv->window);
|
||||||
MetaShadowParams params;
|
|
||||||
cairo_rectangle_int_t shape_bounds;
|
if (appears_focused ? priv->focused_shadow : priv->unfocused_shadow)
|
||||||
|
{
|
||||||
cairo_rectangle_int_t shadow_bounds;
|
cairo_rectangle_int_t shadow_bounds;
|
||||||
cairo_region_overlap_t overlap;
|
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
|
* the shadow is completely obscured and doesn't need to be drawn
|
||||||
* at all.
|
* at all.
|
||||||
*/
|
*/
|
||||||
meta_window_actor_get_shape_bounds (self, &shape_bounds);
|
meta_window_actor_get_shadow_bounds (self, appears_focused, &shadow_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);
|
|
||||||
|
|
||||||
overlap = cairo_region_contains_rectangle (beneath_region, &shadow_bounds);
|
overlap = cairo_region_contains_rectangle (beneath_region, &shadow_bounds);
|
||||||
priv->paint_shadow = overlap != CAIRO_REGION_OVERLAP_OUT;
|
priv->paint_shadow = overlap != CAIRO_REGION_OVERLAP_OUT;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user