a11y refactor

This commit is contained in:
Ashley Wulber 2026-02-04 15:38:07 -05:00
parent c40264a6ed
commit b4346ff3ca
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
6 changed files with 107 additions and 232 deletions

View file

@ -28,7 +28,7 @@ wgpu-bare = ["iced_renderer/wgpu-bare", "iced_widget/wgpu"]
# Enables the `tiny-skia` software renderer
default = ["tiny-skia", "tokio", "wayland", "x11"]
default = ["a11y", "tiny-skia", "tokio", "wayland", "x11"]
# Enable the `tiny-skia` software renderer backend
tiny-skia = ["iced_renderer/tiny-skia"]
# Enables the `image` widget
@ -245,7 +245,6 @@ cosmic-text = { git = "https://github.com/pop-os/cosmic-text.git" }
dark-light = "1.0"
cryoglyph = { package = "cryoglyph", git = "https://github.com/pop-os/glyphon.git", branch = "iced-0.14" }
resvg = "0.45"
# glyphon = { package = "iced_glyphon", path = "../../../glyphon" }
web-sys = "0.3.69"
guillotiere = "0.6"
half = "2.2"
@ -308,16 +307,9 @@ winapi = "0.3"
window_clipboard = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-0.13-2" }
dnd = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-0.13-2" }
mime = { git = "https://github.com/pop-os/window_clipboard.git", tag = "pop-0.13-2" }
# window_clipboard = { path = "../../window_clipboard", tag = "pop-0.13-2" }
# dnd = { path = "../../window_clipboard/dnd", tag = "pop-0.13" }
# mime = { path = "../../window_clipboard/mime", tag = "pop-0.13" }
# winit = { git = "https://github.com/pop-os/winit.git", tag = "iced-xdg-surface-0.13" }
winit = { path = "../../winit/winit" }
winit-core = { path = "../../winit/winit-core" }
winit = { git = "https://github.com/pop-os/winit.git", branch = "iced-0.14-rebase" }
winit-core = { git = "https://github.com/pop-os/winit.git", branch = "iced-0.14-rebase" }
cursor-icon = "1.1.0"
# winit = { git = "https://github.com/iced-rs/winit.git", rev = "254d6b3420ce4e674f516f7a2bd440665e05484d" }
# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" }
# winit = { path = "../../../winit" }
[workspace.lints.rust]
@ -345,6 +337,3 @@ useless_conversion = "deny"
[workspace.lints.rustdoc]
broken_intra_doc_links = "forbid"
# [patch."https://github.com/rust-windowing/winit.git"]
# winit = { git = "https://github.com/rust-windowing/winit.git", rev = "241b7a80bba96c91fa3901729cd5dec66abb9be4" }
# winit = { path = "../../../winit" }

View file

