[mutter] Draw the root window background
- From: Owen Taylor <otaylor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] Draw the root window background
- Date: Thu, 18 Nov 2010 19:00:57 +0000 (UTC)
commit 07e6c5aac2ee170819ec0ded694894d666f67174
Author: Owen W. Taylor <otaylor fishsoup net>
Date: Sun Nov 14 12:37:17 2010 -0500
Draw the root window background
Add code to track and draw the root window background. The advantage of doing
it here as compared to in a plugin is that we can use the visiblity smarts
of MetaWindowGroup to optimize out drawing the background when obscured.
If handling other than tracking the _XROOTPMAP_ID property is desired in the
future, more functionality like setting the background from a file or doing
cross-fades can be added.
The new background actor is exposed to plugins via meta_plugin_get_background_actor()
similar to other exposed actors to allow cloning the background for use in
other displays. The actual class is not installed for public consumption at
the moment since it has no useful methods.
https://bugzilla.gnome.org/show_bug.cgi?id=634833
src/Makefile.am | 2 +
src/compositor/compositor-private.h | 1 +
src/compositor/compositor.c | 71 ++++++-
src/compositor/meta-background-actor.c | 380 ++++++++++++++++++++++++++++++++
src/compositor/meta-background-actor.h | 57 +++++
src/compositor/meta-plugin.c | 8 +
src/compositor/meta-window-group.c | 59 +++--
src/include/compositor-mutter.h | 2 +
src/include/meta-plugin.h | 3 +
9 files changed, 556 insertions(+), 27 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 5ad84f3..ff3c30c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -25,6 +25,8 @@ mutter_SOURCES= \
compositor/cogl-utils.h \
compositor/compositor.c \
compositor/compositor-private.h \
+ compositor/meta-background-actor.c \
+ compositor/meta-background-actor.h \
compositor/meta-module.c \
compositor/meta-module.h \
compositor/meta-plugin.c \
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index 37ace96..03d218c 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -35,6 +35,7 @@ struct _MetaCompScreen
MetaScreen *screen;
ClutterActor *stage, *window_group, *overlay_group;
+ ClutterActor *background_actor;
ClutterActor *hidden_group;
GList *windows;
GHashTable *windows_by_xid;
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 7eb10de..4b848b4 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -14,6 +14,7 @@
#include "meta-shadow-factory.h"
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
+#include "meta-background-actor.h"
#include "../core/window-private.h" /* to check window->hidden */
#include "../core/display-private.h" /* for meta_display_lookup_x_window() */
#include <X11/extensions/shape.h>
@@ -136,6 +137,22 @@ process_property_notify (MetaCompositor *compositor,
{
MetaWindowActor *window_actor;
+ if (event->atom == compositor->atom_x_root_pixmap)
+ {
+ GSList *l;
+
+ for (l = meta_display_get_screens (compositor->display); l; l = l->next)
+ {
+ MetaScreen *screen = l->data;
+ if (event->window == meta_screen_get_xroot (screen))
+ {
+ MetaCompScreen *info = meta_screen_get_compositor_data (screen);
+ meta_background_actor_update (META_BACKGROUND_ACTOR (info->background_actor));
+ return;
+ }
+ }
+ }
+
if (window == NULL)
return;
@@ -237,6 +254,27 @@ meta_get_window_group_for_screen (MetaScreen *screen)
}
/**
+ * meta_get_background_actor_for_screen:
+ * @screen: a #MetaScreen
+ *
+ * Gets the actor that draws the root window background under the windows.
+ * The root window background automatically tracks the image or color set
+ * by the environment.
+ *
+ * Returns: (transfer none): The background actor corresponding to @screen
+ */
+ClutterActor *
+meta_get_background_actor_for_screen (MetaScreen *screen)
+{
+ MetaCompScreen *info = meta_screen_get_compositor_data (screen);
+
+ if (!info)
+ return NULL;
+
+ return info->background_actor;
+}
+
+/**
* meta_get_window_actors:
* @screen: a #MetaScreen
*
@@ -494,9 +532,14 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
XSelectInput (xdisplay, xwin, event_mask);
info->window_group = meta_window_group_new (screen);
+ info->background_actor = meta_background_actor_new (screen);
info->overlay_group = clutter_group_new ();
info->hidden_group = clutter_group_new ();
+ clutter_container_add (CLUTTER_CONTAINER (info->window_group),
+ info->background_actor,
+ NULL);
+
clutter_container_add (CLUTTER_CONTAINER (info->stage),
info->window_group,
info->overlay_group,
@@ -844,6 +887,25 @@ sync_actor_stacking (MetaCompScreen *info)
reordered = FALSE;
old = children;
+
+ /* We allow for actors in the window group other than the actors we
+ * know about, but it's up to a plugin to try and keep them stacked correctly
+ * (we really need extra API to make that reliable.)
+ */
+
+ /* Of the actors we know, the bottom actor should be the background actor */
+
+ while (old && old->data != info->background_actor && !META_IS_WINDOW_ACTOR (old->data))
+ old = old->next;
+ if (old == NULL || old->data != info->background_actor)
+ {
+ reordered = TRUE;
+ goto done_with_check;
+ }
+
+ /* Then the window actors should follow in sequence */
+
+ old = old->next;
for (tmp = info->windows; tmp != NULL; tmp = tmp->next)
{
while (old && !META_IS_WINDOW_ACTOR (old->data))
@@ -854,14 +916,13 @@ sync_actor_stacking (MetaCompScreen *info)
if (old == NULL || old->data != tmp->data)
{
reordered = TRUE;
- break;
+ goto done_with_check;
}
old = old->next;
}
- if (old != NULL) /* An extra MetaWindowActor??? .... restack */
- reordered = TRUE;
+ done_with_check:
g_list_free (children);
@@ -874,6 +935,8 @@ sync_actor_stacking (MetaCompScreen *info)
clutter_actor_lower_bottom (CLUTTER_ACTOR (window_actor));
}
+
+ clutter_actor_lower_bottom (info->background_actor);
}
void
@@ -1018,6 +1081,8 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
g_return_if_fail (info);
clutter_actor_set_size (info->stage, width, height);
+ /* Background actor always requests the screen size */
+ clutter_actor_queue_relayout (info->background_actor);
meta_verbose ("Changed size for stage on screen %d to %dx%d\n",
meta_screen_get_screen_number (screen),
diff --git a/src/compositor/meta-background-actor.c b/src/compositor/meta-background-actor.c
new file mode 100644
index 0000000..af86778
--- /dev/null
+++ b/src/compositor/meta-background-actor.c
@@ -0,0 +1,380 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * meta-background-actor.c: Actor for painting the root window background
+ *
+ * Copyright 2009 Sander Dijkhuis
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ * Portions adapted from gnome-shell/src/shell-global.c
+ */
+
+#include <config.h>
+
+#define COGL_ENABLE_EXPERIMENTAL_API
+#include <cogl/cogl-texture-pixmap-x11.h>
+
+#include <X11/Xatom.h>
+
+#include "cogl-utils.h"
+#include "compositor-private.h"
+#include "errors.h"
+#include "meta-background-actor.h"
+
+struct _MetaBackgroundActorClass
+{
+ ClutterActorClass parent_class;
+};
+
+struct _MetaBackgroundActor
+{
+ ClutterActor parent;
+
+ CoglHandle material;
+ MetaScreen *screen;
+ cairo_region_t *visible_region;
+ float texture_width;
+ float texture_height;
+
+ guint have_pixmap : 1;
+};
+
+G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
+
+static void
+set_texture (MetaBackgroundActor *self,
+ CoglHandle texture)
+{
+ MetaDisplay *display;
+
+ display = meta_screen_get_display (self->screen);
+
+ /* This may trigger destruction of an old texture pixmap, which, if
+ * the underlying X pixmap is already gone has the tendency to trigger
+ * X errors inside DRI. For safety, trap errors */
+ meta_error_trap_push (display);
+ cogl_material_set_layer (self->material, 0, texture);
+ meta_error_trap_pop (display);
+
+ self->texture_width = cogl_texture_get_width (texture);
+ self->texture_height = cogl_texture_get_height (texture);
+
+ clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
+}
+
+/* Sets our material to paint with a 1x1 texture of the stage's background
+ * color; doing this when we have no pixmap allows the application to turn
+ * off painting the stage. There might be a performance benefit to
+ * painting in this case with a solid color, but the normal solid color
+ * case is a 1x1 root pixmap, so we'd have to reverse-engineer that to
+ * actually pick up the (small?) performance win. This is just a fallback.
+ */
+static void
+set_texture_to_stage_color (MetaBackgroundActor *self)
+{
+ ClutterActor *stage = meta_get_stage_for_screen (self->screen);
+ ClutterColor color;
+ CoglHandle texture;
+
+ clutter_stage_get_color (CLUTTER_STAGE (stage), &color);
+ texture = meta_create_color_texture_4ub (color.red, color.green,
+ color.blue, 0xff);
+ set_texture (self, texture);
+ cogl_handle_unref (texture);
+}
+
+static void
+on_notify_stage_color (GObject *stage,
+ GParamSpec *pspec,
+ MetaBackgroundActor *self)
+{
+ if (!self->have_pixmap)
+ set_texture_to_stage_color (self);
+}
+
+static void
+meta_background_actor_dispose (GObject *object)
+{
+ MetaBackgroundActor *self = META_BACKGROUND_ACTOR (object);
+
+ meta_background_actor_set_visible_region (self, NULL);
+
+ if (self->material != COGL_INVALID_HANDLE)
+ {
+ cogl_handle_unref (self->material);
+ self->material = COGL_INVALID_HANDLE;
+ }
+
+ if (self->screen != NULL)
+ {
+ ClutterActor *stage = meta_get_stage_for_screen (self->screen);
+ g_signal_handlers_disconnect_by_func (stage,
+ (gpointer) on_notify_stage_color,
+ self);
+ self->screen = NULL;
+ }
+}
+
+static void
+meta_background_actor_get_preferred_width (ClutterActor *actor,
+ gfloat for_height,
+ gfloat *min_width_p,
+ gfloat *natural_width_p)
+{
+ MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
+ int width, height;
+
+ meta_screen_get_size (self->screen, &width, &height);
+
+ if (min_width_p)
+ *min_width_p = width;
+ if (natural_width_p)
+ *natural_width_p = height;
+}
+
+static void
+meta_background_actor_get_preferred_height (ClutterActor *actor,
+ gfloat for_width,
+ gfloat *min_height_p,
+ gfloat *natural_height_p)
+
+{
+ MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
+ int width, height;
+
+ meta_screen_get_size (self->screen, &width, &height);
+
+ if (min_height_p)
+ *min_height_p = height;
+ if (natural_height_p)
+ *natural_height_p = height;
+}
+
+static void
+meta_background_actor_paint (ClutterActor *actor)
+{
+ MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
+ int width, height;
+
+ meta_screen_get_size (self->screen, &width, &height);
+
+ cogl_set_source (self->material);
+
+ if (self->visible_region)
+ {
+ int n_rectangles = cairo_region_num_rectangles (self->visible_region);
+ int i;
+
+ for (i = 0; i < n_rectangles; i++)
+ {
+ cairo_rectangle_int_t rect;
+ cairo_region_get_rectangle (self->visible_region, i, &rect);
+
+ cogl_rectangle_with_texture_coords (rect.x, rect.y,
+ rect.x + rect.width, rect.y + rect.height,
+ rect.x / self->texture_width,
+ rect.y / self->texture_height,
+ (rect.x + rect.width) / self->texture_width,
+ (rect.y + rect.height) / self->texture_height);
+ }
+ }
+ else
+ {
+ cogl_rectangle_with_texture_coords (0.0f, 0.0f,
+ width, height,
+ 0.0f, 0.0f,
+ width / self->texture_width,
+ height / self->texture_height);
+ }
+}
+
+#if CLUTTER_CHECK_VERSION(1, 5, 2)
+static gboolean
+meta_background_actor_get_paint_volume (ClutterActor *actor,
+ ClutterPaintVolume *volume)
+{
+ MetaBackgroundActor *self = META_BACKGROUND_ACTOR (actor);
+ int width, height;
+
+ meta_screen_get_size (self->screen, &width, &height);
+
+ clutter_paint_volume_set_width (volume, width);
+ clutter_paint_volume_set_height (volume, height);
+
+ return TRUE;
+}
+#endif
+
+static void
+meta_background_actor_class_init (MetaBackgroundActorClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+
+ object_class->dispose = meta_background_actor_dispose;
+
+ actor_class->get_preferred_width = meta_background_actor_get_preferred_width;
+ actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
+ actor_class->paint = meta_background_actor_paint;
+#if CLUTTER_CHECK_VERSION(1, 5, 2)
+ actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
+#endif
+}
+
+static void
+meta_background_actor_init (MetaBackgroundActor *background_actor)
+{
+}
+
+/**
+ * @screen: the #MetaScreen
+ * meta_background_actor_new:
+ *
+ * Creates a new actor to draw the background for the given screen.
+ *
+ * Return value: (transfer none): the newly created background actor
+ */
+ClutterActor *
+meta_background_actor_new (MetaScreen *screen)
+{
+ MetaBackgroundActor *self;
+ ClutterActor *stage;
+
+ g_return_val_if_fail (META_IS_SCREEN (screen), NULL);
+
+ self = g_object_new (META_TYPE_BACKGROUND_ACTOR, NULL);
+
+ self->screen = screen;
+
+ self->material = meta_create_texture_material (NULL);
+ cogl_material_set_layer_wrap_mode (self->material, 0,
+ COGL_MATERIAL_WRAP_MODE_REPEAT);
+
+ stage = meta_get_stage_for_screen (self->screen);
+ g_signal_connect (stage, "notify::color",
+ G_CALLBACK (on_notify_stage_color), self);
+
+ meta_background_actor_update (self);
+
+ return CLUTTER_ACTOR (self);
+}
+
+/**
+ * meta_background_actor_update:
+ * @self: a #MetaBackgroundActor
+ *
+ * Refetches the _XROOTPMAP_ID property for the root window and updates
+ * the contents of the background actor based on that. There's no attempt
+ * to optimize out pixmap values that don't change (since a root pixmap
+ * could be replaced by with another pixmap with the same ID under some
+ * circumstances), so this should only be called when we actually receive
+ * a PropertyNotify event for the property.
+ */
+void
+meta_background_actor_update (MetaBackgroundActor *self)
+{
+ MetaDisplay *display;
+ MetaCompositor *compositor;
+ Atom type;
+ int format;
+ gulong nitems;
+ gulong bytes_after;
+ guchar *data;
+ Pixmap root_pixmap_id;
+
+ g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
+
+ display = meta_screen_get_display (self->screen);
+ compositor = meta_display_get_compositor (display);
+
+ root_pixmap_id = None;
+ if (!XGetWindowProperty (meta_display_get_xdisplay (display),
+ meta_screen_get_xroot (self->screen),
+ compositor->atom_x_root_pixmap,
+ 0, LONG_MAX,
+ False,
+ AnyPropertyType,
+ &type, &format, &nitems, &bytes_after, &data) &&
+ type != None)
+ {
+ /* Got a property. */
+ if (type == XA_PIXMAP && format == 32 && nitems == 1)
+ {
+ /* Was what we expected. */
+ root_pixmap_id = *(Pixmap *)data;
+ }
+
+ XFree(data);
+ }
+
+ if (root_pixmap_id != None)
+ {
+ CoglHandle texture;
+
+ meta_error_trap_push (display);
+ texture = cogl_texture_pixmap_x11_new (root_pixmap_id, FALSE);
+ meta_error_trap_pop (display);
+
+ if (texture != COGL_INVALID_HANDLE)
+ {
+ set_texture (self, texture);
+ cogl_handle_unref (texture);
+
+ self->have_pixmap = True;
+ return;
+ }
+ }
+
+ self->have_pixmap = False;
+ set_texture_to_stage_color (self);
+}
+
+/**
+ * meta_background_actor_set_visible_region:
+ * @self: a #MetaBackgroundActor
+ * @visible_region: (allow-none): the area of the actor (in allocate-relative
+ * coordinates) that is visible.
+ *
+ * Sets the area of the background that is unobscured by overlapping windows.
+ * This is used to optimize and only paint the visible portions.
+ */
+void
+meta_background_actor_set_visible_region (MetaBackgroundActor *self,
+ cairo_region_t *visible_region)
+{
+ g_return_if_fail (META_IS_BACKGROUND_ACTOR (self));
+
+ if (self->visible_region)
+ {
+ cairo_region_destroy (self->visible_region);
+ self->visible_region = NULL;
+ }
+
+ if (visible_region)
+ {
+ cairo_rectangle_int_t screen_rect = { 0 };
+ meta_screen_get_size (self->screen, &screen_rect.width, &screen_rect.height);
+
+ /* Doing the intersection here is probably unnecessary - MetaWindowGroup
+ * should never compute a visible area that's larger than the root screen!
+ * but it's not that expensive and adds some extra robustness.
+ */
+ self->visible_region = cairo_region_create_rectangle (&screen_rect);
+ cairo_region_intersect (self->visible_region, visible_region);
+ }
+}
+
diff --git a/src/compositor/meta-background-actor.h b/src/compositor/meta-background-actor.h
new file mode 100644
index 0000000..b211c4b
--- /dev/null
+++ b/src/compositor/meta-background-actor.h
@@ -0,0 +1,57 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * meta-background-actor.h: Actor for painting the root window background
+ *
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef META_BACKGROUND_ACTOR_H
+#define META_BACKGROUND_ACTOR_H
+
+#include <clutter/clutter.h>
+
+#include "screen.h"
+
+/**
+ * MetaBackgroundActor:
+ *
+ * This class handles tracking and painting the root window background.
+ * By integrating with #MetaWindowGroup we can avoid painting parts of
+ * the background that are obscured by other windows.
+ */
+
+#define META_TYPE_BACKGROUND_ACTOR (meta_background_actor_get_type ())
+#define META_BACKGROUND_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKGROUND_ACTOR, MetaBackgroundActor))
+#define META_BACKGROUND_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BACKGROUND_ACTOR, MetaBackgroundActorClass))
+#define META_IS_BACKGROUND_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKGROUND_ACTOR))
+#define META_IS_BACKGROUND_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BACKGROUND_ACTOR))
+#define META_BACKGROUND_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BACKGROUND_ACTOR, MetaBackgroundActorClass))
+
+typedef struct _MetaBackgroundActor MetaBackgroundActor;
+typedef struct _MetaBackgroundActorClass MetaBackgroundActorClass;
+typedef struct _MetaBackgroundActorPrivate MetaBackgroundActorPrivate;
+
+GType meta_background_actor_get_type (void);
+
+ClutterActor *meta_background_actor_new (MetaScreen *screen);
+
+void meta_background_actor_update (MetaBackgroundActor *actor);
+void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
+ cairo_region_t *visible_region);
+
+#endif /* META_BACKGROUND_ACTOR_H */
diff --git a/src/compositor/meta-plugin.c b/src/compositor/meta-plugin.c
index 8a544c2..d18c8e1 100644
--- a/src/compositor/meta-plugin.c
+++ b/src/compositor/meta-plugin.c
@@ -351,6 +351,14 @@ meta_plugin_get_window_group (MetaPlugin *plugin)
return meta_get_window_group_for_screen (priv->screen);
}
+ClutterActor *
+meta_plugin_get_background_actor (MetaPlugin *plugin)
+{
+ MetaPluginPrivate *priv = META_PLUGIN (plugin)->priv;
+
+ return meta_get_background_actor_for_screen (priv->screen);
+}
+
/**
* _meta_plugin_effect_started:
* @plugin: the plugin
diff --git a/src/compositor/meta-window-group.c b/src/compositor/meta-window-group.c
index d501d83..857eab0 100644
--- a/src/compositor/meta-window-group.c
+++ b/src/compositor/meta-window-group.c
@@ -9,6 +9,7 @@
#include "meta-window-actor-private.h"
#include "meta-window-group.h"
+#include "meta-background-actor.h"
struct _MetaWindowGroupClass
{
@@ -152,31 +153,37 @@ meta_window_group_paint (ClutterActor *actor)
for (l = children; l; l = l->next)
{
- MetaWindowActor *window_actor;
- gboolean x, y;
-
- if (!META_IS_WINDOW_ACTOR (l->data) || !CLUTTER_ACTOR_IS_VISIBLE (l->data))
+ if (!CLUTTER_ACTOR_IS_VISIBLE (l->data))
continue;
- window_actor = l->data;
+ if (META_IS_WINDOW_ACTOR (l->data))
+ {
+ MetaWindowActor *window_actor = l->data;
+ gboolean x, y;
+
+ if (!actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
+ continue;
- if (!actor_is_untransformed (CLUTTER_ACTOR (window_actor), &x, &y))
- continue;
+ /* Temporarily move to the coordinate system of the actor */
+ cairo_region_translate (visible_region, - x, - y);
- /* Temporarily move to the coordinate system of the actor */
- cairo_region_translate (visible_region, - x, - y);
+ meta_window_actor_set_visible_region (window_actor, visible_region);
- meta_window_actor_set_visible_region (window_actor, visible_region);
+ if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
+ {
+ cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
+ if (obscured_region)
+ cairo_region_subtract (visible_region, obscured_region);
+ }
- if (clutter_actor_get_paint_opacity (CLUTTER_ACTOR (window_actor)) == 0xff)
+ meta_window_actor_set_visible_region_beneath (window_actor, visible_region);
+ cairo_region_translate (visible_region, x, y);
+ }
+ else if (META_IS_BACKGROUND_ACTOR (l->data))
{
- cairo_region_t *obscured_region = meta_window_actor_get_obscured_region (window_actor);
- if (obscured_region)
- cairo_region_subtract (visible_region, obscured_region);
+ MetaBackgroundActor *background_actor = l->data;
+ meta_background_actor_set_visible_region (background_actor, visible_region);
}
-
- meta_window_actor_set_visible_region_beneath (window_actor, visible_region);
- cairo_region_translate (visible_region, x, y);
}
cairo_region_destroy (visible_region);
@@ -188,13 +195,17 @@ meta_window_group_paint (ClutterActor *actor)
*/
for (l = children; l; l = l->next)
{
- MetaWindowActor *window_actor;
-
- if (!META_IS_WINDOW_ACTOR (l->data))
- continue;
-
- window_actor = l->data;
- meta_window_actor_reset_visible_regions (window_actor);
+ if (META_IS_WINDOW_ACTOR (l->data))
+ {
+ MetaWindowActor *window_actor = l->data;
+ window_actor = l->data;
+ meta_window_actor_reset_visible_regions (window_actor);
+ }
+ else if (META_IS_BACKGROUND_ACTOR (l->data))
+ {
+ MetaBackgroundActor *background_actor = l->data;
+ meta_background_actor_set_visible_region (background_actor, NULL);
+ }
}
g_list_free (children);
diff --git a/src/include/compositor-mutter.h b/src/include/compositor-mutter.h
index d27e0da..b893106 100644
--- a/src/include/compositor-mutter.h
+++ b/src/include/compositor-mutter.h
@@ -39,4 +39,6 @@ Window meta_get_overlay_window (MetaScreen *screen);
GList *meta_get_window_actors (MetaScreen *screen);
ClutterActor *meta_get_window_group_for_screen (MetaScreen *screen);
+ClutterActor *meta_get_background_actor_for_screen (MetaScreen *screen);
+
#endif
diff --git a/src/include/meta-plugin.h b/src/include/meta-plugin.h
index 78eabe9..36b7fbf 100644
--- a/src/include/meta-plugin.h
+++ b/src/include/meta-plugin.h
@@ -250,6 +250,9 @@ ClutterActor *
meta_plugin_get_window_group (MetaPlugin *plugin);
ClutterActor *
+meta_plugin_get_background_actor (MetaPlugin *plugin);
+
+ClutterActor *
meta_plugin_get_stage (MetaPlugin *plugin);
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]