Skip to content

Commit

Permalink
fix!: Lazily activate Unix adapters (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
DataTriny authored Jan 3, 2024
1 parent 5a4c6f3 commit 54ed036
Show file tree
Hide file tree
Showing 14 changed files with 860 additions and 649 deletions.
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

0 comments on commit 54ed036

Please sign in to comment.