Skip to content

Commit c1251b0

Browse files
committed
Various fixes after rebase
1 parent 57d75b5 commit c1251b0

File tree

7 files changed

+91
-92
lines changed

7 files changed

+91
-92
lines changed

bindings/python/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ edition = "2021"
1111
[lib]
1212
name = "accesskit"
1313
crate-type = ["cdylib"]
14+
doc = false
1415

1516
[features]
1617
extension-module = ["pyo3/extension-module"]

bindings/python/examples/pygame/hello_world.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@
99
WINDOW_WIDTH = 400
1010
WINDOW_HEIGHT = 200
1111

12-
WINDOW_ID = accesskit.NodeId(1)
13-
BUTTON_1_ID = accesskit.NodeId(2)
14-
BUTTON_2_ID = accesskit.NodeId(3)
15-
ANNOUNCEMENT_ID = accesskit.NodeId(4)
12+
WINDOW_ID = 0
13+
BUTTON_1_ID = 1
14+
BUTTON_2_ID = 2
15+
ANNOUNCEMENT_ID = 3
1616
INITIAL_FOCUS = BUTTON_1_ID
1717

1818
BUTTON_1_RECT = accesskit.Rect(20.0, 20.0, 100.0, 60.0)
@@ -50,7 +50,7 @@ def __init__(self, app_name, source, action_handler):
5050
)
5151
elif os.name == "posix":
5252
self.adapter = accesskit.unix.Adapter.create(
53-
app_name, "pygame", pygame.version.ver, source, action_handler
53+
app_name, "pygame", pygame.version.ver, source, False, action_handler
5454
)
5555
elif PLATFORM_SYSTEM == "Windows":
5656
hwnd = pygame.display.get_wm_info()["window"]
@@ -73,17 +73,23 @@ def update_if_active(self, update_factory):
7373
else:
7474
self.adapter.update(update_factory())
7575

76+
def update_window_focus_state(self, is_focused):
77+
if not self.adapter is None:
78+
if PLATFORM_SYSTEM == "Darwin":
79+
events = self.adapter.update_window_focus_state(is_focused)
80+
if not events is None:
81+
events.raise_events()
82+
elif os.name == "posix":
83+
self.adapter.update_window_focus_state(is_focused)
84+
# On Windows, the subclassing adapter takes care of this.
85+
7686

7787
class WindowState:
7888
def __init__(self):
79-
self._focus = INITIAL_FOCUS
80-
self.is_window_focused = False
89+
self.focus = INITIAL_FOCUS
8190
self.announcement = None
8291
self.node_classes = accesskit.NodeClassSet()
8392

84-
def focus(self):
85-
return self._focus if self.is_window_focused else None
86-
8793
def build_root(self):
8894
builder = accesskit.NodeBuilder(accesskit.Role.WINDOW)
8995
builder.set_children([BUTTON_1_ID, BUTTON_2_ID])
@@ -96,9 +102,8 @@ def build_initial_tree(self):
96102
root = self.build_root()
97103
button_1 = build_button(BUTTON_1_ID, "Button 1", self.node_classes)
98104
button_2 = build_button(BUTTON_2_ID, "Button 2", self.node_classes)
99-
result = accesskit.TreeUpdate()
105+
result = accesskit.TreeUpdate.with_focus(self.focus)
100106
result.tree = accesskit.Tree(WINDOW_ID)
101-
result.focus = self.focus()
102107
result.nodes.append((WINDOW_ID, root))
103108
result.nodes.append((BUTTON_1_ID, button_1))
104109
result.nodes.append((BUTTON_2_ID, button_2))
@@ -118,21 +123,19 @@ def press_button(self, adapter, id):
118123
adapter.update_if_active(self.build_tree_update_for_button_press)
119124

120125
def build_tree_update_for_button_press(self):
121-
update = accesskit.TreeUpdate()
126+
update = accesskit.TreeUpdate.with_focus(self.focus)
122127
update.nodes.append(
123128
(ANNOUNCEMENT_ID, build_announcement(self.announcement, self.node_classes))
124129
)
125130
update.nodes.append((WINDOW_ID, self.build_root()))
126-
update.focus = self.focus()
127131
return update
128132

