============================================================ Rename pipefds to daemon_pipe_fds This fits the naming style of the surrounding code better. Also, we're going to need another pipe, so better to use a specific name here. diff --git a/gnome-settings-daemon/main.c b/gnome-settings-daemon/main.c --- a/gnome-settings-daemon/main.c +++ b/gnome-settings-daemon/main.c @@ -47,7 +47,7 @@ static char *gconf_prefix = NULL; static gboolean no_daemon = FALSE; static gboolean debug = FALSE; -static int pipefds[2]; +static int daemon_pipe_fds[2]; static GOptionEntry entries[] = { {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL }, @@ -247,7 +247,7 @@ daemon_start (void) gnome_settings_profile_msg ("forking daemon"); signal (SIGPIPE, SIG_IGN); - if (-1 == pipe (pipefds)) { + if (-1 == pipe (daemon_pipe_fds)) { g_error ("Could not create pipe: %s", g_strerror (errno)); exit (EXIT_FAILURE); } @@ -262,17 +262,17 @@ daemon_start (void) case 0: /* child */ - close (pipefds[0]); + close (daemon_pipe_fds[0]); return; default: /* parent */ - close (pipefds[1]); + close (daemon_pipe_fds[1]); /* Wait for child to signal that we are good to go. */ - read (pipefds[0], buf, 1); + read (daemon_pipe_fds[0], buf, 1); exit (EXIT_SUCCESS); } @@ -305,8 +305,8 @@ daemon_terminate_parent (void) gnome_settings_profile_msg ("terminating parent"); - write (pipefds[1], "1", 1); - close (pipefds[1]); + write (daemon_pipe_fds[1], "1", 1); + close (daemon_pipe_fds[1]); } static void ============================================================ Listen for SIGTERM and shut down properly diff --git a/gnome-settings-daemon/main.c b/gnome-settings-daemon/main.c --- a/gnome-settings-daemon/main.c +++ b/gnome-settings-daemon/main.c @@ -48,6 +48,7 @@ static char *gconf_prefix = NULL; static gboolean no_daemon = FALSE; static gboolean debug = FALSE; static int daemon_pipe_fds[2]; +static int term_signal_pipe_fds[2]; static GOptionEntry entries[] = { {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, N_("Enable debugging code"), NULL }, @@ -177,6 +178,54 @@ on_session_over (DBusGProxy *proxy, GnomeSettingsManager *manager) } static void +on_term_signal (int signal) +{ + /* Wake up main loop to tell it to shutdown */ + close (term_signal_pipe_fds[1]); + term_signal_pipe_fds[1] = -1; +} + +static gboolean +on_term_signal_pipe_closed (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + GnomeSettingsManager *manager; + + manager = GNOME_SETTINGS_MANAGER (data); + + term_signal_pipe_fds[0] = -1; + + /* Got SIGTERM, time to clean up and get out + */ + gtk_main_quit (); + + return FALSE; +} + +static void +watch_for_term_signal (GnomeSettingsManager *manager) +{ + GIOChannel *channel; + + if (-1 == pipe (term_signal_pipe_fds) || + -1 == fcntl (term_signal_pipe_fds[0], F_SETFD, FD_CLOEXEC) || + -1 == fcntl (term_signal_pipe_fds[1], F_SETFD, FD_CLOEXEC)) { + g_error ("Could not create pipe: %s", g_strerror (errno)); + exit (EXIT_FAILURE); + } + + channel = g_io_channel_unix_new (term_signal_pipe_fds[0]); + g_io_channel_set_encoding (channel, NULL, NULL); + g_io_channel_set_buffered (channel, FALSE); + g_io_add_watch (channel, G_IO_HUP, on_term_signal_pipe_closed, manager); + g_io_channel_unref (channel); + + signal (SIGTERM, on_term_signal); + +} + +static void set_session_over_handler (DBusGConnection *bus, GnomeSettingsManager *manager) { DBusGProxy *session_proxy; @@ -206,6 +255,7 @@ set_session_over_handler (DBusGConnection *bus, GnomeSettingsManager *manager) manager, NULL); + watch_for_term_signal (manager); gnome_settings_profile_end (NULL); } ============================================================ Restore AccessX bits to original values on exit diff --git a/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c --- a/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c +++ b/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c @@ -63,6 +63,7 @@ struct GsdA11yKeyboardManagerPrivate GtkWidget *slowkeys_alert; GtkWidget *preferences_dialog; GtkStatusIcon *status_icon; + XkbDescRec *original_xkb_desc; guint gconf_notify; @@ -1012,6 +1013,10 @@ start_a11y_keyboard_idle_cb (GsdA11yKeyboardManager *manager) (GConfClientNotifyFunc) keyboard_callback, &manager->priv->gconf_notify); + /* Save current xkb state so we can restore it on exit + */ + manager->priv->original_xkb_desc = get_xkb_desc_rec (manager); + event_mask = XkbControlsNotifyMask; #ifdef DEBUG_ACCESSIBILITY event_mask |= XkbAccessXNotifyMask; /* make default when AXN_AXKWarning works */ @@ -1052,6 +1057,31 @@ gsd_a11y_keyboard_manager_start (GsdA11yKeyboardManager *manager, return TRUE; } +static void +restore_server_xkb_config (GsdA11yKeyboardManager *manager) +{ + gdk_error_trap_push (); + XkbSetControls (GDK_DISPLAY (), + XkbSlowKeysMask | + XkbBounceKeysMask | + XkbStickyKeysMask | + XkbMouseKeysMask | + XkbMouseKeysAccelMask | + XkbAccessXKeysMask | + XkbAccessXTimeoutMask | + XkbAccessXFeedbackMask | + XkbControlsEnabledMask, + manager->priv->original_xkb_desc); + + XkbFreeKeyboard (manager->priv->original_xkb_desc, + XkbAllComponentsMask, True); + + XSync (GDK_DISPLAY (), FALSE); + gdk_error_trap_pop (); + + manager->priv->original_xkb_desc = NULL; +} + void gsd_a11y_keyboard_manager_stop (GsdA11yKeyboardManager *manager) { @@ -1074,6 +1104,10 @@ gsd_a11y_keyboard_manager_stop (GsdA11yKeyboardManager *manager) (GdkFilterFunc) cb_xkb_event_filter, manager); + /* Disable all the AccessX bits + */ + restore_server_xkb_config (manager); + if (p->slowkeys_alert != NULL) gtk_widget_destroy (p->slowkeys_alert);