Blame SOURCES/ibus-1686913-prctl.patch

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