From 81284633cc52f063fe13a093501d038b7ba53119 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: Sat, 25 Jun 2022 21:11:26 +0900 Subject: [PATCH] Enable custome theme Also fix ibus restart for GNOME desktop --- ibus-HEAD.patch | 1193 +++++++++++++++++++++++++++++++++++++++++++++-- ibus.spec | 6 +- 2 files changed, 1157 insertions(+), 42 deletions(-) diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index d1cbf2f..c0156e6 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -1059,56 +1059,614 @@ index 00000000..f8dced6b -- 2.35.3 -From 9f2f24e615d7280b11cd244395c6b8122c47177a Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Thu, 26 May 2022 14:47:49 +0900 -Subject: [PATCH] src/tests: Unset G_MESSAGES_DEBUG for gsettings in - xkb-latin-layouts +From 233a3f4d4d3dc6782e74db5bf4e7c28fae729bc9 Mon Sep 17 00:00:00 2001 +From: Hollow Man +Date: Wed, 26 Jan 2022 09:35:11 +0800 +Subject: [PATCH 1/3] Add functionality to change IBus panel themes with + available GTK themes -gsettings cannot get the key value when G_MESSAGES_DEBUG is enabled. +To allow IBus to have their own control of themes. + +https://gitlab.gnome.org/GNOME/gnome-tweaks/-/blob/b9badc47b92dd73f8cedbd2efc66cbaf3ea25773/gtweak/tweaks/tweak_group_appearance.py#L69 + +BUG=https://github.com/ibus/ibus/pull/2327 + +Signed-off-by: Hollow Man --- - src/tests/xkb-latin-layouts | 7 +++++++ - 1 file changed, 7 insertions(+) + data/dconf/org.freedesktop.ibus.gschema.xml | 20 +++ + setup/main.py | 137 ++++++++++++++++++++ + setup/setup.ui | 97 +++++++++++++- + ui/gtk3/bindingcommon.vala | 46 +++++++ + ui/gtk3/panel.vala | 18 +++ + ui/gtk3/panelbinding.vala | 18 +++ + 6 files changed, 335 insertions(+), 1 deletion(-) -diff --git a/src/tests/xkb-latin-layouts b/src/tests/xkb-latin-layouts -index f8dced6b..92464234 100755 ---- a/src/tests/xkb-latin-layouts -+++ b/src/tests/xkb-latin-layouts -@@ -82,9 +82,16 @@ finit() +diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml +index 8b181d76..051f21a5 100644 +--- a/data/dconf/org.freedesktop.ibus.gschema.xml ++++ b/data/dconf/org.freedesktop.ibus.gschema.xml +@@ -210,6 +210,26 @@ + Custom font + Custom font name for language panel + ++ ++ false ++ Use custom theme ++ Use custom theme name for language panel ++ ++ ++ 'Adwaita' ++ Custom theme ++ Custom theme name for language panel ++ ++ ++ false ++ Use custom icon ++ Use custom icon name for language panel ++ ++ ++ 'Adwaita' ++ Custom icon ++ Custom icon name for language panel ++ + + true + Choose glyphs with input method's language on candidate window +diff --git a/setup/main.py b/setup/main.py +index 1b9056a6..71896693 100644 +--- a/setup/main.py ++++ b/setup/main.py +@@ -29,6 +29,7 @@ import os + import signal + import sys + import time ++import glob - test_xkb_keymaps() - { -+ # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append -+ # debug messages to gsettings output and could not get the result correctly. -+ backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG" -+ unset G_MESSAGES_DEBUG - # Loop over top level schemas since "gsettings list-recursively" only - # looks for direct children. - xkb_latin_layouts=`gsettings get org.freedesktop.ibus.general xkb-latin-layouts` -+ if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then -+ export G_MESSAGES_DEBUG=$backup_G_MESSAGES_DEBUG -+ fi - while read keymap ; do - eval keymap="$keymap" - HAS_VARIANT=$($ECHO "$keymap" | grep '(' 2> /dev/null) ||: + from gi import require_version as gi_require_version + gi_require_version('GLib', '2.0') +@@ -196,6 +197,79 @@ class Setup(object): + 'sensitive', + Gio.SettingsBindFlags.GET) + ++ # custom theme ++ self.__model_custom_theme = self.__builder.get_object( ++ "model_custom_theme") ++ self.__combobox_custom_theme = self.__builder.get_object( ++ "combobox_custom_theme") ++ self.__checkbutton_custom_theme = self.__builder.get_object( ++ "checkbutton_custom_theme") ++ ++ def update_combobox_custom_theme(settings, key): ++ theme_name_list = self.__init_available_gtk_themes() ++ self.__model_custom_theme.clear() ++ for name in theme_name_list: ++ self.__model_custom_theme.append([name]) ++ current_theme = self.__settings_panel.get_string(key) ++ try: ++ current_theme_number = theme_name_list.index(current_theme) ++ except ValueError: ++ self.__settings_panel.reset(key) ++ current_theme = self.__settings_panel.get_string(key) ++ current_theme_number = theme_name_list.index(current_theme) ++ self.__combobox_custom_theme.set_active(current_theme_number) ++ ++ update_combobox_custom_theme(None, 'custom-theme') ++ self.__settings_panel.bind('use-custom-theme', ++ self.__checkbutton_custom_theme, ++ 'active', ++ Gio.SettingsBindFlags.DEFAULT) ++ self.__settings_panel.connect('changed::custom-theme', ++ update_combobox_custom_theme) ++ self.__settings_panel.bind('use-custom-theme', ++ self.__combobox_custom_theme, ++ 'sensitive', ++ Gio.SettingsBindFlags.DEFAULT) ++ self.__combobox_custom_theme.connect("changed", ++ self.__on_combobox_custom_theme_changed) ++ ++ ++ # custom icon ++ self.__model_custom_icon = self.__builder.get_object( ++ "model_custom_icon") ++ self.__combobox_custom_icon = self.__builder.get_object( ++ "combobox_custom_icon") ++ self.__checkbutton_custom_icon = self.__builder.get_object( ++ "checkbutton_custom_icon") ++ ++ def update_combobox_custom_icon(settings, key): ++ icon_name_list = self.__init_available_gtk_icons() ++ self.__model_custom_icon.clear() ++ for name in icon_name_list: ++ self.__model_custom_icon.append([name]) ++ current_icon = self.__settings_panel.get_string(key) ++ try: ++ current_icon_number = icon_name_list.index(current_icon) ++ except ValueError: ++ self.__settings_panel.reset(key) ++ current_icon = self.__settings_panel.get_string(key) ++ current_icon_number = icon_name_list.index(current_icon) ++ self.__combobox_custom_icon.set_active(current_icon_number) ++ ++ update_combobox_custom_icon(None, 'custom-icon') ++ self.__settings_panel.bind('use-custom-icon', ++ self.__checkbutton_custom_icon, ++ 'active', ++ Gio.SettingsBindFlags.DEFAULT) ++ self.__settings_panel.connect('changed::custom-icon', ++ update_combobox_custom_icon) ++ self.__settings_panel.bind('use-custom-icon', ++ self.__combobox_custom_icon, ++ 'sensitive', ++ Gio.SettingsBindFlags.DEFAULT) ++ self.__combobox_custom_icon.connect("changed", ++ self.__on_combobox_custom_icon_changed) ++ + # show icon on system tray + self.__checkbutton_show_icon_on_systray = self.__builder.get_object( + "checkbutton_show_icon_on_systray") +@@ -588,6 +662,69 @@ class Setup(object): + _("Use shortcut with shift to switch to the previous input method") + entry.set_tooltip_text(tooltip) + ++ def __init_available_gtk_themes(self): ++ path_list = [] ++ path_list.append(os.path.join(GLib.get_home_dir(), ".themes")) ++ path_list.append(os.path.join(GLib.get_user_data_dir(), "themes")) ++ path_list.extend(list(map(lambda x: os.path.join( ++ x, "themes"), GLib.get_system_data_dirs()))) ++ theme_name_list = [] ++ gtk_theme_path = [] ++ for path in path_list: ++ gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk.css")) ++ gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk-dark.css")) ++ for path in gtk_theme_path: ++ filename = os.path.basename(path) ++ appendix = "" ++ if filename == "gtk-dark.css": ++ appendix = ":dark" ++ theme_name_list.append(os.path.basename( ++ os.path.dirname(os.path.dirname(path))) + appendix) ++ ++ theme_name_list.extend([ ++ 'Adwaita', 'Adwaita:dark', ++ 'HighContrast', 'HighContrastInverse' ++ ]) ++ theme_name_list = list(set(theme_name_list)) ++ theme_name_list.sort() ++ ++ return theme_name_list ++ ++ def __on_combobox_custom_theme_changed(self, combobox): ++ tree_iter = self.__combobox_custom_theme.get_active_iter() ++ if tree_iter is not None: ++ model = self.__combobox_custom_theme.get_model() ++ theme_name = model[tree_iter][0] ++ self.__settings_panel.set_string('custom-theme', theme_name) ++ ++ def __init_available_gtk_icons(self): ++ path_list = [] ++ path_list.append(os.path.join(GLib.get_home_dir(), ".icons")) ++ path_list.append(os.path.join(GLib.get_user_data_dir(), "icons")) ++ path_list.extend(list(map(lambda x: os.path.join( ++ x, "icons"), GLib.get_system_data_dirs()))) ++ icon_name_list = [] ++ gtk_icon_path = [] ++ for path in path_list: ++ gtk_icon_path.extend(glob.glob(path + "/*/index.theme")) ++ for path in gtk_icon_path: ++ dir = os.path.dirname(path) ++ if not os.path.exists(os.path.join(dir, "cursors")): ++ icon_name_list.append(os.path.basename(dir)) ++ ++ icon_name_list.extend(["Adwaita"]) ++ icon_name_list = list(set(icon_name_list)) ++ icon_name_list.sort() ++ ++ return icon_name_list ++ ++ def __on_combobox_custom_icon_changed(self, combobox): ++ tree_iter = self.__combobox_custom_icon.get_active_iter() ++ if tree_iter is not None: ++ model = self.__combobox_custom_icon.get_model() ++ icon_name = model[tree_iter][0] ++ self.__settings_panel.set_string('custom-icon', icon_name) ++ + def __item_started_column_toggled_cb(self, cell, path_str, model): + + # get toggled iter +diff --git a/setup/setup.ui b/setup/setup.ui +index a15b9083..5a9804f9 100644 +--- a/setup/setup.ui ++++ b/setup/setup.ui +@@ -55,6 +55,18 @@ + + + ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + 3.0 + 1.0 +@@ -1318,13 +1330,96 @@ + 0 + + ++ ++ ++ True ++ False ++ 12 ++ 6 ++ ++ ++ Use custom theme: ++ False ++ True ++ True ++ False ++ False ++ True ++ start ++ True ++ True ++ ++ ++ 0 ++ 0 ++ ++ ++ ++ ++ True ++ False ++ model_custom_theme ++ True ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 0 ++ ++ ++ ++ ++ Use custom icon: ++ False ++ True ++ True ++ False ++ False ++ True ++ start ++ True ++ ++ ++ 0 ++ 1 ++ ++ ++ ++ ++ True ++ False ++ model_custom_icon ++ ++ ++ ++ 0 ++ ++ ++ ++ ++ 1 ++ 1 ++ ++ ++ ++ ++ False ++ False ++ 1 ++ ++ + + + + + True + False +- <b>Fonts</b> ++ <b>Font and Theme</b> + True + + +diff --git a/ui/gtk3/bindingcommon.vala b/ui/gtk3/bindingcommon.vala +index 150d4c39..e825167b 100644 +--- a/ui/gtk3/bindingcommon.vala ++++ b/ui/gtk3/bindingcommon.vala +@@ -212,4 +212,50 @@ class BindingCommon { + css_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } ++ ++ public static void ++ set_custom_theme(GLib.Settings? settings_panel) { ++ if (settings_panel == null) ++ return; ++ ++ bool use_custom_theme = settings_panel.get_boolean("use-custom-theme"); ++ string custom_theme = settings_panel.get_string("custom-theme"); ++ ++ Gtk.Settings gtk_settings = Gtk.Settings.get_default(); ++ ++ if (use_custom_theme == false) ++ custom_theme = ""; ++ ++ if (custom_theme == null || custom_theme == "") { ++ gtk_settings.reset_property("gtk-theme-name"); ++ gtk_settings.reset_property("gtk-application-prefer-dark-theme"); ++ } else { ++ string[] custom_theme_splitted = custom_theme.split(":"); ++ gtk_settings.gtk_theme_name = custom_theme_splitted[0]; ++ if (custom_theme_splitted.length == 2 && ++ custom_theme_splitted[1] == "dark") ++ gtk_settings.gtk_application_prefer_dark_theme = true; ++ else ++ gtk_settings.gtk_application_prefer_dark_theme = false; ++ } ++ } ++ ++ public static void ++ set_custom_icon(GLib.Settings? settings_panel) { ++ if (settings_panel == null) ++ return; ++ ++ bool use_custom_icon = settings_panel.get_boolean("use-custom-icon"); ++ string custom_icon = settings_panel.get_string("custom-icon"); ++ ++ Gtk.Settings gtk_settings = Gtk.Settings.get_default(); ++ ++ if (use_custom_icon == false) ++ custom_icon = ""; ++ ++ if (custom_icon == null || custom_icon == "") ++ gtk_settings.reset_property("gtk-icon-theme-name"); ++ else ++ gtk_settings.gtk_icon_theme_name = custom_icon; ++ } + } +diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala +index 61bfa1b6..101c2b3d 100644 +--- a/ui/gtk3/panel.vala ++++ b/ui/gtk3/panel.vala +@@ -211,6 +211,22 @@ class Panel : IBus.PanelService { + ref m_css_provider); + }); + ++ m_settings_panel.changed["custom-theme"].connect((key) => { ++ BindingCommon.set_custom_theme(m_settings_panel); ++ }); ++ ++ m_settings_panel.changed["use-custom-theme"].connect((key) => { ++ BindingCommon.set_custom_theme(m_settings_panel); ++ }); ++ ++ m_settings_panel.changed["custom-icon"].connect((key) => { ++ BindingCommon.set_custom_icon(m_settings_panel); ++ }); ++ ++ m_settings_panel.changed["use-custom-icon"].connect((key) => { ++ BindingCommon.set_custom_icon(m_settings_panel); ++ }); ++ + m_settings_panel.changed["use-glyph-from-engine-lang"].connect((key) => + { + m_use_engine_lang = m_settings_panel.get_boolean( +@@ -816,6 +832,8 @@ class Panel : IBus.PanelService { + BindingCommon.set_custom_font(m_settings_panel, + null, + ref m_css_provider); ++ BindingCommon.set_custom_theme(m_settings_panel); ++ BindingCommon.set_custom_icon(m_settings_panel); + set_show_icon_on_systray(); + set_lookup_table_orientation(); + set_show_property_panel(); +diff --git a/ui/gtk3/panelbinding.vala b/ui/gtk3/panelbinding.vala +index e63d93f2..3c516afd 100644 +--- a/ui/gtk3/panelbinding.vala ++++ b/ui/gtk3/panelbinding.vala +@@ -270,6 +270,22 @@ class PanelBinding : IBus.PanelService { + ref m_css_provider); + }); + ++ m_settings_panel.changed["custom-theme"].connect((key) => { ++ BindingCommon.set_custom_theme(m_settings_panel); ++ }); ++ ++ m_settings_panel.changed["use-custom-theme"].connect((key) => { ++ BindingCommon.set_custom_theme(m_settings_panel); ++ }); ++ ++ m_settings_panel.changed["custom-icon"].connect((key) => { ++ BindingCommon.set_custom_icon(m_settings_panel); ++ }); ++ ++ m_settings_panel.changed["use-custom-icon"].connect((key) => { ++ BindingCommon.set_custom_icon(m_settings_panel); ++ }); ++ + m_settings_emoji.changed["unicode-hotkey"].connect((key) => { + set_emoji_hotkey(); + }); +@@ -422,6 +438,8 @@ class PanelBinding : IBus.PanelService { + BindingCommon.set_custom_font(m_settings_panel, + m_settings_emoji, + ref m_css_provider); ++ BindingCommon.set_custom_theme(m_settings_panel); ++ BindingCommon.set_custom_icon(m_settings_panel); + set_emoji_favorites(); + if (m_load_emoji_at_startup && !m_loaded_emoji) + set_emoji_lang(); -- 2.35.3 -From 59d9401da254c0152c313f9027457eb234a23a8c Mon Sep 17 00:00:00 2001 +From addab9fdc7f98c172b6fcb1e24faa133368bdaf3 Mon Sep 17 00:00:00 2001 +From: Hollow Man +Date: Wed, 26 Jan 2022 10:03:04 +0800 +Subject: [PATCH 2/3] Revert support for choosing GTK themes dark variant + +So that the theme list won't get too messy + +BUG=https://github.com/ibus/ibus/pull/2327 + +Signed-off-by: Hollow Man +--- + setup/main.py | 10 ++-------- + ui/gtk3/bindingcommon.vala | 14 +++----------- + 2 files changed, 5 insertions(+), 19 deletions(-) + +diff --git a/setup/main.py b/setup/main.py +index 71896693..d0e05666 100644 +--- a/setup/main.py ++++ b/setup/main.py +@@ -672,18 +672,12 @@ class Setup(object): + gtk_theme_path = [] + for path in path_list: + gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk.css")) +- gtk_theme_path.extend(glob.glob(path + "/*/gtk-*/gtk-dark.css")) + for path in gtk_theme_path: +- filename = os.path.basename(path) +- appendix = "" +- if filename == "gtk-dark.css": +- appendix = ":dark" + theme_name_list.append(os.path.basename( +- os.path.dirname(os.path.dirname(path))) + appendix) ++ os.path.dirname(os.path.dirname(path)))) + + theme_name_list.extend([ +- 'Adwaita', 'Adwaita:dark', +- 'HighContrast', 'HighContrastInverse' ++ 'Adwaita', 'HighContrast', 'HighContrastInverse' + ]) + theme_name_list = list(set(theme_name_list)) + theme_name_list.sort() +diff --git a/ui/gtk3/bindingcommon.vala b/ui/gtk3/bindingcommon.vala +index e825167b..4ecb7159 100644 +--- a/ui/gtk3/bindingcommon.vala ++++ b/ui/gtk3/bindingcommon.vala +@@ -226,18 +226,10 @@ class BindingCommon { + if (use_custom_theme == false) + custom_theme = ""; + +- if (custom_theme == null || custom_theme == "") { ++ if (custom_theme == null || custom_theme == "") + gtk_settings.reset_property("gtk-theme-name"); +- gtk_settings.reset_property("gtk-application-prefer-dark-theme"); +- } else { +- string[] custom_theme_splitted = custom_theme.split(":"); +- gtk_settings.gtk_theme_name = custom_theme_splitted[0]; +- if (custom_theme_splitted.length == 2 && +- custom_theme_splitted[1] == "dark") +- gtk_settings.gtk_application_prefer_dark_theme = true; +- else +- gtk_settings.gtk_application_prefer_dark_theme = false; +- } ++ else ++ gtk_settings.gtk_theme_name = custom_theme; + } + + public static void +-- +2.35.3 + +From ff99828cb60915318ed0f40998a1a23d5dea42c7 Mon Sep 17 00:00:00 2001 +From: Hollow Man +Date: Wed, 26 Jan 2022 11:19:40 +0800 +Subject: [PATCH 3/3] Add tooltip text for use custom icon and theme + +BUG=https://github.com/ibus/ibus/pull/2327 + +Signed-off-by: Hollow Man +--- + setup/setup.ui | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/setup/setup.ui b/setup/setup.ui +index 5a9804f9..6ded2061 100644 +--- a/setup/setup.ui ++++ b/setup/setup.ui +@@ -1339,6 +1339,7 @@ + + + Use custom theme: ++ Choose a theme of the candidate window + False + True + True +@@ -1375,6 +1376,7 @@ + + + Use custom icon: ++ Choose a theme of the arrow buttons on the candidate window + False + True + True +-- +2.35.3 + +From 9ad063746ec3d919217ae18acce2d4768bcfca05 Mon Sep 17 00:00:00 2001 From: fujiwarat -Date: Sat, 11 Jun 2022 21:10:12 +0900 +Date: Mon, 20 Jun 2022 21:01:31 +0900 Subject: [PATCH] ui/gtk3: Hide XKB engine but enable it in Plasma Wayland -IBus just cannot forward key events in Plasma Wayland because -IBus has to handle the compose keys. +IBus just cannot defer key events to the secondary input methods +to switch XKB keymaps in Plasma Wayland because IBus has to handle the +compose keys before defer the key events. + +Also update the POT file. BUG=rhbz#2088656 --- - ui/gtk3/panel.vala | 50 ++++++++++++++++++++++++++++++---------------- - 1 file changed, 33 insertions(+), 17 deletions(-) + data/dconf/org.freedesktop.ibus.gschema.xml | 4 +- + ui/gtk3/panel.vala | 50 ++- + 3 files changed, 248 insertions(+), 180 deletions(-) +diff --git a/data/dconf/org.freedesktop.ibus.gschema.xml b/data/dconf/org.freedesktop.ibus.gschema.xml +index 051f21a5..0ece2b4f 100644 +--- a/data/dconf/org.freedesktop.ibus.gschema.xml ++++ b/data/dconf/org.freedesktop.ibus.gschema.xml +@@ -223,12 +223,12 @@ + + false + Use custom icon +- Use custom icon name for language panel ++ Use custom icon name for arrow buttons on candidate window + + + 'Adwaita' + Custom icon +- Custom icon name for language panel ++ Custom icon name for arrow buttons on candidate window + + + true diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala -index 61bfa1b6..28a1aa0b 100644 +index 101c2b3d..452b14c8 100644 --- a/ui/gtk3/panel.vala +++ b/ui/gtk3/panel.vala @@ -41,6 +41,7 @@ class Panel : IBus.PanelService { @@ -1119,7 +1677,7 @@ index 61bfa1b6..28a1aa0b 100644 private GLib.HashTable m_engine_contexts = new GLib.HashTable(GLib.str_hash, GLib.str_equal); -@@ -910,13 +911,20 @@ class Panel : IBus.PanelService { +@@ -928,13 +929,20 @@ class Panel : IBus.PanelService { } private void switch_engine(int i, bool force = false) { @@ -1142,7 +1700,7 @@ index 61bfa1b6..28a1aa0b 100644 set_engine(engine); } -@@ -1006,17 +1014,15 @@ class Panel : IBus.PanelService { +@@ -1024,17 +1032,15 @@ class Panel : IBus.PanelService { string[]? order_names) { string[]? engine_names = unowned_engine_names; @@ -1164,7 +1722,7 @@ index 61bfa1b6..28a1aa0b 100644 continue; if (name in engine_names) names += name; -@@ -1024,7 +1030,7 @@ class Panel : IBus.PanelService { +@@ -1042,7 +1048,7 @@ class Panel : IBus.PanelService { foreach (var name in engine_names) { if (m_is_wayland && name.has_prefix("xkb:")) @@ -1173,7 +1731,7 @@ index 61bfa1b6..28a1aa0b 100644 if (name in names) continue; names += name; -@@ -1065,14 +1071,20 @@ class Panel : IBus.PanelService { +@@ -1083,14 +1089,20 @@ class Panel : IBus.PanelService { } if (m_engines.length == 0) { @@ -1201,7 +1759,7 @@ index 61bfa1b6..28a1aa0b 100644 } else { var current_engine = m_engines[0]; m_engines = engines; -@@ -1289,6 +1301,10 @@ class Panel : IBus.PanelService { +@@ -1307,6 +1319,10 @@ class Panel : IBus.PanelService { var longname = engine.get_longname(); var textdomain = engine.get_textdomain(); var transname = GLib.dgettext(textdomain, longname); @@ -1212,7 +1770,7 @@ index 61bfa1b6..28a1aa0b 100644 var item = new Gtk.MenuItem.with_label( "%s - %s".printf (IBus.get_language_name(language), transname)); // Make a copy of engine to workaround a bug in vala. -@@ -1566,7 +1582,7 @@ class Panel : IBus.PanelService { +@@ -1584,7 +1600,7 @@ class Panel : IBus.PanelService { if (engine != null) { var name = engine.get_name(); @@ -1224,3 +1782,556 @@ index 61bfa1b6..28a1aa0b 100644 -- 2.35.3 +From 78ce092914e00d6af3b2b90263dd6f41de75741e Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Sat, 25 Jun 2022 20:48:50 +0900 +Subject: [PATCH] tools: Enable ibus restart in GNOME desktop + +If ibus-daemon is called via systemd, IBus restart API cannot restart +ibus-daemon but just terminates it. +Now ibus restart command checks the systemd avaiability and restart +ibus-daemon via systemd. +ibus start command is also added to launch ibus-daemon with systemd. +--- + tools/Makefile.am | 3 +- + tools/ibus.1.in | 30 +++++- + tools/main.vala | 231 ++++++++++++++++++++++++++++++++++++++++++++-- + 3 files changed, 252 insertions(+), 12 deletions(-) + +diff --git a/tools/Makefile.am b/tools/Makefile.am +index 5c18d3d6..e380a9aa 100644 +--- a/tools/Makefile.am ++++ b/tools/Makefile.am +@@ -3,7 +3,7 @@ + # ibus - The Input Bus + # + # Copyright (c) 2007-2013 Peng Huang +-# Copyright (c) 2015-2017 Takao Fujiwara ++# Copyright (c) 2015-2022 Takao Fujiwara + # Copyright (c) 2007-2017 Red Hat, Inc. + # + # This library is free software; you can redistribute it and/or +@@ -57,6 +57,7 @@ AM_LDADD = \ + AM_VALAFLAGS = \ + --vapidir=$(top_builddir)/bindings/vala \ + --vapidir=$(top_srcdir)/bindings/vala \ ++ --pkg=gio-2.0 \ + --pkg=ibus-1.0 \ + --pkg=posix \ + --pkg=config \ +diff --git a/tools/ibus.1.in b/tools/ibus.1.in +index 525d972e..0c16a0d2 100644 +--- a/tools/ibus.1.in ++++ b/tools/ibus.1.in +@@ -3,7 +3,7 @@ + .\" Copyright (C) Takao Fujiwara , 2013-2017. + .\" Copyright (c) Peng Huang , 2013. + .\" +-.TH "IBUS" 1 "May 2017" "@VERSION@" "User Commands" ++.TH "IBUS" 1 "Jun 2022" "@VERSION@" "User Commands" + .SH NAME + .B ibus + \- command line utility for ibus +@@ -45,13 +45,33 @@ Exit ibus-daemon. + \fBlist-engine\fR + Show ibus engines list. + .TP +-\fBrestart\fR +-Restart ibus-daemon. ++\fBrestart\fR [\fB\-\-type=TYPE|\-\-verbose|\-\-help\fR] ++Restart ibus-daemon. This command tries to restart ibus-daemon via systemd ++firstly and directly secondary by default. If ++.B \-\-type=systemd ++is given, It tries to restart via systemd only. If ++.B \-\-type=direct ++is given, It tries to restart with an IBus API only. GNOME desktop runs ++ibus-daemon via systemd and other desktops run ibus-daemon directly. ++.TP ++\fBstart\fR [\fB\-\-type=TYPE|\-\-verbose|\-\-help\fR] ++Start ibus-daemon. This command tries to start ibus-daemon via systemd ++firstly and directly secondary by default. If ++.B \-\-type=systemd ++is given, It tries to start as a background process via systemd only. If ++.B \-\-type=direct ++is given, It tries to start directly only as a foreground process and other ++option arguments of ibus command are sent to ibus-daemon. E.g. ++ibus start ++.B \-\-type=direct ++.B \-\-xim ++& ++GNOME desktop runs ibus-daemon via systemd and other desktops run ibus-daemon directly. + .TP + \fBversion\fR + Show the ibus version. + .TP +-\fBread\-cache\fR [\fB\-\-system|\-\-file=FILE\fR] ++\fBread\-cache\fR [\fB\-\-system|\-\-file=FILE|\-\-help\fR] + Show the content of the user registry cache if + .B \-\-system + is not given. +@@ -64,7 +84,7 @@ if + .B \-\-file=FILE + is given. + .TP +-\fBwrite\-cache\fR [\fB\-\-system|\-\-file=FILE\fR] ++\fBwrite\-cache\fR [\fB\-\-system|\-\-file=FILE|\-\-help\fR] + Save the user registry cache if + .B \-\-system + is not given. +diff --git a/tools/main.vala b/tools/main.vala +index 26e7fd88..71134334 100644 +--- a/tools/main.vala ++++ b/tools/main.vala +@@ -3,7 +3,7 @@ + * ibus - The Input Bus + * + * Copyright(c) 2013 Peng Huang +- * Copyright(c) 2015-2020 Takao Fujiwara ++ * Copyright(c) 2015-2022 Takao Fujiwara + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -27,17 +27,22 @@ private const string IBUS_SCHEMAS_GENERAL_HOTKEY = + private const string IBUS_SCHEMAS_PANEL = "org.freedesktop.ibus.panel"; + private const string IBUS_SCHEMAS_PANEL_EMOJI = + "org.freedesktop.ibus.panel.emoji"; ++private const string SYSTEMD_SESSION_GNOME_FILE = ++ "org.freedesktop.IBus.session.GNOME.service"; + + bool name_only = false; + /* system() exists as a public API. */ + bool is_system = false; + string cache_file = null; + string engine_id = null; ++bool verbose = false; ++string daemon_type = null; + + class EngineList { + public IBus.EngineDesc[] data = {}; + } + ++ + IBus.Bus? get_bus() { + var bus = new IBus.Bus(); + if (!bus.is_connected ()) +@@ -45,6 +50,123 @@ IBus.Bus? get_bus() { + return bus; + } + ++ ++GLib.DBusConnection? get_session_bus(bool verbose) { ++ try { ++ return GLib.Bus.get_sync (GLib.BusType.SESSION, null); ++ } catch (GLib.IOError e) { ++ if (verbose) ++ stderr.printf("%s\n", e.message); ++ } ++ return null; ++} ++ ++string? ++get_ibus_systemd_object_path(GLib.DBusConnection connection, ++ bool verbose) { ++ string object_path = null; ++ const string service_file = SYSTEMD_SESSION_GNOME_FILE; ++ try { ++ var variant = connection.call_sync ( ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ "GetUnit", ++ new GLib.Variant("(s)", service_file), ++ new GLib.VariantType("(o)"), ++ GLib.DBusCallFlags.NONE, ++ -1, ++ null); ++ variant.get("(o)", ref object_path); ++ if (verbose) { ++ stderr.printf("Succeed to get an object path \"%s\" for IBus " + ++ "systemd service file \"%s\".\n", ++ object_path, service_file); ++ } ++ return object_path; ++ } catch (GLib.Error e) { ++ if (verbose) { ++ stderr.printf("IBus systemd service file \"%s\" is not installed " + ++ "in your system: %s\n", service_file, e.message); ++ } ++ } ++ return null; ++} ++ ++ ++bool ++is_running_daemon_via_systemd(GLib.DBusConnection connection, ++ string object_path, ++ bool verbose) { ++ string? state = null; ++ try { ++ var variant = connection.call_sync ( ++ "org.freedesktop.systemd1", ++ object_path, ++ "org.freedesktop.DBus.Properties", ++ "Get", ++ new GLib.Variant("(ss)", ++ "org.freedesktop.systemd1.Unit", ++ "ActiveState"), ++ new GLib.VariantType("(v)"), ++ GLib.DBusCallFlags.NONE, ++ -1, ++ null); ++ GLib.Variant child = null; ++ variant.get("(v)", ref child); ++ state = child.dup_string(); ++ if (verbose) { ++ stderr.printf("Succeed to get the state \"%s\" for an object " + ++ "path \"%s\".\n", state, object_path); ++ } ++ } catch (GLib.Error e) { ++ if (verbose) ++ stderr.printf("%s\n", e.message); ++ return false; ++ } ++ if (state == "active") ++ return true; ++ return false; ++} ++ ++ ++bool ++start_daemon_via_systemd(GLib.DBusConnection connection, ++ bool restart, ++ bool verbose) { ++ string object_path = null; ++ const string service_file = SYSTEMD_SESSION_GNOME_FILE; ++ string method = "StartUnit"; ++ if (restart) ++ method = "RestartUnit"; ++ try { ++ var variant = connection.call_sync ( ++ "org.freedesktop.systemd1", ++ "/org/freedesktop/systemd1", ++ "org.freedesktop.systemd1.Manager", ++ method, ++ new GLib.Variant("(ss)", service_file, "fail"), ++ new GLib.VariantType("(o)"), ++ GLib.DBusCallFlags.NONE, ++ -1, ++ null); ++ variant.get("(o)", ref object_path); ++ if (verbose) { ++ stderr.printf("Succeed to restart IBus daemon via IBus systemd " + ++ "service file \"%s\": \"%s\"\n", ++ service_file, object_path); ++ } ++ return true; ++ } catch (GLib.Error e) { ++ if (verbose) { ++ stderr.printf("Failed to restart IBus daemon via IBus systemd " + ++ "service file \"%s\": %s\n", service_file, e.message); ++ } ++ } ++ return false; ++} ++ ++ + int list_engine(string[] argv) { + const OptionEntry[] options = { + { "name-only", 0, 0, OptionArg.NONE, out name_only, +@@ -99,6 +221,7 @@ int list_engine(string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + private int exec_setxkbmap(IBus.EngineDesc engine) { + string layout = engine.get_layout(); + string variant = engine.get_layout_variant(); +@@ -149,6 +272,7 @@ private int exec_setxkbmap(IBus.EngineDesc engine) { + return Posix.EXIT_SUCCESS; + } + ++ + int get_set_engine(string[] argv) { + var bus = get_bus(); + string engine = null; +@@ -182,20 +306,100 @@ int get_set_engine(string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + int message_watch(string[] argv) { + return Posix.EXIT_SUCCESS; + } + +-int restart_daemon(string[] argv) { +- var bus = get_bus(); +- if (bus == null) { +- stderr.printf(_("Can't connect to IBus.\n")); ++ ++int start_daemon_real(string[] argv, ++ bool restart) { ++ const OptionEntry[] options = { ++ { "type", 0, 0, OptionArg.STRING, out daemon_type, ++ N_("Start or restart daemon with \"direct\" or \"systemd\" TYPE."), ++ "TYPE" }, ++ { "verbose", 0, 0, OptionArg.NONE, out verbose, ++ N_("Show debug messages."), null }, ++ { null } ++ }; ++ ++ var option = new OptionContext(); ++ option.add_main_entries(options, Config.GETTEXT_PACKAGE); ++ option.set_ignore_unknown_options(true); ++ ++ try { ++ option.parse(ref argv); ++ } catch (OptionError e) { ++ stderr.printf("%s\n", e.message); ++ return Posix.EXIT_FAILURE; ++ } ++ if (daemon_type != null && daemon_type != "direct" && ++ daemon_type != "systemd") { ++ stderr.printf("type argument must be \"direct\" or \"systemd\"\n"); ++ return Posix.EXIT_FAILURE; ++ } ++ ++ do { ++ if (daemon_type == "direct") ++ break; ++ GLib.DBusConnection? connection = get_session_bus(verbose); ++ if (connection == null) ++ break; ++ string? object_path = get_ibus_systemd_object_path(connection, verbose); ++ if (object_path == null) ++ break; ++ if (restart && ++ !is_running_daemon_via_systemd(connection, object_path, verbose)) ++ break; ++ if (start_daemon_via_systemd(connection, restart, verbose)) ++ return Posix.EXIT_SUCCESS; + return Posix.EXIT_FAILURE; ++ } while (false); ++ ++ if (daemon_type == "systemd") ++ return Posix.EXIT_FAILURE; ++ if (restart) { ++ var bus = get_bus(); ++ if (bus == null) { ++ stderr.printf(_("Can't connect to IBus.\n")); ++ return Posix.EXIT_FAILURE; ++ } ++ bus.exit(true); ++ if (verbose) { ++ stderr.printf("Succeed to restart ibus-daemon with an IBus API " + ++ "directly.\n"); ++ } ++ } else { ++ string startarg = "ibus-daemon"; ++ argv[0] = startarg; ++ var paths = GLib.Environment.get_variable("PATH").split(":"); ++ foreach (unowned string path in paths) { ++ var full_path = "%s/%s".printf(path, startarg); ++ if (GLib.FileUtils.test(full_path, GLib.FileTest.IS_EXECUTABLE)) { ++ startarg = full_path; ++ break; ++ } ++ } ++ // When ibus-daemon is launched by GLib.Process.spawn_async(), ++ // the parent process will be systemd ++ if (verbose) { ++ stderr.printf("Running \"%s\" directly as a foreground " + ++ "process.\n", startarg); ++ } ++ Posix.execv(startarg, argv); + } +- bus.exit(true); + return Posix.EXIT_SUCCESS; + } + ++ ++int restart_daemon(string[] argv) { ++ return start_daemon_real(argv, true); ++} ++ ++int start_daemon(string[] argv) { ++ return start_daemon_real(argv, false); ++} ++ + int exit_daemon(string[] argv) { + var bus = get_bus(); + if (bus == null) { +@@ -206,11 +410,13 @@ int exit_daemon(string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + int print_version(string[] argv) { + print("IBus %s\n", Config.PACKAGE_VERSION); + return Posix.EXIT_SUCCESS; + } + ++ + int read_cache (string[] argv) { + const OptionEntry[] options = { + { "system", 0, 0, OptionArg.NONE, out is_system, +@@ -251,6 +457,7 @@ int read_cache (string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + int write_cache (string[] argv) { + const OptionEntry[] options = { + { "system", 0, 0, OptionArg.NONE, out is_system, +@@ -283,12 +490,14 @@ int write_cache (string[] argv) { + Posix.EXIT_SUCCESS : Posix.EXIT_FAILURE; + } + ++ + int print_address(string[] argv) { + string address = IBus.get_address(); + print("%s\n", address != null ? address : "(null)"); + return Posix.EXIT_SUCCESS; + } + ++ + private int read_config_options(string[] argv) { + const OptionEntry[] options = { + { "engine-id", 0, 0, OptionArg.STRING, out engine_id, +@@ -309,6 +518,7 @@ private int read_config_options(string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + private GLib.SList get_ibus_schemas() { + string[] ids = {}; + if (engine_id != null) { +@@ -342,6 +552,7 @@ private GLib.SList get_ibus_schemas() { + return ibus_schemas; + } + ++ + int read_config(string[] argv) { + if (read_config_options(argv) == Posix.EXIT_FAILURE) + return Posix.EXIT_FAILURE; +@@ -370,6 +581,7 @@ int read_config(string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + int reset_config(string[] argv) { + if (read_config_options(argv) == Posix.EXIT_FAILURE) + return Posix.EXIT_FAILURE; +@@ -401,6 +613,7 @@ int reset_config(string[] argv) { + return Posix.EXIT_SUCCESS; + } + ++ + #if EMOJI_DICT + int emoji_dialog(string[] argv) { + string cmd = Config.LIBEXECDIR + "/ibus-ui-emojier"; +@@ -427,11 +640,13 @@ int emoji_dialog(string[] argv) { + } + #endif + ++ + int print_help(string[] argv) { + print_usage(stdout); + return Posix.EXIT_SUCCESS; + } + ++ + delegate int EntryFunc(string[] argv); + + struct CommandEntry { +@@ -440,12 +655,14 @@ struct CommandEntry { + unowned EntryFunc entry; + } + ++ + const CommandEntry commands[] = { + { "engine", N_("Set or get engine"), get_set_engine }, + { "exit", N_("Exit ibus-daemon"), exit_daemon }, + { "list-engine", N_("Show available engines"), list_engine }, + { "watch", N_("(Not implemented)"), message_watch }, + { "restart", N_("Restart ibus-daemon"), restart_daemon }, ++ { "start", N_("Start ibus-daemon"), start_daemon }, + { "version", N_("Show version"), print_version }, + { "read-cache", N_("Show the content of registry cache"), read_cache }, + { "write-cache", N_("Create registry cache"), write_cache }, +@@ -460,6 +677,7 @@ const CommandEntry commands[] = { + + static string program_name; + ++ + void print_usage(FileStream stream) { + stream.printf(_("Usage: %s COMMAND [OPTION...]\n\n"), program_name); + stream.printf(_("Commands:\n")); +@@ -470,6 +688,7 @@ void print_usage(FileStream stream) { + } + } + ++ + public int main(string[] argv) { + GLib.Intl.setlocale(GLib.LocaleCategory.ALL, ""); + GLib.Intl.bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR); +-- +2.35.3 + +From 6203b6c4e1d41e731bdccb1338ed45c93bc56903 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 21 Jun 2022 00:49:46 +0900 +Subject: [PATCH] src/tests: Unset G_MESSAGES_DEBUG for gsettings in + xkb-latin-layouts + +gsettings cannot get the key value when G_MESSAGES_DEBUG is enabled. +Add denylist.txt to engine/Makefile.am +--- + engine/Makefile.am | 3 ++- + src/tests/xkb-latin-layouts | 7 +++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/engine/Makefile.am b/engine/Makefile.am +index 03867f52..7256fbc8 100644 +--- a/engine/Makefile.am ++++ b/engine/Makefile.am +@@ -4,7 +4,7 @@ + # + # Copyright (c) 2010-2016, Google Inc. All rights reserved. + # Copyright (c) 2007-2016 Peng Huang +-# Copyright (c) 2013-2020 Takao Fujiwara ++# Copyright (c) 2013-2021 Takao Fujiwara + # + # This library is free software; you can redistribute it and/or + # modify it under the terms of the GNU Lesser General Public +@@ -88,6 +88,7 @@ CLEANFILES = \ + $(NULL) + + EXTRA_DIST = \ ++ denylist.txt \ + gensimple.py \ + iso639converter.py \ + simple.xml.in \ +diff --git a/src/tests/xkb-latin-layouts b/src/tests/xkb-latin-layouts +index f8dced6b..92464234 100755 +--- a/src/tests/xkb-latin-layouts ++++ b/src/tests/xkb-latin-layouts +@@ -82,9 +82,16 @@ finit() + + test_xkb_keymaps() + { ++ # G_MESSAGES_DEBUG=all or G_MESSAGES_DEBUG=GLib-GIO-DEBUG would append ++ # debug messages to gsettings output and could not get the result correctly. ++ backup_G_MESSAGES_DEBUG="$G_MESSAGES_DEBUG" ++ unset G_MESSAGES_DEBUG + # Loop over top level schemas since "gsettings list-recursively" only + # looks for direct children. + xkb_latin_layouts=`gsettings get org.freedesktop.ibus.general xkb-latin-layouts` ++ if [ x"$backup_G_MESSAGES_DEBUG" != x ] ; then ++ export G_MESSAGES_DEBUG=$backup_G_MESSAGES_DEBUG ++ fi + while read keymap ; do + eval keymap="$keymap" + HAS_VARIANT=$($ECHO "$keymap" | grep '(' 2> /dev/null) ||: +-- +2.35.3 + diff --git a/ibus.spec b/ibus.spec index 14567df..b9808aa 100644 --- a/ibus.spec +++ b/ibus.spec @@ -39,7 +39,7 @@ Name: ibus Version: 1.5.26 -Release: 10%{?dist} +Release: 11%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ URL: https://github.com/ibus/%name/wiki @@ -522,6 +522,10 @@ dconf update || : %{_datadir}/installed-tests/ibus %changelog +* Sat Jun 25 2022 Takao Fujiwara - 1.5.26-11 +- Enable custome theme +- Fix ibus restart for GNOME desktop + * Mon Jun 13 2022 Python Maint - 1.5.26-10 - Rebuilt for Python 3.11