mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
MetaBackground: untie background rendering from MetaScreen
Rather than associating background textures with a MetaScreen, associate them with GnomeBG objects. This allows to have different actors that render different backgrounds, without losing the ability to share textures. https://bugzilla.gnome.org/show_bug.cgi?id=688210
This commit is contained in:
parent
5a83ef71c9
commit
0a1ee4aa54
@ -227,7 +227,7 @@ typelib_DATA = Meta-$(api_version).typelib
|
||||
INTROSPECTION_GIRS = Meta-$(api_version).gir
|
||||
|
||||
Meta-$(api_version).gir: libmutter.la
|
||||
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0
|
||||
@META_GIR@_INCLUDES = GObject-2.0 GDesktopEnums-3.0 Gdk-3.0 Gtk-3.0 Clutter-1.0 xlib-2.0 xfixes-4.0 Cogl-1.0 GnomeDesktop-3.0
|
||||
@META_GIR@_EXPORT_PACKAGES = libmutter
|
||||
@META_GIR@_CFLAGS = $(INCLUDES)
|
||||
@META_GIR@_LIBS = libmutter.la
|
||||
|
@ -573,7 +573,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
||||
}
|
||||
|
||||
info->window_group = meta_window_group_new (screen);
|
||||
info->background_actor = meta_background_actor_new_for_screen (screen);
|
||||
info->background_actor = meta_background_actor_new (screen, NULL);
|
||||
info->overlay_group = clutter_group_new ();
|
||||
|
||||
clutter_container_add (CLUTTER_CONTAINER (info->window_group),
|
||||
@ -1183,8 +1183,6 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
||||
|
||||
XResizeWindow (xdisplay, xwin, width, height);
|
||||
|
||||
meta_background_actor_screen_size_changed (screen);
|
||||
|
||||
meta_verbose ("Changed size for stage on screen %d to %dx%d\n",
|
||||
meta_screen_get_screen_number (screen),
|
||||
width, height);
|
||||
|
@ -12,9 +12,6 @@
|
||||
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
||||
cairo_region_t *visible_region);
|
||||
|
||||
void meta_background_actor_update (MetaScreen *screen);
|
||||
void meta_background_actor_screen_size_changed (MetaScreen *screen);
|
||||
|
||||
GTask *meta_background_draw_async (MetaScreen *screen,
|
||||
GnomeBG *bg,
|
||||
GCancellable *cancellable,
|
||||
|
@ -36,40 +36,39 @@
|
||||
|
||||
#define CROSSFADE_DURATION 1000
|
||||
|
||||
/* We allow creating multiple MetaBackgroundActors for the same MetaScreen to
|
||||
/* We allow creating multiple MetaBackgroundActors for the same MetaScreen and GnomeBG to
|
||||
* allow different rendering options to be set for different copies.
|
||||
* But we want to share the same underlying CoglTexture for efficiency and
|
||||
* to avoid driver bugs that might occur if we created multiple CoglTexturePixmaps
|
||||
* for the same pixmap.
|
||||
* But we want to share the same underlying CoglTexture for efficiency.
|
||||
*
|
||||
* This structure holds common information.
|
||||
*/
|
||||
typedef struct _MetaScreenBackground MetaScreenBackground;
|
||||
typedef struct _MetaBackground MetaBackground;
|
||||
|
||||
struct _MetaScreenBackground
|
||||
struct _MetaBackground
|
||||
{
|
||||
MetaScreen *screen;
|
||||
GSList *actors;
|
||||
|
||||
GSettings *settings;
|
||||
GnomeBG *bg;
|
||||
MetaScreen *screen;
|
||||
GCancellable *cancellable;
|
||||
|
||||
float texture_width;
|
||||
float texture_height;
|
||||
CoglTexture *old_texture;
|
||||
CoglTexture *texture;
|
||||
CoglMaterialWrapMode wrap_mode;
|
||||
|
||||
GTask *rendering_task;
|
||||
};
|
||||
|
||||
struct _MetaBackgroundActorPrivate
|
||||
{
|
||||
MetaScreenBackground *background;
|
||||
MetaScreen *screen;
|
||||
MetaBackground *background;
|
||||
GnomeBG *settings;
|
||||
|
||||
CoglPipeline *single_pipeline;
|
||||
CoglPipeline *crossfade_pipeline;
|
||||
CoglPipeline *pipeline;
|
||||
CoglMaterialWrapMode wrap_mode;
|
||||
|
||||
cairo_region_t *visible_region;
|
||||
float dim_factor;
|
||||
@ -81,6 +80,9 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_SCREEN,
|
||||
PROP_SETTINGS,
|
||||
|
||||
PROP_DIM_FACTOR,
|
||||
PROP_CROSSFADE_PROGRESS,
|
||||
|
||||
@ -91,68 +93,89 @@ static GParamSpec *obj_props[PROP_LAST];
|
||||
|
||||
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
||||
|
||||
static void clear_old_texture (MetaScreenBackground *background);
|
||||
static void set_texture (MetaScreenBackground *background,
|
||||
CoglHandle texture);
|
||||
static void meta_background_update (GnomeBG *bg,
|
||||
MetaBackground *background);
|
||||
static void meta_background_actor_screen_size_changed (MetaScreen *screen,
|
||||
MetaBackgroundActor *actor);
|
||||
static void meta_background_actor_constructed (GObject *object);
|
||||
|
||||
static void clear_old_texture (MetaBackground *background);
|
||||
static void set_texture (MetaBackground *background,
|
||||
CoglHandle texture);
|
||||
|
||||
static void
|
||||
free_screen_background (MetaScreenBackground *background)
|
||||
meta_background_free (MetaBackground *background)
|
||||
{
|
||||
set_texture (background, COGL_INVALID_HANDLE);
|
||||
|
||||
g_cancellable_cancel (background->cancellable);
|
||||
g_object_unref (background->cancellable);
|
||||
|
||||
g_object_unref (background->bg);
|
||||
g_object_unref (background->settings);
|
||||
g_clear_object (&background->rendering_task);
|
||||
|
||||
g_slice_free (MetaBackground, background);
|
||||
}
|
||||
|
||||
static void
|
||||
on_settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
MetaScreenBackground *background)
|
||||
on_settings_changed (GSettings *settings,
|
||||
const char *key,
|
||||
GnomeBG *bg)
|
||||
{
|
||||
gnome_bg_load_from_preferences (background->bg,
|
||||
background->settings);
|
||||
gnome_bg_load_from_preferences (bg, settings);
|
||||
}
|
||||
|
||||
static MetaScreenBackground *
|
||||
meta_screen_background_get (MetaScreen *screen)
|
||||
static GnomeBG *
|
||||
meta_background_get_default_settings (void)
|
||||
{
|
||||
MetaScreenBackground *background;
|
||||
GSettings *settings;
|
||||
GnomeBG *bg;
|
||||
|
||||
background = g_object_get_data (G_OBJECT (screen), "meta-screen-background");
|
||||
if (background == NULL)
|
||||
settings = g_settings_new ("org.gnome.desktop.background");
|
||||
bg = gnome_bg_new ();
|
||||
|
||||
g_signal_connect (settings, "changed",
|
||||
G_CALLBACK (on_settings_changed), bg);
|
||||
on_settings_changed (settings, NULL, bg);
|
||||
|
||||
/* Just to keep settings alive */
|
||||
g_object_set_data_full (G_OBJECT (bg), "g-settings",
|
||||
g_object_ref (settings), g_object_unref);
|
||||
g_object_unref (settings);
|
||||
|
||||
return bg;
|
||||
}
|
||||
|
||||
static MetaBackground *
|
||||
meta_background_get (MetaScreen *screen,
|
||||
GnomeBG *bg)
|
||||
{
|
||||
static GQuark background_quark;
|
||||
MetaBackground *background;
|
||||
|
||||
if (G_UNLIKELY (background_quark == 0))
|
||||
background_quark = g_quark_from_static_string ("meta-background");
|
||||
|
||||
background = g_object_get_qdata (G_OBJECT (bg), background_quark);
|
||||
if (G_UNLIKELY (background == NULL))
|
||||
{
|
||||
background = g_new0 (MetaScreenBackground, 1);
|
||||
background = g_slice_new0 (MetaBackground);
|
||||
g_object_set_qdata_full (G_OBJECT (bg), background_quark,
|
||||
background, (GDestroyNotify) meta_background_free);
|
||||
|
||||
background->screen = screen;
|
||||
g_object_set_data_full (G_OBJECT (screen), "meta-screen-background",
|
||||
background, (GDestroyNotify) free_screen_background);
|
||||
|
||||
background->settings = g_settings_new ("org.gnome.desktop.background");
|
||||
g_signal_connect (background->settings, "changed",
|
||||
G_CALLBACK (on_settings_changed), background);
|
||||
|
||||
background->bg = gnome_bg_new ();
|
||||
g_signal_connect_object (background->bg, "transitioned",
|
||||
G_CALLBACK (meta_background_actor_update),
|
||||
screen, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (background->bg, "changed",
|
||||
G_CALLBACK (meta_background_actor_update),
|
||||
screen, G_CONNECT_SWAPPED);
|
||||
|
||||
background->texture_width = -1;
|
||||
background->texture_height = -1;
|
||||
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||
|
||||
on_settings_changed (background->settings, NULL, background);
|
||||
g_signal_connect (bg, "transitioned",
|
||||
G_CALLBACK (meta_background_update), background);
|
||||
g_signal_connect (bg, "changed",
|
||||
G_CALLBACK (meta_background_update), background);
|
||||
|
||||
/* GnomeBG has queued a changed event, but we need to start rendering now,
|
||||
or it will be too late when we paint the first frame.
|
||||
*/
|
||||
g_object_set_data (G_OBJECT (background->bg), "ignore-pending-change", GINT_TO_POINTER (TRUE));
|
||||
meta_background_actor_update (screen);
|
||||
g_object_set_data (G_OBJECT (bg), "ignore-pending-change", GINT_TO_POINTER (TRUE));
|
||||
meta_background_update (bg, background);
|
||||
}
|
||||
|
||||
return background;
|
||||
@ -170,10 +193,10 @@ update_actor_pipeline (MetaBackgroundActor *self,
|
||||
priv->is_crossfading = TRUE;
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->old_texture);
|
||||
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->background->wrap_mode);
|
||||
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->wrap_mode);
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 1, priv->background->texture);
|
||||
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 1, priv->background->wrap_mode);
|
||||
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 1, priv->wrap_mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -181,7 +204,7 @@ update_actor_pipeline (MetaBackgroundActor *self,
|
||||
priv->is_crossfading = FALSE;
|
||||
|
||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->texture);
|
||||
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->background->wrap_mode);
|
||||
cogl_pipeline_set_layer_wrap_mode (priv->pipeline, 0, priv->wrap_mode);
|
||||
}
|
||||
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||
@ -196,7 +219,7 @@ crossfade_completed (ClutterTimeline *timeline,
|
||||
}
|
||||
|
||||
static void
|
||||
clear_old_texture (MetaScreenBackground *background)
|
||||
clear_old_texture (MetaBackground *background)
|
||||
{
|
||||
if (background->old_texture != COGL_INVALID_HANDLE)
|
||||
{
|
||||
@ -206,12 +229,13 @@ clear_old_texture (MetaScreenBackground *background)
|
||||
}
|
||||
|
||||
static void
|
||||
set_texture (MetaScreenBackground *background,
|
||||
CoglHandle texture)
|
||||
set_texture (MetaBackground *background,
|
||||
CoglHandle texture)
|
||||
{
|
||||
GSList *l;
|
||||
gboolean crossfade;
|
||||
int width, height;
|
||||
CoglMaterialWrapMode wrap_mode;
|
||||
|
||||
if (background->old_texture != COGL_INVALID_HANDLE)
|
||||
{
|
||||
@ -246,14 +270,15 @@ set_texture (MetaScreenBackground *background,
|
||||
* side of the image via bilinear filtering.
|
||||
*/
|
||||
if (width == background->texture_width && height == background->texture_height)
|
||||
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
|
||||
wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
|
||||
else
|
||||
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||
wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||
|
||||
for (l = background->actors; l; l = l->next)
|
||||
{
|
||||
MetaBackgroundActor *actor = l->data;
|
||||
|
||||
actor->priv->wrap_mode = wrap_mode;
|
||||
update_actor_pipeline (actor, crossfade);
|
||||
|
||||
if (crossfade)
|
||||
@ -281,29 +306,8 @@ set_texture (MetaScreenBackground *background,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_wrap_mode (MetaScreenBackground *background)
|
||||
{
|
||||
GSList *l;
|
||||
int width, height;
|
||||
|
||||
meta_screen_get_size (background->screen, &width, &height);
|
||||
|
||||
if (width == background->texture_width && height == background->texture_height)
|
||||
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
|
||||
else
|
||||
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||
|
||||
for (l = background->actors; l != NULL; l++)
|
||||
{
|
||||
MetaBackgroundActor *actor = l->data;
|
||||
|
||||
update_actor_pipeline (actor, actor->priv->is_crossfading);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
meta_background_ensure_rendered (MetaScreenBackground *background)
|
||||
meta_background_ensure_rendered (MetaBackground *background)
|
||||
{
|
||||
if (G_LIKELY (background->rendering_task == NULL ||
|
||||
background->texture != COGL_INVALID_HANDLE))
|
||||
@ -326,8 +330,9 @@ meta_background_actor_dispose (GObject *object)
|
||||
priv->background = NULL;
|
||||
}
|
||||
|
||||
g_clear_pointer(&priv->single_pipeline, cogl_object_unref);
|
||||
g_clear_pointer(&priv->crossfade_pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&priv->single_pipeline, cogl_object_unref);
|
||||
g_clear_pointer (&priv->crossfade_pipeline, cogl_object_unref);
|
||||
g_clear_object (&priv->settings);
|
||||
|
||||
G_OBJECT_CLASS (meta_background_actor_parent_class)->dispose (object);
|
||||
}
|
||||
@ -342,7 +347,7 @@ meta_background_actor_get_preferred_width (ClutterActor *actor,
|
||||
MetaBackgroundActorPrivate *priv = self->priv;
|
||||
int width, height;
|
||||
|
||||
meta_screen_get_size (priv->background->screen, &width, &height);
|
||||
meta_screen_get_size (priv->screen, &width, &height);
|
||||
|
||||
if (min_width_p)
|
||||
*min_width_p = width;
|
||||
@ -361,7 +366,7 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
|
||||
MetaBackgroundActorPrivate *priv = self->priv;
|
||||
int width, height;
|
||||
|
||||
meta_screen_get_size (priv->background->screen, &width, &height);
|
||||
meta_screen_get_size (priv->screen, &width, &height);
|
||||
|
||||
if (min_height_p)
|
||||
*min_height_p = height;
|
||||
@ -381,7 +386,7 @@ meta_background_actor_paint (ClutterActor *actor)
|
||||
|
||||
meta_background_ensure_rendered (priv->background);
|
||||
|
||||
meta_screen_get_size (priv->background->screen, &width, &height);
|
||||
meta_screen_get_size (priv->screen, &width, &height);
|
||||
|
||||
color_component = (int)(0.5 + opacity * priv->dim_factor);
|
||||
|
||||
@ -440,7 +445,7 @@ meta_background_actor_get_paint_volume (ClutterActor *actor,
|
||||
MetaBackgroundActorPrivate *priv = self->priv;
|
||||
int width, height;
|
||||
|
||||
meta_screen_get_size (priv->background->screen, &width, &height);
|
||||
meta_screen_get_size (priv->screen, &width, &height);
|
||||
|
||||
clutter_paint_volume_set_width (volume, width);
|
||||
clutter_paint_volume_set_height (volume, height);
|
||||
@ -480,6 +485,31 @@ meta_background_actor_set_dim_factor (MetaBackgroundActor *self,
|
||||
g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_DIM_FACTOR]);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_set_screen (MetaBackgroundActor *self,
|
||||
MetaScreen *screen)
|
||||
{
|
||||
self->priv->screen = screen;
|
||||
g_object_add_weak_pointer (G_OBJECT (screen), (void**) &self->priv->screen);
|
||||
|
||||
g_signal_connect_object (screen, "monitors-changed",
|
||||
G_CALLBACK (meta_background_actor_screen_size_changed), self, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_set_settings (MetaBackgroundActor *self,
|
||||
GnomeBG *settings)
|
||||
{
|
||||
MetaBackgroundActorPrivate *priv;
|
||||
|
||||
priv = self->priv;
|
||||
|
||||
if (settings)
|
||||
priv->settings = g_object_ref (settings);
|
||||
else
|
||||
priv->settings = meta_background_get_default_settings ();
|
||||
}
|
||||
|
||||
static void
|
||||
meta_background_actor_get_property(GObject *object,
|
||||
guint prop_id,
|
||||
@ -496,6 +526,13 @@ meta_background_actor_get_property(GObject *object,
|
||||
break;
|
||||
case PROP_CROSSFADE_PROGRESS:
|
||||
g_value_set_float (value, priv->crossfade_progress);
|
||||
break;
|
||||
case PROP_SETTINGS:
|
||||
g_value_set_object (value, priv->settings);
|
||||
break;
|
||||
case PROP_SCREEN:
|
||||
g_value_set_object (value, priv->screen);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -518,6 +555,12 @@ meta_background_actor_set_property(GObject *object,
|
||||
case PROP_CROSSFADE_PROGRESS:
|
||||
meta_background_actor_set_crossfade_progress (self, g_value_get_float (value));
|
||||
break;
|
||||
case PROP_SETTINGS:
|
||||
meta_background_actor_set_settings (self, GNOME_BG (g_value_get_object (value)));
|
||||
break;
|
||||
case PROP_SCREEN:
|
||||
meta_background_actor_set_screen (self, META_SCREEN (g_value_get_object (value)));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@ -536,12 +579,37 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
||||
object_class->dispose = meta_background_actor_dispose;
|
||||
object_class->get_property = meta_background_actor_get_property;
|
||||
object_class->set_property = meta_background_actor_set_property;
|
||||
object_class->constructed = meta_background_actor_constructed;
|
||||
|
||||
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;
|
||||
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
|
||||
|
||||
/**
|
||||
* MetaBackgroundActor:screen:
|
||||
*
|
||||
* The #MetaScreen this actor is operating on.
|
||||
*/
|
||||
pspec = g_param_spec_object ("screen",
|
||||
"Screen",
|
||||
"The screen the actor is on",
|
||||
META_TYPE_SCREEN,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_SCREEN] = pspec;
|
||||
|
||||
/**
|
||||
* MetaBackgroundActor:settings:
|
||||
*
|
||||
* The #GnomeBG object holding settings for this background.
|
||||
*/
|
||||
pspec = g_param_spec_object ("settings",
|
||||
"Settings",
|
||||
"Object holding required information to render a background",
|
||||
GNOME_TYPE_BG,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_SETTINGS] = pspec;
|
||||
|
||||
/**
|
||||
* MetaBackgroundActor:dim-factor:
|
||||
*
|
||||
@ -578,28 +646,22 @@ meta_background_actor_init (MetaBackgroundActor *self)
|
||||
META_TYPE_BACKGROUND_ACTOR,
|
||||
MetaBackgroundActorPrivate);
|
||||
priv->dim_factor = 1.0;
|
||||
priv->crossfade_progress = 0.0;
|
||||
priv->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_actor_new:
|
||||
* @screen: the #MetaScreen
|
||||
*
|
||||
* Creates a new actor to draw the background for the given screen.
|
||||
*
|
||||
* Return value: the newly created background actor
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_background_actor_new_for_screen (MetaScreen *screen)
|
||||
static void
|
||||
meta_background_actor_constructed (GObject *object)
|
||||
{
|
||||
MetaBackgroundActor *self;
|
||||
MetaBackgroundActorPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (META_IS_SCREEN (screen), NULL);
|
||||
G_OBJECT_CLASS (meta_background_actor_parent_class)->constructed (object);
|
||||
|
||||
self = g_object_new (META_TYPE_BACKGROUND_ACTOR, NULL);
|
||||
self = META_BACKGROUND_ACTOR (object);
|
||||
priv = self->priv;
|
||||
|
||||
priv->background = meta_screen_background_get (screen);
|
||||
priv->background = meta_background_get (priv->screen, priv->settings);
|
||||
priv->background->actors = g_slist_prepend (priv->background->actors, self);
|
||||
|
||||
priv->single_pipeline = meta_create_texture_material (priv->background->texture);
|
||||
@ -608,8 +670,28 @@ meta_background_actor_new_for_screen (MetaScreen *screen)
|
||||
|
||||
if (priv->background->texture != COGL_INVALID_HANDLE)
|
||||
update_actor_pipeline (self, FALSE);
|
||||
}
|
||||
|
||||
return CLUTTER_ACTOR (self);
|
||||
/**
|
||||
* meta_background_actor_new:
|
||||
* @screen: the #MetaScreen
|
||||
* @settings: (allow-none): a #GnomeBG holding the background configuration,
|
||||
* or %NULL to pick the default one.
|
||||
*
|
||||
* Creates a new actor to draw the background for the given screen.
|
||||
*
|
||||
* Return value: the newly created background actor
|
||||
*/
|
||||
ClutterActor *
|
||||
meta_background_actor_new (MetaScreen *screen,
|
||||
GnomeBG *settings)
|
||||
{
|
||||
g_return_val_if_fail (META_IS_SCREEN (screen), NULL);
|
||||
|
||||
return g_object_new (META_TYPE_BACKGROUND_ACTOR,
|
||||
"screen", screen,
|
||||
"settings", settings,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -617,25 +699,26 @@ on_background_drawn (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
MetaScreen *screen = META_SCREEN (object);
|
||||
MetaScreenBackground *background;
|
||||
MetaBackground *background;
|
||||
CoglHandle texture;
|
||||
GError *error;
|
||||
|
||||
background = meta_screen_background_get (screen);
|
||||
|
||||
g_clear_object (&background->rendering_task);
|
||||
g_clear_object (&background->cancellable);
|
||||
|
||||
error = NULL;
|
||||
texture = meta_background_draw_finish (screen, result, &error);
|
||||
texture = meta_background_draw_finish (META_SCREEN (object), result, &error);
|
||||
|
||||
/* Don't even access user_data if cancelled, it might be already
|
||||
freed */
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
{
|
||||
g_error_free (error);
|
||||
return;
|
||||
}
|
||||
|
||||
background = user_data;
|
||||
|
||||
g_clear_object (&background->rendering_task);
|
||||
g_clear_object (&background->cancellable);
|
||||
|
||||
if (texture != COGL_INVALID_HANDLE)
|
||||
{
|
||||
set_texture (background, texture);
|
||||
@ -650,21 +733,19 @@ on_background_drawn (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_actor_update:
|
||||
* @screen: a #MetaScreen
|
||||
/*
|
||||
* meta_background_update:
|
||||
* @bg: the #GnomeBG that triggered the update
|
||||
* @background: a #MetaBackground
|
||||
*
|
||||
* Forces a redraw of the background. The redraw happens asynchronously in
|
||||
* a thread, and the actual on screen change is therefore delayed until
|
||||
* the redraw is finished.
|
||||
*/
|
||||
void
|
||||
meta_background_actor_update (MetaScreen *screen)
|
||||
meta_background_update (GnomeBG *bg,
|
||||
MetaBackground *background)
|
||||
{
|
||||
MetaScreenBackground *background;
|
||||
|
||||
background = meta_screen_background_get (screen);
|
||||
|
||||
if (background->cancellable)
|
||||
{
|
||||
g_cancellable_cancel (background->cancellable);
|
||||
@ -674,10 +755,10 @@ meta_background_actor_update (MetaScreen *screen)
|
||||
g_clear_object (&background->rendering_task);
|
||||
|
||||
background->cancellable = g_cancellable_new ();
|
||||
background->rendering_task = meta_background_draw_async (screen,
|
||||
background->bg,
|
||||
background->rendering_task = meta_background_draw_async (background->screen,
|
||||
bg,
|
||||
background->cancellable,
|
||||
on_background_drawn, NULL);
|
||||
on_background_drawn, background);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -708,7 +789,7 @@ meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
||||
if (visible_region)
|
||||
{
|
||||
cairo_rectangle_int_t screen_rect = { 0 };
|
||||
meta_screen_get_size (priv->background->screen, &screen_rect.width, &screen_rect.height);
|
||||
meta_screen_get_size (priv->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!
|
||||
@ -719,22 +800,26 @@ meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* meta_background_actor_screen_size_changed:
|
||||
* @screen: a #MetaScreen
|
||||
*
|
||||
* Called by the compositor when the size of the #MetaScreen changes
|
||||
*/
|
||||
void
|
||||
meta_background_actor_screen_size_changed (MetaScreen *screen)
|
||||
static void
|
||||
meta_background_actor_screen_size_changed (MetaScreen *screen,
|
||||
MetaBackgroundActor *actor)
|
||||
{
|
||||
MetaScreenBackground *background = meta_screen_background_get (screen);
|
||||
GSList *l;
|
||||
MetaBackgroundActorPrivate *priv;
|
||||
MetaBackground *background;
|
||||
int width, height;
|
||||
|
||||
update_wrap_mode (background);
|
||||
priv = actor->priv;
|
||||
background = priv->background;
|
||||
|
||||
for (l = background->actors; l; l = l->next)
|
||||
clutter_actor_queue_relayout (l->data);
|
||||
meta_screen_get_size (screen, &width, &height);
|
||||
|
||||
if (width == background->texture_width && height == background->texture_height)
|
||||
priv->wrap_mode = COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE;
|
||||
else
|
||||
priv->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||
|
||||
update_actor_pipeline (actor, actor->priv->is_crossfading);
|
||||
clutter_actor_queue_relayout (CLUTTER_ACTOR (actor));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,7 +239,7 @@ meta_screen_class_init (MetaScreenClass *klass)
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (MetaScreenClass, monitors_changed),
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
|
@ -12,7 +12,7 @@ mutter_plugin_api_version=@MUTTER_PLUGIN_API_VERSION@
|
||||
|
||||
Name: libmutter
|
||||
Description: Mutter window manager library
|
||||
Requires: gsettings-desktop-schemas gtk+-3.0 @CLUTTER_PACKAGE@ x11
|
||||
Requires: gsettings-desktop-schemas gtk+-3.0 @CLUTTER_PACKAGE@ x11 gnome-desktop-3.0
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lmutter
|
||||
Cflags: -I${includedir}/mutter -DMUTTER_MAJOR_VERSION=${mutter_major_version} -DMUTTER_MINOR_VERSION=${mutter_minor_version} -DMUTTER_MICRO_VERSION=${mutter_micro_version} -DMUTTER_PLUGIN_API_VERSION=${mutter_plugin_api_version}
|
||||
|
@ -24,6 +24,8 @@
|
||||
#define META_BACKGROUND_ACTOR_H
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||
#include <libgnome-desktop/gnome-bg.h>
|
||||
|
||||
#include <meta/screen.h>
|
||||
|
||||
@ -60,7 +62,8 @@ struct _MetaBackgroundActor
|
||||
|
||||
GType meta_background_actor_get_type (void);
|
||||
|
||||
ClutterActor *meta_background_actor_new_for_screen (MetaScreen *screen);
|
||||
ClutterActor *meta_background_actor_new (MetaScreen *screen,
|
||||
GnomeBG *settings);
|
||||
|
||||
/**
|
||||
* MetaSnippetHook:
|
||||
|
Loading…
Reference in New Issue
Block a user