From 32572618cdcc36162b5769eb4c71964db9734061 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Tue, 6 Aug 2019 18:55:14 +0900 Subject: [PATCH] bus: Exit ibus-daemon with parent's death ibus-daemon can be restarted unexpectedly during logging out the session and double ibus-x11 prevent from enabling XIM in XGetSelectionOwner() for the "ibus" atom. ibus-daemon always will exit the process when the parent process dies to avoid this problem. --- bus/main.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 3 +++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/bus/main.c b/bus/main.c index 3223d541..e11a5ebd 100644 --- a/bus/main.c +++ b/bus/main.c @@ -32,6 +32,10 @@ #include #include +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + #include "global.h" #include "ibusimpl.h" #include "server.h" @@ -164,6 +168,15 @@ _sig_usr2_handler (int sig) g_mem_profile (); } +#ifdef HAVE_SYS_PRCTL_H +static void +_sig_usr1_handler (int sig) +{ + g_warning ("The parent process died."); + bus_server_quit (FALSE); +} +#endif + gint main (gint argc, gchar **argv) { @@ -204,7 +217,7 @@ main (gint argc, gchar **argv) /* daemonize process */ if (daemonize) { if (daemon (1, 0) != 0) { - g_printerr ("Can not daemonize ibus.\n"); + g_printerr ("Cannot daemonize ibus.\n"); exit (-1); } } @@ -276,6 +289,47 @@ main (gint argc, gchar **argv) exit (-1); } + if (!daemonize) { + if (getppid () == 1) { + g_warning ("The parent process died."); + exit (0); + } +#ifdef HAVE_SYS_PRCTL_H + /* Currently ibus-x11 detects XIOError and assume the error as the + * desktop session is closed and ibus-x11 calls Exit D-Bus method to + * exit ibus-daemon. But a few desktop sessions cause XError before + * XIOError and GTK does not allow to bind XError by applications and + * GTK calls gdk_x_error() with XError. + * + * E.g. GdkX11Screen calls XGetSelectionOwner() for "_XSETTINGS_S?" + * atoms during the logout but the selection owner already becomes + * NULL and the NULL window causes XError with + * gdk_x11_window_foreign_new_for_display(). + * + * Since ibus-x11 exits with XError before XIOError, gnome-shell + * can detects the exit of ibus-daemon a little earlier and + * gnome-shell restarts ibus-daemon but gnome-shell dies soon. + * Then gnome-shell dies but ibus-daemon is alive, it's a problem. + * Because it causes double ibus-x11 of GDM and a login user + * and double XSetSelectionOwner() is not allowed for the unique + * "ibus" atom and the user cannot use XIM but not GtkIMModule. + * + * Probably we could fix the ibus process problem if we would fix + * XError about the X selection owner or stop to restart ibus-daemon + * in gonme-shell when the session is logging out. + * Maybe using SessionManager.LogoutRemote() or + * global.screen.get_display().get_xdisplay() + * But I assume thereare other scenarios to causes the problem. + * + * And I decided ibus-daemon always exits with the parent's death here + * to avoid unexpected ibus restarts during the logout. + */ + if (prctl (PR_SET_PDEATHSIG, SIGUSR1)) + g_printerr ("Cannot bind SIGUSR1 for parent death\n"); + else + signal (SIGUSR1, _sig_usr1_handler); +#endif + } bus_server_run (); return 0; } diff --git a/configure.ac b/configure.ac index f1df3ac1..fdd316a9 100644 --- a/configure.ac +++ b/configure.ac @@ -140,6 +140,9 @@ AC_HEADER_STDC LT_INIT IT_PROG_INTLTOOL([0.35.0]) +# Check header filess. +AC_CHECK_HEADERS([sys/prctl.h]) + # Check functions. AC_CHECK_FUNCS(daemon)