summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Davis <smd.seandavis@gmail.com>2015-04-25 21:08:40 -0400
committerSean Davis <smd.seandavis@gmail.com>2015-04-25 21:08:40 -0400
commit816a86665ead4ec61c713435555a58173e2239b2 (patch)
treee5ea35ec006e3c1a8484afdfdc8f940cbb969762
parent0190eb0d47807188d4719c98cb90351abcc838ff (diff)
parenta4d76234c24d2d2a06123d947cad9ca3120709b5 (diff)
downloadlightdm-gtk-greeter-git-816a86665ead4ec61c713435555a58173e2239b2.tar.gz
Merge in post-2.0.0 fixes branch
-rw-r--r--src/Makefile.am2
-rw-r--r--src/greeterbackground.c114
-rw-r--r--src/greeterbackground.h19
-rw-r--r--src/greeterconfiguration.c371
-rw-r--r--src/greeterconfiguration.h57
-rw-r--r--src/lightdm-gtk-greeter-fallback.css10
-rw-r--r--src/lightdm-gtk-greeter.c371
-rw-r--r--src/lightdm-gtk-greeter.glade7
8 files changed, 679 insertions, 272 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b714947..1b79984 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,8 @@ lightdm_gtk_greeter_SOURCES = \
lightdm-gtk-greeter.c \
greeterbackground.c \
greeterbackground.h \
+ greeterconfiguration.c \
+ greeterconfiguration.h \
greetermenubar.c \
greetermenubar.h
diff --git a/src/greeterbackground.c b/src/greeterbackground.c
index 4487644..aaef3a5 100644
--- a/src/greeterbackground.c
+++ b/src/greeterbackground.c
@@ -58,7 +58,7 @@ typedef struct
} BackgroundConfig;
/* Transition configuration
- Used to as part of <MonitorConfig> and <Monitor> */
+ Used as part of <MonitorConfig> and <Monitor> */
typedef struct
{
/* Transition duration, in ms */
@@ -177,9 +177,6 @@ struct _GreeterBackgroundPrivate
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
@@ -205,10 +202,10 @@ void greeter_background_set_active_monitor_config (GreeterBackground* backgrou
void greeter_background_set_monitor_config (GreeterBackground* background,
const gchar* name,
const gchar* bg, /* NULL to use fallback value */
- gboolean user_bg, gboolean user_bg_used,
- gboolean laptop, gboolean laptop_used,
+ gint user_bg, /* -1 to use fallback value */
+ gint laptop, /* -1 to use fallback value */
gint transition_duration, /* -1 to use fallback value */
- const gchar* transition_type); /* NULL to use fallback value */
+ TransitionType 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);
@@ -296,7 +293,7 @@ static void set_root_pixmap_id (GdkScreen* screen,
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 gdouble transition_func_ease_in_out (gdouble x);
/* Implemented in lightdm-gtk-greeter.c */
gpointer greeter_save_focus(GtkWidget* widget);
@@ -317,7 +314,7 @@ static const MonitorConfig DEFAULT_MONITOR_CONFIG =
.transition =
{
.duration = 500,
- .func = transition_func_easy_in_out,
+ .func = transition_func_ease_in_out,
.draw = (TransitionDraw)monitor_transition_draw_alpha
}
};
@@ -413,10 +410,10 @@ 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,
+ gint user_bg,
+ gint laptop,
gint transition_duration,
- const gchar* transition_type)
+ TransitionType transition_type)
{
g_return_if_fail(GREETER_IS_BACKGROUND(background));
GreeterBackgroundPrivate* priv = background->priv;
@@ -427,29 +424,22 @@ greeter_background_set_monitor_config(GreeterBackground* background,
if(!background_config_initialize(&config->bg, bg))
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->user_bg = user_bg >= 0 ? user_bg : FALLBACK->user_bg;
+ config->laptop = laptop >= 0 ? laptop : FALLBACK->laptop;
config->transition.duration = transition_duration >= 0 ? transition_duration : FALLBACK->transition.duration;
config->transition.draw = FALLBACK->transition.draw;
- if(transition_type)
+ switch(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);
+ case TRANSITION_TYPE_NONE:
+ config->transition.func = NULL; break;
+ case TRANSITION_TYPE_LINEAR:
+ config->transition.func = transition_func_linear; break;
+ case TRANSITION_TYPE_EASE_IN_OUT:
+ config->transition.func = transition_func_ease_in_out; break;
+ default:
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);
@@ -495,12 +485,18 @@ greeter_background_connect(GreeterBackground* background,
g_return_if_fail(GREETER_IS_BACKGROUND(background));
g_return_if_fail(GDK_IS_SCREEN(screen));
- g_debug("[Background] Connecting to screen: %p", screen);
+ g_debug("[Background] Connecting to screen: %p (%dx%dpx, %dx%dmm)", screen,
+ gdk_screen_get_width(screen), gdk_screen_get_height(screen),
+ gdk_screen_get_width_mm(screen), gdk_screen_get_height_mm(screen));
GreeterBackgroundPrivate* priv = background->priv;
-
+ gpointer saved_focus = NULL;
if(priv->screen)
+ {
+ if (priv->active_monitor)
+ saved_focus = greeter_save_focus(priv->child);
greeter_background_disconnect(background);
+ }
priv->screen = screen;
priv->monitors_size = gdk_screen_get_n_monitors(screen);
@@ -513,7 +509,9 @@ greeter_background_connect(GreeterBackground* background,
Monitor* first_not_skipped_monitor = NULL;
GHashTable* images_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
+ cairo_region_t *screen_region = cairo_region_create();
gint i;
+
for(i = 0; i < priv->monitors_size; ++i)
{
const MonitorConfig* config;
@@ -553,6 +551,15 @@ greeter_background_connect(GreeterBackground* background,
config = &DEFAULT_MONITOR_CONFIG;
}
+ /* Simple check to skip fully overlapped monitors.
+ Actually, it's can track only monitors in "mirrors" mode. Nothing more. */
+ if(cairo_region_contains_rectangle(screen_region, &monitor->geometry) == CAIRO_REGION_OVERLAP_IN)
+ {
+ g_debug("[Background] Skipping monitor %s #%d, its area is already used by other monitors", printable_name, i);
+ continue;
+ }
+ cairo_region_union_rectangle(screen_region, &monitor->geometry);
+
if(!first_not_skipped_monitor)
first_not_skipped_monitor = monitor;
@@ -578,9 +585,8 @@ greeter_background_connect(GreeterBackground* background,
for(item = priv->accel_groups; item != NULL; item = g_slist_next(item))
gtk_window_add_accel_group(monitor->window, item->data);
- if(priv->follow_cursor)
- g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event",
- G_CALLBACK(monitor_window_enter_notify_cb), monitor);
+ g_signal_connect(G_OBJECT(monitor->window), "enter-notify-event",
+ G_CALLBACK(monitor_window_enter_notify_cb), monitor);
if(config->user_bg)
priv->customized_monitors = g_slist_prepend(priv->customized_monitors, monitor);
@@ -624,9 +630,16 @@ greeter_background_connect(GreeterBackground* background,
}
}
}
+
if(!priv->active_monitor)
greeter_background_set_active_monitor(background, NULL);
+ if(saved_focus)
+ {
+ greeter_restore_focus(saved_focus);
+ g_free(saved_focus);
+ }
+
priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed",
G_CALLBACK(greeter_background_monitors_changed_cb),
background);
@@ -768,8 +781,9 @@ greeter_background_set_active_monitor(GreeterBackground* background,
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_widget_reparent(priv->child, GTK_WIDGET(active->window));
+ else
+ gtk_container_add(GTK_CONTAINER(active->window), priv->child);
gtk_window_present(active->window);
greeter_restore_focus(focus);
@@ -1393,8 +1407,30 @@ monitor_window_enter_notify_cb(GtkWidget* widget,
GdkEventCrossing* event,
const Monitor* monitor)
{
- if(monitor->object->priv->active_monitor != monitor &&
- greeter_background_monitor_enabled(monitor->object, monitor))
+ if(monitor->object->priv->active_monitor == monitor)
+ {
+ GdkWindow *gdkwindow = gtk_widget_get_window (widget);
+ Window window = GDK_WINDOW_XID (gdkwindow);
+ Display *display = GDK_WINDOW_XDISPLAY (gdkwindow);
+
+ static Atom wm_protocols = None;
+ static Atom wm_take_focus = None;
+
+ if (!wm_protocols)
+ wm_protocols = XInternAtom(display, "WM_PROTOCOLS", False);
+ if (!wm_take_focus)
+ wm_take_focus = XInternAtom(display, "WM_TAKE_FOCUS", False);
+
+ XEvent ev = {0};
+ ev.xclient.type = ClientMessage;
+ ev.xclient.window = window;
+ ev.xclient.message_type = wm_protocols;
+ ev.xclient.format = 32;
+ ev.xclient.data.l[0] = wm_take_focus;
+ ev.xclient.data.l[1] = CurrentTime;
+ XSendEvent(display, window, False, 0L, &ev);
+ }
+ else if(monitor->object->priv->follow_cursor && greeter_background_monitor_enabled(monitor->object, monitor))
greeter_background_set_active_monitor(monitor->object, monitor);
return FALSE;
}
@@ -1633,7 +1669,7 @@ transition_func_linear(gdouble x)
}
static gdouble
-transition_func_easy_in_out(gdouble x)
+transition_func_ease_in_out(gdouble x)
{
return (1 - cos(M_PI*x))/2;
}
diff --git a/src/greeterbackground.h b/src/greeterbackground.h
index 659aa8e..27a489a 100644
--- a/src/greeterbackground.h
+++ b/src/greeterbackground.h
@@ -14,6 +14,19 @@ G_BEGIN_DECLS
#define GREETER_BACKGROUND_DEFAULT "*"
+typedef enum
+{
+ TRANSITION_TYPE_NONE,
+ TRANSITION_TYPE_EASE_IN_OUT,
+ TRANSITION_TYPE_LINEAR,
+ TRANSITION_TYPE_FALLBACK
+} TransitionType;
+
+typedef enum
+{
+ TRANSITION_EFFECT_NONE,
+} TransitionEffect;
+
typedef struct _GreeterBackground GreeterBackground;
typedef struct _GreeterBackgroundClass GreeterBackgroundClass;
@@ -25,10 +38,10 @@ void greeter_background_set_active_monitor_config (GreeterBackground* backgrou
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,
+ gint user_bg,
+ gint laptop,
gint transition_duration,
- const gchar* transition_func);
+ TransitionType transition_type);
void greeter_background_remove_monitor_config (GreeterBackground* background,
const gchar* name);
gchar** greeter_background_get_configured_monitors (GreeterBackground* background);
diff --git a/src/greeterconfiguration.c b/src/greeterconfiguration.c
new file mode 100644
index 0000000..a248cc7
--- /dev/null
+++ b/src/greeterconfiguration.c
@@ -0,0 +1,371 @@
+
+#include <glib.h>
+
+#include "greeterconfiguration.h"
+
+
+static GKeyFile* greeter_config = NULL;
+static GKeyFile* state_config = NULL;
+static gchar* state_filename = NULL;
+
+static GKeyFile* get_file_for_group (const gchar** group);
+static void save_key_file (GKeyFile* config, const gchar* path);
+static gboolean get_int (GKeyFile* config, const gchar* group, const gchar* key, gint* out);
+static gboolean get_bool (GKeyFile* config, const gchar* group, const gchar* key, gboolean* out);
+
+/* Implementation */
+
+static GList*
+append_directory_content(GList* files, const gchar* path)
+{
+ GError* error = NULL;
+ gchar* full_path = g_build_filename(path, "lightdm", "lightdm-gtk-greeter.conf.d", NULL);
+ GDir* dir = g_dir_open(full_path, 0, &error);
+ if(error && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ g_warning("[Configuration] Failed to read configuration directory '%s': %s", full_path, error->message);
+ g_clear_error(&error);
+
+ GList* content = NULL;
+ if(dir)
+ {
+ const gchar *name;
+ while((name = g_dir_read_name(dir)))
+ {
+ if(!g_str_has_suffix(name, ".conf"))
+ continue;
+ content = g_list_prepend(content, g_build_filename(full_path, name, NULL));
+ }
+ g_dir_close(dir);
+
+ if(content)
+ content = g_list_sort(content, (GCompareFunc)g_strcmp0);
+ }
+
+ content = g_list_append(content, g_build_filename(path, "lightdm", "lightdm-gtk-greeter.conf", NULL));
+
+ GList* list_iter;
+ for(list_iter = content; list_iter; list_iter = g_list_next(list_iter))
+ {
+ if(g_file_test(list_iter->data, G_FILE_TEST_IS_REGULAR))
+ files = g_list_prepend(files, list_iter->data);
+ else
+ g_free(list_iter->data);
+ }
+
+ g_list_free(content);
+ g_free(full_path);
+ return files;
+}
+
+void
+config_init(void)
+{
+ GError* error = NULL;
+
+ gchar* state_config_dir = g_build_filename(g_get_user_cache_dir(), "lightdm-gtk-greeter", NULL);
+ state_filename = g_build_filename(state_config_dir, "state", NULL);
+ g_mkdir_with_parents(state_config_dir, 0775);
+ g_free(state_config_dir);
+
+ state_config = g_key_file_new();
+ g_key_file_load_from_file(state_config, state_filename, G_KEY_FILE_NONE, &error);
+ if (error && !g_error_matches(error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+ g_warning("[Configuration] Failed to load state from %s: %s", state_filename, error->message);
+ g_clear_error(&error);
+
+
+ gint i;
+ GList* files = NULL;
+
+ const gchar* const* dirs = g_get_system_data_dirs();
+ for(i = 0; dirs[i]; ++i)
+ files = append_directory_content(files, dirs[i]);
+
+ dirs = g_get_system_config_dirs();
+ for(i = 0; dirs[i]; ++i)
+ files = append_directory_content(files, dirs[i]);
+
+ gchar* config_path_tmp = g_path_get_dirname(CONFIG_FILE);
+ gchar* config_path = g_path_get_dirname(config_path_tmp);
+ files = append_directory_content(files, config_path);
+ g_free(config_path_tmp);
+ g_free(config_path);
+
+ files = g_list_reverse(files);
+
+ GKeyFile* tmp_config = NULL;
+ GList* file_iter = NULL;
+ for(file_iter = files; file_iter; file_iter = g_list_next(file_iter))
+ {
+ const gchar* path = file_iter->data;
+
+ if(!tmp_config)
+ tmp_config = g_key_file_new();
+
+ if(!g_key_file_load_from_file(tmp_config, path, G_KEY_FILE_NONE, &error))
+ {
+ if(error)
+ {
+ g_warning("[Configuration] Failed to read file '%s': %s", path, error->message);
+ g_clear_error(&error);
+ }
+ else
+ g_warning("[Configuration] Failed to read file '%s'", path);
+ continue;
+ }
+ g_message("[Configuration] Reading file: %s", path);
+
+ if(!greeter_config)
+ {
+ greeter_config = tmp_config;
+ tmp_config = NULL;
+ continue;
+ }
+
+ gchar** group_iter = NULL;
+ gchar** groups = g_key_file_get_groups(tmp_config, NULL);
+ for(group_iter = groups; *group_iter; ++group_iter)
+ {
+ if(**group_iter == '-')
+ {
+ g_key_file_remove_group(greeter_config, *group_iter + 1, NULL);
+ continue;
+ }
+
+ gchar** key_iter = NULL;
+ gchar** keys = g_key_file_get_keys(tmp_config, *group_iter, NULL, NULL);
+ for(key_iter = keys; *key_iter; ++key_iter)
+ {
+ if(**key_iter == '-')
+ {
+ g_key_file_remove_key(greeter_config, *group_iter, *key_iter + 1, NULL);
+ continue;
+ }
+
+ gchar* value = g_key_file_get_value(tmp_config, *group_iter, *key_iter, NULL);
+ if(value)
+ {
+ g_key_file_set_value(greeter_config, *group_iter, *key_iter, value);
+ g_free(value);
+ }
+ }
+ g_strfreev(keys);
+ }
+ g_strfreev(groups);
+ }
+ if (tmp_config)
+ g_key_file_unref(tmp_config);
+ g_list_free_full(files, g_free);
+
+ if(!greeter_config)
+ greeter_config = g_key_file_new();
+}
+
+static GKeyFile*
+get_file_for_group(const gchar** group)
+{
+ if(!*group)
+ *group = CONFIG_GROUP_DEFAULT;
+
+ if(*group[0] == '/')
+ {
+ (*group)++;
+ return state_config;
+ }
+
+ return greeter_config;
+}
+
+static void
+save_key_file(GKeyFile* config, const gchar* path)
+{
+ GError* error = NULL;
+ gsize data_length = 0;
+ gchar* data = g_key_file_to_data(config, &data_length, &error);
+
+ if(error)
+ {
+ g_warning("[Configuration] Failed to save file: %s", error->message);
+ g_clear_error(&error);
+ }
+
+ if(data)
+ {
+ g_file_set_contents(path, data, data_length, &error);
+ if(error)
+ {
+ g_warning("[Configuration] Failed to save file: %s", error->message);
+ g_clear_error(&error);
+ }
+ g_free(data);
+ }
+}
+
+static gboolean
+get_int(GKeyFile* config, const gchar* group, const gchar* key, gint* out)
+{
+ GError* error = NULL;
+ *out = g_key_file_get_integer(config, group, key, &error);
+ if(!error)
+ return TRUE;
+ if(g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE))
+ g_warning("[Configuration] Failed to parse integer value [%s] %s: %s", group, key, error->message);
+ g_clear_error(&error);
+ return FALSE;
+}
+
+static gboolean
+get_bool(GKeyFile* config, const gchar* group, const gchar* key, gboolean* out)
+{
+ GError* error = NULL;
+ *out = g_key_file_get_boolean(config, group, key, &error);
+ if(!error)
+ return TRUE;
+ if(g_error_matches(error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE))
+ g_warning("[Configuration] Failed to parse boolean value [%s] %s: %s", group, key, error->message);
+ g_clear_error(&error);
+ return FALSE;
+}
+
+gchar**
+config_get_groups(const gchar* prefix)
+{
+ gsize groups_size = 0, i, next;
+ gchar** groups = g_key_file_get_groups(greeter_config, &groups_size);
+
+ for(i = next = 0; i < groups_size; ++i)
+ if(groups[i] && g_str_has_prefix(groups[i], prefix))
+ {
+ if(i != next)
+ {
+ g_free (groups[next]);
+ groups[next] = groups[i];
+ groups[i] = NULL;
+ }
+ ++next;
+ }
+
+ if(groups)
+ groups[next] = NULL;
+
+ return groups;
+}
+
+gboolean
+config_has_key(const gchar* group, const gchar* key)
+{
+ GKeyFile* file = get_file_for_group(&group);
+ return g_key_file_has_key(file, group, key, NULL);
+}
+
+gchar*
+config_get_string(const gchar* group, const gchar* key, const gchar* fallback)
+{
+ GKeyFile* file = get_file_for_group(&group);
+ gchar* value = g_key_file_get_value(file, group, key, NULL);
+ return value || !fallback ? value : g_strdup(fallback);
+}
+
+void
+config_set_string(const gchar* group, const gchar* key, const gchar* value)
+{
+ if(get_file_for_group(&group) != state_config)
+ {
+ g_warning("[Configuration] %s(%s, %s, '%s')", __func__, group, key, value);
+ return;
+ }
+
+ g_key_file_set_value(state_config, group, key, value);
+ save_key_file(state_config, state_filename);
+}
+
+gchar**
+config_get_string_list(const gchar* group, const gchar* key, gchar** fallback)
+{
+ GKeyFile* file = get_file_for_group(&group);
+ gchar** value = g_key_file_get_string_list(file, group, key, NULL, NULL);
+ return value || !fallback ? value : g_strdupv(fallback);
+}
+
+gint
+config_get_int(const gchar* group, const gchar* key, gint fallback)
+{
+ GKeyFile* file = get_file_for_group(&group);
+ gint value;
+ if(!get_int(file, group, key, &value))
+ return fallback;
+ return value;
+}
+
+void
+config_set_int(const gchar* group, const gchar* key, gint value)
+{
+ if(get_file_for_group(&group) != state_config)
+ {
+ g_warning("[Configuration] %s(%s, %s, %d)", __func__, group, key, value);
+ return;
+ }
+
+ g_key_file_set_integer(state_config, group, key, value);
+ save_key_file(state_config, state_filename);
+}
+
+gboolean
+config_get_bool(const gchar* group, const gchar* key, gboolean fallback)
+{
+ GKeyFile* file = get_file_for_group(&group);
+ gboolean value;
+ if(!get_bool(file, group, key, &value))
+ return fallback;
+ return value;
+}
+
+void
+config_set_bool(const gchar* group, const gchar* key, gboolean value)
+{
+ if(get_file_for_group(&group) != state_config)
+ {
+ g_warning("[Configuration] %s(%s, %s, %d)", __func__, group, key, value);
+ return;
+ }
+
+ g_key_file_set_boolean(state_config, group, key, value);
+ save_key_file(state_config, state_filename);
+}
+
+gint
+config_get_enum(const gchar* group, const gchar* key, gint fallback, const gchar* first_item, ...)
+{
+ if(!first_item)
+ return fallback;
+
+ GKeyFile* file = get_file_for_group(&group);
+ gchar* value = g_key_file_get_value(file, group, key, NULL);
+
+ if(!value)
+ return fallback;
+
+ va_list var_args;
+ va_start(var_args, first_item);
+
+ gboolean found = FALSE;
+ const gchar* item_name = first_item;
+ while(item_name)
+ {
+ gint item_value = va_arg(var_args, gint);
+ if(g_strcmp0(value, item_name) == 0)
+ {
+ found = TRUE;
+ fallback = item_value;
+ break;
+ }
+ item_name = va_arg(var_args, gchar*);
+ }
+ va_end(var_args);
+
+ if(!found)
+ g_warning("[Configuration] Failed to parse enum value [%s] %s: %s", group, key, value);
+
+ return fallback;
+}
+
diff --git a/src/greeterconfiguration.h b/src/greeterconfiguration.h
new file mode 100644
index 0000000..fee59f4
--- /dev/null
+++ b/src/greeterconfiguration.h
@@ -0,0 +1,57 @@
+
+#ifndef GREETER_CONFIGURATION_H
+#define GREETER_CONFIGURATION_H
+
+#include <glib.h>
+
+
+#define CONFIG_GROUP_DEFAULT "greeter"
+#define CONFIG_KEY_INDICATORS "indicators"
+#define CONFIG_KEY_DEBUGGING "allow-debugging"
+#define CONFIG_KEY_SCREENSAVER_TIMEOUT "screensaver-timeout"
+#define CONFIG_KEY_THEME "theme-name"
+#define CONFIG_KEY_ICON_THEME "icon-theme-name"
+#define CONFIG_KEY_FONT "font-name"
+#define CONFIG_KEY_DPI "xft-dpi"
+#define CONFIG_KEY_ANTIALIAS "xft-antialias"
+#define CONFIG_KEY_HINT_STYLE "xft-hintstyle"
+#define CONFIG_KEY_RGBA "xft-rgba"
+#define CONFIG_KEY_HIDE_USER_IMAGE "hide-user-image"
+#define CONFIG_KEY_DEFAULT_USER_IMAGE "default-user-image"
+#define CONFIG_KEY_KEYBOARD "keyboard"
+#define CONFIG_KEY_READER "reader"
+#define CONFIG_KEY_CLOCK_FORMAT "clock-format"
+#define CONFIG_KEY_ACTIVE_MONITOR "active-monitor"
+#define CONFIG_KEY_POSITION "position"
+#define CONFIG_KEY_PANEL_POSITION "panel-position"
+#define CONFIG_KEY_KEYBOARD_POSITION "keyboard-position"
+#define CONFIG_KEY_A11Y_STATES "a11y-states"
+
+#define CONFIG_GROUP_MONITOR "monitor:"
+#define CONFIG_KEY_BACKGROUND "background"
+#define CONFIG_KEY_USER_BACKGROUND "user-background"
+#define CONFIG_KEY_LAPTOP "laptop"
+#define CONFIG_KEY_T_TYPE "transition-type"
+#define CONFIG_KEY_T_DURATION "transition-duration"
+
+#define STATE_SECTION_GREETER "/greeter"
+#define STATE_SECTION_A11Y "/a11y-states"
+#define STATE_KEY_LAST_USER "last-user"
+#define STATE_KEY_LAST_SESSION "last-session"
+
+
+void config_init (void);
+
+gchar** config_get_groups (const gchar* prefix);
+gboolean config_has_key (const gchar* group, const gchar* key);
+
+gchar* config_get_string (const gchar* group, const gchar* key, const gchar* fallback);
+void config_set_string (const gchar* group, const gchar* key, const gchar* value);
+gchar** config_get_string_list (const gchar* group, const gchar* key, gchar** fallback);
+gint config_get_int (const gchar* group, const gchar* key, gint fallback);
+void config_set_int (const gchar* group, const gchar* key, gint value);
+gboolean config_get_bool (const gchar* group, const gchar* key, gboolean fallback);
+void config_set_bool (const gchar* group, const gchar* key, gboolean value);
+gint config_get_enum (const gchar* group, const gchar* key, gint fallback, const gchar* first_name, ...) G_GNUC_NULL_TERMINATED;
+
+#endif //GREETER_CONFIGURATION_H
diff --git a/src/lightdm-gtk-greeter-fallback.css b/src/lightdm-gtk-greeter-fallback.css
index f98064b..1d28490 100644
--- a/src/lightdm-gtk-greeter-fallback.css
+++ b/src/lightdm-gtk-greeter-fallback.css
@@ -1,12 +1,12 @@
#layout_menuitem>GtkLabel
{
- border: 1px solid alpha(@menu_fg_color, 0.8);
- border-radius: 0.5em;
- padding: 0px 0.25em;
- background: alpha(@menu_fg_color, 0.2);
+ border: 1px solid alpha(@menu_fg_color, 0.8);
+ border-radius: 0.5em;
+ padding: 0px 0.25em;
+ background: alpha(@menu_fg_color, 0.2);
}
#layout_menuitem
{
- padding: 1px;
+ padding: 1px;
}
diff --git a/src/lightdm-gtk-greeter.c b/src/lightdm-gtk-greeter.c
index 69627ab..98dd246 100644
--- a/src/lightdm-gtk-greeter.c
+++ b/src/lightdm-gtk-greeter.c
@@ -47,18 +47,15 @@
#include <lightdm.h>
+#include "src/greeterconfiguration.h"
#include "src/greetermenubar.h"
#include "src/greeterbackground.h"
#include "src/lightdm-gtk-greeter-ui.h"
#include "src/lightdm-gtk-greeter-css-fallback.h"
#include "src/lightdm-gtk-greeter-css-application.h"
-static LightDMGreeter *greeter;
-/* State file */
-static GKeyFile *state;
-static gchar *state_filename;
-static void save_state_file (void);
+static LightDMGreeter *greeter;
/* List of spawned processes */
static GSList *pids_to_close = NULL;
@@ -70,7 +67,8 @@ static void close_pid (GPid pid, gboolean remove);
static void sigterm_cb (gpointer user_data);
/* Screen window */
-static GtkOverlay *screen_overlay;
+static GtkOverlay *screen_overlay;
+static GtkWidget *screen_overlay_child;
/* Login window */
static GtkWidget *login_window;
@@ -123,7 +121,7 @@ typedef struct
DimensionPosition width, height;
} WindowPosition;
-static WindowPosition* key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value);
+static WindowPosition* str_to_position (const gchar *str, const WindowPosition *default_value);
/* Function translate user defined coordinates to absolute value */
static gint get_absolute_position (const DimensionPosition *p, gint screen, gint window);
gboolean screen_overlay_get_child_position_cb (GtkWidget *overlay, GtkWidget *widget, GdkRectangle *allocation, gpointer user_data);
@@ -263,7 +261,7 @@ static gboolean menu_item_accel_closure_cb (GtkAccelGroup *accel_group, GObject
/* Maybe unnecessary (in future) trick to enable accelerators for hidden/detached menu items */
static void reassign_menu_item_accel (GtkWidget *item);
-static void init_indicators (GKeyFile* config);
+static void init_indicators (void);
static void layout_selected_cb (GtkCheckMenuItem *menuitem, gpointer user_data);
static void update_layouts_menu (void);
@@ -283,15 +281,14 @@ void a11y_contrast_cb (GtkCheckMenuItem *item);
void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data);
void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data);
-/* Power indciator */
+/* Power indicator */
static void power_menu_cb (GtkWidget *menuitem, gpointer userdata);
void suspend_cb (GtkWidget *widget, LightDMGreeter *greeter);
void hibernate_cb (GtkWidget *widget, LightDMGreeter *greeter);
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);
+static void read_monitor_configuration (const gchar *group, const gchar *name);
struct SavedFocusData
{
@@ -299,6 +296,28 @@ struct SavedFocusData
gint editable_pos;
};
+gpointer greeter_save_focus(GtkWidget* widget);
+void greeter_restore_focus(const gpointer saved_data);
+
+
+static void
+read_monitor_configuration (const gchar *group, const gchar *name)
+{
+ g_debug ("[Configuration] Monitor configuration found: '%s'", name);
+
+ gchar *background = config_get_string (group, CONFIG_KEY_BACKGROUND, NULL);
+ greeter_background_set_monitor_config (greeter_background, name, background,
+ config_get_bool (group, CONFIG_KEY_USER_BACKGROUND, -1),
+ config_get_bool (group, CONFIG_KEY_LAPTOP, -1),
+ config_get_int (group, CONFIG_KEY_T_DURATION, -1),
+ config_get_enum (group, CONFIG_KEY_T_TYPE,
+ TRANSITION_TYPE_FALLBACK,
+ "none", TRANSITION_TYPE_NONE,
+ "linear", TRANSITION_TYPE_LINEAR,
+ "ease-in-out", TRANSITION_TYPE_EASE_IN_OUT, NULL));
+ g_free (background);
+}
+
gpointer
greeter_save_focus(GtkWidget* widget)
{
@@ -316,43 +335,16 @@ greeter_save_focus(GtkWidget* widget)
void
greeter_restore_focus(const gpointer saved_data)
{
- if (!saved_data)
+ struct SavedFocusData *data = saved_data;
+
+ if (!saved_data || !GTK_IS_WIDGET (data->widget))
return;
- struct SavedFocusData *data = saved_data;
- if (GTK_IS_WIDGET (data->widget))
- gtk_widget_grab_focus (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
-save_state_file (void)
-{
- GError *error = NULL;
- gsize data_length = 0;
- gchar *data = g_key_file_to_data (state, &data_length, &error);
-
- if (error)
- {
- g_warning ("Failed to save state file: %s", error->message);
- g_clear_error (&error);
- }
-
- if (data)
- {
- g_file_set_contents (state_filename, data, data_length, &error);
- if (error)
- {
- g_warning ("Failed to save state file: %s", error->message);
- g_clear_error (&error);
- }
- g_free (data);
- }
-}
-
/* Terminating */
static GPid
@@ -564,15 +556,14 @@ read_position_from_str (const gchar *s, DimensionPosition *x)
}
static WindowPosition*
-key_file_get_position (GKeyFile *key_file, const gchar *group_name, const gchar *key, const WindowPosition *default_value)
+str_to_position (const gchar *str, const WindowPosition *default_value)
{
WindowPosition* pos = g_new0 (WindowPosition, 1);
- gchar *value = g_key_file_get_value (key_file, group_name, key, NULL);
-
*pos = *default_value;
- if (value)
+ if (str)
{
+ gchar *value = g_strdup (str);
gchar *x = value;
gchar *y = strchr (value, ' ');
if (y)
@@ -732,7 +723,7 @@ set_user_image (const gchar *username)
}
else
{
- g_warning ("Failed to load user image: %s", error->message);
+ g_debug ("Failed to load user image: %s", error->message);
g_clear_error (&error);
}
}
@@ -849,6 +840,7 @@ menu_command_run (MenuCommand *command)
if (id != 0 && end_ptr > text)
{
socket = GTK_SOCKET (gtk_socket_new ());
+ gtk_container_foreach (GTK_CONTAINER (command->widget), (GtkCallback)gtk_widget_destroy, NULL);
gtk_container_add (GTK_CONTAINER (command->widget), GTK_WIDGET (socket));
gtk_socket_add_id (socket, id);
gtk_widget_show_all (GTK_WIDGET (command->widget));
@@ -879,6 +871,7 @@ menu_command_run (MenuCommand *command)
g_warning ("[Command/%s] Failed to run: %s", command->name, error->message);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE);
}
+
g_clear_error (&error);
return command->pid;
@@ -911,8 +904,7 @@ menu_command_terminated_cb (GPid pid, gint status, MenuCommand *command)
static void
a11y_menuitem_toggled_cb (GtkCheckMenuItem *item, const gchar* name)
{
- g_key_file_set_boolean (state, "a11y-states", name, gtk_check_menu_item_get_active (item));
- save_state_file ();
+ config_set_bool (STATE_SECTION_A11Y, name, gtk_check_menu_item_get_active (item));
}
/* Session */
@@ -942,7 +934,7 @@ set_session (const gchar *session)
if (!session || !is_valid_session (sessions, session))
{
/* previous session */
- last_session = g_key_file_get_value (state, "greeter", "last-session", NULL);
+ last_session = config_get_string (STATE_SECTION_GREETER, STATE_KEY_LAST_SESSION, NULL);
if (last_session && g_strcmp0 (session, last_session) != 0 &&
is_valid_session (sessions, last_session))
session = last_session;
@@ -1410,9 +1402,8 @@ reassign_menu_item_accel (GtkWidget *item)
}
static void
-init_indicators (GKeyFile* config)
+init_indicators (void)
{
- gchar **names = NULL;
gsize length = 0;
guint i;
GHashTable *builtin_items = NULL;
@@ -1421,27 +1412,14 @@ init_indicators (GKeyFile* config)
#ifdef HAVE_LIBINDICATOR
gboolean inited = FALSE;
#endif
- gboolean fallback = FALSE;
const gchar *DEFAULT_LAYOUT[] = {"~host", "~spacer", "~clock", "~spacer",
"~session", "~language", "~a11y", "~power", NULL};
- if (g_key_file_has_key (config, "greeter", "indicators", NULL))
- { /* no option = default list, empty value = empty list */
- names = g_key_file_get_string_list (config, "greeter", "indicators", &length, NULL);
- }
- else if (g_key_file_has_key (config, "greeter", "show-indicators", NULL))
- { /* fallback mode: no option = empty value = default list */
- names = g_key_file_get_string_list (config, "greeter", "show-indicators", &length, NULL);
- if (length == 0)
- fallback = TRUE;
- }
-
- if (!names || fallback)
- {
+ gchar **names = config_get_string_list (NULL, CONFIG_KEY_INDICATORS, NULL);
+ if (!names)
names = (gchar**)DEFAULT_LAYOUT;
- length = g_strv_length (names);
- }
+ length = g_strv_length (names);
builtin_items = g_hash_table_new (g_str_hash, g_str_equal);
@@ -1925,8 +1903,7 @@ start_authentication (const gchar *username)
pending_questions = NULL;
}
- g_key_file_set_value (state, "greeter", "last-user", username);
- save_state_file ();
+ config_set_string (STATE_SECTION_GREETER, STATE_KEY_LAST_USER, username);
if (g_strcmp0 (username, "*other") == 0)
{
@@ -2018,8 +1995,7 @@ start_session (void)
session = get_session ();
/* Remember last choice */
- g_key_file_set_value (state, "greeter", "last-session", session);
- save_state_file ();
+ config_set_string (STATE_SECTION_GREETER, STATE_KEY_LAST_SESSION, session);
greeter_background_save_xroot (greeter_background);
@@ -2436,7 +2412,6 @@ load_user_list (void)
const GList *items, *item;
GtkTreeModel *model;
GtkTreeIter iter;
- gchar *last_user;
const gchar *selected_user;
gboolean logged_in = FALSE;
@@ -2474,7 +2449,7 @@ load_user_list (void)
2, PANGO_WEIGHT_NORMAL,
-1);
- last_user = g_key_file_get_value (state, "greeter", "last-user", NULL);
+ gchar *last_user = config_get_string (STATE_SECTION_GREETER, STATE_KEY_LAST_USER, NULL);
if (lightdm_greeter_get_select_user_hint (greeter))
selected_user = lightdm_greeter_get_select_user_hint (greeter);
@@ -2513,54 +2488,40 @@ load_user_list (void)
set_displayed_user (greeter, name);
g_free (name);
}
-
}
g_free (last_user);
}
static GdkFilterReturn
-focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
+wm_window_filter (GdkXEvent *gxevent, GdkEvent *event, gpointer data)
{
- XEvent* xevent = (XEvent*)gxevent;
- GdkWindow* keyboard_win = a11y_keyboard_command && a11y_keyboard_command->widget ?
- gtk_widget_get_window (GTK_WIDGET (a11y_keyboard_command->widget)) : NULL;
+ XEvent *xevent = (XEvent*)gxevent;
if (xevent->type == MapNotify)
{
- Window xwin = xevent->xmap.window;
- Window keyboard_xid = 0;
- GdkDisplay* display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
- GdkWindow* win = gdk_x11_window_foreign_new_for_display (display, xwin);
+ GdkDisplay *display = gdk_x11_lookup_xdisplay (xevent->xmap.display);
+ GdkWindow *win = gdk_x11_window_foreign_new_for_display (display, xevent->xmap.window);
GdkWindowTypeHint win_type = gdk_window_get_type_hint (win);
- /* Check to see if this window is our onboard window, since we don't want to focus it. */
- if (keyboard_win)
- keyboard_xid = gdk_x11_window_get_xid (keyboard_win);
-
- if (xwin != keyboard_xid
- && win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP
- && win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
- {
+ if (win_type != GDK_WINDOW_TYPE_HINT_COMBO &&
+ win_type != GDK_WINDOW_TYPE_HINT_TOOLTIP &&
+ win_type != GDK_WINDOW_TYPE_HINT_NOTIFICATION)
+ /*
+ if (win_type == GDK_WINDOW_TYPE_HINT_DESKTOP ||
+ win_type == GDK_WINDOW_TYPE_HINT_DIALOG)
+ */
gdk_window_focus (win, GDK_CURRENT_TIME);
- /* Make sure to keep keyboard above */
- if (keyboard_win)
- gdk_window_raise (keyboard_win);
- }
}
else if (xevent->type == UnmapNotify)
{
Window xwin;
- int revert_to;
- XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to);
+ int revert_to = RevertToNone;
+ XGetInputFocus (xevent->xunmap.display, &xwin, &revert_to);
if (revert_to == RevertToNone)
- {
- gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME);
- /* Make sure to keep keyboard above */
- if (keyboard_win)
- gdk_window_raise (keyboard_win);
- }
+ gdk_window_lower (gtk_widget_get_window (gtk_widget_get_toplevel (GTK_WIDGET (screen_overlay))));
}
+
return GDK_FILTER_CONTINUE;
}
@@ -2583,19 +2544,19 @@ debug_log_handler (const gchar *log_domain, GLogLevelFlags log_level, const gcha
int
main (int argc, char **argv)
{
- GKeyFile *config;
GtkBuilder *builder;
const GList *items, *item;
GtkWidget *image;
- gchar *value, **values, *state_dir;
+ gchar *value;
GtkIconTheme *icon_theme;
GtkCssProvider *css_provider;
GError *error = NULL;
- Display *display;
/* Prevent memory from being swapped out, as we are dealing with passwords */
mlockall (MCL_CURRENT | MCL_FUTURE);
+ g_message ("Starting %s (%s, %s)", PACKAGE_STRING, __DATE__, __TIME__);
+
/* Disable global menus */
g_unsetenv ("UBUNTU_MENUPROXY");
@@ -2613,13 +2574,9 @@ main (int argc, char **argv)
g_unix_signal_add (SIGTERM, (GSourceFunc)sigterm_cb, NULL);
- config = g_key_file_new ();
- g_key_file_load_from_file (config, CONFIG_FILE, G_KEY_FILE_NONE, &error);
- if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
- g_warning ("Failed to load configuration from %s: %s\n", CONFIG_FILE, error->message);
- g_clear_error (&error);
+ config_init ();
- if (g_key_file_get_boolean (config, "greeter", "allow-debugging", NULL))
+ if (config_get_bool (NULL, CONFIG_KEY_DEBUGGING, FALSE))
g_log_set_default_handler (debug_log_handler, NULL);
/* init gtk */
@@ -2628,7 +2585,7 @@ main (int argc, char **argv)
/* Disabling GtkInspector shortcuts.
It is still possible to run GtkInspector with GTK_DEBUG=interactive.
Assume that user knows what he's doing. */
- if (!g_key_file_get_boolean (config, "greeter", "allow-debugging", NULL))
+ if (!config_get_bool (NULL, CONFIG_KEY_DEBUGGING, FALSE))
{
GtkWidget *fake_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkBindingSet *set = gtk_binding_set_by_class (G_OBJECT_GET_CLASS (fake_window));
@@ -2660,20 +2617,10 @@ main (int argc, char **argv)
}
#ifdef HAVE_LIBIDO
+ g_debug ("Initializing IDO library");
ido_init ();
#endif
- state_dir = g_build_filename (g_get_user_cache_dir (), "lightdm-gtk-greeter", NULL);
- g_mkdir_with_parents (state_dir, 0775);
- state_filename = g_build_filename (state_dir, "state", NULL);
- g_free (state_dir);
-
- state = g_key_file_new ();
- g_key_file_load_from_file (state, state_filename, G_KEY_FILE_NONE, &error);
- if (error && !g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
- g_warning ("Failed to load state from %s: %s\n", state_filename, error->message);
- g_clear_error (&error);
-
greeter = lightdm_greeter_new ();
g_signal_connect (greeter, "show-prompt", G_CALLBACK (show_prompt_cb), NULL);
g_signal_connect (greeter, "show-message", G_CALLBACK (show_message_cb), NULL);
@@ -2686,69 +2633,65 @@ main (int argc, char **argv)
gdk_window_set_cursor (gdk_get_default_root_window (), gdk_cursor_new (GDK_LEFT_PTR));
/* Make the greeter behave a bit more like a screensaver if used as un/lock-screen by blanking the screen */
- gchar* end_ptr = NULL;
- int screensaver_timeout = 60;
- value = g_key_file_get_value (config, "greeter", "screensaver-timeout", NULL);
- if (value)
- screensaver_timeout = g_ascii_strtoll (value, &end_ptr, 0);
- g_free (value);
-
- display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
if (lightdm_greeter_get_lock_hint (greeter))
{
+ Display *display = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
XGetScreenSaver (display, &timeout, &interval, &prefer_blanking, &allow_exposures);
XForceScreenSaver (display, ScreenSaverActive);
- XSetScreenSaver (display, screensaver_timeout, 0, ScreenSaverActive, DefaultExposures);
+ XSetScreenSaver (display, config_get_int (NULL, CONFIG_KEY_SCREENSAVER_TIMEOUT, 60), 0,
+ ScreenSaverActive, DefaultExposures);
}
/* Set GTK+ settings */
- value = g_key_file_get_value (config, "greeter", "theme-name", NULL);
+ value = config_get_string (NULL, CONFIG_KEY_THEME, NULL);
if (value)
{
- g_debug ("Using Gtk+ theme %s", value);
+ g_debug ("[Configuration] Changing GTK+ theme to '%s'", value);
g_object_set (gtk_settings_get_default (), "gtk-theme-name", value, NULL);
+ g_free (value);
}
- g_free (value);
g_object_get (gtk_settings_get_default (), "gtk-theme-name", &default_theme_name, NULL);
- g_debug ("Default Gtk+ theme is '%s'", default_theme_name);
+ g_debug ("[Configuration] GTK+ theme: '%s'", default_theme_name);
- value = g_key_file_get_value (config, "greeter", "icon-theme-name", NULL);
+ value = config_get_string (NULL, CONFIG_KEY_ICON_THEME, NULL);
if (value)
{
- g_debug ("Using icon theme %s", value);
+ g_debug ("[Configuration] Changing icons theme to '%s'", value);
g_object_set (gtk_settings_get_default (), "gtk-icon-theme-name", value, NULL);
+ g_free (value);
}
- g_free (value);
g_object_get (gtk_settings_get_default (), "gtk-icon-theme-name", &default_icon_theme_name, NULL);
- g_debug ("Default theme is '%s'", default_icon_theme_name);
+ g_debug ("[Configuration] Icons theme: '%s'", default_icon_theme_name);
- value = g_key_file_get_value (config, "greeter", "font-name", NULL);
+ value = config_get_string (NULL, CONFIG_KEY_FONT, "Sans 10");
if (value)
{
- g_debug ("Using font %s", value);
- g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL);
- }
- else
- {
- value = g_strdup ("Sans 10");
+ g_debug ("[Configuration] Changing font to '%s'", value);
g_object_set (gtk_settings_get_default (), "gtk-font-name", value, NULL);
+ g_free (value);
}
g_object_get (gtk_settings_get_default (), "gtk-font-name", &default_font_name, NULL);
- value = g_key_file_get_value (config, "greeter", "xft-dpi", NULL);
- if (value)
- g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", (int) (1024 * atof (value)), NULL);
- value = g_key_file_get_value (config, "greeter", "xft-antialias", NULL);
- if (value)
- g_object_set (gtk_settings_get_default (), "gtk-xft-antialias", g_strcmp0 (value, "true") == 0, NULL);
- g_free (value);
- value = g_key_file_get_value (config, "greeter", "xft-hintstyle", NULL);
+ g_debug ("[Configuration] Font: '%s'", default_font_name);
+
+ if (config_has_key (NULL, CONFIG_KEY_DPI))
+ g_object_set (gtk_settings_get_default (), "gtk-xft-dpi", 1024*config_get_int (NULL, CONFIG_KEY_DPI, 96), NULL);
+
+ if (config_has_key (NULL, CONFIG_KEY_ANTIALIAS))
+ g_object_set (gtk_settings_get_default (), "gtk-xft-antialias", config_get_bool (NULL, CONFIG_KEY_ANTIALIAS, FALSE), NULL);
+
+ value = config_get_string (NULL, CONFIG_KEY_HINT_STYLE, NULL);
if (value)
+ {
g_object_set (gtk_settings_get_default (), "gtk-xft-hintstyle", value, NULL);
- g_free (value);
- value = g_key_file_get_value (config, "greeter", "xft-rgba", NULL);
+ g_free (value);
+ }
+
+ value = config_get_string (NULL, CONFIG_KEY_RGBA, NULL);
if (value)
+ {
g_object_set (gtk_settings_get_default (), "gtk-xft-rgba", value, NULL);
- g_free (value);
+ g_free (value);
+ }
#ifdef AT_SPI_COMMAND
spawn_line_pid (AT_SPI_COMMAND, G_SPAWN_SEARCH_PATH, NULL);
@@ -2769,6 +2712,7 @@ main (int argc, char **argv)
/* Screen window */
screen_overlay = GTK_OVERLAY (gtk_builder_get_object (builder, "screen_overlay"));
+ screen_overlay_child = GTK_WIDGET (gtk_builder_get_object (builder, "screen_overlay_child"));
/* Login window */
login_window = GTK_WIDGET (gtk_builder_get_object (builder, "login_window"));
@@ -2817,7 +2761,7 @@ main (int argc, char **argv)
gtk_accel_map_add_entry ("<Login>/a11y/reader", GDK_KEY_F4, 0);
gtk_accel_map_add_entry ("<Login>/power/shutdown", GDK_KEY_F4, GDK_MOD1_MASK);
- init_indicators (config);
+ init_indicators ();
/* Hide empty panel */
GList *menubar_items = gtk_container_get_children (GTK_CONTAINER (menubar));
@@ -2826,7 +2770,7 @@ main (int argc, char **argv)
else
g_list_free (menubar_items);
- if (g_key_file_get_boolean (config, "greeter", "hide-user-image", NULL))
+ if (config_get_bool (NULL, CONFIG_KEY_HIDE_USER_IMAGE, FALSE))
{
gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (builder, "user_image_border")));
gtk_widget_hide (GTK_WIDGET (user_image)); /* Hide to mark image is disabled */
@@ -2834,7 +2778,7 @@ main (int argc, char **argv)
}
else
{
- value = g_key_file_get_value (config, "greeter", "default-user-image", NULL);
+ value = config_get_string (NULL, CONFIG_KEY_DEFAULT_USER_IMAGE, NULL);
if (value)
{
if (value[0] == '#')
@@ -2929,16 +2873,23 @@ main (int argc, char **argv)
gtk_container_add (GTK_CONTAINER (a11y_menuitem), image);
}
- value = g_key_file_get_value (config, "greeter", "keyboard", NULL);
- a11y_keyboard_command = menu_command_parse_extended ("keyboard", value, keyboard_menuitem, "onboard", "--xid");
- g_free (value);
-
+ value = config_get_string (NULL, CONFIG_KEY_KEYBOARD, NULL);
+ if (value)
+ {
+ a11y_keyboard_command = menu_command_parse_extended ("keyboard", value, keyboard_menuitem, "onboard", "--xid");
+ g_free (value);
+ }
gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL);
- value = g_key_file_get_value (config, "greeter", "reader", NULL);
- a11y_reader_command = menu_command_parse ("reader", value, reader_menuitem);
+
+
+ value = config_get_string (NULL, CONFIG_KEY_READER, NULL);
+ if (value)
+ {
+ a11y_reader_command = menu_command_parse ("reader", value, reader_menuitem);
+ g_free (value);
+ }
gtk_widget_set_visible (reader_menuitem, a11y_reader_command != NULL);
- g_free (value);
/* Power menu */
if (gtk_widget_get_visible (power_menuitem))
@@ -2997,9 +2948,7 @@ main (int argc, char **argv)
{
gtk_menu_item_set_label (GTK_MENU_ITEM (clock_menuitem), "");
clock_label = gtk_bin_get_child (GTK_BIN (clock_menuitem));
- clock_format = g_key_file_get_value (config, "greeter", "clock-format", NULL);
- if (!clock_format)
- clock_format = "%a, %H:%M";
+ clock_format = config_get_string (NULL, CONFIG_KEY_CLOCK_FORMAT, "%a, %H:%M");
clock_timeout_thread ();
gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL);
}
@@ -3023,49 +2972,21 @@ main (int argc, char **argv)
/* Background */
greeter_background = greeter_background_new (GTK_WIDGET (screen_overlay));
- value = g_key_file_get_value (config, "greeter", "active-monitor", NULL);
+ value = config_get_string (NULL, CONFIG_KEY_ACTIVE_MONITOR, NULL);
greeter_background_set_active_monitor_config (greeter_background, value ? value : "#cursor");
g_free (value);
- const gchar *CONFIG_MONITOR_PREFIX = "monitor:";
+ read_monitor_configuration (CONFIG_GROUP_DEFAULT, GREETER_BACKGROUND_DEFAULT);
+
gchar **config_group;
- gchar **config_groups = g_key_file_get_groups (config, NULL);
+ gchar **config_groups = config_get_groups (CONFIG_GROUP_MONITOR);
for (config_group = config_groups; *config_group; ++config_group)
{
- gchar *name_to_free = NULL;
- const gchar *name = *config_group;
+ const gchar *name = *config_group + sizeof (CONFIG_GROUP_MONITOR);
+ while (*name && g_ascii_isspace (*name))
+ ++name;
- 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, *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);
- 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, background,
- user_bg, user_bg_error == NULL,
- laptop, laptop_error == NULL,
- duration_error == NULL ? tr_duration : -1,
- tr_type);
-
- g_free (tr_type);
- g_free (background);
- g_free (name_to_free);
- g_clear_error (&user_bg_error);
- g_clear_error (&laptop_error);
+ read_monitor_configuration (*config_group, name);
}
g_strfreev (config_groups);
@@ -3087,22 +3008,26 @@ main (int argc, char **argv)
}
/* Windows positions */
- g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION,
- key_file_get_position (config, "greeter", "position", &WINDOW_POS_CENTER), g_free);
-
- value = g_key_file_get_value (config, "greeter", "panel-position", NULL);
- if (g_strcmp0 (value, "bottom") == 0)
- gtk_widget_set_valign (panel_window, GTK_ALIGN_END);
+ value = config_get_string (NULL, CONFIG_KEY_POSITION, NULL);
+ g_object_set_data_full (G_OBJECT (login_window), WINDOW_DATA_POSITION, str_to_position (value, &WINDOW_POS_CENTER), g_free);
g_free (value);
+
+ gtk_widget_set_valign (panel_window, config_get_enum (NULL, CONFIG_KEY_PANEL_POSITION, GTK_ALIGN_START,
+ "bottom", GTK_ALIGN_END,
+ "top", GTK_ALIGN_START, NULL));
+
if (a11y_keyboard_command)
- g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION,
- key_file_get_position (config, "greeter", "keyboard-position", &KEYBOARD_POSITION), g_free);
+ {
+ value = config_get_string (NULL, CONFIG_KEY_KEYBOARD_POSITION, NULL);
+ g_object_set_data_full (G_OBJECT (a11y_keyboard_command->widget), WINDOW_DATA_POSITION, str_to_position (value, &KEYBOARD_POSITION), g_free);
+ g_free (value);
+ }
gtk_builder_connect_signals (builder, greeter);
- values = g_key_file_get_string_list (config, "greeter", "a11y-states", NULL, NULL);
- if (values && *values)
+ gchar **a11y_states = config_get_string_list (NULL, CONFIG_KEY_A11Y_STATES, NULL);
+ if (a11y_states && *a11y_states)
{
GHashTable *items = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (items, "contrast", contrast_menuitem);
@@ -3112,7 +3037,7 @@ main (int argc, char **argv)
gpointer item;
gchar **values_iter;
- for (values_iter = values; *values_iter; ++values_iter)
+ for (values_iter = a11y_states; *values_iter; ++values_iter)
{
value = *values_iter;
switch (value[0])
@@ -3131,19 +3056,19 @@ main (int argc, char **argv)
gtk_widget_get_visible (GTK_WIDGET (item)))
{
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
- g_key_file_get_boolean (state, "a11y-states", value, NULL));
+ config_get_bool (STATE_SECTION_A11Y, value, FALSE));
g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (a11y_menuitem_toggled_cb), g_strdup (value));
}
}
}
g_hash_table_unref (items);
}
- g_strfreev (values);
+ g_strfreev (a11y_states);
- /* focus fix (source: unity-greeter) */
+ /* There is no window manager, so we need to implement some of its functionality */
GdkWindow* root_window = gdk_get_default_root_window ();
gdk_window_set_events (root_window, gdk_window_get_events (root_window) | GDK_SUBSTRUCTURE_MASK);
- gdk_window_add_filter (root_window, focus_upon_map, NULL);
+ gdk_window_add_filter (root_window, wm_window_filter, NULL);
gtk_widget_show (GTK_WIDGET (screen_overlay));
diff --git a/src/lightdm-gtk-greeter.glade b/src/lightdm-gtk-greeter.glade
index 1230d2e..11fb826 100644
--- a/src/lightdm-gtk-greeter.glade
+++ b/src/lightdm-gtk-greeter.glade
@@ -282,6 +282,7 @@
<property name="name">cancel_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="power_button_clicked_cb" swapped="no"/>
</object>
<packing>
@@ -296,6 +297,7 @@
<property name="name">power_ok_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="power_button_clicked_cb" swapped="no"/>
</object>
<packing>
@@ -326,10 +328,9 @@
<property name="vexpand">True</property>
<signal name="get-child-position" handler="screen_overlay_get_child_position_cb" swapped="no"/>
<child>
- <object class="GtkBox" id="screen-child">
+ <object class="GtkEventBox" id="screen_overlay_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="orientation">vertical</property>
<child>
<placeholder/>
</child>
@@ -541,6 +542,7 @@
<property name="name">cancel_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="cancel_cb" swapped="no"/>
</object>
<packing>
@@ -555,6 +557,7 @@
<property name="name">login_button</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="receives_default">False</property>
<signal name="clicked" handler="login_cb" swapped="no"/>
</object>
<packing>