Skip to content

Commit

Permalink
More Component interface methods and events
Browse files Browse the repository at this point in the history
  • Loading branch information
DataTriny committed Dec 26, 2022
1 parent 207954c commit 3ca92fb
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 18 deletions.
5 changes: 2 additions & 3 deletions Cargo.lock

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

9 changes: 9 additions & 0 deletions consumer/src/tree.rs
Expand Up @@ -3,6 +3,7 @@
// the LICENSE-APACHE file) or the MIT license (found in
// the LICENSE-MIT file), at your option.

use accesskit::kurbo::Point;
use accesskit::{
Action, ActionData, ActionHandler, ActionRequest, Live, Node as NodeData, NodeId,
TextSelection, Tree as TreeData, TreeUpdate,
Expand Down Expand Up @@ -386,6 +387,14 @@ impl Tree {
})
}

pub fn scroll_to_point(&self, target: NodeId, point: Point) {
self.action_handler.do_action(ActionRequest {
action: Action::ScrollToPoint,
target,
data: Some(ActionData::ScrollToPoint(point)),
})
}

pub fn select_text_range(&self, range: &TextRange) {
let selection = TextSelection {
anchor: range.start.downgrade(),
Expand Down
2 changes: 1 addition & 1 deletion platforms/unix/Cargo.toml
Expand Up @@ -13,7 +13,7 @@ edition = "2021"
[dependencies]
accesskit = { version = "0.8.1", path = "../../common" }
accesskit_consumer = { version = "0.11.0", path = "../../consumer" }
atspi = "0.3.10"
atspi = { git = "https://github.com/odilia-app/atspi" }
parking_lot = "0.12.1"
serde = "1.0"
zbus = "3.6"
6 changes: 5 additions & 1 deletion platforms/unix/src/adapter.rs
Expand Up @@ -163,7 +163,11 @@ impl Adapter {
self.adapter
.register_interfaces(self.tree, new_node.id(), new_interfaces ^ kept_interfaces)
.unwrap();
new_wrapper.enqueue_changes(&mut self.queue, &old_wrapper);
new_wrapper.enqueue_changes(
&self.adapter.root_window_bounds.read(),
&mut self.queue,
&old_wrapper,
);
}
fn focus_moved(&mut self, old_node: Option<&DetachedNode>, new_node: Option<&Node>) {
if let Some(root_window) = root_window(&self.tree.read()) {
Expand Down
23 changes: 18 additions & 5 deletions platforms/unix/src/atspi/bus.rs
Expand Up @@ -75,20 +75,21 @@ impl Bus {
pub fn emit_object_event(&self, target: &ObjectId, event: &ObjectEvent) -> Result<()> {
let interface = "org.a11y.atspi.Event.Object";
let signal = match event {
ObjectEvent::StateChanged(_, _) => "StateChanged",
ObjectEvent::BoundsChanged(_) => "BoundsChanged",
ObjectEvent::PropertyChanged(_) => "PropertyChange",
ObjectEvent::StateChanged(_, _) => "StateChanged",
};
let properties = HashMap::new();
match event {
ObjectEvent::StateChanged(state, value) => self.emit_event(
ObjectEvent::BoundsChanged(bounds) => self.emit_event(
target,
interface,
signal,
EventBody {
kind: state,
detail1: *value as i32,
kind: "",
detail1: 0,
detail2: 0,
any_data: 0i32.into(),
any_data: Value::from(*bounds),
properties,
},
),
Expand Down Expand Up @@ -128,6 +129,18 @@ impl Bus {
properties,
},
),
ObjectEvent::StateChanged(state, value) => self.emit_event(
target,
interface,
signal,
EventBody {
kind: state,
detail1: *value as i32,
detail2: 0,
any_data: 0i32.into(),
properties,
},
),
}
}

Expand Down
14 changes: 13 additions & 1 deletion platforms/unix/src/atspi/interfaces/component.rs
Expand Up @@ -9,7 +9,7 @@ use crate::{
util::WindowBounds,
PlatformNode,
};
use atspi::CoordType;
use atspi::{component::Layer, CoordType};
use parking_lot::RwLock;
use std::sync::{Arc, Weak};
use zbus::{fdo, MessageHeader};
Expand Down Expand Up @@ -64,7 +64,19 @@ impl ComponentInterface {
extents
}

fn get_layer(&self) -> fdo::Result<Layer> {
self.node.get_layer()
}

fn grab_focus(&self) -> fdo::Result<bool> {
self.node.grab_focus()
}

fn scroll_to_point(&self, coord_type: CoordType, x: i32, y: i32) -> fdo::Result<bool> {
let window_bounds = self.upgrade_bounds()?;
let scrolled = self
.node
.scroll_to_point(&window_bounds.read(), coord_type, x, y);
scrolled
}
}
6 changes: 4 additions & 2 deletions platforms/unix/src/atspi/interfaces/events.rs
Expand Up @@ -3,7 +3,7 @@
// the LICENSE-APACHE file) or the MIT license (found in
// the LICENSE-MIT file), at your option.

use crate::atspi::{ObjectId, ObjectRef};
use crate::atspi::{ObjectId, ObjectRef, Rect};
use atspi::{accessible::Role, State};

pub(crate) enum QueuedEvent {
Expand All @@ -26,9 +26,11 @@ pub(crate) enum Property {
Value(f64),
}

#[allow(clippy::enum_variant_names)]
pub(crate) enum ObjectEvent {
StateChanged(State, bool),
BoundsChanged(Rect),
PropertyChanged(Property),
StateChanged(State, bool),
}

pub(crate) enum WindowEvent {
Expand Down
13 changes: 11 additions & 2 deletions platforms/unix/src/atspi/mod.rs
Expand Up @@ -4,22 +4,31 @@
// the LICENSE-MIT file), at your option.

use serde::{Deserialize, Serialize};
use zbus::zvariant::Type;
use zbus::zvariant::{OwnedValue, Type, Value};

mod bus;
pub(crate) mod interfaces;
mod object_address;
mod object_id;
mod object_ref;

#[derive(Debug, Default, Serialize, Deserialize, Type)]
#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, OwnedValue, Type, Value)]
pub(crate) struct Rect {
x: i32,
y: i32,
width: i32,
height: i32,
}

impl Rect {
pub const INVALID: Rect = Rect {
x: -1,
y: -1,
width: -1,
height: -1,
};
}

impl From<accesskit::kurbo::Rect> for Rect {
fn from(value: accesskit::kurbo::Rect) -> Rect {
Rect {
Expand Down
84 changes: 81 additions & 3 deletions platforms/unix/src/node.rs
Expand Up @@ -15,9 +15,15 @@ use crate::{
},
util::{AppContext, WindowBounds},
};
use accesskit::{kurbo::Point, CheckedState, DefaultActionVerb, NodeId, Role};
use accesskit::{
kurbo::{Affine, Point, Rect},
CheckedState, DefaultActionVerb, NodeId, Role,
};
use accesskit_consumer::{DetachedNode, FilterResult, Node, NodeState, Tree, TreeState};
use atspi::{accessible::Role as AtspiRole, CoordType, Interface, InterfaceSet, State, StateSet};
use atspi::{
accessible::Role as AtspiRole, component::Layer, CoordType, Interface, InterfaceSet, State,
StateSet,
};
use parking_lot::RwLock;
use std::{
iter::FusedIterator,
Expand Down Expand Up @@ -432,13 +438,45 @@ impl<'a> NodeWrapper<'a> {
})
}

fn raw_bounds_and_transform(&self) -> (Option<Rect>, Affine) {
let state = self.node_state();
(state.raw_bounds(), state.direct_transform())
}

fn extents(&self, window_bounds: &WindowBounds) -> AtspiRect {
if self.is_root() {
return window_bounds.outer.into();
}
match self {
Self::Node(node) => node.bounding_box().map_or_else(
|| AtspiRect::INVALID,
|bounds| {
let window_top_left = window_bounds.inner.origin();
let node_origin = bounds.origin();
let new_origin = Point::new(
window_top_left.x + node_origin.x,
window_top_left.y + node_origin.y,
);
bounds.with_origin(new_origin).into()
},
),
_ => unreachable!(),
}
}

fn current_value(&self) -> Option<f64> {
self.node_state().numeric_value()
}

pub fn enqueue_changes(&self, queue: &mut Vec<QueuedEvent>, old: &NodeWrapper) {
pub fn enqueue_changes(
&self,
window_bounds: &WindowBounds,
queue: &mut Vec<QueuedEvent>,
old: &NodeWrapper,
) {
self.enqueue_state_changes(queue, old);
self.enqueue_property_changes(queue, old);
self.enqueue_bounds_changes(window_bounds, queue, old);
}

fn enqueue_state_changes(&self, queue: &mut Vec<QueuedEvent>, old: &NodeWrapper) {
Expand Down Expand Up @@ -491,6 +529,20 @@ impl<'a> NodeWrapper<'a> {
}
}
}

fn enqueue_bounds_changes(
&self,
window_bounds: &WindowBounds,
queue: &mut Vec<QueuedEvent>,
old: &NodeWrapper,
) {
if self.raw_bounds_and_transform() != old.raw_bounds_and_transform() {
queue.push(QueuedEvent::Object {
target: self.id(),
event: ObjectEvent::BoundsChanged(self.extents(window_bounds)),
});
}
}
}

pub(crate) fn unknown_object(id: &ObjectId) -> fdo::Error {
Expand Down Expand Up @@ -740,12 +792,38 @@ impl PlatformNode {
})
}

pub fn get_layer(&self) -> fdo::Result<Layer> {
self.resolve(|node| {
let wrapper = NodeWrapper::Node(&node);
if wrapper.role() == AtspiRole::Window {
Ok(Layer::Window)
} else {
Ok(Layer::Widget)
}
})
}

pub fn grab_focus(&self) -> fdo::Result<bool> {
let tree = self.validate_for_action()?;
tree.set_focus(self.node_id);
Ok(true)
}

pub fn scroll_to_point(
&self,
window_bounds: &WindowBounds,
coord_type: CoordType,
x: i32,
y: i32,
) -> fdo::Result<bool> {
let tree = self.validate_for_action()?;
let is_root = self.node_id == tree.read().root_id();
let top_left = window_bounds.top_left(coord_type, is_root);
let point = Point::new(f64::from(x) - top_left.x, f64::from(y) - top_left.y);
tree.scroll_to_point(self.node_id, point);
Ok(true)
}

pub fn minimum_value(&self) -> fdo::Result<f64> {
self.resolve(|node| Ok(node.state().min_numeric_value().unwrap_or(std::f64::MIN)))
}
Expand Down

0 comments on commit 3ca92fb

Please sign in to comment.