diff -Naur ibus-1.5.25/src/ibusshare.c ibus-1.5.25.new/src/ibusshare.c --- ibus-1.5.25/src/ibusshare.c 2021-08-20 02:48:40.000000000 +0200 +++ ibus-1.5.25.new/src/ibusshare.c 2021-09-08 19:41:27.233077477 +0200 @@ -90,79 +90,132 @@ return g_getenv("IBUS_SESSION_ID"); } +static const gchar *ibus_get_socket_path_internal (gboolean compat, gchar *client_display); + const gchar * ibus_get_socket_path (void) { static gchar *path = NULL; if (path == NULL) { - gchar *hostname = "unix"; - gchar *display; - gchar *displaynumber = "0"; - /* gchar *screennumber = "0"; */ - gboolean is_wayland = FALSE; - gchar *p; - - path = g_strdup (g_getenv ("IBUS_ADDRESS_FILE")); - if (path != NULL) { - return path; + path = ibus_get_socket_path_internal (FALSE, NULL); + } + return path; +} + +static const gchar * +ibus_get_socket_path_x11_compat (void) +{ + static gchar *path = NULL; + if (path == NULL) + path = ibus_get_socket_path_internal (TRUE, NULL); + return path; +} + +static const gchar * +ibus_get_socket_path_gnome_xwayland_compat (void) +{ + static gchar *path = NULL; + if (path == NULL) { + gint setup_display_number; + gchar *client_display; + gchar **tokens; + + tokens = g_strsplit (ibus_get_socket_path_x11_compat (), "-", 3); + if (tokens[0] != NULL && tokens[1] != NULL && tokens[2] != NULL) { + setup_display_number = g_strtod(tokens[2], NULL); + if (setup_display_number > 0) { + client_display = g_strdup_printf (":%d", setup_display_number - 1); + path = ibus_get_socket_path_internal (TRUE, client_display); + } } - if (_display == NULL) { + g_strfreev (tokens); + } + return path; +} + +static const gchar * +ibus_get_socket_path_internal (gboolean compat, gchar *client_display) +{ + gchar *path = NULL; + + gchar *hostname = "unix"; + gchar *display; + gchar *displaynumber = "0"; + /* gchar *screennumber = "0"; */ + gboolean is_wayland = FALSE; + gchar *p; + + path = g_strdup (g_getenv ("IBUS_ADDRESS_FILE")); + if (path != NULL) { + return path; + } + + if (_display == NULL) { + if (compat) { + if (client_display == NULL) + display = g_strdup (g_getenv ("DISPLAY")); + else + display = client_display; + } else { display = g_strdup (g_getenv ("WAYLAND_DISPLAY")); if (display) is_wayland = TRUE; - else + else if (client_display == NULL) display = g_strdup (g_getenv ("DISPLAY")); + else + display = client_display; } - else { - display = g_strdup (_display); - } - - if (is_wayland) { - displaynumber = display; - } else if (display) { - p = display; - hostname = display; - for (; *p != ':' && *p != '\0'; p++); + } + else { + display = g_strdup (_display); + } - if (*p == ':') { - *p = '\0'; - p++; - displaynumber = p; - } + if (is_wayland) { + displaynumber = display; + } else if (display) { + p = display; + hostname = display; + for (; *p != ':' && *p != '\0'; p++); + + if (*p == ':') { + *p = '\0'; + p++; + displaynumber = p; + } - for (; *p != '.' && *p != '\0'; p++); + for (; *p != '.' && *p != '\0'; p++); - if (*p == '.') { - *p = '\0'; - p++; - /* Do not use screennumber - screennumber = p; */ - } + if (*p == '.') { + *p = '\0'; + p++; + /* Do not use screennumber + screennumber = p; */ } + } - if (hostname[0] == '\0') - hostname = "unix"; + if (hostname[0] == '\0') + hostname = "unix"; + + p = g_strdup_printf ("%s-%s-%s", + ibus_get_local_machine_id (), + hostname, + displaynumber); + /* Qt5 IBus module has a hard-coded path and we cannot change this + * for the back compatibility. + * XDG_RUNTIME_DIR is not useful because it's generated by + * login but not `su` command and ibus-daemon can be run with `su` + * and we may change the path to XDG_CACHE_HOME in the future. + */ + path = g_build_filename (g_get_user_config_dir (), + "ibus", + "bus", + p, + NULL); + g_free (p); + g_free (display); - p = g_strdup_printf ("%s-%s-%s", - ibus_get_local_machine_id (), - hostname, - displaynumber); - /* Qt5 IBus module has a hard-coded path and we cannot change this - * for the back compatibility. - * XDG_RUNTIME_DIR is not useful because it's generated by - * login but not `su` command and ibus-daemon can be run with `su` - * and we may change the path to XDG_CACHE_HOME in the future. - */ - path = g_build_filename (g_get_user_config_dir (), - "ibus", - "bus", - p, - NULL); - g_free (p); - g_free (display); - } return path; } @@ -243,14 +296,42 @@ return address; } +static void ibus_write_address_internal (const gchar *address, const gchar *socket_path); + void ibus_write_address (const gchar *address) { + + + const gchar *socket_path; + const gchar *socket_path_compat; + + socket_path = ibus_get_socket_path (); + ibus_write_address_internal (address, socket_path); + + if (g_getenv ("WAYLAND_DISPLAY") != NULL) { + socket_path_compat = ibus_get_socket_path_x11_compat (); + ibus_write_address_internal (address, socket_path_compat); + + if (g_getenv ("GNOME_SETUP_DISPLAY") != NULL && + strcmp (g_getenv ("GNOME_SETUP_DISPLAY"), g_getenv ("DISPLAY")) == 0) { + /* Running from gnome-shell with the setup display; write the socket ++ * address to an additional path for X11 clients */ + socket_path_compat = ibus_get_socket_path_gnome_xwayland_compat (); + if (socket_path_compat != NULL) + ibus_write_address_internal (address, socket_path_compat); + } + } +} + +static void +ibus_write_address_internal (const gchar *address, const gchar *socket_path) +{ FILE *pf; gchar *path; g_return_if_fail (address != NULL); - path = g_path_get_dirname (ibus_get_socket_path ()); + path = g_path_get_dirname (socket_path); errno = 0; if (g_mkdir_with_parents (path, 0700)) { g_warning ("Failed to mkdir %s: %s", path, g_strerror (errno)); @@ -260,11 +341,11 @@ g_free (path); errno = 0; - if (g_unlink (ibus_get_socket_path ())) { + if (g_unlink (socket_path)) { g_warning ("Failed to unlink %s: %s", - ibus_get_socket_path (), g_strerror (errno)); + socket_path, g_strerror (errno)); } - pf = fopen (ibus_get_socket_path (), "w"); + pf = fopen (socket_path, "w"); g_return_if_fail (pf != NULL); fprintf (pf,