68 lines
2.1 KiB
Go
68 lines
2.1 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package app
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
|
|
"git.stormux.org/storm/cthulhu/internal/lifecycle"
|
|
"git.stormux.org/storm/cthulhu/internal/platform/session"
|
|
"git.stormux.org/storm/cthulhu/internal/platform/wayland"
|
|
"git.stormux.org/storm/cthulhu/internal/platform/xorg"
|
|
)
|
|
|
|
type desktopInputBackend interface {
|
|
Start(context.Context) error
|
|
Stop(context.Context) error
|
|
}
|
|
|
|
// Missing desktop keyboard capabilities must not prevent AT-SPI, speech and
|
|
// braille from running on Wayland. Explicit X11 backends keep their existing
|
|
// optional Xwayland startup behavior.
|
|
// Other backends retain their own startup contract. The lifecycle runner still
|
|
// owns cleanup, including a native listener whose startup failed.
|
|
func desktopInputService(name string, backend desktopInputBackend, logger *slog.Logger) lifecycle.Service {
|
|
service := lifecycle.Service{Name: name, Start: backend.Start, Stop: backend.Stop}
|
|
switch backend.(type) {
|
|
case *wayland.Keyboard:
|
|
service.Start = func(ctx context.Context) error {
|
|
err := backend.Start(ctx)
|
|
if ctx.Err() != nil {
|
|
return ctx.Err()
|
|
}
|
|
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
|
return err
|
|
}
|
|
if err != nil {
|
|
logger.Warn("Wayland keyboard access unavailable; continuing with AT-SPI reading only", "error", err)
|
|
}
|
|
return nil
|
|
}
|
|
case *xorg.Listener, *xorg.CommandListener:
|
|
if session.Wayland() {
|
|
service.Start = func(ctx context.Context) error {
|
|
return startOptionalXorg(ctx, name, backend.Start, logger)
|
|
}
|
|
}
|
|
}
|
|
return service
|
|
}
|
|
|
|
func startOptionalXorg(ctx context.Context, name string, start func(context.Context) error, logger *slog.Logger) error {
|
|
err := start(ctx)
|
|
if ctx.Err() != nil {
|
|
return ctx.Err()
|
|
}
|
|
if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
|
return err
|
|
}
|
|
if err != nil {
|
|
logger.Warn("X11 input service unavailable on Wayland; continuing without it", "service", name, "error", err)
|
|
}
|
|
return nil
|
|
}
|