MetaBackground: reintroduce animated backgrounds

Replace the previous background loader with a MetaBackgroundSlideshow class,
which replaces the slideshow code from GnomeBG.
This commit is contained in:
Giovanni Campagna 2013-02-13 14:46:07 +01:00
parent f254879226
commit db7fa793b0
3 changed files with 1040 additions and 73 deletions

View File

@ -9,15 +9,39 @@
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);
GTask *meta_background_draw_async (MetaScreen *screen, /**
const char *picture_uri, * MetaBackgroundSlideshow:
GCancellable *cancellable, *
GAsyncReadyCallback callback, * A class for handling animated backgrounds.
gpointer user_data); */
CoglHandle meta_background_draw_finish (MetaScreen *screen,
GAsyncResult *result, #define META_TYPE_BACKGROUND_SLIDESHOW (meta_background_slideshow_get_type ())
char **picture_uri, #define META_BACKGROUND_SLIDESHOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), META_TYPE_BACKGROUND_SLIDESHOW, MetaBackgroundSlideshow))
GError **error); #define META_BACKGROUND_SLIDESHOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), META_TYPE_BACKGROUND_SLIDESHOW, MetaBackgroundSlideshowClass))
#define META_IS_BACKGROUND_SLIDESHOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), META_TYPE_BACKGROUND_SLIDESHOW))
#define META_IS_BACKGROUND_SLIDESHOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), META_TYPE_BACKGROUND_SLIDESHOW))
#define META_BACKGROUND_SLIDESHOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), META_TYPE_BACKGROUND_SLIDESHOW, MetaBackgroundSlideshowClass))
typedef struct _MetaBackgroundSlideshow MetaBackgroundSlideshow;
typedef struct _MetaBackgroundSlideshowClass MetaBackgroundSlideshowClass;
GType meta_background_slideshow_get_type (void) G_GNUC_CONST;
MetaBackgroundSlideshow *meta_background_slideshow_new (MetaScreen *screen,
const char *picture_uri);
const char *meta_background_slideshow_get_uri (MetaBackgroundSlideshow *slideshow);
GTask *meta_background_slideshow_draw_async (MetaBackgroundSlideshow *slideshow,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
CoglHandle meta_background_slideshow_draw_finish (MetaBackgroundSlideshow *slideshow,
GAsyncResult *result,
GError **error);
int meta_background_slideshow_get_next_timeout (MetaBackgroundSlideshow *slideshow);
#endif /* META_BACKGROUND_ACTOR_PRIVATE_H */ #endif /* META_BACKGROUND_ACTOR_PRIVATE_H */

View File

@ -25,6 +25,8 @@
#include <config.h> #include <config.h>
#include <string.h>
#include <clutter/clutter.h> #include <clutter/clutter.h>
#include "cogl-utils.h" #include "cogl-utils.h"
@ -43,6 +45,7 @@
typedef struct _MetaBackground MetaBackground; typedef struct _MetaBackground MetaBackground;
typedef struct { typedef struct {
MetaBackgroundSlideshow *slideshow;
CoglTexture *texture; CoglTexture *texture;
float texture_width; float texture_width;
float texture_height; float texture_height;
@ -52,7 +55,6 @@ typedef struct {
ClutterColor colors[2]; ClutterColor colors[2];
GDesktopBackgroundStyle style; GDesktopBackgroundStyle style;
GDesktopBackgroundShading shading; GDesktopBackgroundShading shading;
char *picture_uri;
} MetaBackgroundState; } MetaBackgroundState;
struct _MetaBackground struct _MetaBackground
@ -65,6 +67,8 @@ struct _MetaBackground
MetaBackgroundState old_state; MetaBackgroundState old_state;
MetaBackgroundState state; MetaBackgroundState state;
GSettings *settings; GSettings *settings;
MetaBackgroundSlideshow *pending_slideshow;
GSource *timeout;
GTask *rendering_task; GTask *rendering_task;
}; };
@ -101,16 +105,17 @@ 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 meta_background_update (MetaBackground *background, static void meta_background_uri_changed (MetaBackground *background,
const char *picture_uri); const char *picture_uri);
static gboolean meta_background_update (MetaBackground *background);
static void meta_background_actor_screen_size_changed (MetaScreen *screen, static void meta_background_actor_screen_size_changed (MetaScreen *screen,
MetaBackgroundActor *actor); MetaBackgroundActor *actor);
static void meta_background_actor_constructed (GObject *object); static void meta_background_actor_constructed (GObject *object);
static void clear_state (MetaBackgroundState *state); static void clear_state (MetaBackgroundState *state);
static void set_texture (MetaBackground *background, static void set_texture (MetaBackground *background,
CoglHandle texture, CoglHandle texture,
const char *picture_uri); MetaBackgroundSlideshow *slideshow);
static void static void
meta_background_free (MetaBackground *background) meta_background_free (MetaBackground *background)
@ -131,11 +136,16 @@ on_settings_changed (GSettings *settings,
const char *key, const char *key,
MetaBackground *background) MetaBackground *background)
{ {
char *picture_uri; if (strcmp (key, "picture-uri") == 0)
{
char *picture_uri;
picture_uri = g_settings_get_string (settings, "picture-uri"); picture_uri = g_settings_get_string (settings, "picture-uri");
meta_background_update (background, picture_uri); meta_background_uri_changed (background, picture_uri);
g_free (picture_uri); g_free (picture_uri);
}
else
meta_background_update (background);
} }
static GSettings * static GSettings *
@ -166,7 +176,7 @@ meta_background_get (MetaScreen *screen,
g_signal_connect (settings, "changed", g_signal_connect (settings, "changed",
G_CALLBACK (on_settings_changed), background); G_CALLBACK (on_settings_changed), background);
on_settings_changed (settings, NULL, background); on_settings_changed (settings, "picture-uri", background);
} }
return background; return background;
@ -186,8 +196,7 @@ static inline void
clear_state (MetaBackgroundState *state) clear_state (MetaBackgroundState *state)
{ {
g_clear_pointer (&state->texture, cogl_handle_unref); g_clear_pointer (&state->texture, cogl_handle_unref);
g_free (state->picture_uri); g_clear_object (&state->slideshow);
state->picture_uri = NULL;
} }
static void static void
@ -218,13 +227,14 @@ get_color_from_settings (GSettings *settings,
} }
static void static void
set_texture (MetaBackground *background, set_texture (MetaBackground *background,
CoglHandle texture, CoglHandle texture,
const char *picture_uri) MetaBackgroundSlideshow *slideshow)
{ {
GSList *l; GSList *l;
gboolean crossfade; gboolean crossfade;
int width, height; int width, height;
int timeout;
g_assert (texture != COGL_INVALID_HANDLE); g_assert (texture != COGL_INVALID_HANDLE);
@ -242,7 +252,23 @@ set_texture (MetaBackground *background,
background->state.shading = g_settings_get_enum (background->settings, "color-shading-type"); background->state.shading = g_settings_get_enum (background->settings, "color-shading-type");
background->state.texture_width = cogl_texture_get_width (background->state.texture); background->state.texture_width = cogl_texture_get_width (background->state.texture);
background->state.texture_height = cogl_texture_get_height (background->state.texture); background->state.texture_height = cogl_texture_get_height (background->state.texture);
background->state.picture_uri = g_strdup (picture_uri); background->state.slideshow = g_object_ref (slideshow);
timeout = meta_background_slideshow_get_next_timeout (slideshow);
if (background->timeout != NULL)
g_source_destroy (background->timeout);
if (timeout > 0)
{
background->timeout = g_timeout_source_new (timeout * 1000);
g_source_set_callback (background->timeout,
(GSourceFunc) (meta_background_update),
background, NULL);
g_source_attach (background->timeout, NULL);
}
else
background->timeout = NULL;
crossfade = state_is_valid (&background->old_state); crossfade = state_is_valid (&background->old_state);
@ -987,13 +1013,14 @@ on_background_drawn (GObject *object,
GAsyncResult *result, GAsyncResult *result,
gpointer user_data) gpointer user_data)
{ {
MetaBackgroundSlideshow *slideshow;
MetaBackground *background; MetaBackground *background;
CoglHandle texture; CoglHandle texture;
GError *error; GError *error;
char *picture_uri;
error = NULL; error = NULL;
texture = meta_background_draw_finish (META_SCREEN (object), result, &picture_uri, &error); slideshow = META_BACKGROUND_SLIDESHOW (object);
texture = meta_background_slideshow_draw_finish (slideshow, result, &error);
/* Don't even access user_data if cancelled, it might be already /* Don't even access user_data if cancelled, it might be already
freed */ freed */
@ -1010,9 +1037,8 @@ on_background_drawn (GObject *object,
if (texture != COGL_INVALID_HANDLE) if (texture != COGL_INVALID_HANDLE)
{ {
set_texture (background, texture, picture_uri); set_texture (background, texture, slideshow);
cogl_handle_unref (texture); cogl_handle_unref (texture);
g_free (picture_uri);
return; return;
} }
else else
@ -1024,7 +1050,7 @@ on_background_drawn (GObject *object,
} }
/* /*
* meta_background_update: * meta_background_uri_changed:
* @background: a #MetaBackground * @background: a #MetaBackground
* @picture_uri: the new image URI * @picture_uri: the new image URI
* *
@ -1032,11 +1058,15 @@ on_background_drawn (GObject *object,
* 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 static void
meta_background_update (MetaBackground *background, meta_background_uri_changed (MetaBackground *background,
const char *picture_uri) const char *picture_uri)
{ {
if (g_strcmp0 (background->state.picture_uri, picture_uri) == 0) MetaBackgroundSlideshow *current_slideshow;
current_slideshow = background->pending_slideshow;
if (current_slideshow &&
strcmp (meta_background_slideshow_get_uri (current_slideshow), picture_uri) == 0)
return; return;
if (background->cancellable) if (background->cancellable)
@ -1046,13 +1076,38 @@ meta_background_update (MetaBackground *background,
} }
g_clear_object (&background->rendering_task); g_clear_object (&background->rendering_task);
g_clear_object (&background->pending_slideshow);
background->cancellable = g_cancellable_new (); background->cancellable = g_cancellable_new ();
background->pending_slideshow = meta_background_slideshow_new (background->screen,
picture_uri);
background->rendering_task = meta_background_draw_async (background->screen, background->rendering_task = meta_background_slideshow_draw_async (background->pending_slideshow,
picture_uri, background->cancellable,
background->cancellable, on_background_drawn, background);
on_background_drawn, background); }
static gboolean
meta_background_update (MetaBackground *background)
{
if (background->timeout)
{
g_source_destroy (background->timeout);
background->timeout = NULL;
}
if (background->cancellable)
{
g_cancellable_cancel (background->cancellable);
g_object_unref (background->cancellable);
}
g_clear_object (&background->rendering_task);
background->rendering_task = meta_background_slideshow_draw_async (background->state.slideshow,
background->cancellable,
on_background_drawn, background);
return FALSE;
} }
/** /**

File diff suppressed because it is too large Load Diff