diff options
author | Andrew P. <pan.pav.7c5@gmail.com> | 2014-08-09 17:18:49 +0300 |
---|---|---|
committer | Andrew P. <pan.pav.7c5@gmail.com> | 2014-08-09 17:18:49 +0300 |
commit | a97438ffc3154e71e02797f3cf5409ef4df9d57a (patch) | |
tree | d5aeae182f195da718f24e949d7d01aa4559e77c | |
parent | d8ccd45bd6bf07a53bedfc98a1b6a04d8e7d6884 (diff) | |
parent | dc21d736355c97e9289f0e90c2e7e3c704da832a (diff) | |
download | lightdm-gtk-greeter-git-a97438ffc3154e71e02797f3cf5409ef4df9d57a.tar.gz |
Merge "states-and-orca" branch
-rw-r--r-- | data/lightdm-gtk-greeter.conf | 5 | ||||
-rw-r--r-- | src/lightdm-gtk-greeter.c | 496 | ||||
-rw-r--r-- | src/lightdm-gtk-greeter.glade | 11 |
3 files changed, 343 insertions, 169 deletions
diff --git a/data/lightdm-gtk-greeter.conf b/data/lightdm-gtk-greeter.conf index 442e84b..762a513 100644 --- a/data/lightdm-gtk-greeter.conf +++ b/data/lightdm-gtk-greeter.conf @@ -12,7 +12,9 @@ # show-indicators = semi-colon ";" separated list of allowed indicator modules. Built-in indicators include "~a11y", "~language", "~session", "~power". Unity indicators can be represented by short name (e.g. "sound", "power"), service file name, or absolute path # show-clock (true or false) # clock-format = strftime-format string, e.g. %H:%M -# keyboard = command to launch on-screen keyboard +# keyboard = command to launch on-screen keyboard (e.g. onboard) +# reader = command to launch screen reader (e.g. orca) +# a11y-states = states of accessibility features: "name" - save state on exit, "-name" - disabled at start (default value for unlisted), "+name" - enabled at start. Allowed names: contrast, font, keyboard, reader. # position = main window position: x y # default-user-image = Image used as default user icon, path or #icon-name # hide-user-image = true|false, false by default @@ -32,5 +34,6 @@ #show-clock= #clock-format= #keyboard= +#reader= #position= #screensaver-timeout= diff --git a/src/lightdm-gtk-greeter.c b/src/lightdm-gtk-greeter.c index 1a7a553..accb323 100644 --- a/src/lightdm-gtk-greeter.c +++ b/src/lightdm-gtk-greeter.c @@ -61,8 +61,10 @@ #endif static LightDMGreeter *greeter; + static GKeyFile *state; static gchar *state_filename; +static void save_state_file (void); /* Defaults */ static gchar *default_font_name, *default_theme_name, *default_icon_theme_name; @@ -73,7 +75,8 @@ static GtkWidget *menubar; static GtkWidget *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem, *layout_menuitem, *session_badge; static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem; -static GtkWidget *keyboard_menuitem, *clock_menuitem, *clock_label, *host_menuitem; +static GtkWidget *clock_menuitem, *clock_label, *host_menuitem; +static GtkWidget *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem; static GtkMenu *session_menu, *language_menu, *layout_menu; /* Login Window Widgets */ @@ -86,10 +89,54 @@ static GtkInfoBar *info_bar; static GtkButton *cancel_button, *login_button; static gchar *clock_format; -static gchar **a11y_keyboard_command; -static GPid a11y_kbd_pid = 0; -static GError *a11y_keyboard_error; -static GtkWindow *onboard_window; + +typedef struct +{ + gint value; + /* +0 and -0 */ + gint sign; + /* interpret 'value' as percentage of screen width/height */ + gboolean percentage; + /* -1: left/top, 0: center, +1: right,bottom */ + gint anchor; +} DimensionPosition; + +typedef struct +{ + DimensionPosition x, y; +} WindowPosition; + +/* Function translate user defined coordinates to absolute value */ +static gint get_absolute_position (const DimensionPosition *p, gint screen, gint window); +static const WindowPosition WINDOW_POS_CENTER = {.x = { 50, +1, TRUE, 0}, .y = { 50, +1, TRUE, 0}}; +static const WindowPosition WINDOW_POS_TOP_LEFT = {.x = { 0, +1, FALSE, -1}, .y = { 0, +1, FALSE, -1}}; +static const WindowPosition ONBOARD_WINDOW_POS = {.x = { 50, +1, TRUE, 0}, .y = { 0, -1, FALSE, +1}}; +static const WindowPosition ONBOARD_WINDOW_SIZE = {.x = {610, 0, FALSE, 0}, .y = {210, 0, FALSE, 0}}; +static WindowPosition main_window_pos; +static WindowPosition panel_window_pos; + +typedef struct +{ + gchar **argv; + gint argc; + + GPid pid; + GtkWidget *menu_item; + GtkWidget *widget; +} MenuCommand; + +static MenuCommand *menu_command_parse (const gchar *value, GtkWidget *menu_item); +static MenuCommand *menu_command_parse_extended (const gchar *value, GtkWidget *menu_item, + const gchar *xid_supported, const gchar *xid_arg, + const WindowPosition *size); +static gboolean menu_command_run (MenuCommand *command); +static gboolean menu_command_stop (MenuCommand *command); +static void command_terminated_cb (GPid pid, gint status, MenuCommand *command); + +static MenuCommand *a11y_keyboard_command; +static MenuCommand *a11y_reader_command; + +static void a11y_menuitem_toggled_cb (GtkCheckMenuItem *item, const gchar* name); /* Pending Questions */ static GSList *pending_questions = NULL; @@ -120,27 +167,6 @@ typedef struct gchar *text; } PAMConversationMessage; -typedef struct -{ - gint value; - /* +0 and -0 */ - gint sign; - /* interpret 'value' as percentage of screen width/height */ - gboolean percentage; - /* -1: left/top, 0: center, +1: right,bottom */ - gint anchor; -} DimensionPosition; - -typedef struct -{ - DimensionPosition x, y; -} WindowPosition; - -static const WindowPosition WINDOW_POS_CENTER = {.x = {50, +1, TRUE, 0}, .y = {50, +1, TRUE, 0}}; -static const WindowPosition WINDOW_POS_TOP_LEFT = {.x = {0, +1, FALSE, -1}, .y = {0, +1, FALSE, -1}}; -static WindowPosition main_window_pos; -static WindowPosition panel_window_pos; - static GdkPixbuf* default_user_pixbuf = NULL; static gchar* default_user_icon = "avatar-default"; @@ -201,6 +227,200 @@ key_file_get_boolean_extended (GKeyFile *key_file, const gchar *group_name, cons } 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); + } +} + +/* MenuCommand */ + +static MenuCommand* +menu_command_parse (const gchar *value, GtkWidget *menu_item) +{ + return menu_command_parse_extended (value, menu_item, NULL, NULL, NULL); +} + +static MenuCommand* +menu_command_parse_extended (const gchar *value, GtkWidget *menu_item, + const gchar *xid_supported, const gchar *xid_arg, + const WindowPosition *size) +{ + if (!value) + return NULL; + + GError *error = NULL; + gchar **argv; + gint argc = 0; + + if (!g_shell_parse_argv (value, &argc, &argv, &error)) + { + if (error) + g_warning ("Failed to parse command line: %s", error->message); + g_clear_error (&error); + return NULL; + } + + MenuCommand *command = g_new0 (MenuCommand, 1); + command->menu_item = menu_item; + command->argc = argc; + command->argv = argv; + + if (g_strcmp0 (argv[0], xid_supported) == 0) + { + gboolean have_xid_arg = FALSE; + gint i; + for (i = 1; i < argc; ++i) + if (g_strcmp0 (argv[i], xid_arg) == 0) + { + have_xid_arg = TRUE; + break; + } + if (!have_xid_arg) + { + gchar *new_value = g_strdup_printf ("%s %s", value, xid_arg); + + if (g_shell_parse_argv (new_value, &argc, &argv, &error)) + { + g_strfreev (command->argv); + command->argc = argc; + command->argv = argv; + have_xid_arg = TRUE; + } + else + { + if (error) + g_warning ("Failed to parse command line: %s", error->message); + g_clear_error (&error); + } + g_free (new_value); + } + + if (have_xid_arg) + { + GdkRectangle screen; + command->widget = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gdk_screen_get_monitor_geometry (gdk_screen_get_default (), + /* must be replaced with background->active_monitor */ + gdk_screen_get_primary_monitor (gdk_screen_get_default ()), + &screen); + gtk_widget_set_size_request (command->widget, + get_absolute_position (&size->x, screen.width, 0), + get_absolute_position (&size->y, screen.height, 0)); + } + } + return command; +} + +static gboolean +menu_command_run (MenuCommand *command) +{ + g_return_val_if_fail (command && g_strv_length (command->argv), FALSE); + + GError *error = NULL; + gboolean spawned = FALSE; + if (command->widget) + { + GtkSocket* socket = NULL; + gint out_fd = 0; + + if (g_spawn_async_with_pipes (NULL, command->argv, NULL, G_SPAWN_SEARCH_PATH, + NULL, NULL, &command->pid, NULL, &out_fd, NULL, &error)) + { + gchar* text = NULL; + GIOChannel* out_channel = g_io_channel_unix_new (out_fd); + if (g_io_channel_read_line (out_channel, &text, NULL, NULL, &error) == G_IO_STATUS_NORMAL) + { + gchar* end_ptr = NULL; + + text = g_strstrip (text); + gint id = g_ascii_strtoll (text, &end_ptr, 0); + + if (id != 0 && end_ptr > text) + { + socket = GTK_SOCKET (gtk_socket_new ()); + gtk_container_add (GTK_CONTAINER (command->widget), GTK_WIDGET (socket)); + gtk_socket_add_id (socket, id); + gtk_widget_show_all (GTK_WIDGET (command->widget)); + spawned = TRUE; + } + else + g_warning ("Failed to get '%s' socket: unrecognized output", command->argv[0]); + + g_free(text); + } + } + } + else + { + spawned = g_spawn_async (NULL, command->argv, NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, NULL, &command->pid, &error); + if (spawned) + g_child_watch_add (command->pid, (GChildWatchFunc)command_terminated_cb, command); + } + + if(!spawned) + { + if (error) + g_warning ("Command spawning error: '%s'", error->message); + command->pid = 0; + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE); + } + g_clear_error(&error); + return spawned; +} + +static gboolean +menu_command_stop (MenuCommand *command) +{ + g_return_val_if_fail (command, FALSE); + + if (command->pid) + { + kill (command->pid, SIGTERM); + g_spawn_close_pid (command->pid); + command->pid = 0; + if (command->menu_item) + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (command->menu_item), FALSE); + if (command->widget) + gtk_widget_hide (command->widget); + } + return TRUE; +} + +static void +command_terminated_cb (GPid pid, gint status, MenuCommand *command) +{ + menu_command_stop (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 (); +} + +static void pam_message_finalize (PAMConversationMessage *message) { g_free (message->text); @@ -858,6 +1078,7 @@ set_user_image (const gchar *username) if (username) user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); + if (user) { path = lightdm_user_get_image (user); @@ -956,7 +1177,7 @@ cairo_region_from_rectangle (gint width, gint height, gint radius) region = gdk_region_rectangle (&rect); - while(x >= y) + while (x >= y) { rect.x = -x + radius; @@ -971,12 +1192,12 @@ cairo_region_from_rectangle (gint width, gint height, gint radius) rect.width = y - radius + width - rect.x; rect.height = x - radius + height - rect.y; - gdk_region_union_with_rect(region, &rect); + gdk_region_union_with_rect (region, &rect); y++; radiusError += yChange; yChange += 2; - if(((radiusError << 1) + xChange) > 0) + if (((radiusError << 1) + xChange) > 0) { x--; radiusError += xChange; @@ -994,9 +1215,10 @@ login_window_size_allocate (GtkWidget *widget, GdkRectangle *allocation, gpointe GdkWindow *window = gtk_widget_get_window (widget); if (window_region) - gdk_region_destroy(window_region); + gdk_region_destroy (window_region); window_region = cairo_region_from_rectangle (allocation->width, allocation->height, radius); - if (window) { + if (window) + { gdk_window_shape_combine_region(window, window_region, 0, 0); gdk_window_input_shape_combine_region(window, window_region, 0, 0); } @@ -1008,10 +1230,6 @@ login_window_size_allocate (GtkWidget *widget, GdkRectangle *allocation, gpointe static void start_authentication (const gchar *username) { - gchar *data; - gsize data_length; - GError *error = NULL; - cancelling = FALSE; prompted = FALSE; password_prompted = FALSE; @@ -1024,18 +1242,7 @@ start_authentication (const gchar *username) } g_key_file_set_value (state, "greeter", "last-user", username); - 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); + save_state_file (); if (g_strcmp0 (username, "*other") == 0) { @@ -1118,9 +1325,6 @@ start_session (void) { gchar *language; gchar *session; - gchar *data; - gsize data_length; - GError *error = NULL; language = get_language (); if (language) @@ -1131,21 +1335,7 @@ start_session (void) /* Remember last choice */ g_key_file_set_value (state, "greeter", "last-session", session); - - greeter_background_save_xroot (greeter_background); - - 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); + save_state_file (); if (!lightdm_greeter_start_session_sync (greeter, session, NULL)) { @@ -1843,82 +2033,26 @@ a11y_contrast_cb (GtkCheckMenuItem *item) } } -static void -keyboard_terminated_cb (GPid pid, gint status, gpointer user_data) +void a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data); +G_MODULE_EXPORT +void +a11y_keyboard_cb (GtkCheckMenuItem *item, gpointer user_data) { - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (keyboard_menuitem), FALSE); + if (gtk_check_menu_item_get_active (item)) + menu_command_run (a11y_keyboard_command); + else + menu_command_stop (a11y_keyboard_command); } -void a11y_keyboard_cb (GtkCheckMenuItem *item); +void a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data); G_MODULE_EXPORT void -a11y_keyboard_cb (GtkCheckMenuItem *item) +a11y_reader_cb (GtkCheckMenuItem *item, gpointer user_data) { if (gtk_check_menu_item_get_active (item)) - { - gboolean spawned = FALSE; - if (onboard_window) - { - GtkSocket* socket = NULL; - gint out_fd = 0; - - if (g_spawn_async_with_pipes (NULL, a11y_keyboard_command, NULL, G_SPAWN_SEARCH_PATH, - NULL, NULL, &a11y_kbd_pid, NULL, &out_fd, NULL, - &a11y_keyboard_error)) - { - gchar* text = NULL; - GIOChannel* out_channel = g_io_channel_unix_new (out_fd); - if (g_io_channel_read_line(out_channel, &text, NULL, NULL, &a11y_keyboard_error) == G_IO_STATUS_NORMAL) - { - gchar* end_ptr = NULL; - - text = g_strstrip (text); - gint id = g_ascii_strtoll (text, &end_ptr, 0); - - if (id != 0 && end_ptr > text) - { - socket = GTK_SOCKET (gtk_socket_new ()); - gtk_container_add (GTK_CONTAINER (onboard_window), GTK_WIDGET (socket)); - gtk_socket_add_id (socket, id); - gtk_widget_show_all (GTK_WIDGET (onboard_window)); - spawned = TRUE; - } - else - g_debug ("onboard keyboard command error : 'unrecognized output'"); - - g_free(text); - } - } - } - else - { - spawned = g_spawn_async (NULL, a11y_keyboard_command, NULL, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, NULL, &a11y_kbd_pid, &a11y_keyboard_error); - if (spawned) - g_child_watch_add (a11y_kbd_pid, keyboard_terminated_cb, NULL); - } - - if(!spawned) - { - if (a11y_keyboard_error) - g_debug ("a11y keyboard command error : '%s'", a11y_keyboard_error->message); - a11y_kbd_pid = 0; - g_clear_error(&a11y_keyboard_error); - gtk_check_menu_item_set_active (item, FALSE); - } - } + menu_command_run (a11y_reader_command); else - { - if (a11y_kbd_pid != 0) - { - kill (a11y_kbd_pid, SIGTERM); - g_spawn_close_pid (a11y_kbd_pid); - a11y_kbd_pid = 0; - if (onboard_window) - gtk_widget_hide (GTK_WIDGET(onboard_window)); - } - } + menu_command_stop (a11y_reader_command); } static void @@ -2063,7 +2197,8 @@ static GdkFilterReturn focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data) { XEvent* xevent = (XEvent*)gxevent; - GdkWindow* keyboard_win = onboard_window ? gtk_widget_get_window (GTK_WIDGET (onboard_window)) : NULL; + GdkWindow* keyboard_win = a11y_keyboard_command && a11y_keyboard_command->widget ? + gtk_widget_get_window (GTK_WIDGET (a11y_keyboard_command->widget)) : NULL; if (xevent->type == MapNotify) { Window xwin = xevent->xmap.window; @@ -2086,11 +2221,8 @@ focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data) { gdk_window_focus (win, GDK_CURRENT_TIME); /* Make sure to keep keyboard above */ - if (onboard_window) - { - if (keyboard_win) - gdk_window_raise (keyboard_win); - } + if (keyboard_win) + gdk_window_raise (keyboard_win); } } else if (xevent->type == UnmapNotify) @@ -2103,11 +2235,8 @@ focus_upon_map (GdkXEvent *gxevent, GdkEvent *event, gpointer data) { gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME); /* Make sure to keep keyboard above */ - if (onboard_window) - { - if (keyboard_win) - gdk_window_raise (keyboard_win); - } + if (keyboard_win) + gdk_window_raise (keyboard_win); } } return GDK_FILTER_CONTINUE; @@ -2291,12 +2420,11 @@ int main (int argc, char **argv) { GKeyFile *config; - GdkRectangle monitor_geometry; GtkBuilder *builder; const GList *items, *item; GtkCellRenderer *renderer; GtkWidget *image, *infobar_compat, *content_area; - gchar *value, *state_dir; + gchar *value, **values, *state_dir; #if GTK_CHECK_VERSION (3, 0, 0) GtkIconTheme *icon_theme; GtkCssProvider *css_provider; @@ -2427,15 +2555,7 @@ main (int argc, char **argv) if (value) g_object_set (gtk_settings_get_default (), "gtk-xft-rgba", value, NULL); g_free (value); - - /* Get a11y on screen keyboard command*/ - gint argp; - value = g_key_file_get_value (config, "greeter", "keyboard", NULL); - g_debug ("a11y keyboard command is '%s'", value); - /* Set NULL to blank to avoid warnings */ - if (!value) { value = g_strdup(""); } - g_shell_parse_argv (value, &argp, &a11y_keyboard_command, NULL); - g_free (value); + builder = gtk_builder_new (); if (!gtk_builder_add_from_string (builder, lightdm_gtk_greeter_ui, @@ -2506,16 +2626,20 @@ main (int argc, char **argv) language_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "language_menuitem")); language_menu = GTK_MENU(gtk_builder_get_object (builder, "language_menu")); a11y_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "a11y_menuitem")); + contrast_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "high_contrast_menuitem")); + font_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "large_font_menuitem")); + keyboard_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "keyboard_menuitem")); + reader_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "reader_menuitem")); power_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "power_menuitem")); layout_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "layout_menuitem")); layout_menu = GTK_MENU(gtk_builder_get_object (builder, "layout_menu")); - keyboard_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "keyboard_menuitem")); clock_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "clock_menuitem")); host_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "host_menuitem")); gtk_accel_map_add_entry ("<Login>/a11y/font", GDK_KEY_F1, 0); gtk_accel_map_add_entry ("<Login>/a11y/contrast", GDK_KEY_F2, 0); gtk_accel_map_add_entry ("<Login>/a11y/keyboard", GDK_KEY_F3, 0); + 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); #ifdef START_INDICATOR_SERVICES @@ -2635,6 +2759,20 @@ 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 (value, keyboard_menuitem, "onboard", "--xid", + &ONBOARD_WINDOW_SIZE); + g_free (value); + + gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL); + if (a11y_keyboard_command) + g_signal_connect (a11y_keyboard_command->widget, "size-allocate", G_CALLBACK (center_window), (gpointer)&ONBOARD_WINDOW_POS); + + value = g_key_file_get_value (config, "greeter", "reader", NULL); + a11y_reader_command = menu_command_parse (value, reader_menuitem); + gtk_widget_set_visible (reader_menuitem, a11y_reader_command != NULL); + g_free (value); + /* Power menu */ if (gtk_widget_get_visible (power_menuitem)) { @@ -2814,22 +2952,44 @@ main (int argc, char **argv) g_signal_connect (GTK_WIDGET (login_window), "size-allocate", G_CALLBACK (center_window), &main_window_pos); gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (login_window)), GDK_CURRENT_TIME); - if (a11y_keyboard_command) + values = g_key_file_get_string_list (config, "greeter", "a11y-states", NULL, NULL); + if (values && *values) { - /* If command is onboard, position the application at the bottom-center of the screen */ - if (g_strcmp0(a11y_keyboard_command[0], "onboard") == 0) + GHashTable *items = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (items, "contrast", contrast_menuitem); + g_hash_table_insert (items, "font", font_menuitem); + g_hash_table_insert (items, "keyboard", keyboard_menuitem); + g_hash_table_insert (items, "reader", reader_menuitem); + + gpointer item; + gchar **values_iter; + for (values_iter = values; *values_iter; ++values_iter) { - gint argp; - value = "onboard --xid"; - g_debug ("a11y keyboard command is now '%s'", value); - g_shell_parse_argv (value, &argp, &a11y_keyboard_command, NULL); - onboard_window = GTK_WINDOW (gtk_window_new(GTK_WINDOW_TOPLEVEL)); - gtk_widget_set_size_request (GTK_WIDGET (onboard_window), 605, 205); - gtk_window_move (onboard_window, (monitor_geometry.width - 605)/2, monitor_geometry.height - 205); + value = *values_iter; + switch (value[0]) + { + case '-': + continue; + case '+': + if (g_hash_table_lookup_extended (items, &value[1], NULL, &item) && + gtk_widget_get_visible (GTK_WIDGET (item))) + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); + break; + case '~': + value++; + default: + if (g_hash_table_lookup_extended (items, value, NULL, &item) && + 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)); + g_signal_connect (G_OBJECT (item), "toggled", G_CALLBACK (a11y_menuitem_toggled_cb), g_strdup (value)); + } + } } + g_hash_table_unref (items); } - gtk_widget_set_sensitive (keyboard_menuitem, a11y_keyboard_command != NULL); - gtk_widget_set_visible (keyboard_menuitem, a11y_keyboard_command != NULL); + g_strfreev (values); /* focus fix (source: unity-greeter) */ GdkWindow* root_window = gdk_get_default_root_window (); diff --git a/src/lightdm-gtk-greeter.glade b/src/lightdm-gtk-greeter.glade index 5f12713..2c174d8 100644 --- a/src/lightdm-gtk-greeter.glade +++ b/src/lightdm-gtk-greeter.glade @@ -108,6 +108,17 @@ <signal name="toggled" handler="a11y_keyboard_cb" swapped="no"/> </object> </child> + <child> + <object class="GtkCheckMenuItem" id="reader_menuitem"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="accel_path"><Login>/a11y/reader</property> + <property name="label" translatable="yes">Screen Reader</property> + <property name="use_underline">True</property> + <signal name="toggled" handler="a11y_reader_cb" swapped="no"/> + </object> + </child> </object> </child> </object> |