129-
def update_focus(self, adapter):
133+
def set_focus(self, adapter, focus):
134+
self.focus = focus
130135
adapter.update_if_active(self.build_tree_update_for_focus_update)
131136

132137
def build_tree_update_for_focus_update(self):
133-
update = accesskit.TreeUpdate()
134-
update.focus = self.focus()
135-
return update
138+
return accesskit.TreeUpdate.with_focus(self.focus)
136139

137140

138141
def do_action(request):
@@ -171,26 +174,23 @@ def main():
171174
if event.type == pygame.QUIT:
172175
is_running = False
173176
elif event.type == pygame.WINDOWFOCUSGAINED:
174-
state.is_window_focused = True
175-
state.update_focus(adapter)
177+
adapter.update_window_focus_state(True)
176178
elif event.type == pygame.WINDOWFOCUSLOST:
177-
state.is_window_focused = False
178-
state.update_focus(adapter)
179+
adapter.update_window_focus_state(False)
179180
elif event.type == pygame.KEYDOWN:
180181
if event.key == pygame.K_TAB:
181-
state._focus = (
182-
BUTTON_2_ID if state._focus == BUTTON_1_ID else BUTTON_1_ID
182+
new_focus = (
183+
BUTTON_2_ID if state.focus == BUTTON_1_ID else BUTTON_1_ID
183184
)
184-
state.update_focus(adapter)
185+
state.set_focus(adapter, new_focus)
185186
elif event.key == pygame.K_SPACE:
186-
state.press_button(adapter, state._focus)
187+
state.press_button(adapter, state.focus)
187188
elif event.type == ACCESSKIT_EVENT and event.__dict__["target"] in [
188189
BUTTON_1_ID,
189190
BUTTON_2_ID,
190191
]:
191192
if event.__dict__["event"] == SET_FOCUS_MSG:
192-
state._focus = event.__dict__["target"]
193-
state.update_focus(adapter)
193+
state.set_focus(adapter, event.__dict__["target"])
194194
elif event.__dict__["event"] == DO_DEFAULT_ACTION_MSG:
195195
state.press_button(adapter, event.__dict__["target"])
196196

bindings/python/src/common.rs

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
// the LICENSE-APACHE file) or the MIT license (found in
44
// the LICENSE-MIT file), at your option.
55

6-
use pyo3::{basic::CompareOp, prelude::*, types::PyList};
7-
use std::num::NonZeroU128;
6+
use pyo3::{prelude::*, types::PyList};
87

98
#[pyclass(module = "accesskit")]
109
pub struct NodeClassSet(accesskit::NodeClassSet);
@@ -99,43 +98,7 @@ impl NodeBuilder {
9998
}
10099
}
101100

102-
#[derive(Clone, Copy)]
103-
#[pyclass(module = "accesskit")]
104-
pub struct NodeId(accesskit::NodeId);
105-
106-
#[pymethods]
107-
impl NodeId {
108-
#[new]
109-
pub fn new(content: NonZeroU128) -> NodeId {
110-
Self(accesskit::NodeId(content))
111-
}
112-
113-
pub fn __richcmp__(&self, other: &NodeId, op: CompareOp) -> bool {
114-
match op {
115-
CompareOp::Eq => self.0 == other.0,
116-
CompareOp::Ne => self.0 != other.0,
117-
_ => false,
118-
}
119-
}
120-
}
121-
122-
impl From<NodeId> for accesskit::NodeId {
123-
fn from(id: NodeId) -> Self {
124-
id.0
125-
}
126-
}
127-
128-
impl From<accesskit::NodeId> for NodeId {
129-
fn from(id: accesskit::NodeId) -> Self {
130-
Self(id)
131-
}
132-
}
133-
134-
impl From<&accesskit::NodeId> for NodeId {
135-
fn from(id: &accesskit::NodeId) -> Self {
136-
Self(*id)
137-
}
138-
}
101+
pub type NodeId = u64;
139102

140103
#[derive(Clone)]
141104
#[pyclass(module = "accesskit")]
@@ -178,9 +141,9 @@ impl From<CustomAction> for accesskit::CustomAction {
178141
}
179142
}
180143

