Skip to content

Commit

Permalink
Fix panic with Narrator on Windows when transferring narrator focus
Browse files Browse the repository at this point in the history
The action requests on Windows typically come in from a non-main thread,
so we'd try to clone the send wrapper in `do_action`
in a non-main thread. That panics unfortunately - send-wrapper
requires the clone to be done in the original thread.

To work around this, wrap the send-wrapper in an Arc, which we can
safely clone. Then inside the closure invoked from within the main thread,
we can clone the send wrapper safely and then take out the Weak
from it (safely as well).
  • Loading branch information
tronical committed Jun 15, 2023
1 parent 6db6711 commit 5efbbef
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions internal/backends/winit/accesskit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,20 +426,24 @@ struct CachedNode {
}

struct ActionForwarder {
wrapped_window_adapter_weak: send_wrapper::SendWrapper<Weak<WinitWindowAdapter>>,
wrapped_window_adapter_weak: Arc<send_wrapper::SendWrapper<Weak<WinitWindowAdapter>>>,
}

impl ActionForwarder {
pub fn new(window_adapter: &Weak<WinitWindowAdapter>) -> Self {
Self { wrapped_window_adapter_weak: send_wrapper::SendWrapper::new(window_adapter.clone()) }
Self {
wrapped_window_adapter_weak: Arc::new(send_wrapper::SendWrapper::new(
window_adapter.clone(),
)),
}
}
}

impl accesskit::ActionHandler for ActionForwarder {
fn do_action(&self, request: ActionRequest) {
let wrapped_window_adapter_weak = self.wrapped_window_adapter_weak.clone();
i_slint_core::api::invoke_from_event_loop(move || {
let Some(window_adapter) = wrapped_window_adapter_weak.take().upgrade() else { return };
let Some(window_adapter) = wrapped_window_adapter_weak.as_ref().clone().take().upgrade() else { return };
window_adapter.accesskit_adapter.handle_request(request)
})
.ok();
Expand Down

0 comments on commit 5efbbef

Please sign in to comment.