Skip to content

Commit

Permalink
Update to Vello 0.3.0, Parley main, AccessKit 0.17 (#616)
Browse files Browse the repository at this point in the history
The biggest remaining issue in this PR is that IME support is not
present.

However, I think landing this is *better* than not landing it, because:
1) If we don't land it, it's going to languish again
2) Getting IME support back can be parallelised (cc @tomcur)
3) Getting Vello 0.3.0 and Parley 0.2.0 unlocks real advantages,
including full emoji support (#420).

To be clear, my first follow-up priority will be connecting the IME back
up. I do not however think this should block on Parley 0.3.0.

Discussion in
https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Updating.20Parley.20dependency
  • Loading branch information
DJMcNab authored Nov 18, 2024
1 parent 30cb5fb commit 10dc9d1
Show file tree
Hide file tree
Showing 61 changed files with 3,113 additions and 4,383 deletions.
1,443 changes: 611 additions & 832 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ homepage = "https://xilem.dev/"

[workspace.lints]
# unsafe code is not allowed in Xilem or Masonry
# We would like to set this to `forbid`, but we have to use `deny` because `android_activity`
# We would like to set this to `forbid`, but we have to use `deny` because `android_activity`
# requires us to use the unsafe `#[no_mangle]` attribute
# (And cargo doesn't let us have platform specific lints here)
rust.unsafe_code = "deny"
Expand Down Expand Up @@ -104,19 +104,21 @@ clippy.duplicated_attributes = "allow"
[workspace.dependencies]
masonry = { version = "0.2.0", path = "masonry" }
xilem_core = { version = "0.1.0", path = "xilem_core" }
vello = "0.2.1"
wgpu = "0.20.1"
vello = "0.3"
wgpu = "22.1.0"
kurbo = "0.11.1"
parley = "0.1.0"
peniko = "0.1.1"
parley = { git = "https://github.com/linebender/parley", rev = "217f243aa61178229da694b1d2b0598afcf29aff", features = [
"accesskit",
] }
peniko = "0.2.0"
winit = "0.30.4"
tracing = { version = "0.1.40", default-features = false }
smallvec = "1.13.2"
dpi = "0.1.1"
image = { version = "0.25.2", default-features = false }
web-time = "1.1.0"
bitflags = "2.6.0"
accesskit = "0.16.0"
accesskit_winit = "0.22.0"
accesskit = "0.17.0"
accesskit_winit = "0.23.0"
nv-flip = "0.1.2"
time = "0.3.36"
5 changes: 1 addition & 4 deletions masonry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,6 @@ serde = { version = "1.0.204", features = ["derive"] }
serde_json = "1.0.120"
futures-intrusive = "0.5.0"
pollster = "0.3.0"
unicode-segmentation = "1.11.0"
# TODO: Is this still the most up-to-date crate for this?
xi-unicode = "0.3.0"
tracing-subscriber = { version = "0.3.18", features = ["env-filter", "time"] }
accesskit.workspace = true
accesskit_winit.workspace = true
Expand All @@ -58,7 +55,7 @@ cursor-icon = "1.1.0"
dpi.workspace = true
nv-flip.workspace = true
tracing-tracy = { version = "0.11.3", optional = true }
wgpu-profiler = { optional = true, version = "0.17.0", default-features = false }
wgpu-profiler = { optional = true, version = "0.18.2", default-features = false }

[target.'cfg(target_arch = "wasm32")'.dependencies]
web-time.workspace = true
Expand Down
21 changes: 12 additions & 9 deletions masonry/examples/calc_masonry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
)]
#![expect(elided_lifetimes_in_paths, reason = "Deferred: Noisy")]