181-
impl From<&accesskit::CustomAction> for CustomAction {
182-
fn from(action: &accesskit::CustomAction) -> Self {
183-
Self(action.clone())
144+
impl From<accesskit::CustomAction> for CustomAction {
145+
fn from(action: accesskit::CustomAction) -> Self {
146+
Self(action)
184147
}
185148
}
186149

@@ -205,7 +168,7 @@ impl TextPosition {
205168

206169
#[setter]
207170
pub fn set_node(&mut self, node: NodeId) {
208-
self.0.node = node.into()
171+
self.0.node = node.into();
209172
}
210173

211174
#[getter]
@@ -369,15 +332,15 @@ macro_rules! vec_property_methods {
369332
impl Node {
370333
$(#[getter]
371334
pub fn $getter(&self, py: Python) -> Py<PyList> {
372-
let values = self.inner().$getter().iter().map(<$py_item_type>::from).map(|i| i.into_py(py));
335+
let values = self.inner().$getter().iter().cloned().map(<$py_item_type>::from).map(|i| i.into_py(py));
373336
PyList::new(py, values).into()
374337
})*
375338
}
376339
$(#[pymethods]
377340
impl NodeBuilder {
378341
#[getter]
379342
pub fn $getter(&self, py: Python) -> Py<PyList> {
380-
let values = self.inner().$getter().iter().map(<$py_item_type>::from).map(|i| i.into_py(py));
343+
let values = self.inner().$getter().iter().cloned().map(<$py_item_type>::from).map(|i| i.into_py(py));
381344
PyList::new(py, values).into()
382345
}
383346
pub fn $setter(&mut self, values: &PyList) {
@@ -656,25 +619,20 @@ vec_property_methods! {
656619
#[pyclass(module = "accesskit", get_all, set_all)]
657620
pub struct Tree {
658621
pub root: NodeId,
659-
pub root_scroller: Option<NodeId>,
660622
}
661623

662624
#[pymethods]
663625
impl Tree {
664626
#[new]
665627
pub fn new(root: NodeId) -> Self {
666-
Self {
667-
root,
668-
root_scroller: None,
669-
}
628+
Self { root }
670629
}
671630
}
672631

673632
impl From<Tree> for accesskit::Tree {
674633
fn from(tree: Tree) -> Self {
675634
Self {
676635
root: tree.root.into(),
677-
root_scroller: tree.root_scroller.map(Into::into),
678636
}
679637
}
680638
}
@@ -684,17 +642,17 @@ impl From<Tree> for accesskit::Tree {
684642
pub struct TreeUpdate {
685643
pub nodes: Py<PyList>,
686644
pub tree: Option<Py<Tree>>,
687-
pub focus: Option<NodeId>,
645+
pub focus: NodeId,
688646
}
689647

690648
#[pymethods]
691649
impl TreeUpdate {
692-
#[new]
693-
pub fn new(py: Python<'_>) -> Self {
650+
#[staticmethod]
651+
pub fn with_focus(py: Python<'_>, focus: NodeId) -> Self {
694652
Self {
695653
nodes: PyList::empty(py).into(),
696654
tree: None,
697-
focus: None,
655+
focus,
698656
}
699657
}
700658
}
@@ -713,7 +671,7 @@ impl From<TreeUpdate> for accesskit::TreeUpdate {
713671
tree: update
714672
.tree
715673
.map(|tree| accesskit::Tree::from(*tree.as_ref(py).borrow())),
716-
focus: update.focus.map(Into::into),
674+
focus: update.focus.into(),
717675
})
718676
}
719677
}

bindings/python/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ fn accesskit(py: Python<'_>, m: &PyModule) -> PyResult<()> {
4646
m.add_class::<NodeClassSet>()?;
4747
m.add_class::<Node>()?;
4848
m.add_class::<NodeBuilder>()?;
49-
m.add_class::<NodeId>()?;
5049
m.add_class::<Tree>()?;
5150
m.add_class::<TreeUpdate>()?;
5251
m.add_class::<Affine>()?;

bindings/python/src/macos.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,30 @@ impl Adapter {
3939
///
4040
/// `view` must be a valid, unreleased pointer to an `NSView`.
4141
#[new]
42-
pub unsafe fn new(view: isize, initial_state: TreeUpdate, handler: Py<PyAny>) -> Self {
42+
pub unsafe fn new(
43+
view: isize,
44+
initial_state: TreeUpdate,
45+
is_view_focused: bool,
46+
handler: Py<PyAny>,
47+
) -> Self {
4348
Self(accesskit_macos::Adapter::new(
4449
view as *mut _,
4550
initial_state.into(),
51+
is_view_focused,
4652
Box::new(PythonActionHandler(handler)),
4753
))
4854
}
4955

50-
/// You must call `accesskit.macos.QueuedEvents.raise` on the returned value. It can be `None` in case of error.
56+
/// You must call `accesskit.macos.QueuedEvents.raise_events` on the returned value.
5157
pub fn update(&self, update: TreeUpdate) -> QueuedEvents {
5258
self.0.update(update.into()).into()
5359
}
5460

61+
/// You must call `accesskit.macos.QueuedEvents.raise_events` on the returned value.
62+
pub fn update_view_focus_state(&self, is_focused: bool) -> QueuedEvents {
63+
self.0.update_view_focus_state(is_focused).into()
64+
}
65+
5566
pub fn view_children(&self) -> isize {
5667
self.0.view_children() as _
5768
}
@@ -72,6 +83,8 @@ pub struct SubclassingAdapter(accesskit_macos::SubclassingAdapter);
7283
#[pymethods]
7384
impl SubclassingAdapter {
7485
/// Create an adapter that dynamically subclasses the specified view.
86+
/// This must be done before the view is shown or focused for
87+
/// the first time.
7588
///
7689
/// The action handler will always be called on the main thread.
7790
///
@@ -127,12 +140,12 @@ impl SubclassingAdapter {
127140
))
128141
}
129142

130-
/// You must call `accesskit.macos.QueuedEvents.raise` on the returned value. It can be `None` in case of error.
143+
/// You must call `accesskit.macos.QueuedEvents.raise_events` on the returned value.
131144
pub fn update(&self, update: TreeUpdate) -> QueuedEvents {
132145
self.0.update(update.into()).into()
133146
}
134147

135-
/// You must call `accesskit.macos.QueuedEvents.raise` on the returned value. It can be `None` in case of error or if the window is not active.
148+
/// You must call `accesskit.macos.QueuedEvents.raise_events` on the returned value. It can be `None` if the window is not active.
136149
pub fn update_if_active(
137150
&self,
138151
py: Python<'_>,
@@ -145,6 +158,11 @@ impl SubclassingAdapter {
145158
})
146159
.map(Into::into)
147160
}
161+
162+
/// You must call `accesskit.macos.QueuedEvents.raise_events` on the returned value. It can be `None` if the window is not active.
163+
pub fn update_view_focus_state(&self, is_focused: bool) -> Option<QueuedEvents> {
164+
self.0.update_view_focus_state(is_focused).map(Into::into)
165+
}
148166
}
149167

150168
/// Modifies the specified class, which must be a subclass of `NSWindow`,

bindings/python/src/unix.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ impl Adapter {
1717
toolkit_name: &str,
1818
toolkit_version: &str,
1919
source: Py<PyAny>,
20+
is_window_focused: bool,
2021
handler: Py<PyAny>,
2122
) -> Option<Self> {
2223
accesskit_unix::Adapter::new(
@@ -33,6 +34,7 @@ impl Adapter {
3334
.into()
3435
})
3536
},
37+
is_window_focused,
3638
Box::new(PythonActionHandler(handler)),
3739
)
3840
.map(Self)
@@ -45,4 +47,8 @@ impl Adapter {
4547
pub fn update(&self, update: TreeUpdate) {
4648
self.0.update(update.into());
4749
}
50+
51+
pub fn update_window_focus_state(&self, is_focused: bool) {
52+
self.0.update_window_focus_state(is_focused);
53+
}
4854
}

0 commit comments

Comments
 (0)