fix(client-linux): share one GamepadService across app activations
apple / swift (push) Successful in 1m30s
arch / build-publish (push) Successful in 9m24s
apple / screenshots (push) Successful in 6m48s
ci / rust (push) Failing after 36s
ci / web (push) Successful in 58s
android / android (push) Successful in 11m35s
ci / docs-site (push) Successful in 1m2s
ci / bench (push) Successful in 4m59s
decky / build-publish (push) Successful in 26s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 2m48s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 33s
deb / build-publish (push) Successful in 9m19s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m46s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m24s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 55s
flatpak / build-publish (push) Successful in 4m49s
docker / deploy-docs (push) Has been cancelled
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
apple / swift (push) Successful in 1m30s
arch / build-publish (push) Successful in 9m24s
apple / screenshots (push) Successful in 6m48s
ci / rust (push) Failing after 36s
ci / web (push) Successful in 58s
android / android (push) Successful in 11m35s
ci / docs-site (push) Successful in 1m2s
ci / bench (push) Successful in 4m59s
decky / build-publish (push) Successful in 26s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 2m48s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 33s
deb / build-publish (push) Successful in 9m19s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m46s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m24s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 55s
flatpak / build-publish (push) Successful in 4m49s
docker / deploy-docs (push) Has been cancelled
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Has been cancelled
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Has been cancelled
`build_ui` (the GTK `activate` handler) started a fresh SDL3 gamepad worker thread on every reactivation of the already-running singleton (another --connect, the launcher clicked twice, ...). sdl3 only lets the first thread ever to call sdl3::init() hold "main thread" status, so every later activation's worker thread failed permanently with "Cannot initialize `Sdl` from a thread other than the main thread", silently disabling controller support for the rest of the process. Start the GamepadService once in run() and clone it into build_ui instead of starting a new one per activation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -154,13 +154,21 @@ pub fn run() -> glib::ExitCode {
|
||||
builder = builder.flags(gtk::gio::ApplicationFlags::NON_UNIQUE);
|
||||
}
|
||||
let app = builder.build();
|
||||
app.connect_activate(build_ui);
|
||||
// One SDL context for the whole process: `activate` fires again on every subsequent
|
||||
// launch forwarded to this already-running singleton (another `--connect`, the desktop
|
||||
// icon clicked twice, …). SDL only ever lets the FIRST thread that calls `sdl3::init()`
|
||||
// hold the "main thread" — a second `GamepadService::start()` from a later `activate`
|
||||
// would spawn a new thread that fails that check forever. Starting it once here and
|
||||
// cloning it into each `build_ui` keeps the worker thread (and its pad state) shared
|
||||
// across every window instead.
|
||||
let gamepad = crate::gamepad::GamepadService::start();
|
||||
app.connect_activate(move |gtk_app| build_ui(gtk_app, gamepad.clone()));
|
||||
// GTK doesn't see our argv (`--connect` is handled in `build_ui`); an empty argv also
|
||||
// keeps GApplication from rejecting unknown options.
|
||||
app.run_with_args(&[] as &[&str])
|
||||
}
|
||||
|
||||
fn build_ui(gtk_app: &adw::Application) {
|
||||
fn build_ui(gtk_app: &adw::Application, gamepad: crate::gamepad::GamepadService) {
|
||||
let identity = match crate::trust::load_or_create_identity() {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
@@ -203,7 +211,7 @@ fn build_ui(gtk_app: &adw::Application) {
|
||||
toasts,
|
||||
settings: Rc::new(RefCell::new(Settings::load())),
|
||||
identity,
|
||||
gamepad: crate::gamepad::GamepadService::start(),
|
||||
gamepad,
|
||||
busy: std::cell::Cell::new(false),
|
||||
fullscreen,
|
||||
// (`--browse` makes cli_connect_request None — browse mode returns to the
|
||||
|
||||
Reference in New Issue
Block a user