use accesskit::{DefaultActionVerb, NodeBuilder, Role};
use accesskit::{Node, Role};
use masonry::dpi::LogicalSize;
use masonry::text::StyleProperty;
use masonry::widget::{Align, CrossAxisAlignment, Flex, Label, RootWidget, SizedBox};
use masonry::{
AccessCtx, AccessEvent, Action, AppDriver, BoxConstraints, Color, DriverCtx, EventCtx,
Expand Down Expand Up @@ -178,7 +179,7 @@ impl Widget for CalcButton {
fn on_access_event(&mut self, ctx: &mut EventCtx, event: &AccessEvent) {
if ctx.target() == ctx.widget_id() {
match event.action {
accesskit::Action::Default => {
accesskit::Action::Click => {
ctx.submit_action(Action::Other(Box::new(self.action)));
}
_ => {}
Expand Down Expand Up @@ -230,14 +231,14 @@ impl Widget for CalcButton {
Role::Button
}

fn accessibility(&mut self, _ctx: &mut AccessCtx, node: &mut NodeBuilder) {
fn accessibility(&mut self, _ctx: &mut AccessCtx, node: &mut Node) {
let _name = match self.action {
CalcAction::Digit(digit) => digit.to_string(),
CalcAction::Op(op) => op.to_string(),
};
// We may want to add a name if it doesn't interfere with the child label
// ctx.current_node().set_name(name);
node.set_default_action_verb(DefaultActionVerb::Click);
node.add_action(accesskit::Action::Click);
}

fn children_ids(&self) -> SmallVec<[WidgetId; 16]> {
Expand Down Expand Up @@ -274,9 +275,11 @@ fn op_button_with_label(op: char, label: String) -> CalcButton {
const LIGHT_BLUE: Color = Color::rgb8(0x5c, 0xc4, 0xff);

CalcButton::new(
SizedBox::new(Align::centered(Label::new(label).with_text_size(24.)))
.background(BLUE)
.expand(),
SizedBox::new(Align::centered(
Label::new(label).with_style(StyleProperty::FontSize(24.)),
))
.background(BLUE)
.expand(),
CalcAction::Op(op),
BLUE,
LIGHT_BLUE,
Expand All @@ -292,7 +295,7 @@ fn digit_button(digit: u8) -> CalcButton {
const LIGHT_GRAY: Color = Color::rgb8(0x71, 0x71, 0x71);
CalcButton::new(
SizedBox::new(Align::centered(
Label::new(format!("{digit}")).with_text_size(24.),
Label::new(format!("{digit}")).with_style(StyleProperty::FontSize(24.)),
))
.background(GRAY)
.expand(),
Expand Down Expand Up @@ -320,7 +323,7 @@ fn flex_row(
}

fn build_calc() -> impl Widget {
let display = Label::new(String::new()).with_text_size(32.0);
let display = Label::new(String::new()).with_style(StyleProperty::FontSize(32.));
Flex::column()
.gap(0.0)
.with_flex_spacer(0.2)
Expand Down
22 changes: 11 additions & 11 deletions masonry/examples/custom_widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#![expect(clippy::shadow_unrelated, reason = "Deferred: Noisy")]
#![expect(clippy::cast_possible_truncation, reason = "Deferred: Noisy")]

use accesskit::{NodeBuilder, Role};
use accesskit::{Node, Role};
use masonry::kurbo::{BezPath, Stroke};
use masonry::widget::{ObjectFit, RootWidget};
use masonry::{
Expand All @@ -22,7 +22,7 @@ use parley::layout::Alignment;
use parley::style::{FontFamily, FontStack, StyleProperty};
use smallvec::SmallVec;
use tracing::{trace_span, Span};
use vello::peniko::{Brush, Fill, Format, Image};
use vello::peniko::{Fill, Format, Image};
use vello::Scene;
use winit::window::Window;

Expand Down Expand Up @@ -100,22 +100,22 @@ impl Widget for CustomWidget {
let mut lcx = parley::LayoutContext::new();
let mut text_layout_builder = lcx.ranged_builder(ctx.text_contexts().0, &self.0, 1.0);

text_layout_builder.push_default(&StyleProperty::FontStack(FontStack::Single(
text_layout_builder.push_default(StyleProperty::FontStack(FontStack::Single(
FontFamily::Generic(parley::style::GenericFamily::Serif),
)));
text_layout_builder.push_default(&StyleProperty::FontSize(24.0));
text_layout_builder.push_default(&StyleProperty::Brush(Brush::Solid(fill_color).into()));
text_layout_builder.push_default(StyleProperty::FontSize(24.0));

let mut text_layout = text_layout_builder.build();
text_layout.break_all_lines(None, Alignment::Start);
let mut text_layout = text_layout_builder.build(&self.0);
text_layout.break_all_lines(None);
text_layout.align(None, Alignment::Start);

let mut scratch_scene = Scene::new();
// We can pass a transform matrix to rotate the text we render
masonry::text::render_text(
scene,
&mut scratch_scene,
Affine::rotate(std::f64::consts::FRAC_PI_4).then_translate((80.0, 40.0).into()),
&text_layout,
&[fill_color.into()],
true,
);

// Let's burn some CPU to make a (partially transparent) image buffer
Expand All @@ -129,9 +129,9 @@ impl Widget for CustomWidget {
Role::Window
}

fn accessibility(&mut self, _ctx: &mut AccessCtx, node: &mut NodeBuilder) {
fn accessibility(&mut self, _ctx: &mut AccessCtx, node: &mut Node) {
let text = &self.0;
node.set_name(
node.set_label(
format!("This is a demo of the Masonry Widget trait. Masonry has accessibility tree support. The demo shows colored shapes with the text '{text}'."),
);
}
Expand Down
5 changes: 3 additions & 2 deletions masonry/examples/grid_masonry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#![windows_subsystem = "windows"]

use masonry::dpi::LogicalSize;
use masonry::text::StyleProperty;
use masonry::widget::{Button, Grid, GridParams, Prose, RootWidget, SizedBox};
use masonry::{Action, AppDriver, Color, DriverCtx, PointerButton, WidgetId};
use parley::layout::Alignment;
Expand Down Expand Up @@ -44,8 +45,8 @@ fn grid_button(params: GridParams) -> Button {
fn main() {
let label = SizedBox::new(
Prose::new("Change spacing by right and left clicking on the buttons")
.with_text_size(14.0)
.with_text_alignment(Alignment::Middle),
.with_style(StyleProperty::FontSize(14.0))
.with_alignment(Alignment::Middle),
)
.border(Color::rgb8(40, 40, 80), 1.0);
let button_inputs = vec![
Expand Down
6 changes: 4 additions & 2 deletions masonry/examples/hello_masonry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#![windows_subsystem = "windows"]

use masonry::dpi::LogicalSize;
use masonry::text::StyleProperty;
use masonry::widget::{Button, Flex, Label, RootWidget};
use masonry::{Action, AppDriver, DriverCtx, WidgetId};
use parley::fontique::Weight;
Expand All @@ -32,8 +33,9 @@ impl AppDriver for Driver {

fn main() {
let label = Label::new("Hello")
.with_text_size(32.0)
.with_weight(Weight::BOLD);
.with_style(StyleProperty::FontSize(32.0))
// Ideally there's be an Into in Parley for this
.with_style(StyleProperty::FontWeight(Weight::BOLD));
let button = Button::new("Say hello");

// Arrange the two widgets vertically, with some padding
Expand Down
33 changes: 21 additions & 12 deletions masonry/src/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use winit::window::ResizeDirection;
use crate::action::Action;
use crate::passes::layout::run_layout_on;
use crate::render_root::{MutateCallback, RenderRootSignal, RenderRootState};
use crate::text::TextBrush;
use crate::text::BrushIndex;
use crate::theme::get_debug_color;
use crate::tree_arena::{ArenaMutChildren, ArenaRefChildren};
use crate::widget::{WidgetMut, WidgetRef, WidgetState};
Expand Down Expand Up @@ -199,6 +199,26 @@ impl_context_method!(
}
);

// Methods for all exclusive context types (i.e. those which have exclusive access to the global state).
impl_context_method! {
AccessCtx<'_>,
ComposeCtx<'_>,
EventCtx<'_>,
LayoutCtx<'_>,
MutateCtx<'_>,
PaintCtx<'_>,
UpdateCtx<'_>,
{
/// Get the contexts needed to build and paint text sections.
///
/// Note that in many cases, these contexts are.
pub fn text_contexts(&mut self) -> (&mut FontContext, &mut LayoutContext<BrushIndex>) {
(
&mut self.global_state.font_context,
&mut self.global_state.text_layout_context,
)
}
}}
// --- MARK: GET LAYOUT ---
// Methods on all context types except LayoutCtx
// These methods access layout info calculated during the layout pass.
Expand Down Expand Up @@ -1119,17 +1139,6 @@ impl ComposeCtx<'_> {
}
}

// --- MARK: OTHER STUFF ---
impl_context_method!(LayoutCtx<'_>, PaintCtx<'_>, {
/// Get the contexts needed to build and paint text sections.
pub fn text_contexts(&mut self) -> (&mut FontContext, &mut LayoutContext<TextBrush>) {
(
&mut self.global_state.font_context,
&mut self.global_state.text_layout_context,
)
}
});

impl PaintCtx<'_> {
/// Whether debug paint is enabled.
///
Expand Down
6 changes: 3 additions & 3 deletions masonry/src/doc/02_implementing_widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ trait Widget {
fn paint(&mut self, ctx: &mut PaintCtx, scene: &mut Scene);
fn accessibility_role(&self) -> Role;
fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut NodeBuilder);
fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut Node);
// ...
}
Expand Down Expand Up @@ -218,7 +218,7 @@ use masonry::{
PaintCtx, AccessCtx
};
use vello::Scene;
use accesskit::{NodeBuilder, Role};
use accesskit::{Node, Role};
impl Widget for ColorRectangle {
// ...
Expand All @@ -238,7 +238,7 @@ impl Widget for ColorRectangle {
Role::Button
}
fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut NodeBuilder) {
fn accessibility(&mut self, ctx: &mut AccessCtx, node: &mut Node) {
node.set_default_action_verb(DefaultActionVerb::Click);
}
Expand Down
2 changes: 1 addition & 1 deletion masonry/src/doc/03_implementing_container_widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ impl Widget for VerticalStack {
Role::GenericContainer
}
fn accessibility(&mut self, _ctx: &mut AccessCtx, _node: &mut NodeBuilder) {}
fn accessibility(&mut self, _ctx: &mut AccessCtx, _node: &mut Node) {}
// ...
}
Expand Down
2 changes: 1 addition & 1 deletion masonry/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ impl TextEvent {
impl AccessEvent {
pub fn short_name(&self) -> &'static str {
match self.action {
accesskit::Action::Default => "Default",
accesskit::Action::Click => "Click",
accesskit::Action::Focus => "Focus",
accesskit::Action::Blur => "Blur",
accesskit::Action::Collapse => "Collapse",
Expand Down
4 changes: 0 additions & 4 deletions masonry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,6 @@
#![expect(clippy::todo, reason = "We have a lot of 'real' todos")]
#![expect(clippy::missing_errors_doc, reason = "Can be quite noisy?")]
#![expect(clippy::missing_panics_doc, reason = "Can be quite noisy?")]
#![expect(
clippy::partial_pub_fields,
reason = "Potentially controversial code style"
)]
#![expect(
clippy::shadow_unrelated,
reason = "Potentially controversial code style"
Expand Down
17 changes: 4 additions & 13 deletions masonry/src/passes/accessibility.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2024 the Xilem Authors
// SPDX-License-Identifier: Apache-2.0

use accesskit::{NodeBuilder, NodeId, Tree, TreeUpdate};
use accesskit::{Node, NodeId, Tree, TreeUpdate};
use tracing::{debug, info_span, trace};
use vello::kurbo::Rect;

Expand Down Expand Up @@ -53,16 +53,10 @@ fn build_accessibility_tree(
};
let mut node = build_access_node(widget.item, &mut ctx);
widget.item.accessibility(&mut ctx, &mut node);
let node = node.build();

let id: NodeId = ctx.widget_state.id.into();
if ctx.global_state.trace.access {
trace!(
"Built node {} with role={:?}, default_action={:?}",
id.0,
node.role(),
node.default_action_verb(),
);
trace!("Built node {} with role={:?}", id.0, node.role());
}
ctx.tree_update.nodes.push((id, node));
}
Expand Down Expand Up @@ -93,8 +87,8 @@ fn build_accessibility_tree(
}

// --- MARK: BUILD NODE ---
fn build_access_node(widget: &mut dyn Widget, ctx: &mut AccessCtx) -> NodeBuilder {
let mut node = NodeBuilder::new(widget.accessibility_role());
fn build_access_node(widget: &mut dyn Widget, ctx: &mut AccessCtx) -> Node {
let mut node = Node::new(widget.accessibility_role());
node.set_bounds(to_accesskit_rect(
ctx.widget_state.window_layout_rect(),
ctx.scale_factor,
Expand All @@ -111,9 +105,6 @@ fn build_access_node(widget: &mut dyn Widget, ctx: &mut AccessCtx) -> NodeBuilde

// Note - These WidgetState flags can be modified by other passes.
// When that happens, the other pass should set flags to request an accessibility pass.
if ctx.is_hovered() {
node.set_hovered();
}
if ctx.is_disabled() {
node.set_disabled();
}
Expand Down
2 changes: 0 additions & 2 deletions masonry/src/passes/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,6 @@ pub(crate) fn run_update_pointer_pass(root: &mut RenderRoot) {

if ctx.widget_state.is_hovered != is_hovered {
widget.update(ctx, &Update::HoveredChanged(is_hovered));
ctx.widget_state.request_accessibility = true;
ctx.widget_state.needs_accessibility = true;
}
ctx.widget_state.is_hovered = is_hovered;
});
Expand Down
Loading

0 comments on commit 10dc9d1

Please sign in to comment.