Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix!: Lazily activate Unix adapters #324

Merged
merged 9 commits into from
Jan 3, 2024
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 15 additions & 21 deletions bindings/c/examples/sdl/hello_world.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void accesskit_sdl_adapter_init(struct accesskit_sdl_adapter *adapter,
(void *)wmInfo.info.cocoa.window, source, source_userdata, handler);
#elif defined(UNIX)
adapter->adapter =
accesskit_unix_adapter_new(source, source_userdata, false, handler);
accesskit_unix_adapter_new(source, source_userdata, handler);
#elif defined(_WIN32)
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
Expand Down Expand Up @@ -111,10 +111,8 @@ void accesskit_sdl_adapter_update_if_active(
accesskit_macos_queued_events_raise(events);
}
#elif defined(UNIX)
if (adapter->adapter != NULL) {
accesskit_unix_adapter_update(adapter->adapter,
update_factory(update_factory_userdata));
}
accesskit_unix_adapter_update_if_active(adapter->adapter, update_factory,
update_factory_userdata);
#elif defined(_WIN32)
accesskit_windows_queued_events *events =
accesskit_windows_subclassing_adapter_update_if_active(
Expand All @@ -135,29 +133,25 @@ void accesskit_sdl_adapter_update_window_focus_state(
accesskit_macos_queued_events_raise(events);
}
#elif defined(UNIX)
if (adapter->adapter != NULL) {
accesskit_unix_adapter_update_window_focus_state(adapter->adapter,
is_focused);
}
accesskit_unix_adapter_update_window_focus_state(adapter->adapter,
is_focused);
#endif
/* On Windows, the subclassing adapter takes care of this. */
}

void accesskit_sdl_adapter_update_root_window_bounds(
const struct accesskit_sdl_adapter *adapter, SDL_Window *window) {
#if defined(UNIX)
if (adapter->adapter != NULL) {
int x, y, width, height;
SDL_GetWindowPosition(window, &x, &y);
SDL_GetWindowSize(window, &width, &height);
int top, left, bottom, right;
SDL_GetWindowBordersSize(window, &top, &left, &bottom, &right);
accesskit_rect outer_bounds = {x - left, y - top, x + width + right,
y + height + bottom};
accesskit_rect inner_bounds = {x, y, x + width, y + height};
accesskit_unix_adapter_set_root_window_bounds(adapter->adapter,
outer_bounds, inner_bounds);
}
int x, y, width, height;
SDL_GetWindowPosition(window, &x, &y);
SDL_GetWindowSize(window, &width, &height);
int top, left, bottom, right;
SDL_GetWindowBordersSize(window, &top, &left, &bottom, &right);
accesskit_rect outer_bounds = {x - left, y - top, x + width + right,
y + height + bottom};
accesskit_rect inner_bounds = {x, y, x + width, y + height};
accesskit_unix_adapter_set_root_window_bounds(adapter->adapter, outer_bounds,
inner_bounds);
#endif
}

Expand Down
8 changes: 7 additions & 1 deletion bindings/c/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1123,5 +1123,11 @@ impl ActionHandler for FfiActionHandler {
}
}

#[repr(transparent)]
pub struct tree_update_factory_userdata(pub *mut c_void);

unsafe impl Send for tree_update_factory_userdata {}

/// This function can't return a null pointer. Ownership of the returned value will be transfered to the caller.
pub type tree_update_factory = Option<extern "C" fn(*mut c_void) -> *mut tree_update>;
pub type tree_update_factory =
Option<extern "C" fn(tree_update_factory_userdata) -> *mut tree_update>;
7 changes: 5 additions & 2 deletions bindings/c/src/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// the LICENSE-MIT file), at your option.

