Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wayland support with keyboard emulation and capture using uinput #1679

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ distribution corresponding packages):
- Treal support: `libusb` (1.0) and `libudev` are needed by
the [`hidapi` package](https://pypi.org/project/hidapi/).
- log / notifications support: `libdbus` is needed.
- Uinput support: `libxkbcommon` are needed by the [`xkbcommon` package](https://pypi.org/project/xkbcommon)

For the rest of the steps, follow the [developer guide](../doc/developer_guide.md).
1 change: 1 addition & 0 deletions news.d/feature/1679.linux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added keyboard emulation and capture using uinput, compatible with X11, Wayland and anything else on linux and bsd.
15 changes: 13 additions & 2 deletions plover/gui_qt/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from PyQt5.QtWidgets import (
QMainWindow,
QMenu,
QApplication,
)

from plover import _, log
Expand Down Expand Up @@ -151,6 +152,14 @@ def set_visible(self, visible):
else:
self.showMinimized()

def _is_wayland(self):
"""
Calling .activateWindow() on a window results in this error:
Qt: Wayland does not support QWindow::requestActivate()
This function returns a boolean used to determine whether to run activateWindow()
"""
return "wayland" in QApplication.platformName().lower()

def _activate_dialog(self, name, args=(), manage_windows=False):
if manage_windows:
previous_window = wmctrl.GetForegroundWindow()
Expand All @@ -166,7 +175,8 @@ def on_finished():
wmctrl.SetForegroundWindow(previous_window)
dialog.finished.connect(on_finished)
dialog.showNormal()
dialog.activateWindow()
if not self._is_wayland():
dialog.activateWindow()
dialog.raise_()

def _add_translation(self, dictionary=None, manage_windows=False):
Expand All @@ -177,7 +187,8 @@ def _add_translation(self, dictionary=None, manage_windows=False):

def _focus(self):
self.showNormal()
self.activateWindow()
if not self._is_wayland():
self.activateWindow()
self.raise_()

def _configure(self, manage_windows=False):
Expand Down
9 changes: 9 additions & 0 deletions plover/oslayer/linux/display_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import os

"""
This value should be one of:
- x11
- wayland
- tty
"""
DISPLAY_SERVER = os.environ.get("XDG_SESSION_TYPE", None)
7 changes: 6 additions & 1 deletion plover/oslayer/linux/keyboardcontrol.py
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
from .keyboardcontrol_x11 import KeyboardCapture, KeyboardEmulation # pylint: disable=unused-import
from .display_server import DISPLAY_SERVER

if DISPLAY_SERVER == "x11":
from .keyboardcontrol_x11 import KeyboardCapture, KeyboardEmulation # pylint: disable=unused-import
else:
from .keyboardcontrol_uinput import KeyboardCapture, KeyboardEmulation #pylint: disable=unused-import
Loading