diff options
author | Sean Davis <smd.seandavis@gmail.com> | 2015-04-25 21:08:40 -0400 |
---|---|---|
committer | Sean Davis <smd.seandavis@gmail.com> | 2015-04-25 21:08:40 -0400 |
commit | 816a86665ead4ec61c713435555a58173e2239b2 (patch) | |
tree | e5ea35ec006e3c1a8484afdfdc8f940cbb969762 | |
parent | 0190eb0d47807188d4719c98cb90351abcc838ff (diff) | |
parent | a4d76234c24d2d2a06123d947cad9ca3120709b5 (diff) | |
download | lightdm-gtk-greeter-git-816a86665ead4ec61c713435555a58173e2239b2.tar.gz |
Merge in post-2.0.0 fixes branch
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/greeterbackground.c | 114 | ||||
-rw-r--r-- | src/greeterbackground.h | 19 | ||||
-rw-r--r-- | src/greeterconfiguration.c | 371 | ||||
-rw-r--r-- | src/greeterconfiguration.h | 57 | ||||
-rw-r--r-- | src/lightdm-gtk-greeter-fallback.css | 10 | ||||
-rw-r--r-- | src/lightdm-gtk-greeter.c | 371 | ||||
-rw-r--r-- | src/lightdm-gtk-greeter.glade | 7 |
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> |