use crate::{
action_handler, box_from_ptr, ref_from_ptr, tree_update, tree_update_factory, BoxCastPtr,
CastPtr,
action_handler, box_from_ptr, ref_from_ptr, tree_update, tree_update_factory,
tree_update_factory_userdata, BoxCastPtr, CastPtr,
};
use accesskit_macos::{
add_focus_forwarder_to_window_class, Adapter, NSPoint, QueuedEvents, SubclassingAdapter,
Expand Down Expand Up @@ -147,6 +147,7 @@ impl macos_subclassing_adapter {
handler: *mut action_handler,
) -> *mut macos_subclassing_adapter {
let source = source.unwrap();
let source_userdata = tree_update_factory_userdata(source_userdata);
let handler = box_from_ptr(handler);
let adapter = SubclassingAdapter::new(
view,
Expand Down Expand Up @@ -174,6 +175,7 @@ impl macos_subclassing_adapter {
handler: *mut action_handler,
) -> *mut macos_subclassing_adapter {
let source = source.unwrap();
let source_userdata = tree_update_factory_userdata(source_userdata);
let handler = box_from_ptr(handler);
let adapter = SubclassingAdapter::for_window(
window,
Expand Down Expand Up @@ -211,6 +213,7 @@ impl macos_subclassing_adapter {
update_factory_userdata: *mut c_void,
) -> *mut macos_queued_events {
let update_factory = update_factory.unwrap();
let update_factory_userdata = tree_update_factory_userdata(update_factory_userdata);
let adapter = ref_from_ptr(adapter);
let events =
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
Expand Down
36 changes: 18 additions & 18 deletions bindings/c/src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
// the LICENSE-MIT file), at your option.

use crate::{
action_handler, box_from_ptr, ref_from_ptr, tree_update, tree_update_factory, BoxCastPtr,
CastPtr,
action_handler, box_from_ptr, ref_from_ptr, tree_update_factory, tree_update_factory_userdata,
BoxCastPtr, CastPtr,
};
use accesskit::Rect;
use accesskit_unix::Adapter;
use std::{os::raw::c_void, ptr};
use std::os::raw::c_void;

pub struct unix_adapter {
_private: [u8; 0],
Expand All @@ -22,22 +22,20 @@ impl CastPtr for unix_adapter {
impl BoxCastPtr for unix_adapter {}

impl unix_adapter {
/// This function will take ownership of the pointer returned by `initial_state`, which can't be null.
/// This function will take ownership of the pointer returned by `source`, which can't be null.
///
/// `source` can be called from any thread.
#[no_mangle]
pub extern "C" fn accesskit_unix_adapter_new(
initial_state: tree_update_factory,
initial_state_userdata: *mut c_void,
is_window_focused: bool,
source: tree_update_factory,
source_userdata: *mut c_void,
handler: *mut action_handler,
) -> *mut unix_adapter {
let initial_state = initial_state.unwrap();
let source = source.unwrap();
let source_userdata = tree_update_factory_userdata(source_userdata);
let handler = box_from_ptr(handler);
let adapter = Adapter::new(
move || *box_from_ptr(initial_state(initial_state_userdata)),
is_window_focused,
handler,
);
adapter.map_or_else(ptr::null_mut, BoxCastPtr::to_mut_ptr)
let adapter = Adapter::new(move || *box_from_ptr(source(source_userdata)), handler);
BoxCastPtr::to_mut_ptr(adapter)
}

#[no_mangle]
Expand All @@ -57,13 +55,15 @@ impl unix_adapter {

/// This function takes ownership of `update`.
#[no_mangle]
pub extern "C" fn accesskit_unix_adapter_update(
pub extern "C" fn accesskit_unix_adapter_update_if_active(
adapter: *const unix_adapter,
update: *mut tree_update,
update_factory: tree_update_factory,
update_factory_userdata: *mut c_void,
) {
let update_factory = update_factory.unwrap();
let update_factory_userdata = tree_update_factory_userdata(update_factory_userdata);
let adapter = ref_from_ptr(adapter);
let update = box_from_ptr(update);
adapter.update(*update);
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
}

/// Update the tree state based on whether the window is focused.
Expand Down
4 changes: 3 additions & 1 deletion bindings/c/src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

use crate::{
action_handler, box_from_ptr, opt_struct, ref_from_ptr, tree_update, tree_update_factory,
BoxCastPtr, CastPtr,
tree_update_factory_userdata, BoxCastPtr, CastPtr,
};
use accesskit_windows::*;
use std::{os::raw::c_void, ptr};
Expand Down Expand Up @@ -151,6 +151,7 @@ impl windows_subclassing_adapter {
handler: *mut action_handler,
) -> *mut windows_subclassing_adapter {
let source = source.unwrap();
let source_userdata = tree_update_factory_userdata(source_userdata);
let handler = box_from_ptr(handler);
let adapter = SubclassingAdapter::new(
hwnd,
Expand Down Expand Up @@ -188,6 +189,7 @@ impl windows_subclassing_adapter {
update_factory_userdata: *mut c_void,
) -> *mut windows_queued_events {
let update_factory = update_factory.unwrap();
let update_factory_userdata = tree_update_factory_userdata(update_factory_userdata);
let adapter = ref_from_ptr(adapter);
let events =
adapter.update_if_active(|| *box_from_ptr(update_factory(update_factory_userdata)));
Expand Down
3 changes: 2 additions & 1 deletion platforms/unix/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ tokio = ["dep:tokio", "atspi/tokio", "zbus/tokio"]
accesskit = { version = "0.12.1", path = "../../common" }
accesskit_consumer = { version = "0.16.1", path = "../../consumer" }
async-channel = "2.1.1"
async-lock = "2.7.0"
async-once-cell = "0.5.3"
atspi = { version = "0.19", default-features = false }
futures-lite = "1.13"
futures-util = "0.3.27"
once_cell = "1.17.1"
serde = "1.0"
tokio = { version = "1.32.0", optional = true, features = ["rt", "net", "time"] }
zbus = { version = "3.14", default-features = false }

Loading