[Pkg-xfce-devel] Getting orca started in lightdm
Samuel Thibault
sthibault at debian.org
Mon Oct 20 22:14:42 UTC 2014
Samuel Thibault, le Tue 21 Oct 2014 00:07:41 +0200, a écrit :
> Samuel Thibault, le Mon 20 Oct 2014 22:58:14 +0200, a écrit :
> > Yves-Alexis Perez, le Mon 20 Oct 2014 22:47:41 +0200, a écrit :
> > > On lun., 2014-10-20 at 22:42 +0200, Samuel Thibault wrote:
> > > > I forgot to answer this:
> > > >
> > > > Yves-Alexis Perez, le Mon 20 Oct 2014 22:34:22 +0200, a écrit :
> > > > > I guess that this is not about the user session but really
> > > > > about the greeter?
> > > >
> > > > Yes, in order to be able to login non-blindly.
> > >
> > > Ok. Then I think you need to ask upstream about that, because overriding
> > > the wrapper doesn't look like the best way to do it.
> >
> > On the long run, I agree, but for Jessie I guess it is too late for
> > getting the source code change in?
>
> Actually support was contributed upstream on
>
> https://bugs.launchpad.net/lightdm-gtk-greeter/+bug/1319848
>
> I'm having a look at backporting it to the Debian package.
Here is a backport of the upstream patch. It is then a matter of the
orca package to define reader= (and thus allowing to start the reader by
just pressing F4), and the d-i to define a11y-states=+reader.
Do you feel like uploading this change for Jessie, or we'd rather go the
wrapper way for Jessie?
Samuel
-------------- next part --------------
=== modified file 'data/lightdm-gtk-greeter.conf'
Index: data/lightdm-gtk-greeter.conf
===================================================================
--- data/lightdm-gtk-greeter.conf.orig
+++ data/lightdm-gtk-greeter.conf
@@ -10,7 +10,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.
# position = main window position: x y
# default-user-image = Image used as default user icon, path or #icon-name
# screensaver-timeout = Timeout (in seconds) until the screen blanks when the greeter is called as lockscreen
@@ -28,5 +30,6 @@ show-indicators=~language;~session;~powe
#show-clock=
#clock-format=
#keyboard=
+#reader=
#position=
#screensaver-timeout=
Index: src/lightdm-gtk-greeter.c
===================================================================
--- src/lightdm-gtk-greeter.c.orig
+++ src/lightdm-gtk-greeter.c
@@ -54,8 +54,10 @@
#include <src/lightdm-gtk-greeter-ui.h>
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;
@@ -67,7 +69,7 @@ static GtkWindow *panel_window;
static GtkWidget *clock_label;
static GtkWidget *menubar, *power_menuitem, *session_menuitem, *language_menuitem, *a11y_menuitem, *session_badge;
static GtkWidget *suspend_menuitem, *hibernate_menuitem, *restart_menuitem, *shutdown_menuitem;
-static GtkWidget *keyboard_menuitem;
+static GtkWidget *contrast_menuitem, *font_menuitem, *keyboard_menuitem, *reader_menuitem;
static GtkMenu *session_menu, *language_menu;
/* Login Window Widgets */
@@ -80,10 +82,52 @@ 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 CENTERED_WINDOW_POS = {.x = {50, +1, TRUE, 0}, .y = {50, +1, TRUE, 0}};
+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;
+
+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;
@@ -119,27 +163,203 @@ typedef struct
gchar *text;
} PAMConversationMessage;
-typedef struct
+GdkPixbuf* default_user_pixbuf = NULL;
+gchar* default_user_icon = "avatar-default";
+
+
+static void
+save_state_file (void)
{
- 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;
+ GError *error = NULL;
+ gsize data_length = 0;
+ gchar *data = g_key_file_to_data (state, &data_length, &error);
-typedef struct
+ 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)
{
- DimensionPosition x, y;
-} WindowPosition;
+ return menu_command_parse_extended (value, menu_item, NULL, NULL, NULL);
+}
-const WindowPosition CENTERED_WINDOW_POS = { .x = {50, +1, TRUE, 0}, .y = {50, +1, TRUE, 0} };
-WindowPosition main_window_pos;
+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;
-GdkPixbuf* default_user_pixbuf = NULL;
-gchar* default_user_icon = "avatar-default";
+ 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)
@@ -915,10 +1135,6 @@ background_window_expose (GtkWidget *
static void
start_authentication (const gchar *username)
{
- gchar *data;
- gsize data_length;
- GError *error = NULL;
-
cancelling = FALSE;
prompted = FALSE;
password_prompted = FALSE;
@@ -931,18 +1147,7 @@ start_authentication (const gchar *usern
}
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)
{
@@ -1025,9 +1230,6 @@ start_session (void)
{
gchar *language;
gchar *session;
- gchar *data;
- gsize data_length;
- GError *error = NULL;
language = get_language ();
if (language)
@@ -1038,19 +1240,7 @@ start_session (void)
/* Remember last choice */
g_key_file_set_value (state, "greeter", "last-session", session);
-
- 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))
{
@@ -1711,82 +1901,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
@@ -2180,7 +2314,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;
@@ -2203,11 +2338,8 @@ focus_upon_map (GdkXEvent *gxevent, GdkE
{
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)
@@ -2220,11 +2352,8 @@ focus_upon_map (GdkXEvent *gxevent, GdkE
{
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;
@@ -2239,7 +2368,7 @@ main (int argc, char **argv)
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)
GdkRGBA background_color;
GtkIconTheme *icon_theme;
@@ -2415,15 +2544,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,
@@ -2453,8 +2574,6 @@ main (int argc, char **argv)
gtk_style_context_add_provider (GTK_STYLE_CONTEXT(gtk_widget_get_style_context(GTK_WIDGET(menubar))), GTK_STYLE_PROVIDER (css_provider), 800);
#endif
- keyboard_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "keyboard_menuitem"));
-
/* Login window */
login_window = GTK_WINDOW (gtk_builder_get_object (builder, "login_window"));
user_image = GTK_IMAGE (gtk_builder_get_object (builder, "user_image"));
@@ -2508,11 +2627,17 @@ main (int argc, char **argv)
session_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "session_menuitem"));
language_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "language_menuitem"));
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"));
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
@@ -2630,6 +2755,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))
{
@@ -2745,22 +2884,44 @@ main (int argc, char **argv)
gtk_widget_show (GTK_WIDGET (login_window));
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);
gdk_threads_add_timeout (1000, (GSourceFunc) clock_timeout_thread, NULL);
/* focus fix (source: unity-greeter) */
Index: src/lightdm-gtk-greeter.glade
===================================================================
--- src/lightdm-gtk-greeter.glade.orig
+++ src/lightdm-gtk-greeter.glade
@@ -136,6 +136,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>
Index: src/lightdm-gtk-greeter-ui.h
===================================================================
--- src/lightdm-gtk-greeter-ui.h.orig
+++ src/lightdm-gtk-greeter-ui.h
@@ -80,118 +80,124 @@ static const char lightdm_gtk_greeter_ui
"ty><property name=\"label\" translatable=\"yes\">On Screen Keyboard</pr"
"operty><property name=\"use_underline\">True</property><signal name=\"t"
"oggled\" handler=\"a11y_keyboard_cb\" swapped=\"no\"/></object></child>"
- "</object></child></object></child><child><object class=\"GtkMenuItem\" "
- "id=\"language_menuitem\"><property name=\"visible\">True</property><pro"
- "perty name=\"can_focus\">True</property><property name=\"label\">[langu"
- "age_code]</property><child type=\"submenu\"><object class=\"GtkMenu\" i"
- "d=\"language_menu\"><property name=\"visible\">True</property><property"
- " name=\"can_focus\">False</property></object></child></object></child><"
- "child><object class=\"GtkMenuItem\" id=\"session_menuitem\"><property n"
- "ame=\"visible\">True</property><property name=\"can_focus\">True</prope"
- "rty><child type=\"submenu\"><object class=\"GtkMenu\" id=\"session_menu"
- "\"><property name=\"visible\">True</property><property name=\"can_focus"
- "\">False</property></object></child></object></child></object><packing>"
- "<property name=\"expand\">False</property><property name=\"fill\">True<"
- "/property><property name=\"pack_type\">end</property><property name=\"p"
- "osition\">2</property></packing></child></object></child></object><obje"
- "ct class=\"GtkListStore\" id=\"user_liststore\"><columns><column type=\""
- "gchararray\"/><column type=\"gchararray\"/><column type=\"gint\"/></col"
- "umns></object><object class=\"GtkWindow\" id=\"login_window\"><property"
- " name=\"name\">login_window</property><property name=\"can_focus\">Fals"
- "e</property><property name=\"resizable\">False</property><property name"
- "=\"decorated\">False</property><accel-groups><group name=\"a11y_accelgr"
- "oup\"/><group name=\"power_accelgroup\"/></accel-groups><signal name=\""
- "key-press-event\" handler=\"login_window_key_press_cb\" swapped=\"no\"/"
- "><child><object class=\"GtkVBox\" id=\"vbox2\"><property name=\"visible"
- "\">True</property><property name=\"can_focus\">False</property><child><"
- "object class=\"GtkFrame\" id=\"content_frame\"><property name=\"name\">"
- "content_frame</property><property name=\"visible\">True</property><prop"
- "erty name=\"can_focus\">False</property><property name=\"label_xalign\""
- ">0</property><property name=\"shadow_type\">none</property><child><obje"
- "ct class=\"GtkTable\" id=\"table1\"><property name=\"visible\">True</pr"
- "operty><property name=\"can_focus\">False</property><property name=\"ma"
- "rgin_left\">24</property><property name=\"margin_right\">24</property><"
- "property name=\"margin_top\">24</property><property name=\"n_rows\">3</"
- "property><property name=\"n_columns\">2</property><property name=\"colu"
- "mn_spacing\">18</property><property name=\"row_spacing\">6</property><c"
- "hild><object class=\"GtkComboBox\" id=\"user_combobox\"><property name="
- "\"name\">user_combobox</property><property name=\"width_request\">200</"
- "property><property name=\"can_focus\">False</property><property name=\""
- "model\">user_liststore</property><signal name=\"changed\" handler=\"use"
- "r_combobox_active_changed_cb\" swapped=\"no\"/></object><packing><prope"
- "rty name=\"left_attach\">1</property><property name=\"right_attach\">2<"
- "/property><property name=\"y_options\"/></packing></child><child><objec"
- "t class=\"GtkEntry\" id=\"password_entry\"><property name=\"name\">prom"
- "pt_entry</property><property name=\"width_request\">200</property><prop"
- "erty name=\"visible\">True</property><property name=\"can_focus\">True<"
- "/property><property name=\"visibility\">False</property><property name="
- "\"invisible_char\">\342\200\242</property><property name=\"primary_icon"
- "_activatable\">False</property><property name=\"secondary_icon_activata"
- "ble\">False</property><signal name=\"activate\" handler=\"login_cb\" sw"
- "apped=\"no\"/><signal name=\"key-press-event\" handler=\"password_key_p"
- "ress_cb\" swapped=\"no\"/></object><packing><property name=\"left_attac"
- "h\">1</property><property name=\"right_attach\">2</property><property n"
- "ame=\"top_attach\">2</property><property name=\"bottom_attach\">3</prop"
- "erty><property name=\"y_options\"/></packing></child><child><object cla"
- "ss=\"GtkEntry\" id=\"username_entry\"><property name=\"name\">prompt_en"
- "try</property><property name=\"can_focus\">True</property><property nam"
- "e=\"no_show_all\">True</property><property name=\"invisible_char\">\342"
- "\200\242</property><signal name=\"focus-out-event\" handler=\"username_"
- "focus_out_cb\" swapped=\"no\"/><signal name=\"key-press-event\" handler"
- "=\"username_key_press_cb\" swapped=\"no\"/></object><packing><property "
- "name=\"left_attach\">1</property><property name=\"right_attach\">2</pro"
- "perty><property name=\"top_attach\">1</property><property name=\"bottom"
- "_attach\">2</property></packing></child><child><object class=\"GtkFrame"
- "\" id=\"user_image_border\"><property name=\"name\">user_image_border</"
- "property><property name=\"visible\">True</property><property name=\"can"
- "_focus\">False</property><property name=\"label_xalign\">0</property><p"
- "roperty name=\"shadow_type\">none</property><child><object class=\"GtkI"
- "mage\" id=\"user_image\"><property name=\"name\">user_image</property><"
- "property name=\"visible\">True</property><property name=\"can_focus\">F"
- "alse</property><property name=\"pixel_size\">80</property><property nam"
- "e=\"icon_name\">avatar-default</property></object></child></object><pac"
- "king><property name=\"bottom_attach\">3</property><property name=\"x_op"
- "tions\"/><property name=\"y_options\"/></packing></child></object></chi"
- "ld><child type=\"label_item\"><placeholder/></child></object><packing><"
- "property name=\"expand\">True</property><property name=\"fill\">True</p"
- "roperty><property name=\"position\">0</property></packing></child><chil"
- "d><object class=\"GtkAlignment\" id=\"infobar_compat\"><property name=\""
- "visible\">True</property><property name=\"can_focus\">False</property><"
- "child><object class=\"GtkLabel\" id=\"message_label\"><property name=\""
+ "<child><object class=\"GtkCheckMenuItem\" id=\"reader_menuitem\"><prope"
+ "rty name=\"use_action_appearance\">False</property><property name=\"vis"
+ "ible\">True</property><property name=\"can_focus\">False</property><pro"
+ "perty 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></child><child><object class=\"GtkMenuItem\" id=\"language_menui"
+ "tem\"><property name=\"visible\">True</property><property name=\"can_fo"
+ "cus\">True</property><property name=\"label\">[language_code]</property"
+ "><child type=\"submenu\"><object class=\"GtkMenu\" id=\"language_menu\""
+ "><property name=\"visible\">True</property><property name=\"can_focus\""
+ ">False</property></object></child></object></child><child><object class"
+ "=\"GtkMenuItem\" id=\"session_menuitem\"><property name=\"visible\">Tru"
+ "e</property><property name=\"can_focus\">True</property><child type=\"s"
+ "ubmenu\"><object class=\"GtkMenu\" id=\"session_menu\"><property name=\""
"visible\">True</property><property name=\"can_focus\">False</property><"
- "property name=\"label\" comments=\"This is a placeholder string and wil"
- "l be replaced with a message from PAM\">[message]</property></object></"
- "child></object><packing><property name=\"expand\">True</property><prope"
- "rty name=\"fill\">True</property><property name=\"position\">1</propert"
- "y></packing></child><child><object class=\"GtkFrame\" id=\"buttonbox_fr"
- "ame\"><property name=\"name\">buttonbox_frame</property><property name="
- "\"visible\">True</property><property name=\"can_focus\">False</property"
- "><property name=\"label_xalign\">0</property><property name=\"shadow_ty"
- "pe\">none</property><child><object class=\"GtkHBox\" id=\"hbox2\"><prop"
- "erty name=\"visible\">True</property><property name=\"can_focus\">False"
- "</property><property name=\"margin_left\">24</property><property name=\""
- "margin_right\">24</property><property name=\"margin_bottom\">24</proper"
- "ty><child><object class=\"GtkButton\" id=\"login_button\"><property nam"
- "e=\"label\" translatable=\"yes\">Log In</property><property name=\"name"
- "\">login_button</property><property name=\"visible\">True</property><pr"
- "operty name=\"can_focus\">True</property><property name=\"receives_defa"
- "ult\">True</property><signal name=\"clicked\" handler=\"login_cb\" swap"
- "ped=\"no\"/></object><packing><property name=\"expand\">False</property"
- "><property name=\"fill\">True</property><property name=\"pack_type\">en"
- "d</property><property name=\"position\">0</property></packing></child><"
- "child><object class=\"GtkButton\" id=\"cancel_button\"><property name=\""
- "label\" translatable=\"yes\">Cancel</property><property name=\"name\">c"
- "ancel_button</property><property name=\"visible\">True</property><prope"
- "rty name=\"can_focus\">True</property><property name=\"receives_default"
- "\">True</property><signal name=\"clicked\" handler=\"cancel_cb\" swappe"
- "d=\"no\"/></object><packing><property name=\"expand\">False</property><"
- "property name=\"fill\">True</property><property name=\"position\">1</pr"
- "operty></packing></child></object></child><child type=\"label_item\"><p"
- "laceholder/></child></object><packing><property name=\"expand\">True</p"
- "roperty><property name=\"fill\">True</property><property name=\"positio"
- "n\">2</property></packing></child></object></child></object></interface"
- ">"
+ "/object></child></object></child></object><packing><property name=\"exp"
+ "and\">False</property><property name=\"fill\">True</property><property "
+ "name=\"pack_type\">end</property><property name=\"position\">2</propert"
+ "y></packing></child></object></child></object><object class=\"GtkListSt"
+ "ore\" id=\"user_liststore\"><columns><column type=\"gchararray\"/><colu"
+ "mn type=\"gchararray\"/><column type=\"gint\"/></columns></object><obje"
+ "ct class=\"GtkWindow\" id=\"login_window\"><property name=\"name\">logi"
+ "n_window</property><property name=\"can_focus\">False</property><proper"
+ "ty name=\"resizable\">False</property><property name=\"decorated\">Fals"
+ "e</property><accel-groups><group name=\"a11y_accelgroup\"/><group name="
+ "\"power_accelgroup\"/></accel-groups><signal name=\"key-press-event\" h"
+ "andler=\"login_window_key_press_cb\" swapped=\"no\"/><child><object cla"
+ "ss=\"GtkVBox\" id=\"vbox2\"><property name=\"visible\">True</property><"
+ "property name=\"can_focus\">False</property><child><object class=\"GtkF"
+ "rame\" id=\"content_frame\"><property name=\"name\">content_frame</prop"
+ "erty><property name=\"visible\">True</property><property name=\"can_foc"
+ "us\">False</property><property name=\"label_xalign\">0</property><prope"
+ "rty name=\"shadow_type\">none</property><child><object class=\"GtkTable"
+ "\" id=\"table1\"><property name=\"visible\">True</property><property na"
+ "me=\"can_focus\">False</property><property name=\"margin_left\">24</pro"
+ "perty><property name=\"margin_right\">24</property><property name=\"mar"
+ "gin_top\">24</property><property name=\"n_rows\">3</property><property "
+ "name=\"n_columns\">2</property><property name=\"column_spacing\">18</pr"
+ "operty><property name=\"row_spacing\">6</property><child><object class="
+ "\"GtkComboBox\" id=\"user_combobox\"><property name=\"name\">user_combo"
+ "box</property><property name=\"width_request\">200</property><property "
+ "name=\"can_focus\">False</property><property name=\"model\">user_listst"
+ "ore</property><signal name=\"changed\" handler=\"user_combobox_active_c"
+ "hanged_cb\" swapped=\"no\"/></object><packing><property name=\"left_att"
+ "ach\">1</property><property name=\"right_attach\">2</property><property"
+ " name=\"y_options\"/></packing></child><child><object class=\"GtkEntry\""
+ " id=\"password_entry\"><property name=\"name\">prompt_entry</property><"
+ "property name=\"width_request\">200</property><property name=\"visible\""
+ ">True</property><property name=\"can_focus\">True</property><property n"
+ "ame=\"visibility\">False</property><property name=\"invisible_char\">\342"
+ "\200\242</property><property name=\"primary_icon_activatable\">False</p"
+ "roperty><property name=\"secondary_icon_activatable\">False</property><"
+ "signal name=\"activate\" handler=\"login_cb\" swapped=\"no\"/><signal n"
+ "ame=\"key-press-event\" handler=\"password_key_press_cb\" swapped=\"no\""
+ "/></object><packing><property name=\"left_attach\">1</property><propert"
+ "y name=\"right_attach\">2</property><property name=\"top_attach\">2</pr"
+ "operty><property name=\"bottom_attach\">3</property><property name=\"y_"
+ "options\"/></packing></child><child><object class=\"GtkEntry\" id=\"use"
+ "rname_entry\"><property name=\"name\">prompt_entry</property><property "
+ "name=\"can_focus\">True</property><property name=\"no_show_all\">True</"
+ "property><property name=\"invisible_char\">\342\200\242</property><sign"
+ "al name=\"focus-out-event\" handler=\"username_focus_out_cb\" swapped=\""
+ "no\"/><signal name=\"key-press-event\" handler=\"username_key_press_cb\""
+ " swapped=\"no\"/></object><packing><property name=\"left_attach\">1</pr"
+ "operty><property name=\"right_attach\">2</property><property name=\"top"
+ "_attach\">1</property><property name=\"bottom_attach\">2</property></pa"
+ "cking></child><child><object class=\"GtkFrame\" id=\"user_image_border\""
+ "><property name=\"name\">user_image_border</property><property name=\"v"
+ "isible\">True</property><property name=\"can_focus\">False</property><p"
+ "roperty name=\"label_xalign\">0</property><property name=\"shadow_type\""
+ ">none</property><child><object class=\"GtkImage\" id=\"user_image\"><pr"
+ "operty name=\"name\">user_image</property><property name=\"visible\">Tr"
+ "ue</property><property name=\"can_focus\">False</property><property nam"
+ "e=\"pixel_size\">80</property><property name=\"icon_name\">avatar-defau"
+ "lt</property></object></child></object><packing><property name=\"bottom"
+ "_attach\">3</property><property name=\"x_options\"/><property name=\"y_"
+ "options\"/></packing></child></object></child><child type=\"label_item\""
+ "><placeholder/></child></object><packing><property name=\"expand\">True"
+ "</property><property name=\"fill\">True</property><property name=\"posi"
+ "tion\">0</property></packing></child><child><object class=\"GtkAlignmen"
+ "t\" id=\"infobar_compat\"><property name=\"visible\">True</property><pr"
+ "operty name=\"can_focus\">False</property><child><object class=\"GtkLab"
+ "el\" id=\"message_label\"><property name=\"visible\">True</property><pr"
+ "operty name=\"can_focus\">False</property><property name=\"label\" comm"
+ "ents=\"This is a placeholder string and will be replaced with a message"
+ " from PAM\">[message]</property></object></child></object><packing><pro"
+ "perty name=\"expand\">True</property><property name=\"fill\">True</prop"
+ "erty><property name=\"position\">1</property></packing></child><child><"
+ "object class=\"GtkFrame\" id=\"buttonbox_frame\"><property name=\"name\""
+ ">buttonbox_frame</property><property name=\"visible\">True</property><p"
+ "roperty name=\"can_focus\">False</property><property name=\"label_xalig"
+ "n\">0</property><property name=\"shadow_type\">none</property><child><o"
+ "bject class=\"GtkHBox\" id=\"hbox2\"><property name=\"visible\">True</p"
+ "roperty><property name=\"can_focus\">False</property><property name=\"m"
+ "argin_left\">24</property><property name=\"margin_right\">24</property>"
+ "<property name=\"margin_bottom\">24</property><child><object class=\"Gt"
+ "kButton\" id=\"login_button\"><property name=\"label\" translatable=\"y"
+ "es\">Log In</property><property name=\"name\">login_button</property><p"
+ "roperty name=\"visible\">True</property><property name=\"can_focus\">Tr"
+ "ue</property><property name=\"receives_default\">True</property><signal"
+ " name=\"clicked\" handler=\"login_cb\" swapped=\"no\"/></object><packin"
+ "g><property name=\"expand\">False</property><property name=\"fill\">Tru"
+ "e</property><property name=\"pack_type\">end</property><property name=\""
+ "position\">0</property></packing></child><child><object class=\"GtkButt"
+ "on\" id=\"cancel_button\"><property name=\"label\" translatable=\"yes\""
+ ">Cancel</property><property name=\"name\">cancel_button</property><prop"
+ "erty name=\"visible\">True</property><property name=\"can_focus\">True<"
+ "/property><property name=\"receives_default\">True</property><signal na"
+ "me=\"clicked\" handler=\"cancel_cb\" swapped=\"no\"/></object><packing>"
+ "<property name=\"expand\">False</property><property name=\"fill\">True<"
+ "/property><property name=\"position\">1</property></packing></child></o"
+ "bject></child><child type=\"label_item\"><placeholder/></child></object"
+ "><packing><property name=\"expand\">True</property><property name=\"fil"
+ "l\">True</property><property name=\"position\">2</property></packing></"
+ "child></object></child></object></interface>"
};
-static const unsigned lightdm_gtk_greeter_ui_length = 12254u;
+static const unsigned lightdm_gtk_greeter_ui_length = 12708u;
More information about the Pkg-xfce-devel
mailing list