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);
|
builder = builder.flags(gtk::gio::ApplicationFlags::NON_UNIQUE);
|
||||||
}
|
}
|
||||||
let app = builder.build();
|
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
|
// GTK doesn't see our argv (`--connect` is handled in `build_ui`); an empty argv also
|
||||||
// keeps GApplication from rejecting unknown options.
|
// keeps GApplication from rejecting unknown options.
|
||||||
app.run_with_args(&[] as &[&str])
|
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() {
|
let identity = match crate::trust::load_or_create_identity() {
|
||||||
Ok(i) => i,
|
Ok(i) => i,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -203,7 +211,7 @@ fn build_ui(gtk_app: &adw::Application) {
|
|||||||
toasts,
|
toasts,
|
||||||
settings: Rc::new(RefCell::new(Settings::load())),
|
settings: Rc::new(RefCell::new(Settings::load())),
|
||||||
identity,
|
identity,
|
||||||
gamepad: crate::gamepad::GamepadService::start(),
|
gamepad,
|
||||||
busy: std::cell::Cell::new(false),
|
busy: std::cell::Cell::new(false),
|
||||||
fullscreen,
|
fullscreen,
|
||||||
// (`--browse` makes cli_connect_request None — browse mode returns to the
|
// (`--browse` makes cli_connect_request None — browse mode returns to the
|
||||||
|
|||||||
Reference in New Issue
Block a user