Skip to content
Open
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
7 changes: 7 additions & 0 deletions platforms/macos/src/subclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,13 @@ impl SubclassingAdapter {
}
}

// SAFETY: SubclassingAdapter is always created and accessed on the main thread.
// The Send + Sync bounds are required by iced's Proxy<T> / Notifier trait,
// which wraps the adapter in a channel — but actual accessibility callbacks
// only ever fire on the main thread.
unsafe impl Send for SubclassingAdapter {}
unsafe impl Sync for SubclassingAdapter {}

impl Drop for SubclassingAdapter {
fn drop(&mut self) {
let prev_class = self.associated.ivars().prev_class;
Expand Down
16 changes: 10 additions & 6 deletions platforms/windows/src/subclass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,15 @@ impl SubclassingAdapter {
/// handler will always be called on that thread. The action handler
/// may or may not be called on that thread.
///
/// # Panics
/// # Note
///
/// Panics if the window is already visible.
/// Ideally, this should be called before the window is shown for the first
/// time, but it will still work if the window is already visible.
pub fn new(
hwnd: HWND,
activation_handler: impl 'static + ActivationHandler,
action_handler: impl 'static + ActionHandler + Send,
) -> Self {
if unsafe { IsWindowVisible(hwnd) }.into() {
panic!("The AccessKit Windows subclassing adapter must be created before the window is shown (made visible) for the first time.");
}

let mut r#impl = SubclassImpl::new(hwnd, activation_handler, action_handler);
r#impl.install();
Self(r#impl)
Expand Down Expand Up @@ -195,6 +192,13 @@ impl SubclassingAdapter {
}
}

// SAFETY: SubclassingAdapter is always created and accessed on the UI thread.
// The Send + Sync bounds are required by iced's Proxy<T> / Notifier trait,
// which wraps the adapter in a channel — but actual accessibility callbacks
// (WM_GETOBJECT, focus changes) only ever fire on the window's thread.
unsafe impl Send for SubclassingAdapter {}
unsafe impl Sync for SubclassingAdapter {}

impl Drop for SubclassingAdapter {
fn drop(&mut self) {
self.0.uninstall();
Expand Down
10 changes: 4 additions & 6 deletions platforms/winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,18 @@ impl Adapter {
/// the first update. However, remember that each of these handlers may be
/// called on any thread, depending on the underlying platform adapter.
///
/// # Panics
/// # Note
///
/// Panics if the window is already visible.
/// Ideally, this should be called before the window is shown for the first
/// time, but it will still work if the window is already visible (the
/// platform adapter will attach to the existing window).
pub fn with_direct_handlers(
event_loop: &dyn ActiveEventLoop,
window: &dyn Window,
activation_handler: impl 'static + ActivationHandler + Send,
action_handler: impl 'static + ActionHandler + Send,
deactivation_handler: impl 'static + DeactivationHandler + Send,
) -> Self {
if window.is_visible() == Some(true) {
panic!("The AccessKit winit adapter must be created before the window is shown (made visible) for the first time.");
}

let inner = platform_impl::Adapter::new(
event_loop,
window,
Expand Down
2 changes: 1 addition & 1 deletion platforms/winit/src/platform_impl/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub struct Adapter {
impl Adapter {
pub fn new(
_event_loop: &dyn ActiveEventLoop,
window: &Window,
window: &dyn Window,
activation_handler: impl 'static + ActivationHandler,
action_handler: impl 'static + ActionHandler + Send,
_deactivation_handler: impl 'static + DeactivationHandler,
Expand Down