From 506e5f21f7994a6abaee03cffebd1a6079376d9b Mon Sep 17 00:00:00 2001 From: Gavin John Date: Wed, 5 Aug 2026 23:03:32 -0400 Subject: [PATCH 1/2] fix: detect ibus/fcitx5 via D-Bus instead of process name --- .../oslayer/linux/keyboardcontrol_uinput.py | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/plover/oslayer/linux/keyboardcontrol_uinput.py b/plover/oslayer/linux/keyboardcontrol_uinput.py index f4835c684..fe2cf8c4d 100644 --- a/plover/oslayer/linux/keyboardcontrol_uinput.py +++ b/plover/oslayer/linux/keyboardcontrol_uinput.py @@ -1,6 +1,8 @@ import os import selectors import threading +import ctypes +import ctypes.util from evdev import ( InputDevice, @@ -13,8 +15,6 @@ from evdev import ( ecodes as e, ) -from psutil import process_iter - from plover import log from plover.key_combo import parse_key_combo from plover.machine.keyboard_capture import Capture @@ -30,6 +30,11 @@ get_modifier_keycodes, get_wayland_keymap, ) +from plover.oslayer.linux.log_dbus import ( + DBUS_BUS_SESSION, + DBusError, + ctypes_func, +) from plover.output.keyboard import GenericKeyboardEmulation # EV keycodes of keys considered modifiers when not able to automatically be @@ -46,6 +51,9 @@ } +IME_DBUS_NAMES = ("org.freedesktop.IBus", "org.fcitx.Fcitx5") + + def get_available_devices(): input_devices = [InputDevice(path) for path in list_devices()] keyboard_devices = [dev for dev in input_devices if filter_devices(dev)] @@ -78,10 +86,45 @@ def __init__(self): self._ui = UInput(res) # Check that ibus or fcitx5 is running - if not any(p.name() in ["ibus-daemon", "fcitx5"] for p in process_iter()): - log.warning( - "It appears that an input method, such as ibus or fcitx5, is not running on your system. Without this, some text may not be output correctly." - ) + libname = ctypes.util.find_library("dbus-1") + if libname is None: + log.warning("Unable to find libdbus to probe for ibus and fcitx5") + else: + libdbus = ctypes.cdll.LoadLibrary(libname) + try: + error_init = ctypes_func(libdbus, "void dbus_error_init error_p") + error_is_set = ctypes_func(libdbus, "bool dbus_error_is_set error_p") + error_free = ctypes_func(libdbus, "void dbus_error_free error_p") + bus_get = ctypes_func(libdbus, "connection_p dbus_bus_get uint error_p") + bus_name_has_owner = ctypes_func( + libdbus, "bool dbus_bus_name_has_owner connection_p char_p error_p" + ) + except AttributeError: + log.warning("Unable to load libdbus symbols") + else: + error = DBusError() + error_init(error) + bus = bus_get(DBUS_BUS_SESSION, ctypes.byref(error)) + if error_is_set(error): + log.warning(f"Unable to connect to session bus: {error}") + error_free(error) + elif bus is None: + log.warning(f"Unable to connect to session bus (returned null)") + else: + for name in IME_DBUS_NAMES: + error_init(error) + has_owner = bus_name_has_owner( + bus, ctypes.c_char_p(name.encode()), ctypes.byref(error) + ) + if error_is_set(error): + error_free(error) + elif has_owner: + log.info(f"Found IME on D-Bus: ${name}") + break + else: + log.warning( + "It appears that an input method, such as ibus or fcitx5, is not running on your system. Without this, some text may not be output correctly." + ) self._key_to_keycodeinfo = {} From 0e038f1852dc912e2061bf41c31a62faf592d7e7 Mon Sep 17 00:00:00 2001 From: Gavin John Date: Thu, 6 Aug 2026 19:28:55 -0400 Subject: [PATCH 2/2] docs: add news fragment for PR #1862 --- news.d/bugfix/1862.linux.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 news.d/bugfix/1862.linux.md diff --git a/news.d/bugfix/1862.linux.md b/news.d/bugfix/1862.linux.md new file mode 100644 index 000000000..b584c4491 --- /dev/null +++ b/news.d/bugfix/1862.linux.md @@ -0,0 +1 @@ +Fix ibus/fcitx5 detection incorrectly warning about a missing input method by probing D-Bus for the running service instead of matching on process name.