Skip to content
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ The status commands verify managed integration configuration and, where applicab

`setup-greeter` shows an arrow-key menu of installed supported managers. Scripts can select one directly with `--manager plasma-login`, `--manager greetd`, or `--manager lightdm`. Setup checks the selected manager and its current configuration before writing files. It does not restart the display manager, so reboot or restart it after setup.

Plasma Login Manager and LightDM use their own greeter startup hooks. The greetd adapter saves and wraps the existing default-session command. It starts that command before Axidev OSK, keeps the greeter authoritative, and restores the exact command during removal.
Plasma Login Manager configures Axidev OSK as KWin's input method for the login manager and session lock screen. Plasma 6.7 setup also adds an exact marked block to Plasma's lock-screen QML so the password interface remains visible while using the keyboard. This integration is limited to Plasma versions from 6.7.0 up to, but not including, 7.0.0. LightDM uses its greeter startup hook. The greetd adapter saves and wraps the existing default-session command, starts that command before Axidev OSK, and restores the exact command during removal.

The keyboard retries with exponential backoff while the greeter remains active. A keyboard or display-detection failure never stops the greeter. Failures appear in the system journal under `axidev-osk-greeter`.

Expand Down
6 changes: 4 additions & 2 deletions packaging/linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ sudo axidev-osk linux setup-greeter --manager lightdm

Setup validates every required account, hook, and existing file before changing the manager. It configures one manager and never restarts it. Reboot or restart the selected display manager after setup.

Plasma Login Manager uses an `axidev-osk-greeter.service` user unit tied to `plasma-login-wayland.target`. LightDM uses a `greeter-wrapper` drop-in. greetd replaces only the default-session command line with `/etc/axidev-osk/greetd-session-wrapper`, while `/etc/axidev-osk/greeter.json` keeps the exact original value for removal.
Plasma Login Manager configures Axidev OSK as KWin's input method for both the login manager and the session lock screen. On Plasma versions from 6.7.0 up to, but not including, 7.0.0, setup also adds one marked block to `/usr/share/plasma/shells/org.kde.plasma.desktop/contents/lockscreen/LockScreenUi.qml`. The block keeps the password interface visible while the pointer uses Axidev OSK. Running setup again restores a block removed by a Plasma package update before reporting any other managed-file drift. Setup and removal refuse partial or edited markers.

LightDM uses a `greeter-wrapper` drop-in. greetd replaces only the default-session command line with `/etc/axidev-osk/greetd-session-wrapper`, while `/etc/axidev-osk/greeter.json` keeps the exact original value for removal.

The LightDM and greetd shell wrappers start the original greeter before invoking the Axidev launcher. A missing Python package, incompatible Qt runtime, keyboard crash, or display-detection error cannot stop the original greeter. The keyboard retries after 1, 2, 4, 8, 16, 32, and then 60 seconds until the greeter exits.

Expand Down Expand Up @@ -203,7 +205,7 @@ Uninstall stops when permission or autostart cleanup fails. `uninstall --force`

Permission setup manages `/etc/modules-load.d/axidev-osk-uinput.conf` and `/etc/udev/rules.d/70-axidev-io-uinput.rules` through the application command line. Removal deletes only files whose contents still match Axidev OSK's definitions, and it does not unload the shared `uinput` module. Autostart setup manages the selected user's XDG autostart file.

Files owned by a configured manager are conditional. `/etc/axidev-osk/greeter.json` records the selected adapter. Plasma Login Manager owns its user service and target link. LightDM owns its drop-in and wrapper. greetd owns its wrapper and restores the previous command during removal.
Files owned by a configured manager are conditional. `/etc/axidev-osk/greeter.json` records the selected adapter. Plasma Login Manager owns its KWin input-method desktop entry, systemd drop-in, and KWin configuration. It also adds and removes only the exact marked block in Plasma's lock-screen QML. LightDM owns its drop-in and wrapper. greetd owns its wrapper and restores the previous command during removal.

The uninstaller removes exact managed greeter files before it disables the Axidev OSK uinput rule. It stops on changed files unless `--force` is selected. Shared `uinput` memberships remain in place.

Expand Down
34 changes: 31 additions & 3 deletions src/axidev_osk/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import ctypes
import logging
import os
import sys
from importlib.metadata import PackageNotFoundError, version
from importlib.resources import files
Expand All @@ -12,8 +13,11 @@
from PySide6.QtWidgets import QApplication

from .runtime.application import ApplicationRuntime
from .runtime.registries import ServiceRegistry
from .services.keyboard import KeyboardService
from .services.kwin_lock import KWinLockService
from .services.single_instance import ExistingInstanceActivated
from .windows.overlay import prepare_always_on_top_window_environment
from .windows.overlay import OverlayBackend, prepare_always_on_top_window_environment


_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -48,6 +52,21 @@ def _set_application_icon(app: QApplication) -> None:
app.setWindowIcon(icon)


def _input_panel_services(
app: QApplication,
backend: OverlayBackend,
*,
lock_lifecycle: bool,
) -> ServiceRegistry | None:
if backend != OverlayBackend.WAYLAND_INPUT_PANEL:
return None
services = ServiceRegistry()
services.register("keyboard", KeyboardService(), autostart=not lock_lifecycle)
if lock_lifecycle:
services.register("kwin_lock", KWinLockService(parent=app))
return services


def main() -> int:
"""Run the Axidev OSK Qt application.

Expand All @@ -68,12 +87,21 @@ def main() -> int:
)
_set_process_name("axidev-osk")
_logger.info("Starting axidev-osk v%s", _package_version())
prepare_always_on_top_window_environment()
overlay_backend = prepare_always_on_top_window_environment()
lock_lifecycle = (
overlay_backend == OverlayBackend.WAYLAND_INPUT_PANEL
and os.environ.get("AXIDEV_OSK_GREETER") != "1"
)
app = QApplication(sys.argv)
app.setApplicationName("axidev-osk")
_set_application_icon(app)
app.setQuitOnLastWindowClosed(False)
runtime = ApplicationRuntime(app)
runtime = ApplicationRuntime(
app,
services=_input_panel_services(app, overlay_backend, lock_lifecycle=lock_lifecycle),
confirm_quit=overlay_backend != OverlayBackend.WAYLAND_INPUT_PANEL,
show_startup_windows=not lock_lifecycle,
)
try:
return runtime.start()
except ExistingInstanceActivated:
Expand Down
Loading