lightdm-gtk-greeter-team team mailing list archive
-
lightdm-gtk-greeter-team team
-
Mailing list archive
-
Message #00655
[Merge] lp:~kalgasnik/lightdm-gtk-greeter/background-transition into lp:lightdm-gtk-greeter
Andrew P. has proposed merging lp:~kalgasnik/lightdm-gtk-greeter/background-transition into lp:lightdm-gtk-greeter.
Requested reviews:
LightDM Gtk+ Greeter Development Team (lightdm-gtk-greeter-team)
For more details, see:
https://code.launchpad.net/~kalgasnik/lightdm-gtk-greeter/background-transition/+merge/241082
Add transition to backgrounds change.
1. Transition function: easy-in-out
2. Animation: drawing new background with different alpha over old background
3. Redraw timeout: 30ms
4. Duration: 500ms
5. Delay before changing to user's background: 250ms
At first I thought to make all these things configurable, but someone can say that it is too much.
"transition-duration" is enough.
Enabled by default, I'm not sure that it is good idea.
--
https://code.launchpad.net/~kalgasnik/lightdm-gtk-greeter/background-transition/+merge/241082
Your team LightDM Gtk+ Greeter Development Team is requested to review the proposed merge of lp:~kalgasnik/lightdm-gtk-greeter/background-transition into lp:lightdm-gtk-greeter.
=== modified file 'src/Makefile.am'
--- src/Makefile.am 2014-08-20 23:23:59 +0000
+++ src/Makefile.am 2014-11-07 14:12:38 +0000
@@ -41,7 +41,8 @@
$(LIBX11_LIBS) \
$(LIBINDICATOR_LIBS) \
$(LIBIDO_LIBS) \
- $(LIBXKLAVIER_LIBS)
+ $(LIBXKLAVIER_LIBS)\
+ -lm
if MAINTAINER_MODE
@@ -65,4 +66,4 @@
EXTRA_DIST = \
lightdm-gtk-greeter.glade \
lightdm-gtk-greeter-fallback.css \
- lightdm-gtk-greeter-application.css
\ No newline at end of file
+ lightdm-gtk-greeter-application.css
=== modified file 'src/greeterbackground.c'
--- src/greeterbackground.c 2014-08-31 17:45:52 +0000
+++ src/greeterbackground.c 2014-11-07 14:12:38 +0000
@@ -1,4 +1,5 @@
+#include <math.h>
#include <cairo-xlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@@ -34,6 +35,9 @@
static const gchar* SCALING_MODE_PREFIXES[] = {"#source:", "#zoomed:", "#stretched:", NULL};
+typedef gdouble (*TransitionFunction)(gdouble x);
+typedef void (*TransitionDraw)(gpointer monitor, cairo_t* cr);
+
/* Background configuration (parsed from background=... option).
Used to fill <Background> */
typedef struct
@@ -50,18 +54,34 @@
} options;
} BackgroundConfig;
+/* Transition configuration
+ Used to as part of <MonitorConfig> and <Monitor> */
+typedef struct
+{
+ /* Transition duration, in ms */
+ glong duration;
+ /* Timer timeout, in ms */
+ glong timeout;
+ TransitionFunction func;
+ /* Function to draw monitor background */
+ TransitionDraw draw;
+} TransitionConfig;
+
/* Store monitor configuration */
typedef struct
{
BackgroundConfig bg;
gboolean user_bg;
gboolean laptop;
+
+ TransitionConfig transition;
} MonitorConfig;
/* Actual drawing information attached to monitor.
* Used to separate configured monitor background and user background. */
typedef struct
{
+ gint ref_count;
BackgroundType type;
union
{
@@ -80,12 +100,25 @@
gulong window_draw_handler_id;
/* Configured background */
- Background background_configured;
- /* Background used to display user-background */
- Background background_custom;
+ Background* background_configured;
/* Current monitor background: &background_configured or &background_custom
* Monitors with type = BACKGROUND_TYPE_SKIP have background = NULL */
- const Background* background;
+ Background* background;
+
+ struct
+ {
+ TransitionConfig config;
+
+ /* Old background, stage == 0.0 */
+ Background* from;
+ /* New background, stage == 1.0 */
+ Background* to;
+
+ gint timer_id;
+ gint64 started;
+ /* Current stage */
+ gdouble stage;
+ } transition;
} Monitor;
struct _GreeterBackground
@@ -141,6 +174,9 @@
gboolean follow_cursor;
/* Use cursor position to determinate initial active monitor */
gboolean follow_cursor_to_init;
+
+ /* Name => transition function, inited in set_monitor_config() */
+ GHashTable* transition_types;
};
enum
@@ -151,20 +187,6 @@
static guint background_signals[BACKGROUND_SIGNAL_LAST] = {0};
-static const MonitorConfig DEFAULT_MONITOR_CONFIG =
-{
- .bg =
- {
- .type = BACKGROUND_TYPE_COLOR,
- .options =
- {
- .color = {.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}
- }
- },
- .user_bg = TRUE,
- .laptop = FALSE
-};
-
static const gchar* DBUS_UPOWER_NAME = "org.freedesktop.UPower";
static const gchar* DBUS_UPOWER_PATH = "/org/freedesktop/UPower";
static const gchar* DBUS_UPOWER_INTERFACE = "org.freedesktop.UPower";
@@ -177,15 +199,13 @@
void greeter_background_set_active_monitor_config (GreeterBackground* background,
const gchar* value);
-void greeter_background_set_default_config (GreeterBackground* background,
- const gchar* bg,
- gboolean user_bg,
- gboolean laptop);
void greeter_background_set_monitor_config (GreeterBackground* background,
const gchar* name,
- const gchar* bg,
+ const gchar* bg, /* NULL to use fallback value */
gboolean user_bg, gboolean user_bg_used,
- gboolean laptop, gboolean laptop_used);
+ gboolean laptop, gboolean laptop_used,
+ gint transition_duration, /* -1 to use fallback value */
+ const gchar* transition_type); /* NULL to use fallback value */
void greeter_background_remove_monitor_config (GreeterBackground* background,
const gchar* name);
gchar** greeter_background_get_configured_monitors (GreeterBackground* background);
@@ -227,17 +247,26 @@
MonitorConfig* dest);
/* struct Background */
-static gboolean background_initialize (Background* bg,
- const BackgroundConfig* config,
+static Background* background_new (const BackgroundConfig* config,
const Monitor* monitor,
GHashTable* images_cache);
+static Background* background_ref (Background* bg);
+static void background_unref (Background** bg);
static void background_finalize (Background* bg);
/* struct Monitor */
static void monitor_finalize (Monitor* info);
static void monitor_set_background (Monitor* monitor,
- const Background* background);
+ Background* background);
+static void monitor_start_transition (Monitor* monitor,
+ Background* from,
+ Background* to);
+static void monitor_stop_transition (Monitor* monitor);
+static gboolean monitor_transition_cb (Monitor* monitor);
+static void monitor_transition_draw_alpha (const Monitor* monitor,
+ cairo_t* cr);
static void monitor_draw_background (const Monitor* monitor,
+ const Background* background,
cairo_t* cr);
static gboolean monitor_window_draw_cb (GtkWidget* widget,
cairo_t* cr,
@@ -259,7 +288,29 @@
Pixmap xpixmap);
static void set_surface_as_root (GdkScreen* screen,
cairo_surface_t* surface);
+static gdouble transition_func_linear (gdouble x);
+static gdouble transition_func_easy_in_out (gdouble x);
+static const MonitorConfig DEFAULT_MONITOR_CONFIG =
+{
+ .bg =
+ {
+ .type = BACKGROUND_TYPE_COLOR,
+ .options =
+ {
+ .color = {.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0}
+ }
+ },
+ .user_bg = TRUE,
+ .laptop = FALSE,
+ .transition =
+ {
+ .duration = 500,
+ .timeout = 30,
+ .func = transition_func_easy_in_out,
+ .draw = (TransitionDraw)monitor_transition_draw_alpha
+ }
+};
/* Implementation */
@@ -302,7 +353,7 @@
self->priv->laptop_lid_closed = FALSE;
}
-GreeterBackground*
+GreeterBackground*
greeter_background_new(GtkWidget* child)
{
GreeterBackground* background = GREETER_BACKGROUND(g_object_new(greeter_background_get_type(), NULL));
@@ -346,42 +397,56 @@
}
void
-greeter_background_set_default_config(GreeterBackground* background,
- const gchar* bg,
- gboolean user_bg,
- gboolean laptop)
-{
- g_return_if_fail(GREETER_IS_BACKGROUND(background));
- GreeterBackgroundPrivate* priv = background->priv;
-
- if(priv->default_config)
- monitor_config_free(priv->default_config);
-
- priv->default_config = g_new0(MonitorConfig, 1);
- if(!background_config_initialize(&priv->default_config->bg, bg))
- background_config_copy(&DEFAULT_MONITOR_CONFIG.bg, &priv->default_config->bg);
- priv->default_config->user_bg = user_bg;
- priv->default_config->laptop = laptop;
-}
-
-void
greeter_background_set_monitor_config(GreeterBackground* background,
const gchar* name,
const gchar* bg,
gboolean user_bg, gboolean user_bg_used,
- gboolean laptop, gboolean laptop_used)
+ gboolean laptop, gboolean laptop_used,
+ gint transition_duration,
+ const gchar* transition_type)
{
g_return_if_fail(GREETER_IS_BACKGROUND(background));
GreeterBackgroundPrivate* priv = background->priv;
MonitorConfig* config = g_new0(MonitorConfig, 1);
+ const MonitorConfig* FALLBACK = (g_strcmp0(name, GREETER_BACKGROUND_DEFAULT) == 0) ? &DEFAULT_MONITOR_CONFIG : priv->default_config;
+
if(!background_config_initialize(&config->bg, bg))
- background_config_copy(&priv->default_config->bg, &config->bg);
- config->user_bg = user_bg_used ? user_bg : priv->default_config->user_bg;
- config->laptop = laptop_used ? laptop : priv->default_config->laptop;
-
- g_hash_table_insert(priv->configs, g_strdup(name), config);
+ background_config_copy(&FALLBACK->bg, &config->bg);
+ config->user_bg = user_bg_used ? user_bg : FALLBACK->user_bg;
+ config->laptop = laptop_used ? laptop : FALLBACK->laptop;
+ config->transition.duration = transition_duration >= 0 ? transition_duration : FALLBACK->transition.duration;
+ config->transition.timeout = FALLBACK->transition.timeout;
+ config->transition.draw = FALLBACK->transition.draw;
+
+ if(transition_type)
+ {
+ if(!priv->transition_types)
+ {
+ priv->transition_types = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ g_hash_table_insert(priv->transition_types, g_strdup("none"), NULL);
+ g_hash_table_insert(priv->transition_types, g_strdup("linear"), transition_func_linear);
+ g_hash_table_insert(priv->transition_types, g_strdup("easy-in-out"), transition_func_easy_in_out);
+ }
+ if(!g_hash_table_lookup_extended(priv->transition_types, transition_type, NULL, (gpointer*)&config->transition.func))
+ {
+ g_warning("[Background] Invalid transition type for '%s' monitor: '%s'. Using fallback value.",
+ name, transition_type);
+ config->transition.func = FALLBACK->transition.func;
+ }
+ }
+ else
+ config->transition.func = FALLBACK->transition.func;
+
+ if(FALLBACK == priv->default_config)
+ g_hash_table_insert(priv->configs, g_strdup(name), config);
+ else
+ {
+ if(priv->default_config)
+ monitor_config_free(priv->default_config);
+ priv->default_config = config;
+ }
}
void
@@ -503,9 +568,13 @@
if(config->laptop)
priv->laptop_monitors = g_slist_prepend(priv->laptop_monitors, monitor);
- if(!background_initialize(&monitor->background_configured, &config->bg, monitor, images_cache))
- background_initialize(&monitor->background_configured, &DEFAULT_MONITOR_CONFIG.bg, monitor, images_cache);
- monitor_set_background(monitor, &monitor->background_configured);
+ monitor->background_configured = background_new(&config->bg, monitor, images_cache);
+ if(!monitor->background_configured)
+ monitor->background_configured = background_new(&DEFAULT_MONITOR_CONFIG.bg, monitor, images_cache);
+ monitor_set_background(monitor, monitor->background_configured);
+
+ if(config->transition.duration && config->transition.func)
+ monitor->transition.config = config->transition;
if(monitor->name)
g_hash_table_insert(priv->monitors_map, g_strdup(monitor->name), monitor);
@@ -809,13 +878,19 @@
{
Monitor *monitor = iter->data;
- background_finalize(&monitor->background_custom);
- if(config.type != BACKGROUND_TYPE_INVALID &&
- background_initialize(&monitor->background_custom, &config, monitor, images_cache))
- monitor_set_background(monitor, &monitor->background_custom);
+ /* Old background_custom (if used) will be unrefed in monitor_set_background() */
+ Background* bg = NULL;
+ if(config.type != BACKGROUND_TYPE_INVALID)
+ bg = background_new(&config, monitor, images_cache);
+ if(bg)
+ {
+ monitor_set_background(monitor, bg);
+ background_unref(&bg);
+ }
else
- monitor_set_background(monitor, &monitor->background_configured);
+ monitor_set_background(monitor, monitor->background_configured);
}
+
if(images_cache)
g_hash_table_unref(images_cache);
if(config.type != BACKGROUND_TYPE_INVALID)
@@ -841,7 +916,7 @@
monitor = priv->active_monitor;
cairo_save(cr);
cairo_translate(cr, monitor->geometry.x, monitor->geometry.y);
- monitor_draw_background(monitor, cr);
+ monitor_draw_background(monitor, monitor->background, cr);
cairo_restore(cr);
}
set_surface_as_root(priv->screen, surface);
@@ -904,7 +979,7 @@
config->options.image.mode = SCALING_MODE_ZOOMED;
config->options.image.path = g_strdup(value);
- config->type = BACKGROUND_TYPE_IMAGE;
+ config->type = BACKGROUND_TYPE_IMAGE;
}
return TRUE;
}
@@ -941,15 +1016,16 @@
background_config_copy(&source->bg, &dest->bg);
dest->user_bg = source->user_bg;
dest->laptop = source->laptop;
+ dest->transition = source->transition;
return dest;
}
-static gboolean
-background_initialize(Background* bg,
- const BackgroundConfig* config,
- const Monitor* monitor,
- GHashTable* images_cache)
+static Background*
+background_new(const BackgroundConfig* config,
+ const Monitor* monitor,
+ GHashTable* images_cache)
{
+ Background* bg = NULL;
if(config->type == BACKGROUND_TYPE_IMAGE)
{
GdkPixbuf* pixbuf = scale_image_file(config->options.image.path,
@@ -959,16 +1035,42 @@
if(!pixbuf)
{
g_warning("Failed to read wallpaper: %s", config->options.image.path);
- return FALSE;
+ return NULL;
}
+ bg = g_new0(Background, 1);
bg->options.image = pixbuf;
}
else if(config->type == BACKGROUND_TYPE_COLOR)
+ {
+ bg = g_new0(Background, 1);
bg->options.color = config->options.color;
+ }
else
- return FALSE;
+ return NULL;
bg->type = config->type;
- return TRUE;
+ bg->ref_count = 1;
+ return bg;
+}
+
+static Background*
+background_ref(Background* bg)
+{
+ bg->ref_count++;
+ return bg;
+}
+
+static void
+background_unref(Background** bg)
+{
+ if(*bg)
+ {
+ (*bg)->ref_count--;
+ if((*bg)->ref_count == 0)
+ {
+ background_finalize(*bg);
+ *bg = NULL;
+ }
+ }
}
static void
@@ -981,17 +1083,91 @@
static void
monitor_set_background(Monitor* monitor,
- const Background* background)
-{
- monitor->background = background;
- gtk_widget_queue_draw(GTK_WIDGET(monitor->window));
+ Background* background)
+{
+ if(monitor->background == background)
+ return;
+ monitor_stop_transition(monitor);
+ if(monitor->transition.config.duration > 0 && monitor->background)
+ monitor_start_transition(monitor, monitor->background, background);
+ background_unref(&monitor->background);
+ monitor->background = background_ref(background);
+ gtk_widget_queue_draw(GTK_WIDGET(monitor->window));
+}
+
+static void
+monitor_start_transition(Monitor* monitor,
+ Background* from,
+ Background* to)
+{
+ monitor_stop_transition(monitor);
+
+ monitor->transition.from = background_ref(from);
+ monitor->transition.to = background_ref(to);
+
+ monitor->transition.started = g_get_monotonic_time();
+ monitor->transition.timer_id = g_timeout_add(monitor->transition.config.timeout,
+ (GSourceFunc)monitor_transition_cb, monitor);
+ monitor->transition.stage = 0;
+}
+
+static void
+monitor_stop_transition(Monitor* monitor)
+{
+ if(!monitor->transition.timer_id)
+ return;
+ g_source_remove(monitor->transition.timer_id);
+ monitor->transition.timer_id = 0;
+ monitor->transition.started = 0;
+ monitor->transition.stage = 0;
+ background_unref(&monitor->transition.to);
+ background_unref(&monitor->transition.from);
+}
+
+static gboolean
+monitor_transition_cb(Monitor* monitor)
+{
+ if(!monitor->transition.timer_id)
+ return G_SOURCE_REMOVE;
+
+ gint64 span = g_get_monotonic_time() - monitor->transition.started;
+ gdouble x = CLAMP(span/monitor->transition.config.duration/1000.0, 0.0, 1.0);
+ monitor->transition.stage = monitor->transition.config.func(x);
+
+ if(x >= 1.0)
+ monitor_stop_transition(monitor);
+
+ gtk_widget_queue_draw(GTK_WIDGET(monitor->window));
+ return x >= 1.0 ? G_SOURCE_REMOVE : G_SOURCE_CONTINUE;
+}
+
+static void
+monitor_transition_draw_alpha(const Monitor* monitor,
+ cairo_t* cr)
+{
+ monitor_draw_background(monitor, monitor->transition.from, cr);
+
+ cairo_push_group(cr);
+ monitor_draw_background(monitor, monitor->transition.to, cr);
+ cairo_pop_group_to_source(cr);
+
+ cairo_pattern_t* alpha_pattern = cairo_pattern_create_rgba(0.0, 0.0, 0.0, monitor->transition.stage);
+ cairo_mask(cr, alpha_pattern);
+ cairo_pattern_destroy(alpha_pattern);
}
static void
monitor_finalize(Monitor* monitor)
{
- background_finalize(&monitor->background_configured);
- background_finalize(&monitor->background_custom);
+ if(monitor->transition.config.duration)
+ {
+ monitor_stop_transition(monitor);
+ if(monitor->transition.timer_id)
+ g_source_remove(monitor->transition.timer_id);
+ monitor->transition.config.duration = 0;
+ }
+ background_unref(&monitor->background_configured);
+ background_unref(&monitor->background);
g_free(monitor->name);
if(monitor->window_draw_handler_id)
g_signal_handler_disconnect(monitor->window, monitor->window_draw_handler_id);
@@ -1004,20 +1180,21 @@
static void
monitor_draw_background(const Monitor* monitor,
+ const Background* background,
cairo_t* cr)
{
g_return_if_fail(monitor != NULL);
- g_return_if_fail(monitor->background != NULL);
+ g_return_if_fail(background != NULL);
- if(monitor->background->type == BACKGROUND_TYPE_IMAGE && monitor->background->options.image)
+ if(background->type == BACKGROUND_TYPE_IMAGE && background->options.image)
{
- gdk_cairo_set_source_pixbuf(cr, monitor->background->options.image, 0, 0);
+ gdk_cairo_set_source_pixbuf(cr, background->options.image, 0, 0);
cairo_paint(cr);
}
- else if(monitor->background->type == BACKGROUND_TYPE_COLOR)
+ else if(background->type == BACKGROUND_TYPE_COLOR)
{
cairo_rectangle(cr, 0, 0, monitor->geometry.width, monitor->geometry.height);
- gdk_cairo_set_source_rgba(cr, &monitor->background->options.color);
+ gdk_cairo_set_source_rgba(cr, &background->options.color);
cairo_fill(cr);
}
}
@@ -1027,8 +1204,14 @@
cairo_t* cr,
const Monitor* monitor)
{
- if(monitor->background)
- monitor_draw_background(monitor, cr);
+ if(!monitor->background)
+ return FALSE;
+
+ if(monitor->transition.started)
+ monitor_transition_draw_alpha(monitor, cr);
+ else
+ monitor_draw_background(monitor, monitor->background, cr);
+
return FALSE;
}
@@ -1165,7 +1348,7 @@
Display* display,
Pixmap xpixmap)
{
-
+
Window xroot = RootWindow (display, gdk_screen_get_number (screen));
char *atom_names[] = {"_XROOTPMAP_ID", "ESETROOT_PMAP_ID"};
Atom atoms[G_N_ELEMENTS(atom_names)] = {0};
@@ -1261,3 +1444,15 @@
XFlush (display);
XUngrabServer (display);
}
+
+static gdouble
+transition_func_linear(gdouble x)
+{
+ return x;
+}
+
+static gdouble
+transition_func_easy_in_out(gdouble x)
+{
+ return (1 - cos(M_PI*x))/2;
+}
=== modified file 'src/greeterbackground.h'
--- src/greeterbackground.h 2014-08-31 17:45:52 +0000
+++ src/greeterbackground.h 2014-11-07 14:12:38 +0000
@@ -12,6 +12,8 @@
#define GREETER_IS_BACKGROUND(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GREETER_BACKGROUND_TYPE))
#define GREETER_IS_BACKGROUND_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GREETER_BACKGROUND_TYPE))
+#define GREETER_BACKGROUND_DEFAULT "*"
+
typedef struct _GreeterBackground GreeterBackground;
typedef struct _GreeterBackgroundClass GreeterBackgroundClass;
@@ -20,15 +22,13 @@
GreeterBackground* greeter_background_new (GtkWidget* child);
void greeter_background_set_active_monitor_config (GreeterBackground* background,
const gchar* value);
-void greeter_background_set_default_config (GreeterBackground* background,
- const gchar* bg,
- gboolean user_bg,
- gboolean laptop);
void greeter_background_set_monitor_config (GreeterBackground* background,
const gchar* name,
const gchar* bg,
gboolean user_bg, gboolean user_bg_used,
- gboolean laptop, gboolean laptop_used);
+ gboolean laptop, gboolean laptop_used,
+ gint transition_duration,
+ const gchar* transition_func);
void greeter_background_remove_monitor_config (GreeterBackground* background,
const gchar* name);
gchar** greeter_background_get_configured_monitors (GreeterBackground* background);
=== modified file 'src/lightdm-gtk-greeter.c'
--- src/lightdm-gtk-greeter.c 2014-09-01 07:58:56 +0000
+++ src/lightdm-gtk-greeter.c 2014-11-07 14:12:38 +0000
@@ -127,9 +127,6 @@
static const WindowPosition KEYBOARD_POSITION = {.x = { 50, +1, TRUE, 0}, .y = { 0, -1, FALSE, +1}, .use_size = TRUE,
.width = {50, 0, TRUE, 0}, .height = {25, 0, TRUE, 0}};
-/* Configuration */
-static gboolean key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value);
-
/* Clock */
static gchar *clock_format;
static gboolean clock_timeout_thread (void);
@@ -536,21 +533,6 @@
return TRUE;
}
-/* Configuration */
-
-static gboolean
-key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, const gchar *key, gboolean default_value)
-{
- GError* error = NULL;
- gboolean result = g_key_file_get_boolean (key_file, group_name, key, &error);
- if (error)
- {
- g_clear_error (&error);
- return default_value;
- }
- return result;
-}
-
/* Clock */
static gboolean
@@ -1778,17 +1760,42 @@
gtk_widget_set_sensitive (GTK_WIDGET (language_menuitem), !logged_in);
}
+static guint set_user_background_delayed_id = 0;
+
+static gboolean
+set_user_background_delayed_cb (const gchar *value)
+{
+ greeter_background_set_custom_background (greeter_background, value);
+ set_user_background_delayed_id = 0;
+ return G_SOURCE_REMOVE;
+}
+
static void
-set_user_background (const gchar *username)
+set_user_background (const gchar *user_name)
{
- const gchar *path = NULL;
- if (username)
+ const gchar *value = NULL;
+ if (user_name)
{
- LightDMUser *user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username);
+ LightDMUser *user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), user_name);
if (user)
- path = lightdm_user_get_background (user);
- }
- greeter_background_set_custom_background (greeter_background, path);
+ value = lightdm_user_get_background (user);
+ }
+
+ if (set_user_background_delayed_id)
+ {
+ g_source_remove (set_user_background_delayed_id);
+ set_user_background_delayed_id = 0;
+ }
+
+ if (!value)
+ greeter_background_set_custom_background (greeter_background, NULL);
+ else
+ {
+ /* Small delay before changing background */
+ set_user_background_delayed_id = g_timeout_add_full (G_PRIORITY_DEFAULT, 250,
+ (GSourceFunc)set_user_background_delayed_cb,
+ g_strdup (value), g_free);
+ }
}
static void
@@ -2852,36 +2859,45 @@
greeter_background_set_active_monitor_config (greeter_background, value ? value : "#cursor");
g_free (value);
- value = g_key_file_get_value (config, "greeter", "background", NULL);
- greeter_background_set_default_config (greeter_background, value,
- key_file_get_boolean_extended (config, "greeter", "user-background", TRUE),
- key_file_get_boolean_extended (config, "greeter", "laptop", FALSE));
- g_free (value);
-
const gchar *CONFIG_MONITOR_PREFIX = "monitor:";
gchar **config_group;
gchar **config_groups = g_key_file_get_groups (config, NULL);
for (config_group = config_groups; *config_group; ++config_group)
{
- if (!g_str_has_prefix (*config_group, CONFIG_MONITOR_PREFIX))
- continue;
- const gchar *name = *config_group + sizeof (CONFIG_MONITOR_PREFIX);
- while (*name && g_ascii_isspace (*name))
- ++name;
+ gchar *name_to_free = NULL;
+ const gchar *name = *config_group;
+
+ if (g_strcmp0 (*config_group, "greeter") != 0)
+ {
+ if (!g_str_has_prefix (name, CONFIG_MONITOR_PREFIX))
+ continue;
+ name = *config_group + sizeof (CONFIG_MONITOR_PREFIX);
+ while (*name && g_ascii_isspace (*name))
+ ++name;
+ }
+ else
+ name = name_to_free = g_strdup (GREETER_BACKGROUND_DEFAULT);
+
g_debug ("Monitor configuration found: '%s'", name);
- GError *user_bg_error = NULL, *laptop_error = NULL;
+ GError *user_bg_error = NULL, *laptop_error = NULL, *duration_error = NULL;
gboolean user_bg = g_key_file_get_boolean (config, *config_group, "user-background", &user_bg_error);
gboolean laptop = g_key_file_get_boolean (config, *config_group, "laptop", &laptop_error);
- value = g_key_file_get_value (config, *config_group, "background", NULL);
+ gchar *background = g_key_file_get_value (config, *config_group, "background", NULL);
+ gchar *tr_type = g_key_file_get_string (config, *config_group, "transition-type", NULL);
+ gint tr_duration = g_key_file_get_integer (config, *config_group, "transition-duration", &duration_error);
- greeter_background_set_monitor_config (greeter_background, name, value,
+ greeter_background_set_monitor_config (greeter_background, name, background,
user_bg, user_bg_error == NULL,
- laptop, laptop_error == NULL);
+ laptop, laptop_error == NULL,
+ duration_error == NULL ? tr_duration : -1,
+ tr_type);
- g_free (value);
+ g_free (tr_type);
+ g_free (background);
+ g_free (name_to_free);
+ g_clear_error (&user_bg_error);
g_clear_error (&laptop_error);
- g_clear_error (&user_bg_error);
}
g_strfreev (config_groups);
Follow ups