Skip to content

Commit d360d20

Browse files
authored
refactor!: Decouple in-tree focus from host window/view focus (#278)
1 parent 3a7e63a commit d360d20

File tree

26 files changed

+719
-522
lines changed

26 files changed

+719
-522
lines changed

bindings/c/examples/sdl/hello_world.c

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ void accesskit_sdl_adapter_init(struct accesskit_sdl_adapter *adapter,
7676
adapter->adapter = accesskit_macos_subclassing_adapter_for_window(
7777
(void *)wmInfo.info.cocoa.window, source, source_userdata, handler);
7878
#elif defined(UNIX)
79-
adapter->adapter = accesskit_unix_adapter_new(app_name, "SDL", "2.0", source,
80-
source_userdata, handler);
79+
adapter->adapter = accesskit_unix_adapter_new(
80+
app_name, "SDL", "2.0", source, source_userdata, false, handler);
8181
#elif defined(_WIN32)
8282
SDL_SysWMinfo wmInfo;
8383
SDL_VERSION(&wmInfo.version);
@@ -145,6 +145,24 @@ void accesskit_sdl_adapter_update_if_active(
145145
#endif
146146
}
147147

148+
void accesskit_sdl_adapter_update_window_focus_state(
149+
const struct accesskit_sdl_adapter *adapter, bool is_focused) {
150+
#if defined(__APPLE__)
151+
accesskit_macos_queued_events *events =
152+
accesskit_macos_subclassing_adapter_update_view_focus_state(
153+
adapter->adapter, is_focused);
154+
if (events != NULL) {
155+
accesskit_macos_queued_events_raise(events);
156+
}
157+
#elif defined(UNIX)
158+
if (adapter->adapter != NULL) {
159+
accesskit_unix_adapter_update_window_focus_state(adapter->adapter,
160+
is_focused);
161+
}
162+
#endif
163+
/* On Windows, the subclassing adapter takes care of this. */
164+
}
165+
148166
void accesskit_sdl_adapter_update_root_window_bounds(
149167
const struct accesskit_sdl_adapter *adapter, SDL_Window *window) {
150168
#if defined(UNIX)
@@ -165,15 +183,13 @@ void accesskit_sdl_adapter_update_root_window_bounds(
165183

166184
struct window_state {
167185
accesskit_node_id focus;
168-
bool is_window_focused;
169186
const char *announcement;
170187
accesskit_node_class_set *node_classes;
171188
SDL_mutex *mutex;
172189
};
173190

174191
void window_state_init(struct window_state *state) {
175192
state->focus = INITIAL_FOCUS;
176-
state->is_window_focused = false;
177193
state->announcement = NULL;
178194
state->node_classes = accesskit_node_class_set_new();
179195
state->mutex = SDL_CreateMutex();
@@ -192,13 +208,6 @@ void window_state_unlock(struct window_state *state) {
192208
SDL_UnlockMutex(state->mutex);
193209
}
194210

195-
void window_state_set_tree_update_focus(const struct window_state *state,
196-
accesskit_tree_update *update) {
197-
if (state->is_window_focused) {
198-
accesskit_tree_update_set_focus(update, state->focus);
199-
}
200-
}
201-
202211
accesskit_node *window_state_build_root(const struct window_state *state) {
203212
accesskit_node_builder *builder =
204213
accesskit_node_builder_new(ACCESSKIT_ROLE_WINDOW);
@@ -218,10 +227,9 @@ accesskit_tree_update *window_state_build_initial_tree(
218227
build_button(BUTTON_1_ID, "Button 1", state->node_classes);
219228
accesskit_node *button_2 =
220229
build_button(BUTTON_2_ID, "Button 2", state->node_classes);
221-
accesskit_tree_update *result = accesskit_tree_update_with_capacity(
222-
(state->announcement != NULL) ? 4 : 3);
230+
accesskit_tree_update *result = accesskit_tree_update_with_capacity_and_focus(
231+
(state->announcement != NULL) ? 4 : 3, state->focus);
223232
accesskit_tree_update_set_tree(result, accesskit_tree_new(WINDOW_ID));
224-
window_state_set_tree_update_focus(state, result);
225233
accesskit_tree_update_push_node(result, WINDOW_ID, root);
226234
accesskit_tree_update_push_node(result, BUTTON_1_ID, button_1);
227235
accesskit_tree_update_push_node(result, BUTTON_2_ID, button_2);
@@ -238,10 +246,10 @@ accesskit_tree_update *build_tree_update_for_button_press(void *userdata) {
238246
accesskit_node *announcement =
239247
build_announcement(state->announcement, state->node_classes);
240248
accesskit_node *root = window_state_build_root(state);
241-
accesskit_tree_update *update = accesskit_tree_update_with_capacity(2);
249+
accesskit_tree_update *update =
250+
accesskit_tree_update_with_capacity_and_focus(2, state->focus);
242251
accesskit_tree_update_push_node(update, ANNOUNCEMENT_ID, announcement);
243252
accesskit_tree_update_push_node(update, WINDOW_ID, root);
244-
accesskit_tree_update_set_focus(update, state->focus);
245253
return update;
246254
}
247255

@@ -261,13 +269,15 @@ void window_state_press_button(struct window_state *state,
261269

262270
accesskit_tree_update *build_tree_update_for_focus_update(void *userdata) {
263271
struct window_state *state = userdata;
264-
accesskit_tree_update *update = accesskit_tree_update_new();
265-
accesskit_tree_update_set_focus(update, state->focus);
272+
accesskit_tree_update *update =
273+
accesskit_tree_update_with_focus(state->focus);
266274
return update;
267275
}
268276

269-
void window_state_update_focus(struct window_state *state,
270-
const struct accesskit_sdl_adapter *adapter) {
277+
void window_state_set_focus(struct window_state *state,
278+
const struct accesskit_sdl_adapter *adapter,
279+
accesskit_node_id focus) {
280+
state->focus = focus;
271281
accesskit_sdl_adapter_update_if_active(
272282
adapter, build_tree_update_for_focus_update, state);
273283
}
@@ -345,17 +355,10 @@ int main(int argc, char *argv[]) {
345355
event.window.windowID == window_id) {
346356
switch (event.window.event) {
347357
case SDL_WINDOWEVENT_FOCUS_GAINED:
348-
window_state_lock(&state);
349-
state.is_window_focused = true;
350-
window_state_update_focus(&state, &adapter);
351-
window_state_unlock(&state);
352-
continue;
358+
accesskit_sdl_adapter_update_window_focus_state(&adapter, true);
353359
break;
354360
case SDL_WINDOWEVENT_FOCUS_LOST:
355-
window_state_lock(&state);
356-
state.is_window_focused = false;
357-
window_state_update_focus(&state, &adapter);
358-
window_state_unlock(&state);
361+
accesskit_sdl_adapter_update_window_focus_state(&adapter, false);
359362
break;
360363
case SDL_WINDOWEVENT_MAXIMIZED:
361364
case SDL_WINDOWEVENT_MOVED:
@@ -370,12 +373,9 @@ int main(int argc, char *argv[]) {
370373
switch (event.key.keysym.sym) {
371374
case SDLK_TAB:
372375
window_state_lock(&state);
373-
if (state.focus == BUTTON_1_ID) {
374-
state.focus = BUTTON_2_ID;
375-
} else {
376-
state.focus = BUTTON_1_ID;
377-
}
378-
window_state_update_focus(&state, &adapter);
376+
accesskit_node_id new_focus =
377+
(state.focus == BUTTON_1_ID) ? BUTTON_2_ID : BUTTON_1_ID;
378+
window_state_set_focus(&state, &adapter, new_focus);
379379
window_state_unlock(&state);
380380
break;
381381
case SDLK_SPACE:
@@ -391,8 +391,7 @@ int main(int argc, char *argv[]) {
391391
if (target == BUTTON_1_ID || target == BUTTON_2_ID) {
392392
window_state_lock(&state);
393393
if (event.user.code == SET_FOCUS_MSG) {
394-
state.focus = target;
395-
window_state_update_focus(&state, &adapter);
394+
window_state_set_focus(&state, &adapter, target);
396395
} else if (event.user.code == DO_DEFAULT_ACTION_MSG) {
397396
window_state_press_button(&state, &adapter, target);
398397
}

bindings/c/examples/windows/hello_world.c

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,6 @@ void window_state_free(struct window_state *state) {
6868
free(state);
6969
}
7070

71-
void window_state_set_tree_update_focus(struct window_state *state,
72-
accesskit_tree_update *update) {
73-
if (state->is_window_focused) {
74-
accesskit_tree_update_set_focus(update, state->focus);
75-
}
76-
}
77-
7871
accesskit_node *window_state_build_root(struct window_state *state) {
7972
accesskit_node_builder *builder =
8073
accesskit_node_builder_new(ACCESSKIT_ROLE_WINDOW);
@@ -93,10 +86,9 @@ accesskit_tree_update *window_state_build_initial_tree(
9386
build_button(BUTTON_1_ID, "Button 1", state->node_classes);
9487
accesskit_node *button_2 =
9588
build_button(BUTTON_2_ID, "Button 2", state->node_classes);
96-
accesskit_tree_update *result = accesskit_tree_update_with_capacity(
97-
(state->announcement != NULL) ? 4 : 3);
89+
accesskit_tree_update *result = accesskit_tree_update_with_capacity_and_focus(
90+
(state->announcement != NULL) ? 4 : 3, state->focus);
9891
accesskit_tree_update_set_tree(result, accesskit_tree_new(WINDOW_ID));
99-
window_state_set_tree_update_focus(state, result);
10092
accesskit_tree_update_push_node(result, WINDOW_ID, root);
10193
accesskit_tree_update_push_node(result, BUTTON_1_ID, button_1);
10294
accesskit_tree_update_push_node(result, BUTTON_2_ID, button_2);
@@ -129,12 +121,24 @@ accesskit_windows_adapter *window_state_get_or_init_accesskit_adapter(
129121
accesskit_action_handler *action_handler =
130122
accesskit_action_handler_new(do_action, (void *)window);
131123
state->adapter = accesskit_windows_adapter_new(
132-
window, initial_tree, action_handler, state->uia_init_marker);
124+
window, initial_tree, state->is_window_focused, action_handler,
125+
state->uia_init_marker);
133126
state->uia_init_marker = NULL;
134127
return state->adapter;
135128
}
136129
}
137130

131+
void window_state_set_focus(struct window_state *state,
132+
accesskit_node_id focus) {
133+
state->focus = focus;
134+
if (state->adapter != NULL) {
135+
accesskit_tree_update *update = accesskit_tree_update_with_focus(focus);
136+
accesskit_windows_queued_events *events =
137+
accesskit_windows_adapter_update(state->adapter, update);
138+
accesskit_windows_queued_events_raise(events);
139+
}
140+
}
141+
138142
void window_state_press_button(struct window_state *state,
139143
accesskit_node_id id) {
140144
const char *text;
@@ -148,10 +152,10 @@ void window_state_press_button(struct window_state *state,
148152
accesskit_node *announcement =
149153
build_announcement(text, state->node_classes);
150154
accesskit_node *root = window_state_build_root(state);
151-
accesskit_tree_update *update = accesskit_tree_update_with_capacity(2);
155+
accesskit_tree_update *update =
156+
accesskit_tree_update_with_capacity_and_focus(2, state->focus);
152157
accesskit_tree_update_push_node(update, ANNOUNCEMENT_ID, announcement);
153158
accesskit_tree_update_push_node(update, WINDOW_ID, root);
154-
window_state_set_tree_update_focus(state, update);
155159
accesskit_windows_queued_events *events =
156160
accesskit_windows_adapter_update(state->adapter, update);
157161
accesskit_windows_queued_events_raise(events);
@@ -162,14 +166,13 @@ struct window_state *get_window_state(HWND window) {
162166
return (struct window_state *)(GetWindowLongPtr(window, GWLP_USERDATA));
163167
}
164168

165-
void update_focus(HWND window, bool is_window_focused) {
169+
void update_window_focus_state(HWND window, bool is_focused) {
166170
struct window_state *state = get_window_state(window);
167-
state->is_window_focused = is_window_focused;
171+
state->is_window_focused = is_focused;
168172
if (state->adapter != NULL) {
169-
accesskit_tree_update *update = accesskit_tree_update_new();
170-
window_state_set_tree_update_focus(state, update);
171173
accesskit_windows_queued_events *events =
172-
accesskit_windows_adapter_update(state->adapter, update);
174+
accesskit_windows_adapter_update_window_focus_state(state->adapter,
175+
is_focused);
173176
accesskit_windows_queued_events_raise(events);
174177
}
175178
}
@@ -220,19 +223,16 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
220223
}
221224
} else if (msg == WM_SETFOCUS || msg == WM_EXITMENULOOP ||
222225
msg == WM_EXITSIZEMOVE) {
223-
update_focus(hwnd, true);
226+
update_window_focus_state(hwnd, true);
224227
} else if (msg == WM_KILLFOCUS || msg == WM_ENTERMENULOOP ||
225228
msg == WM_ENTERSIZEMOVE) {
226-
update_focus(hwnd, false);
229+
update_window_focus_state(hwnd, false);
227230
} else if (msg == WM_KEYDOWN) {
228231
if (wParam == VK_TAB) {
229232
struct window_state *state = get_window_state(hwnd);
230-
if (state->focus == BUTTON_1_ID) {
231-
state->focus = BUTTON_2_ID;
232-
} else {
233-
state->focus = BUTTON_1_ID;
234-
}
235-
update_focus(hwnd, true);
233+
accesskit_node_id new_focus =
234+
(state->focus == BUTTON_1_ID) ? BUTTON_2_ID : BUTTON_1_ID;
235+
window_state_set_focus(state, new_focus);
236236
} else if (wParam == VK_SPACE) {
237237
struct window_state *window_state = get_window_state(hwnd);
238238
accesskit_node_id id = window_state->focus;
@@ -244,9 +244,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
244244
accesskit_node_id id = (accesskit_node_id)lParam;
245245
if (id == BUTTON_1_ID || id == BUTTON_2_ID) {
246246
struct window_state *state = get_window_state(hwnd);
247-
state->focus = id;
248-
bool is_window_focused = state->is_window_focused;
249-
update_focus(hwnd, is_window_focused);
247+
window_state_set_focus(state, id);
250248
}
251249
} else if (msg == DO_DEFAULT_ACTION_MSG) {
252250
accesskit_node_id id = (accesskit_node_id)lParam;

bindings/c/src/common.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -907,16 +907,24 @@ impl BoxCastPtr for tree_update {}
907907

908908
impl tree_update {
909909
#[no_mangle]
910-
pub extern "C" fn accesskit_tree_update_new() -> *mut tree_update {
911-
let update = TreeUpdate::default();
910+
pub extern "C" fn accesskit_tree_update_with_focus(focus: node_id) -> *mut tree_update {
911+
let update = TreeUpdate {
912+
nodes: vec![],
913+
tree: None,
914+
focus: focus.into(),
915+
};
912916
BoxCastPtr::to_mut_ptr(update)
913917
}
914918

915919
#[no_mangle]
916-
pub extern "C" fn accesskit_tree_update_with_capacity(capacity: usize) -> *mut tree_update {
920+
pub extern "C" fn accesskit_tree_update_with_capacity_and_focus(
921+
capacity: usize,
922+
focus: node_id,
923+
) -> *mut tree_update {
917924
let update = TreeUpdate {
918925
nodes: Vec::with_capacity(capacity),
919-
..Default::default()
926+
tree: None,
927+
focus: focus.into(),
920928
};
921929
BoxCastPtr::to_mut_ptr(update)
922930
}
@@ -954,13 +962,7 @@ impl tree_update {
954962
#[no_mangle]
955963
pub extern "C" fn accesskit_tree_update_set_focus(update: *mut tree_update, focus: node_id) {
956964
let update = mut_from_ptr(update);
957-
update.focus = Some(focus.into());
958-
}
959-
960-
#[no_mangle]
961-
pub extern "C" fn accesskit_tree_update_clear_focus(update: *mut tree_update) {
962-
let update = mut_from_ptr(update);
963-
update.focus = None;
965+
update.focus = focus.into();
964966
}
965967
}
966968

0 commit comments

Comments
 (0)