lightdm-gtk-greeter-team team mailing list archive
-
lightdm-gtk-greeter-team team
-
Mailing list archive
-
Message #00701
[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)
Related bugs:
Bug #1394639 in lightdm-gtk-greeter (Ubuntu): "lightdm fails to start with 3 connected displays but works 2 displays"
https://bugs.launchpad.net/ubuntu/+source/lightdm-gtk-greeter/+bug/1394639
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. Duration: 500ms
4. 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.
--
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-12-10 07:59:47 +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-12-10 07:59:47 +0000
@@ -1,4 +1,5 @@
+#include <math.h>
#include <cairo-xlib.h>
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
@@ -14,6 +15,8 @@
BACKGROUND_TYPE_INVALID,
/* Do not use this monitor */
BACKGROUND_TYPE_SKIP,
+ /* Do not override window background */
+ BACKGROUND_TYPE_DEFAULT,
/* Solid color */
BACKGROUND_TYPE_COLOR,
/* Path to image and scaling mode */
@@ -22,6 +25,7 @@
} BackgroundType;
static const gchar* BACKGROUND_TYPE_SKIP_VALUE = "#skip";
+static const gchar* BACKGROUND_TYPE_DEFAULT_VALUE = "#default";
typedef enum
{
@@ -34,6 +38,9 @@
static const gchar* SCALING_MODE_PREFIXES[] = {"#source:", "#zoomed:", "#stretched:", NULL};
+typedef gdouble (*TransitionFunction)(gdouble x);
+typedef void (*TransitionDraw)(gconstpointer monitor, cairo_t* cr);
+
/* Background configuration (parsed from background=... option).
Used to fill <Background> */
typedef struct
@@ -50,18 +57,32 @@
} options;
} BackgroundConfig;
+/* Transition configuration
+ Used to as part of <MonitorConfig> and <Monitor> */
+typedef struct
+{
+ /* Transition duration, in ms */
+ glong duration;
+ 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,14 +101,29 @@
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;
+
+ guint timer_id;
+ gint64 started;
+ /* Current stage */
+ gdouble stage;
+ } transition;
} Monitor;
+static const Monitor INVALID_MONITOR_STRUCT = {0};
+
struct _GreeterBackground
{
GObject parent_instance;
@@ -141,6 +177,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 +190,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 +202,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);
@@ -212,6 +235,8 @@
GreeterBackground* background);
static void greeter_background_monitors_changed_cb (GdkScreen* screen,
GreeterBackground* background);
+static void greeter_background_child_destroyed_cb (GtkWidget* child,
+ GreeterBackground* background);
/* struct BackgroundConfig */
static gboolean background_config_initialize (BackgroundConfig* config,
@@ -227,17 +252,28 @@
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 (GtkWidget *widget,
+ GdkFrameClock* frame_clock,
+ 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 +295,32 @@
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);
+
+/* Implemented in lightdm-gtk-greeter.c */
+gpointer greeter_save_focus(GtkWidget* widget);
+void greeter_restore_focus(const gpointer saved_data);
+
+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,
+ .func = transition_func_easy_in_out,
+ .draw = (TransitionDraw)monitor_transition_draw_alpha
+ }
+};
/* Implementation */
@@ -302,11 +363,14 @@
self->priv->laptop_lid_closed = FALSE;
}
-GreeterBackground*
+GreeterBackground*
greeter_background_new(GtkWidget* child)
{
+ g_return_val_if_fail(child != NULL, NULL);
+
GreeterBackground* background = GREETER_BACKGROUND(g_object_new(greeter_background_get_type(), NULL));
background->priv->child = child;
+ g_signal_connect(background->priv->child, "destroy", G_CALLBACK(greeter_background_child_destroyed_cb), background);
return background;
}
@@ -346,42 +410,55 @@
}
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.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
@@ -418,12 +495,9 @@
g_return_if_fail(GREETER_IS_BACKGROUND(background));
g_return_if_fail(GDK_IS_SCREEN(screen));
- g_debug("Connecting to screen");
+ g_debug("[Background] Connecting to screen: %p", screen);
GreeterBackgroundPrivate* priv = background->priv;
- gulong screen_monitors_changed_handler_id = (priv->screen == screen) ? priv->screen_monitors_changed_handler_id : 0;
- if(screen_monitors_changed_handler_id)
- priv->screen_monitors_changed_handler_id = 0;
if(priv->screen)
greeter_background_disconnect(background);
@@ -433,6 +507,8 @@
priv->monitors = g_new0(Monitor, priv->monitors_size);
priv->monitors_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ g_debug("[Background] Monitors found: %" G_GSIZE_FORMAT, priv->monitors_size);
+
/* Used to track situation when all monitors marked as "#skip" */
Monitor* first_not_skipped_monitor = NULL;
@@ -449,25 +525,28 @@
const gchar* printable_name = monitor->name ? monitor->name : "<unknown>";
- if(!greeter_background_find_monitor_data(background, priv->configs, monitor, (gpointer*)&config))
- {
- g_debug("No configuration options for monitor %s #%d, using default", printable_name, i);
- config = priv->default_config;
- }
-
gdk_screen_get_monitor_geometry(screen, i, &monitor->geometry);
- g_debug("Monitor: %s #%d (%dx%d at %dx%d)%s", printable_name, i,
+ g_debug("[Background] Monitor: %s #%d (%dx%d at %dx%d)%s", printable_name, i,
monitor->geometry.width, monitor->geometry.height,
monitor->geometry.x, monitor->geometry.y,
(i == gdk_screen_get_primary_monitor(screen)) ? " primary" : "");
+ if(!greeter_background_find_monitor_data(background, priv->configs, monitor, (gpointer*)&config))
+ {
+ g_debug("[Background] No configuration options for monitor %s #%d, using default", printable_name, i);
+ config = priv->default_config;
+ }
+
/* Force last skipped monitor to be active monitor, if there is no other choice */
if(config->bg.type == BACKGROUND_TYPE_SKIP)
{
if(i < priv->monitors_size - 1 || first_not_skipped_monitor)
+ {
+ g_debug("[Background] Skipping monitor %s #%d", printable_name, i);
continue;
- g_debug("Monitor %s #%d can not be skipped, using default configuration for it", printable_name, i);
+ }
+ g_debug("[Background] Monitor %s #%d can not be skipped, using default configuration for it", printable_name, i);
if(priv->default_config->bg.type != BACKGROUND_TYPE_SKIP)
config = priv->default_config;
else
@@ -489,6 +568,12 @@
monitor->window_draw_handler_id = g_signal_connect(G_OBJECT(monitor->window), "draw",
G_CALLBACK(monitor_window_draw_cb),
monitor);
+
+ gchar* window_name = monitor->name ? g_strdup_printf("monitor-%s", monitor->name) : g_strdup_printf("monitor-%d", i);
+ gtk_widget_set_name(GTK_WIDGET(monitor->window), window_name);
+ gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(monitor->window)), "lightdm-gtk-greeter");
+ g_free(window_name);
+
GSList* item;
for(item = priv->accel_groups; item != NULL; item = g_slist_next(item))
gtk_window_add_accel_group(monitor->window, item->data);
@@ -503,9 +588,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);
@@ -528,18 +617,19 @@
if(greeter_background_monitor_enabled(background, monitor) &&
x >= monitor->geometry.x && x < monitor->geometry.x + monitor->geometry.width &&
y >= monitor->geometry.y && y < monitor->geometry.y + monitor->geometry.height)
+ {
+ g_debug("[Background] Pointer position will be used to set active monitor: %dx%d", x, y);
greeter_background_set_active_monitor(background, monitor);
+ break;
+ }
}
}
if(!priv->active_monitor)
greeter_background_set_active_monitor(background, NULL);
- if(screen_monitors_changed_handler_id)
- priv->screen_monitors_changed_handler_id = screen_monitors_changed_handler_id;
- else
- priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed",
- G_CALLBACK(greeter_background_monitors_changed_cb),
- background);
+ priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed",
+ G_CALLBACK(greeter_background_monitors_changed_cb),
+ background);
}
void
@@ -548,12 +638,11 @@
g_return_if_fail(GREETER_IS_BACKGROUND(background));
GreeterBackgroundPrivate* priv = background->priv;
- priv->screen = NULL;
- priv->active_monitor = NULL;
-
if(priv->screen_monitors_changed_handler_id)
g_signal_handler_disconnect(priv->screen, priv->screen_monitors_changed_handler_id);
priv->screen_monitors_changed_handler_id = 0;
+ priv->screen = NULL;
+ priv->active_monitor = NULL;
gint i;
for(i = 0; i < priv->monitors_size; ++i)
@@ -610,6 +699,8 @@
const Monitor* monitor = g_hash_table_lookup(priv->monitors_map, iter->data);
if(monitor && monitor->background && greeter_background_monitor_enabled(background, monitor))
active = monitor;
+ if(active)
+ g_debug("[Background] Active monitor is not specified, using first enabled monitor from 'active-monitor' list");
}
/* All monitors listed in active-monitor-config are disabled (or option is empty) */
@@ -617,9 +708,13 @@
/* Using primary monitor */
if(!active)
{
- active = &priv->monitors[gdk_screen_get_primary_monitor(priv->screen)];
+ gint num = gdk_screen_get_primary_monitor(priv->screen);
+ g_return_if_fail(num < priv->monitors_size);
+ active = &priv->monitors[num];
if(!active->background || !greeter_background_monitor_enabled(background, active))
active = NULL;
+ if(active)
+ g_debug("[Background] Active monitor is not specified, using primary monitor");
}
/* Fallback: first enabled and/or not skipped monitor (screen always have one) */
@@ -639,7 +734,25 @@
}
if(!active)
active = first_not_skipped;
- }
+ if(active)
+ g_debug("[Background] Active monitor is not specified, using first enabled monitor");
+ }
+
+ if(!active && priv->laptop_monitors)
+ {
+ active = priv->laptop_monitors->data;
+ g_debug("[Background] Active monitor is not specified, using laptop monitor");
+ }
+ }
+
+ if(!active)
+ {
+ if(priv->active_monitor)
+ g_warning("[Background] Active monitor is not specified, failed to identify. Active monitor stays the same: %s #%d",
+ priv->active_monitor->name, priv->active_monitor->number);
+ else
+ g_warning("[Background] Active monitor is not specified, failed to identify. Active monitor stays the same: <not defined>");
+ return;
}
if(active == priv->active_monitor)
@@ -647,12 +760,25 @@
priv->active_monitor = active;
- GtkWidget* old_parent = gtk_widget_get_parent(priv->child);
- if(old_parent)
- gtk_container_remove(GTK_CONTAINER(old_parent), priv->child);
- gtk_container_add(GTK_CONTAINER(active->window), priv->child);
-
- g_debug("Active monitor changed to: %s #%d", active->name, active->number);
+ g_return_if_fail(priv->active_monitor != NULL);
+
+ if(priv->child)
+ {
+ GtkWidget* old_parent = gtk_widget_get_parent(priv->child);
+ gpointer focus = greeter_save_focus(priv->child);
+
+ if(old_parent)
+ gtk_container_remove(GTK_CONTAINER(old_parent), priv->child);
+ gtk_container_add(GTK_CONTAINER(active->window), priv->child);
+
+ gtk_window_present(active->window);
+ greeter_restore_focus(focus);
+ g_free(focus);
+ }
+ else
+ g_warning("[Background] Child widget is destroyed or not defined");
+
+ g_debug("[Background] Active monitor changed to: %s #%d", active->name, active->number);
g_signal_emit(background, background_signals[BACKGROUND_SIGNAL_ACTIVE_MONITOR_CHANGED], 0);
gint x, y;
@@ -691,7 +817,7 @@
static void
greeter_background_try_init_dbus(GreeterBackground* background)
{
- g_debug("Creating DBus proxy");
+ g_debug("[Background] Creating DBus proxy");
GError* error = NULL;
GreeterBackgroundPrivate* priv = background->priv;
@@ -710,7 +836,7 @@
if(!priv->laptop_upower_proxy)
{
if(error)
- g_warning("Failed to create dbus proxy: %s", error->message);
+ g_warning("[Background] Failed to create dbus proxy: %s", error->message);
g_clear_error(&error);
return;
}
@@ -719,7 +845,7 @@
gboolean lid_present = g_variant_get_boolean(variant);
g_variant_unref(variant);
- g_debug("UPower.%s property value: %d", DBUS_UPOWER_PROP_LID_IS_PRESENT, lid_present);
+ g_debug("[Background] UPower.%s property value: %d", DBUS_UPOWER_PROP_LID_IS_PRESENT, lid_present);
if(!lid_present)
greeter_background_stop_dbus(background);
@@ -769,13 +895,21 @@
if(new_state == priv->laptop_lid_closed)
return;
- g_debug("UPower: lid state changed to '%s'", priv->laptop_lid_closed ? "closed" : "opened");
-
priv->laptop_lid_closed = new_state;
+ g_debug("[Background] UPower: lid state changed to '%s'", priv->laptop_lid_closed ? "closed" : "opened");
+
if(priv->laptop_monitors)
{
- if(!priv->follow_cursor || (new_state && priv->laptop_monitors->data == priv->active_monitor))
- greeter_background_set_active_monitor(background, NULL);
+ if(priv->laptop_lid_closed)
+ {
+ if(g_slist_find(priv->laptop_monitors, priv->active_monitor))
+ greeter_background_set_active_monitor(background, NULL);
+ }
+ else
+ {
+ if(!priv->follow_cursor)
+ greeter_background_set_active_monitor(background, NULL);
+ }
}
}
@@ -787,6 +921,13 @@
greeter_background_connect(background, screen);
}
+static void
+greeter_background_child_destroyed_cb(GtkWidget* child,
+ GreeterBackground* background)
+{
+ background->priv->child = NULL;
+}
+
void
greeter_background_set_custom_background(GreeterBackground* background,
const gchar* value)
@@ -809,13 +950,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)
@@ -831,18 +978,43 @@
cairo_surface_t* surface = create_root_surface(priv->screen);
cairo_t* cr = cairo_create(surface);
gsize i;
-
- for(i = 0; i <= priv->monitors_size; ++i)
+ gdouble child_opacity;
+
+ const GdkRGBA ROOT_COLOR = {1.0, 1.0, 1.0, 1.0};
+ gdk_cairo_set_source_rgba(cr, &ROOT_COLOR);
+ cairo_paint(cr);
+
+ for(i = 0; i < priv->monitors_size; ++i)
{
const Monitor* monitor = &priv->monitors[i];
- if(monitor == priv->active_monitor || !monitor->background)
+ if(!monitor->background)
continue;
- if(i == priv->monitors_size)
- monitor = priv->active_monitor;
+
+ #ifdef XROOT_DRAW_BACKGROUND_DIRECTLY
+ /* Old method: can't draw default GtkWindow background */
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);
+ #else
+ /* New - can draw anything, but looks tricky a bit */
+ child_opacity = gtk_widget_get_opacity(priv->child);
+ if(monitor == priv->active_monitor)
+ {
+ gtk_widget_set_opacity(priv->child, 0.0);
+ gdk_window_process_updates(gtk_widget_get_window(GTK_WIDGET(priv->child)), FALSE);
+ }
+
+ gdk_cairo_set_source_window(cr, gtk_widget_get_window(GTK_WIDGET(monitor->window)),
+ monitor->geometry.x, monitor->geometry.y);
+ cairo_paint(cr);
+
+ if(monitor == priv->active_monitor)
+ {
+ gtk_widget_set_opacity(priv->child, child_opacity);
+ gdk_window_process_updates(gtk_widget_get_window(GTK_WIDGET(priv->child)), FALSE);
+ }
+ #endif
}
set_surface_as_root(priv->screen, surface);
@@ -887,6 +1059,8 @@
return FALSE;
if(g_strcmp0(value, BACKGROUND_TYPE_SKIP_VALUE) == 0)
config->type = BACKGROUND_TYPE_SKIP;
+ else if(g_strcmp0(value, BACKGROUND_TYPE_DEFAULT_VALUE) == 0)
+ config->type = BACKGROUND_TYPE_DEFAULT;
else if(gdk_rgba_parse(&config->options.color, value))
config->type = BACKGROUND_TYPE_COLOR;
else
@@ -904,7 +1078,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;
}
@@ -912,8 +1086,19 @@
static void
background_config_finalize(BackgroundConfig* config)
{
- if(config->type == BACKGROUND_TYPE_IMAGE)
- g_free(config->options.image.path);
+ switch(config->type)
+ {
+ case BACKGROUND_TYPE_IMAGE:
+ g_free(config->options.image.path);
+ break;
+ case BACKGROUND_TYPE_COLOR:
+ case BACKGROUND_TYPE_DEFAULT:
+ case BACKGROUND_TYPE_SKIP:
+ break;
+ case BACKGROUND_TYPE_INVALID:
+ g_return_if_reached();
+ }
+
config->type = BACKGROUND_TYPE_INVALID;
}
@@ -922,8 +1107,19 @@
BackgroundConfig* dest)
{
*dest = *source;
- if(source->type == BACKGROUND_TYPE_IMAGE)
- dest->options.image.path = g_strdup(source->options.image.path);
+
+ switch(dest->type)
+ {
+ case BACKGROUND_TYPE_IMAGE:
+ dest->options.image.path = g_strdup(source->options.image.path);
+ break;
+ case BACKGROUND_TYPE_COLOR:
+ case BACKGROUND_TYPE_DEFAULT:
+ case BACKGROUND_TYPE_SKIP:
+ break;
+ case BACKGROUND_TYPE_INVALID:
+ g_return_if_reached();
+ }
}
static void
@@ -941,84 +1137,238 @@
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)
-{
- if(config->type == BACKGROUND_TYPE_IMAGE)
- {
- GdkPixbuf* pixbuf = scale_image_file(config->options.image.path,
- config->options.image.mode,
- monitor->geometry.width, monitor->geometry.height,
- images_cache);
- if(!pixbuf)
- {
- g_warning("Failed to read wallpaper: %s", config->options.image.path);
- return FALSE;
- }
- bg->options.image = pixbuf;
- }
- else if(config->type == BACKGROUND_TYPE_COLOR)
- bg->options.color = config->options.color;
- else
- return FALSE;
- bg->type = config->type;
- return TRUE;
+static Background*
+background_new(const BackgroundConfig* config,
+ const Monitor* monitor,
+ GHashTable* images_cache)
+{
+ Background bg = {0};
+
+ switch(config->type)
+ {
+ case BACKGROUND_TYPE_IMAGE:
+ bg.options.image = scale_image_file(config->options.image.path, config->options.image.mode,
+ monitor->geometry.width, monitor->geometry.height,
+ images_cache);
+ if(!bg.options.image)
+ {
+ g_warning("[Background] Failed to read wallpaper: %s", config->options.image.path);
+ return NULL;
+ }
+ break;
+ case BACKGROUND_TYPE_COLOR:
+ bg.options.color = config->options.color;
+ break;
+ case BACKGROUND_TYPE_DEFAULT:
+ break;
+ case BACKGROUND_TYPE_SKIP:
+ case BACKGROUND_TYPE_INVALID:
+ g_return_val_if_reached(NULL);
+ }
+
+ bg.type = config->type;
+ bg.ref_count = 1;
+
+ Background* result = g_new(Background, 1);
+ *result = bg;
+ return result;
+}
+
+static Background*
+background_ref(Background* bg)
+{
+ bg->ref_count++;
+ return bg;
+}
+
+static void
+background_unref(Background** bg)
+{
+ if(!*bg)
+ return;
+ (*bg)->ref_count--;
+ if((*bg)->ref_count == 0)
+ {
+ background_finalize(*bg);
+ *bg = NULL;
+ }
}
static void
background_finalize(Background* bg)
{
- if(bg->type == BACKGROUND_TYPE_IMAGE)
- g_clear_object(&bg->options.image);
+ switch(bg->type)
+ {
+ case BACKGROUND_TYPE_IMAGE:
+ g_clear_object(&bg->options.image);
+ break;
+ case BACKGROUND_TYPE_COLOR:
+ case BACKGROUND_TYPE_DEFAULT:
+ break;
+ case BACKGROUND_TYPE_SKIP:
+ case BACKGROUND_TYPE_INVALID:
+ g_return_if_reached();
+ }
+
bg->type = BACKGROUND_TYPE_INVALID;
}
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);
+
+ switch(background->type)
+ {
+ case BACKGROUND_TYPE_IMAGE:
+ case BACKGROUND_TYPE_COLOR:
+ gtk_widget_set_app_paintable(GTK_WIDGET(monitor->window), TRUE);
+ if(monitor->transition.config.duration > 0 && monitor->background &&
+ monitor->background->type != BACKGROUND_TYPE_DEFAULT)
+ monitor_start_transition(monitor, monitor->background, background);
+ break;
+ case BACKGROUND_TYPE_DEFAULT:
+ gtk_widget_set_app_paintable(GTK_WIDGET(monitor->window), FALSE);
+ break;
+ case BACKGROUND_TYPE_SKIP:
+ case BACKGROUND_TYPE_INVALID:
+ g_return_val_if_reached(NULL);
+ }
+
+ 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 = gtk_widget_add_tick_callback(GTK_WIDGET(monitor->window),
+ (GtkTickCallback)monitor_transition_cb,
+ monitor,
+ NULL);
+ monitor->transition.stage = 0;
+}
+
+static void
+monitor_stop_transition(Monitor* monitor)
+{
+ if(!monitor->transition.timer_id)
+ return;
+ gtk_widget_remove_tick_callback(GTK_WIDGET(monitor->window), 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(GtkWidget *widget,
+ GdkFrameClock* frame_clock,
+ 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);
- g_free(monitor->name);
+ 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;
+ }
+
if(monitor->window_draw_handler_id)
g_signal_handler_disconnect(monitor->window, monitor->window_draw_handler_id);
+
+ background_unref(&monitor->background_configured);
+ background_unref(&monitor->background);
+
if(monitor->window)
+ {
+ GtkWidget* child = gtk_bin_get_child(GTK_BIN(monitor->window));
+ if(child) /* remove greeter widget to avoid "destroy" signal */
+ gtk_container_remove(GTK_CONTAINER(monitor->window), child);
gtk_widget_destroy(GTK_WIDGET(monitor->window));
- monitor->name = NULL;
- monitor->window = NULL;
- monitor->window_draw_handler_id = 0;
+ }
+
+ g_free(monitor->name);
+
+ *monitor = INVALID_MONITOR_STRUCT;
}
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)
- {
- gdk_cairo_set_source_pixbuf(cr, monitor->background->options.image, 0, 0);
- cairo_paint(cr);
- }
- else if(monitor->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);
- cairo_fill(cr);
+ switch(background->type)
+ {
+ case BACKGROUND_TYPE_IMAGE:
+ if(background->options.image)
+ {
+ gdk_cairo_set_source_pixbuf(cr, background->options.image, 0, 0);
+ cairo_paint(cr);
+ }
+ break;
+ case BACKGROUND_TYPE_COLOR:
+ cairo_rectangle(cr, 0, 0, monitor->geometry.width, monitor->geometry.height);
+ gdk_cairo_set_source_rgba(cr, &background->options.color);
+ cairo_fill(cr);
+ break;
+ case BACKGROUND_TYPE_DEFAULT:
+ break;
+ case BACKGROUND_TYPE_SKIP:
+ case BACKGROUND_TYPE_INVALID:
+ g_return_if_reached();
}
}
@@ -1027,8 +1377,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.config.draw(monitor, cr);
+ else
+ monitor_draw_background(monitor, monitor->background, cr);
+
return FALSE;
}
@@ -1051,35 +1407,43 @@
{
gchar* key = NULL;
GdkPixbuf* pixbuf = NULL;
+
if(cache)
{
key = g_strdup_printf("%s\n%d %dx%d", path, mode, width, height);
- if (g_hash_table_lookup_extended(cache, key, NULL, (gpointer*)&pixbuf))
+ if(g_hash_table_lookup_extended(cache, key, NULL, (gpointer*)&pixbuf))
+ {
+ g_free(key);
return GDK_PIXBUF(g_object_ref(pixbuf));
+ }
}
- if (!cache || !g_hash_table_lookup_extended(cache, path, NULL, (gpointer*)&pixbuf))
+ if(!cache || !g_hash_table_lookup_extended(cache, path, NULL, (gpointer*)&pixbuf))
{
GError *error = NULL;
pixbuf = gdk_pixbuf_new_from_file(path, &error);
if(error)
{
- g_warning("Failed to load background: %s", error->message);
+ g_warning("[Background] Failed to load background: %s", error->message);
g_clear_error(&error);
}
else if(cache)
- g_hash_table_insert(cache, g_strdup(path), g_object_ref (pixbuf));
+ g_hash_table_insert(cache, g_strdup(path), g_object_ref(pixbuf));
}
+ else
+ pixbuf = g_object_ref(pixbuf);
if(pixbuf)
{
GdkPixbuf* scaled = scale_image(pixbuf, mode, width, height);
- if (cache)
+ if(cache)
g_hash_table_insert(cache, g_strdup(key), g_object_ref(scaled));
g_object_unref(pixbuf);
pixbuf = scaled;
}
+ g_free(key);
+
return pixbuf;
}
@@ -1142,7 +1506,7 @@
display = XOpenDisplay (gdk_display_get_name (gdk_screen_get_display (screen)));
if (!display)
{
- g_warning ("Failed to create root pixmap");
+ g_warning("[Background] Failed to create root pixmap");
return NULL;
}
@@ -1165,7 +1529,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};
@@ -1214,7 +1578,7 @@
*/
if (!XInternAtoms (display, atom_names, G_N_ELEMENTS(atom_names), False, atoms) ||
atoms[0] == None || atoms[1] == None) {
- g_warning("Could not create atoms needed to set root pixmap id/properties.\n");
+ g_warning("[Background] Could not create atoms needed to set root pixmap id/properties.\n");
return;
}
@@ -1261,3 +1625,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-12-10 07:59:47 +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-12-10 07:59:47 +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);
@@ -183,6 +180,7 @@
static int timeout, interval, prefer_blanking, allow_exposures;
/* Handling monitors backgrounds */
+static const gint USER_BACKGROUND_DELAY = 250;
static GreeterBackground *greeter_background;
/* Authentication state */
@@ -285,6 +283,42 @@
void restart_cb (GtkWidget *widget, LightDMGreeter *greeter);
void shutdown_cb (GtkWidget *widget, LightDMGreeter *greeter);
+gpointer greeter_save_focus(GtkWidget* widget);
+void greeter_restore_focus(const gpointer saved_data);
+
+struct SavedFocusData
+{
+ GtkWidget *widget;
+ gint editable_pos;
+};
+
+gpointer
+greeter_save_focus(GtkWidget* widget)
+{
+ GtkWidget *window = gtk_widget_get_toplevel(widget);
+ if (!GTK_IS_WINDOW (window))
+ return NULL;
+
+ struct SavedFocusData *data = g_new0 (struct SavedFocusData, 1);
+ data->widget = gtk_window_get_focus (GTK_WINDOW (window));
+ data->editable_pos = GTK_IS_EDITABLE(data->widget) ? gtk_editable_get_position (GTK_EDITABLE (data->widget)) : -1;
+
+ return data;
+}
+
+void
+greeter_restore_focus(const gpointer saved_data)
+{
+ if (!saved_data)
+ return;
+
+ struct SavedFocusData *data = saved_data;
+ if (GTK_IS_WIDGET (data->widget))
+ gtk_widget_grab_focus (data->widget);
+ if (GTK_IS_EDITABLE(data->widget) && data->editable_pos > -1)
+ gtk_editable_set_position(GTK_EDITABLE(data->widget), data->editable_pos);
+}
+
/* State file */
static void
@@ -536,21 +570,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
@@ -1771,24 +1790,47 @@
gtk_button_set_label (login_button, _("Unlock"));
else
gtk_button_set_label (login_button, _("Log In"));
- gtk_widget_set_can_default (GTK_WIDGET (login_button), TRUE);
- gtk_widget_grab_default (GTK_WIDGET (login_button));
/* and disable the session and language widgets */
gtk_widget_set_sensitive (GTK_WIDGET (session_menuitem), !logged_in);
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, USER_BACKGROUND_DELAY,
+ (GSourceFunc)set_user_background_delayed_cb,
+ g_strdup (value), g_free);
+ }
}
static void
@@ -2852,36 +2894,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);
=== modified file 'src/lightdm-gtk-greeter.glade'
--- src/lightdm-gtk-greeter.glade 2014-09-24 17:41:33 +0000
+++ src/lightdm-gtk-greeter.glade 2014-12-10 07:59:47 +0000
@@ -282,7 +282,6 @@
<property name="name">cancel_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
<signal name="clicked" handler="power_button_clicked_cb" swapped="no"/>
</object>
<packing>
@@ -297,7 +296,6 @@
<property name="name">power_ok_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
<signal name="clicked" handler="power_button_clicked_cb" swapped="no"/>
</object>
<packing>
@@ -432,7 +430,6 @@
<object class="GtkEntry" id="username_entry">
<property name="name">prompt_entry</property>
<property name="can_focus">True</property>
- <property name="no_show_all">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
<property name="placeholder_text" translatable="yes">Enter your username</property>
@@ -480,7 +477,6 @@
<child>
<object class="GtkInfoBar" id="greeter_infobar">
<property name="name">greeter_infobar</property>
- <property name="app_paintable">True</property>
<property name="can_focus">False</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="infobar-action_area">
@@ -545,7 +541,6 @@
<property name="name">cancel_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
<signal name="clicked" handler="cancel_cb" swapped="no"/>
</object>
<packing>
@@ -560,7 +555,6 @@
<property name="name">login_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="receives_default">True</property>
<signal name="clicked" handler="login_cb" swapped="no"/>
</object>
<packing>
Follow ups