============================================================ Listen for SIGTERM and shut down properly diff -up gnome-settings-daemon-2.22.2.1/gnome-settings-daemon/main.c.shutdown-cleanly gnome-settings-daemon-2.22.2.1/gnome-settings-daemon/main.c --- gnome-settings-daemon-2.22.2.1/gnome-settings-daemon/main.c.shutdown-cleanly 1974-03-20 21:48:41.000000000 -0400 +++ gnome-settings-daemon-2.22.2.1/gnome-settings-daemon/main.c 2008-12-09 16:10:14.000000000 -0500 @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include #include @@ -41,6 +41,7 @@ static char *gconf_prefix = NULL; static gboolean no_daemon = TRUE; static gboolean debug = FALSE; +static int term_signal_pipe_fds[2]; static GOptionEntry entries[] = { {"debug", 0, 0, G_OPTION_ARG_NONE, &debug, "Enable debugging code", NULL }, @@ -189,6 +190,55 @@ gsd_log_default_handler (const gchar * unused_data); } +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); + +} + + int main (int argc, char *argv[]) { @@ -266,6 +316,8 @@ main (int argc, char *argv[]) } } + watch_for_term_signal (manager); + gtk_main (); g_free (gconf_prefix); ============================================================ Restore AccessX bits to original values on exit diff -up gnome-settings-daemon-2.22.2.1/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c.shutdown-cleanly gnome-settings-daemon-2.22.2.1/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c --- gnome-settings-daemon-2.22.2.1/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c.shutdown-cleanly 1974-03-20 21:48:40.000000000 -0400 +++ gnome-settings-daemon-2.22.2.1/plugins/a11y-keyboard/gsd-a11y-keyboard-manager.c 2008-12-09 16:14:52.000000000 -0500 @@ -57,6 +57,7 @@ struct GsdA11yKeyboardManagerPrivate gboolean slowkeys_shortcut_val; GtkWidget *stickykeys_alert; GtkWidget *slowkeys_alert; + XkbDescRec *original_xkb_desc; }; #define GSD_KBD_A11Y_ERROR gsd_kbd_a11y_error_quark () @@ -742,6 +743,10 @@ gsd_a11y_keyboard_manager_start (GsdA11y CONFIG_ROOT, (GConfClientNotifyFunc)keyboard_callback); + /* 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 */ @@ -777,10 +782,39 @@ gsd_a11y_keyboard_manager_start (GsdA11y return ret; } +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) { g_debug ("Stopping a11y_keyboard manager"); + + /* Disable all the AccessX bits + */ + restore_server_xkb_config (manager); } static void ============================================================ Shutdown properly when bus goes away Previously we were just letting libdbus call exit(1) for us which bypasses the clean up paths. 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 @@ -114,6 +114,21 @@ acquire_name_on_proxy (DBusGProxy *bus_proxy) return ret; } +static DBusHandlerResult +bus_message_handler (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + if (dbus_message_is_signal (message, + DBUS_INTERFACE_LOCAL, + "Disconnected")) { + gtk_main_quit (); + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + static DBusGConnection * get_session_bus (void) { @@ -131,7 +146,12 @@ get_session_bus (void) } connection = dbus_g_connection_get_connection (bus); - dbus_connection_set_exit_on_disconnect (connection, TRUE); + dbus_connection_add_filter (connection, + (DBusHandleMessageFunction) + bus_message_handler, + NULL, NULL); + + dbus_connection_set_exit_on_disconnect (connection, FALSE); out: return bus;