mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -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
|
INTROSPECTION_GIRS = Meta-$(api_version).gir
|
||||||
|
|
||||||
Meta-$(api_version).gir: libmutter.la
|
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@_EXPORT_PACKAGES = libmutter
|
||||||
@META_GIR@_CFLAGS = $(INCLUDES)
|
@META_GIR@_CFLAGS = $(INCLUDES)
|
||||||
@META_GIR@_LIBS = libmutter.la
|
@META_GIR@_LIBS = libmutter.la
|
||||||
|
@ -573,7 +573,7 @@ meta_compositor_manage_screen (MetaCompositor *compositor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
info->window_group = meta_window_group_new (screen);
|
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 ();
|
info->overlay_group = clutter_group_new ();
|
||||||
|
|
||||||
clutter_container_add (CLUTTER_CONTAINER (info->window_group),
|
clutter_container_add (CLUTTER_CONTAINER (info->window_group),
|
||||||
@ -1183,8 +1183,6 @@ meta_compositor_sync_screen_size (MetaCompositor *compositor,
|
|||||||
|
|
||||||
XResizeWindow (xdisplay, xwin, width, height);
|
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_verbose ("Changed size for stage on screen %d to %dx%d\n",
|
||||||
meta_screen_get_screen_number (screen),
|
meta_screen_get_screen_number (screen),
|
||||||
width, height);
|
width, height);
|
||||||
|
@ -12,9 +12,6 @@
|
|||||||
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
void meta_background_actor_set_visible_region (MetaBackgroundActor *self,
|
||||||
cairo_region_t *visible_region);
|
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,
|
GTask *meta_background_draw_async (MetaScreen *screen,
|
||||||
GnomeBG *bg,
|
GnomeBG *bg,
|
||||||
GCancellable *cancellable,
|
GCancellable *cancellable,
|
||||||
|
@ -36,40 +36,39 @@
|
|||||||
|
|
||||||
#define CROSSFADE_DURATION 1000
|
#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.
|
* allow different rendering options to be set for different copies.
|
||||||
* But we want to share the same underlying CoglTexture for efficiency and
|
* But we want to share the same underlying CoglTexture for efficiency.
|
||||||
* to avoid driver bugs that might occur if we created multiple CoglTexturePixmaps
|
|
||||||
* for the same pixmap.
|
|
||||||
*
|
*
|
||||||
* This structure holds common information.
|
* This structure holds common information.
|
||||||
*/
|
*/
|
||||||
typedef struct _MetaScreenBackground MetaScreenBackground;
|
typedef struct _MetaBackground MetaBackground;
|
||||||
|
|
||||||
struct _MetaScreenBackground
|
struct _MetaBackground
|
||||||
{
|
{
|
||||||
MetaScreen *screen;
|
|
||||||
GSList *actors;
|
GSList *actors;
|
||||||
|
|
||||||
GSettings *settings;
|
MetaScreen *screen;
|
||||||
GnomeBG *bg;
|
|
||||||
GCancellable *cancellable;
|
GCancellable *cancellable;
|
||||||
|
|
||||||
float texture_width;
|
float texture_width;
|
||||||
float texture_height;
|
float texture_height;
|
||||||
CoglTexture *old_texture;
|
CoglTexture *old_texture;
|
||||||
CoglTexture *texture;
|
CoglTexture *texture;
|
||||||
CoglMaterialWrapMode wrap_mode;
|
|
||||||
|
|
||||||
GTask *rendering_task;
|
GTask *rendering_task;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaBackgroundActorPrivate
|
struct _MetaBackgroundActorPrivate
|
||||||
{
|
{
|
||||||
MetaScreenBackground *background;
|
MetaScreen *screen;
|
||||||
|
MetaBackground *background;
|
||||||
|
GnomeBG *settings;
|
||||||
|
|
||||||
CoglPipeline *single_pipeline;
|
CoglPipeline *single_pipeline;
|
||||||
CoglPipeline *crossfade_pipeline;
|
CoglPipeline *crossfade_pipeline;
|
||||||
CoglPipeline *pipeline;
|
CoglPipeline *pipeline;
|
||||||
|
CoglMaterialWrapMode wrap_mode;
|
||||||
|
|
||||||
cairo_region_t *visible_region;
|
cairo_region_t *visible_region;
|
||||||
float dim_factor;
|
float dim_factor;
|
||||||
@ -81,6 +80,9 @@ enum
|
|||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
|
||||||
|
PROP_SCREEN,
|
||||||
|
PROP_SETTINGS,
|
||||||
|
|
||||||
PROP_DIM_FACTOR,
|
PROP_DIM_FACTOR,
|
||||||
PROP_CROSSFADE_PROGRESS,
|
PROP_CROSSFADE_PROGRESS,
|
||||||
|
|
||||||
@ -91,68 +93,89 @@ static GParamSpec *obj_props[PROP_LAST];
|
|||||||
|
|
||||||
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
G_DEFINE_TYPE (MetaBackgroundActor, meta_background_actor, CLUTTER_TYPE_ACTOR);
|
||||||
|
|
||||||
static void clear_old_texture (MetaScreenBackground *background);
|
static void meta_background_update (GnomeBG *bg,
|
||||||
static void set_texture (MetaScreenBackground *background,
|
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);
|
CoglHandle texture);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_screen_background (MetaScreenBackground *background)
|
meta_background_free (MetaBackground *background)
|
||||||
{
|
{
|
||||||
set_texture (background, COGL_INVALID_HANDLE);
|
set_texture (background, COGL_INVALID_HANDLE);
|
||||||
|
|
||||||
g_cancellable_cancel (background->cancellable);
|
g_cancellable_cancel (background->cancellable);
|
||||||
g_object_unref (background->cancellable);
|
g_object_unref (background->cancellable);
|
||||||
|
|
||||||
g_object_unref (background->bg);
|
g_clear_object (&background->rendering_task);
|
||||||
g_object_unref (background->settings);
|
|
||||||
|
g_slice_free (MetaBackground, background);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_settings_changed (GSettings *settings,
|
on_settings_changed (GSettings *settings,
|
||||||
const char *key,
|
const char *key,
|
||||||
MetaScreenBackground *background)
|
GnomeBG *bg)
|
||||||
{
|
{
|
||||||
gnome_bg_load_from_preferences (background->bg,
|
gnome_bg_load_from_preferences (bg, settings);
|
||||||
background->settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static MetaScreenBackground *
|
static GnomeBG *
|
||||||
meta_screen_background_get (MetaScreen *screen)
|
meta_background_get_default_settings (void)
|
||||||
{
|
{
|
||||||
MetaScreenBackground *background;
|
GSettings *settings;
|
||||||
|
GnomeBG *bg;
|
||||||
|
|
||||||
background = g_object_get_data (G_OBJECT (screen), "meta-screen-background");
|
settings = g_settings_new ("org.gnome.desktop.background");
|
||||||
if (background == NULL)
|
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)
|
||||||
{
|
{
|
||||||
background = g_new0 (MetaScreenBackground, 1);
|
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_slice_new0 (MetaBackground);
|
||||||
|
g_object_set_qdata_full (G_OBJECT (bg), background_quark,
|
||||||
|
background, (GDestroyNotify) meta_background_free);
|
||||||
|
|
||||||
background->screen = screen;
|
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_width = -1;
|
||||||
background->texture_height = -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,
|
/* 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.
|
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));
|
g_object_set_data (G_OBJECT (bg), "ignore-pending-change", GINT_TO_POINTER (TRUE));
|
||||||
meta_background_actor_update (screen);
|
meta_background_update (bg, background);
|
||||||
}
|
}
|
||||||
|
|
||||||
return background;
|
return background;
|
||||||
@ -170,10 +193,10 @@ update_actor_pipeline (MetaBackgroundActor *self,
|
|||||||
priv->is_crossfading = TRUE;
|
priv->is_crossfading = TRUE;
|
||||||
|
|
||||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->old_texture);
|
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_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
|
else
|
||||||
{
|
{
|
||||||
@ -181,7 +204,7 @@ update_actor_pipeline (MetaBackgroundActor *self,
|
|||||||
priv->is_crossfading = FALSE;
|
priv->is_crossfading = FALSE;
|
||||||
|
|
||||||
cogl_pipeline_set_layer_texture (priv->pipeline, 0, priv->background->texture);
|
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));
|
clutter_actor_queue_redraw (CLUTTER_ACTOR (self));
|
||||||
@ -196,7 +219,7 @@ crossfade_completed (ClutterTimeline *timeline,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_old_texture (MetaScreenBackground *background)
|
clear_old_texture (MetaBackground *background)
|
||||||
{
|
{
|
||||||
if (background->old_texture != COGL_INVALID_HANDLE)
|
if (background->old_texture != COGL_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
@ -206,12 +229,13 @@ clear_old_texture (MetaScreenBackground *background)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_texture (MetaScreenBackground *background,
|
set_texture (MetaBackground *background,
|
||||||
CoglHandle texture)
|
CoglHandle texture)
|
||||||
{
|
{
|
||||||
GSList *l;
|
GSList *l;
|
||||||
gboolean crossfade;
|
gboolean crossfade;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
CoglMaterialWrapMode wrap_mode;
|
||||||
|
|
||||||
if (background->old_texture != COGL_INVALID_HANDLE)
|
if (background->old_texture != COGL_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
@ -246,14 +270,15 @@ set_texture (MetaScreenBackground *background,
|
|||||||
* side of the image via bilinear filtering.
|
* side of the image via bilinear filtering.
|
||||||
*/
|
*/
|
||||||
if (width == background->texture_width && height == background->texture_height)
|
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
|
else
|
||||||
background->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||||
|
|
||||||
for (l = background->actors; l; l = l->next)
|
for (l = background->actors; l; l = l->next)
|
||||||
{
|
{
|
||||||
MetaBackgroundActor *actor = l->data;
|
MetaBackgroundActor *actor = l->data;
|
||||||
|
|
||||||
|
actor->priv->wrap_mode = wrap_mode;
|
||||||
update_actor_pipeline (actor, crossfade);
|
update_actor_pipeline (actor, crossfade);
|
||||||
|
|
||||||
if (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
|
static inline void
|
||||||
meta_background_ensure_rendered (MetaScreenBackground *background)
|
meta_background_ensure_rendered (MetaBackground *background)
|
||||||
{
|
{
|
||||||
if (G_LIKELY (background->rendering_task == NULL ||
|
if (G_LIKELY (background->rendering_task == NULL ||
|
||||||
background->texture != COGL_INVALID_HANDLE))
|
background->texture != COGL_INVALID_HANDLE))
|
||||||
@ -328,6 +332,7 @@ meta_background_actor_dispose (GObject *object)
|
|||||||
|
|
||||||
g_clear_pointer (&priv->single_pipeline, cogl_object_unref);
|
g_clear_pointer (&priv->single_pipeline, cogl_object_unref);
|
||||||
g_clear_pointer (&priv->crossfade_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);
|
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;
|
MetaBackgroundActorPrivate *priv = self->priv;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
meta_screen_get_size (priv->background->screen, &width, &height);
|
meta_screen_get_size (priv->screen, &width, &height);
|
||||||
|
|
||||||
if (min_width_p)
|
if (min_width_p)
|
||||||
*min_width_p = width;
|
*min_width_p = width;
|
||||||
@ -361,7 +366,7 @@ meta_background_actor_get_preferred_height (ClutterActor *actor,
|
|||||||
MetaBackgroundActorPrivate *priv = self->priv;
|
MetaBackgroundActorPrivate *priv = self->priv;
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
meta_screen_get_size (priv->background->screen, &width, &height);
|
meta_screen_get_size (priv->screen, &width, &height);
|
||||||
|
|
||||||
if (min_height_p)
|
if (min_height_p)
|
||||||
*min_height_p = height;
|
*min_height_p = height;
|
||||||
@ -381,7 +386,7 @@ meta_background_actor_paint (ClutterActor *actor)
|
|||||||
|
|
||||||
meta_background_ensure_rendered (priv->background);
|
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);
|
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;
|
MetaBackgroundActorPrivate *priv = self->priv;
|
||||||
int width, height;
|
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_width (volume, width);
|
||||||
clutter_paint_volume_set_height (volume, height);
|
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]);
|
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
|
static void
|
||||||
meta_background_actor_get_property(GObject *object,
|
meta_background_actor_get_property(GObject *object,
|
||||||
guint prop_id,
|
guint prop_id,
|
||||||
@ -496,6 +526,13 @@ meta_background_actor_get_property(GObject *object,
|
|||||||
break;
|
break;
|
||||||
case PROP_CROSSFADE_PROGRESS:
|
case PROP_CROSSFADE_PROGRESS:
|
||||||
g_value_set_float (value, priv->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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -518,6 +555,12 @@ meta_background_actor_set_property(GObject *object,
|
|||||||
case PROP_CROSSFADE_PROGRESS:
|
case PROP_CROSSFADE_PROGRESS:
|
||||||
meta_background_actor_set_crossfade_progress (self, g_value_get_float (value));
|
meta_background_actor_set_crossfade_progress (self, g_value_get_float (value));
|
||||||
break;
|
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:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -536,12 +579,37 @@ meta_background_actor_class_init (MetaBackgroundActorClass *klass)
|
|||||||
object_class->dispose = meta_background_actor_dispose;
|
object_class->dispose = meta_background_actor_dispose;
|
||||||
object_class->get_property = meta_background_actor_get_property;
|
object_class->get_property = meta_background_actor_get_property;
|
||||||
object_class->set_property = meta_background_actor_set_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_width = meta_background_actor_get_preferred_width;
|
||||||
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
|
actor_class->get_preferred_height = meta_background_actor_get_preferred_height;
|
||||||
actor_class->paint = meta_background_actor_paint;
|
actor_class->paint = meta_background_actor_paint;
|
||||||
actor_class->get_paint_volume = meta_background_actor_get_paint_volume;
|
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:
|
* MetaBackgroundActor:dim-factor:
|
||||||
*
|
*
|
||||||
@ -578,28 +646,22 @@ meta_background_actor_init (MetaBackgroundActor *self)
|
|||||||
META_TYPE_BACKGROUND_ACTOR,
|
META_TYPE_BACKGROUND_ACTOR,
|
||||||
MetaBackgroundActorPrivate);
|
MetaBackgroundActorPrivate);
|
||||||
priv->dim_factor = 1.0;
|
priv->dim_factor = 1.0;
|
||||||
|
priv->crossfade_progress = 0.0;
|
||||||
|
priv->wrap_mode = COGL_MATERIAL_WRAP_MODE_REPEAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* meta_background_actor_new:
|
meta_background_actor_constructed (GObject *object)
|
||||||
* @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)
|
|
||||||
{
|
{
|
||||||
MetaBackgroundActor *self;
|
MetaBackgroundActor *self;
|
||||||
MetaBackgroundActorPrivate *priv;
|
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 = 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->background->actors = g_slist_prepend (priv->background->actors, self);
|
||||||
|
|
||||||
priv->single_pipeline = meta_create_texture_material (priv->background->texture);
|
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)
|
if (priv->background->texture != COGL_INVALID_HANDLE)
|
||||||
update_actor_pipeline (self, FALSE);
|
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
|
static void
|
||||||
@ -617,25 +699,26 @@ on_background_drawn (GObject *object,
|
|||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
MetaScreen *screen = META_SCREEN (object);
|
MetaBackground *background;
|
||||||
MetaScreenBackground *background;
|
|
||||||
CoglHandle texture;
|
CoglHandle texture;
|
||||||
GError *error;
|
GError *error;
|
||||||
|
|
||||||
background = meta_screen_background_get (screen);
|
|
||||||
|
|
||||||
g_clear_object (&background->rendering_task);
|
|
||||||
g_clear_object (&background->cancellable);
|
|
||||||
|
|
||||||
error = NULL;
|
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))
|
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||||
{
|
{
|
||||||
g_error_free (error);
|
g_error_free (error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
background = user_data;
|
||||||
|
|
||||||
|
g_clear_object (&background->rendering_task);
|
||||||
|
g_clear_object (&background->cancellable);
|
||||||
|
|
||||||
if (texture != COGL_INVALID_HANDLE)
|
if (texture != COGL_INVALID_HANDLE)
|
||||||
{
|
{
|
||||||
set_texture (background, texture);
|
set_texture (background, texture);
|
||||||
@ -650,21 +733,19 @@ on_background_drawn (GObject *object,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* meta_background_actor_update:
|
* meta_background_update:
|
||||||
* @screen: a #MetaScreen
|
* @bg: the #GnomeBG that triggered the update
|
||||||
|
* @background: a #MetaBackground
|
||||||
*
|
*
|
||||||
* Forces a redraw of the background. The redraw happens asynchronously in
|
* Forces a redraw of the background. The redraw happens asynchronously in
|
||||||
* a thread, and the actual on screen change is therefore delayed until
|
* a thread, and the actual on screen change is therefore delayed until
|
||||||
* the redraw is finished.
|
* the redraw is finished.
|
||||||
*/
|
*/
|
||||||
void
|
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)
|
if (background->cancellable)
|
||||||
{
|
{
|
||||||
g_cancellable_cancel (background->cancellable);
|
g_cancellable_cancel (background->cancellable);
|
||||||
@ -674,10 +755,10 @@ meta_background_actor_update (MetaScreen *screen)
|
|||||||
g_clear_object (&background->rendering_task);
|
g_clear_object (&background->rendering_task);
|
||||||
|
|
||||||
background->cancellable = g_cancellable_new ();
|
background->cancellable = g_cancellable_new ();
|
||||||
background->rendering_task = meta_background_draw_async (screen,
|
background->rendering_task = meta_background_draw_async (background->screen,
|
||||||
background->bg,
|
bg,
|
||||||
background->cancellable,
|
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)
|
if (visible_region)
|
||||||
{
|
{
|
||||||
cairo_rectangle_int_t screen_rect = { 0 };
|
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
|
/* Doing the intersection here is probably unnecessary - MetaWindowGroup
|
||||||
* should never compute a visible area that's larger than the root screen!
|
* 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,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void
|
||||||
* meta_background_actor_screen_size_changed:
|
meta_background_actor_screen_size_changed (MetaScreen *screen,
|
||||||
* @screen: a #MetaScreen
|
MetaBackgroundActor *actor)
|
||||||
*
|
|
||||||
* Called by the compositor when the size of the #MetaScreen changes
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
meta_background_actor_screen_size_changed (MetaScreen *screen)
|
|
||||||
{
|
{
|
||||||
MetaScreenBackground *background = meta_screen_background_get (screen);
|
MetaBackgroundActorPrivate *priv;
|
||||||
GSList *l;
|
MetaBackground *background;
|
||||||
|
int width, height;
|
||||||
|
|
||||||
update_wrap_mode (background);
|
priv = actor->priv;
|
||||||
|
background = priv->background;
|
||||||
|
|
||||||
for (l = background->actors; l; l = l->next)
|
meta_screen_get_size (screen, &width, &height);
|
||||||
clutter_actor_queue_relayout (l->data);
|
|
||||||
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,7 @@ mutter_plugin_api_version=@MUTTER_PLUGIN_API_VERSION@
|
|||||||
|
|
||||||
Name: libmutter
|
Name: libmutter
|
||||||
Description: Mutter window manager library
|
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@
|
Version: @VERSION@
|
||||||
Libs: -L${libdir} -lmutter
|
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}
|
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
|
#define META_BACKGROUND_ACTOR_H
|
||||||
|
|
||||||
#include <clutter/clutter.h>
|
#include <clutter/clutter.h>
|
||||||
|
#define GNOME_DESKTOP_USE_UNSTABLE_API
|
||||||
|
#include <libgnome-desktop/gnome-bg.h>
|
||||||
|
|
||||||
#include <meta/screen.h>
|
#include <meta/screen.h>
|
||||||
|
|
||||||
@ -60,7 +62,8 @@ struct _MetaBackgroundActor
|
|||||||
|
|
||||||
GType meta_background_actor_get_type (void);
|
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:
|
* MetaSnippetHook:
|
||||||
|
Loading…
Reference in New Issue
Block a user