@ -10,15 +10,15 @@ async-io = ["accesskit_winit?/async-io"]
tokio = ["accesskit_winit?/tokio"]
[dependencies]
# accesskit = { git = "https://github.com/wash2/accesskit", tag = "iced-xdg-surface-0.13" }
# accesskit_windows = { git = "https://github.com/wash2/accesskit", tag = "iced-xdg-surface-0.13", optional = true }
# accesskit_macos = { git = "https://github.com/wash2/accesskit", tag = "iced-xdg-surface-0.13", optional = true }
# accesskit_winit = { git = "https://github.com/wash2/accesskit", tag = "iced-xdg-surface-0.13", optional = true, default-features = false, features = [
# "rwh_06",
# ] }
accesskit = { path = "../../../accesskit/common" }
accesskit_windows = { path = "../../../accesskit/platforms/windows", optional = true }
accesskit_macos = { path = "../../../accesskit/platforms/macos", optional = true }
accesskit_winit = { path = "../../../accesskit/platforms/winit", optional = true, default-features = false, features = [
accesskit = { git = "https://github.com/wash2/accesskit", branch = "iced-0.14" }
accesskit_windows = { git = "https://github.com/wash2/accesskit", branch = "iced-0.14", optional = true }
accesskit_macos = { git = "https://github.com/wash2/accesskit", branch = "iced-0.14", optional = true }
accesskit_winit = { git = "https://github.com/wash2/accesskit", branch = "iced-0.14", optional = true, default-features = false, features = [
"rwh_06",
] }
# accesskit = { path = "../../../accesskit/common" }
# accesskit_windows = { path = "../../../accesskit/platforms/windows", optional = true }
# accesskit_macos = { path = "../../../accesskit/platforms/macos", optional = true }
# accesskit_winit = { path = "../../../accesskit/platforms/winit", optional = true, default-features = false, features = [
# "rwh_06",
# ] }

View file

@ -15,5 +15,4 @@ iced = { path = "../..", default-features = false, features = [
"debug",
] }
env_logger = "0.10"
# sctk = { package = "smithay-client-toolkit", path = "../../../fork/client-toolkit/" }
cctk.workspace = true

View file

@ -170,7 +170,6 @@ where
sender: oneshot::Sender<()>,
fonts: Vec<Cow<'static, [u8]>>,
graphics_settings: graphics::Settings,
control_sender: mpsc::UnboundedSender<Control>,
is_wayland: bool,
}
struct Runner<Message: 'static, F> {
@ -182,6 +181,7 @@ where
receiver: mpsc::UnboundedReceiver<Control>,
error: Option<Error>,
system_theme: Option<oneshot::Sender<theme::Mode>>,
control_sender: mpsc::UnboundedSender<Control>,
#[cfg(target_arch = "wasm32")]
is_booted: std::rc::Rc<std::cell::RefCell<bool>>,
@ -196,12 +196,12 @@ where
sender: boot_sender,
fonts: settings.fonts,
graphics_settings,
control_sender,
is_wayland,
}),
id: settings.id,
sender: event_sender,
receiver: control_receiver,
control_sender: control_sender.clone(),
error: None,
system_theme: Some(system_theme_sender),
@ -284,7 +284,6 @@ where
sender,
fonts,
graphics_settings,
control_sender,
is_wayland,
}) = self.boot.take()
else {
@ -533,6 +532,53 @@ where
.start_send(Event::StartDnd)
.expect("Send event");
}
Control::InitAdapter(id, window) => {
#[cfg(feature = "a11y")]
{
use crate::a11y::*;
use iced_accessibility::accesskit::{
ActivationHandler, Node, NodeId, Role,
Tree, TreeUpdate,
};
use iced_accessibility::accesskit_winit::Adapter;
let node_id =
iced_runtime::core::id::window_node_id(
);
let activation_handler =
WinitActivationHandler {
proxy: self.control_sender.clone(),
title: String::new(),
};
let action_handler = WinitActionHandler {
id,
proxy: self.control_sender.clone(),
};
let deactivation_handler =
WinitDeactivationHandler {
proxy: self.control_sender.clone(),
};
self.sender
.start_send(Event::A11yAdapter(
id,
(
node_id,
Adapter::with_direct_handlers(
event_loop,
window.as_ref(),
activation_handler,
action_handler,
deactivation_handler,
),
),
))
.expect("send event");
}
}
},
_ => {
break;
@ -561,7 +607,6 @@ where
}
}
#[derive(Debug)]
enum Event<Message: 'static> {
WindowCreated {
id: window::Id,
@ -576,6 +621,11 @@ enum Event<Message: 'static> {
Accessibility(window::Id, iced_accessibility::accesskit::ActionRequest),
#[cfg(feature = "a11y")]
AccessibilityEnabled(bool),
#[cfg(feature = "a11y")]
A11yAdapter(
window::Id,
(u64, iced_accessibility::accesskit_winit::Adapter),
),
Winit(winit::window::WindowId, winit::event::WindowEvent),
AboutToWait,
UserEvent(Action<Message>),
@ -584,7 +634,6 @@ enum Event<Message: 'static> {
StartDnd,
}
#[derive(Debug)]
enum Control {
ChangeFlow(winit::event_loop::ControlFlow),
Exit,
@ -603,6 +652,8 @@ enum Control {
Accessibility(window::Id, iced_accessibility::accesskit::ActionRequest),
#[cfg(feature = "a11y")]
AccessibilityEnabled(bool),
#[cfg(feature = "a11y")]
InitAdapter(window::Id, Arc<dyn winit::window::Window>),
PlatformSpecific(crate::platform_specific::Event),
AboutToWait,
Winit(winit::window::WindowId, winit::event::WindowEvent),
@ -665,50 +716,6 @@ async fn run_instance<P>(
#[cfg(feature = "a11y")]
let (mut adapters, mut a11y_enabled) = (Default::default(), false);
// let (mut adapters, mut a11y_enabled) = if let Some((main_id, title, raw)) =
// window_manager.ids().next().and_then(|id| {
// window_manager
// .get(id)
// .map(|w| (id, w.state.title.clone(), w.raw.clone()))
// }) {
// let node_id = core::id::window_node_id();
// use crate::a11y::*;
// use iced_accessibility::accesskit::{
// ActivationHandler, Node, NodeId, Role, Tree, TreeUpdate,
// };
// use iced_accessibility::accesskit_winit::Adapter;
// let activation_handler = WinitActivationHandler {
// proxy: control_sender.clone(),
// title: title.clone(),
// };
// let action_handler = WinitActionHandler {
// id: main_id,
// proxy: control_sender.clone(),
// };
// let deactivation_handler = WinitDeactivationHandler {
// proxy: control_sender.clone(),
// };
// (
// HashMap::from([(
// main_id,
// (
// node_id,
// Adapter::with_direct_handlers(
// raw.as_ref(),
// activation_handler,
// action_handler,
// deactivation_handler,
// ),
// ),
// )]),
// false,
// )
// } else {
// (Default::default(), false)
// };
#[cfg(all(feature = "linux-theme-detection", target_os = "linux"))]
let mut system_theme = {
@ -765,6 +772,10 @@ async fn run_instance<P>(
make_visible,
on_open,
} => {
#[cfg(feature = "a11y")]
control_sender
.start_send(Control::InitAdapter(id, window.clone()))
.expect("Send control message");
if compositor.is_none() {
let (compositor_sender, compositor_receiver) =
oneshot::channel();
@ -1795,6 +1806,10 @@ async fn run_instance<P>(
}
}
}
#[cfg(feature = "a11y")]
Event::A11yAdapter(id, adapter) => {
_ = adapters.insert(id, adapter);
}
_ => {}
}
}

View file

@ -187,7 +187,7 @@ impl WaylandSpecific {
log::warn!("Missing calloop sender");
return Default::default();
};
let Some(event_sender) = winit_event_sender.as_ref() else {
let Some(event_sender) = winit_event_sender.as_mut() else {
log::warn!("Missing control sender");
return Default::default();
};

View file

@ -353,7 +353,7 @@ impl SctkEvent {
>,
surface_ids: &mut HashMap<ObjectId, SurfaceIdWrapper>,
sctk_tx: &channel::Sender<super::Action>,
control_sender: &mpsc::UnboundedSender<Control>,
control_sender: &mut mpsc::UnboundedSender<Control>,
proxy: &EventLoopProxy,
user_interfaces: &mut UserInterfaces<'a, P>,
events: &mut Vec<(Option<window::Id>, iced_runtime::core::Event)>,
@ -759,45 +759,13 @@ impl SctkEvent {
display,
queue_handle,
);
// TODO must move this to the winit handler, where we have access to the event loop
// #[cfg(feature = "a11y")]
// {
// use crate::a11y::*;
// use iced_accessibility::accesskit::{
// ActivationHandler, Node, NodeId, Role, Tree,
// TreeUpdate,
// };
// use iced_accessibility::accesskit_winit::Adapter;
// let node_id = iced_runtime::core::id::window_node_id();
// let activation_handler = WinitActivationHandler {
// proxy: control_sender.clone(),
// title: String::new(),
// };
// let action_handler = WinitActionHandler {
// id: surface_id,
// proxy: control_sender.clone(),
// };
// let deactivation_handler = WinitDeactivationHandler {
// proxy: control_sender.clone(),
// };
// _ = adapters.insert(
// surface_id,
// (
// node_id,
// Adapter::with_direct_handlers(
// event_loop,
// sctk_winit.as_ref(),
// activation_handler,
// action_handler,
// deactivation_handler,
// ),
// ),
// );
// }
#[cfg(feature = "a11y")]
control_sender
.start_send(Control::InitAdapter(
surface_id,
sctk_winit.clone(),
))
.expect("Send control message");
let window = window_manager.insert(
surface_id,
@ -991,47 +959,13 @@ impl SctkEvent {
display,
queue_handle,
);
// TODO must move this to the winit handler, where we have access to the event loop
// #[cfg(feature = "a11y")]
// {
// use crate::a11y::*;
// use iced_accessibility::accesskit::{
// ActivationHandler, Node, NodeId, Role, Tree,
// TreeUpdate,
// };
// use iced_accessibility::accesskit_winit::Adapter;
// let node_id =
// iced_runtime::core::id::window_node_id();
// let activation_handler = WinitActivationHandler {
// proxy: control_sender.clone(),
// title: String::new(),
// };
// let action_handler = WinitActionHandler {
// id: surface_id,
// proxy: control_sender.clone(),
// };
// let deactivation_handler =
// WinitDeactivationHandler {
// proxy: control_sender.clone(),
// };
// _ = adapters.insert(
// surface_id,
// (
// node_id,
// Adapter::with_direct_handlers(
// event_loop,
// sctk_winit.as_ref(),
// activation_handler,
// action_handler,
// deactivation_handler,
// ),
// ),
// );
// }
#[cfg(feature = "a11y")]
control_sender
.start_send(Control::InitAdapter(
surface_id,
sctk_winit.clone(),
))
.expect("Send control message");
if clipboard.window_id().is_none() {
*clipboard = Clipboard::connect(
@ -1239,45 +1173,13 @@ impl SctkEvent {
display,
queue_handle,
);
// TODO must move this to the winit handler, where we have access to the event loop
// #[cfg(feature = "a11y")]
// {
// use crate::a11y::*;
// use iced_accessibility::accesskit::{
// ActivationHandler, Node, NodeId, Role, Tree, TreeUpdate,
// };
// use iced_accessibility::accesskit_winit::Adapter;
// let node_id = iced_runtime::core::id::window_node_id();
// let activation_handler = WinitActivationHandler {
// proxy: control_sender.clone(),
// // TODO lock screen title
// title: String::new(),
// };
// let action_handler = WinitActionHandler {
// id: surface_id,
// proxy: control_sender.clone(),
// };
// let deactivation_handler = WinitDeactivationHandler {
// proxy: control_sender.clone(),
// };
// _ = adapters.insert(
// surface_id,
// (
// node_id,
// Adapter::with_direct_handlers(
// event_loop,
// sctk_winit.as_ref(),
// activation_handler,
// action_handler,
// deactivation_handler,
// ),
// ),
// );
// }
#[cfg(feature = "a11y")]
control_sender
.start_send(Control::InitAdapter(
surface_id,
sctk_winit.clone(),
))
.expect("Send control message");
if clipboard.window_id().is_none() {
*clipboard = Clipboard::connect(
@ -1515,43 +1417,13 @@ impl SctkEvent {
display,
qh,
);
// #[cfg(feature = "a11y")]
// {
// use crate::a11y::*;
// use iced_accessibility::accesskit::{
// ActivationHandler, NodeBuilder, NodeId, Role, Tree,
// TreeUpdate,
// };
// use iced_accessibility::accesskit_winit::Adapter;
// let node_id = iced_runtime::core::id::window_node_id();
// let activation_handler = WinitActivationHandler {
// proxy: control_sender.clone(),
// title: String::new(),
// };
// let action_handler = WinitActionHandler {
// id: surface_id,
// proxy: control_sender.clone(),
// };
// let deactivation_handler = WinitDeactivationHandler {
// proxy: control_sender.clone(),
// };
// _ = adapters.insert(
// surface_id,
// (
// node_id,
// Adapter::with_direct_handlers(
// sctk_winit.as_ref(),
// activation_handler,
// action_handler,
// deactivation_handler,
// ),
// ),
// );
// }
#[cfg(feature = "a11y")]
control_sender
.start_send(Control::InitAdapter(
surface_id,
sctk_winit.clone(),
))
.expect("Send control message");
if clipboard.window_id().is_none() {
*clipboard = Clipboard::connect(