Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news.d/bugfix/1862.linux.md
Original file line number Diff line number Diff line change
@@ -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.
55 changes: 49 additions & 6 deletions plover/oslayer/linux/keyboardcontrol_uinput.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
import selectors
import threading
import ctypes
import ctypes.util

from evdev import (
InputDevice,
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)]
Expand Down Expand Up @@ -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 = {}

Expand Down