Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add passthrough code #714

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion masonry/src/render_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
use std::collections::{HashMap, VecDeque};

use accesskit::{ActionRequest, TreeUpdate};
use dpi::PhysicalPosition;
use parley::fontique::{self, Collection, CollectionOptions};
use parley::{FontContext, LayoutContext};
use tracing::{info_span, warn};
use vello::kurbo::{self, Rect};
use vello::kurbo::{self, Rect, Vec2};
use vello::Scene;

#[cfg(not(target_arch = "wasm32"))]
Expand Down Expand Up @@ -325,6 +326,28 @@ impl RenderRoot {
self.cursor_icon
}

pub fn is_passthrough(&self, pos: PhysicalPosition<f64>) -> bool {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a doc comment.

let pos = Vec2::new(pos.x, pos.y) / self.scale_factor;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if we were just using dpi::LogicalPosition here.


let mut target_id = self
.get_root_widget()
.find_widget_at_pos(pos.to_point())
.map(|widget| widget.id());

while let Some(widget_id) = target_id {
let parent_id = self.widget_arena.parent_of(widget_id);
let widget = self.widget_arena.get_widget(widget_id);

if !widget.item.is_passthrough() {
return false;
}

target_id = parent_id;
}

true
}

// --- MARK: ACCESS WIDGETS---
/// Get a [`WidgetRef`] to the root widget.
pub fn get_root_widget(&self) -> WidgetRef<dyn Widget> {
Expand Down
8 changes: 8 additions & 0 deletions masonry/src/testing/helper_widgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,10 @@ impl<S: 'static> Widget for ModularWidget<S> {
self.accepts_text_input
}

fn is_passthrough(&self) -> bool {
false
}

fn make_trace_span(&self) -> tracing::Span {
trace_span!("ModularWidget")
}
Expand Down Expand Up @@ -578,6 +582,10 @@ impl<W: Widget> Widget for Recorder<W> {
self.child.accepts_text_input()
}

fn is_passthrough(&self) -> bool {
self.child.is_passthrough()
}

fn make_trace_span(&self) -> tracing::Span {
self.child.make_trace_span()
}
Expand Down
4 changes: 4 additions & 0 deletions masonry/src/widget/flex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,10 @@ impl Widget for Flex {
.collect()
}

fn is_passthrough(&self) -> bool {
true
}

fn make_trace_span(&self) -> Span {
trace_span!("Flex")
}
Expand Down
4 changes: 4 additions & 0 deletions masonry/src/widget/grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ impl Widget for Grid {
.collect()
}

fn is_passthrough(&self) -> bool {
true
}

fn make_trace_span(&self) -> Span {
trace_span!("Grid")
}
Expand Down
4 changes: 4 additions & 0 deletions masonry/src/widget/sized_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,10 @@ impl Widget for SizedBox {
}
}

fn is_passthrough(&self) -> bool {
self.background.is_none()
}

fn make_trace_span(&self) -> Span {
trace_span!("SizedBox")
}
Expand Down
11 changes: 11 additions & 0 deletions masonry/src/widget/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,13 @@ pub trait Widget: AsAny {
false
}

/// Whether this widgets obstructs pointer events for something behind the window.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a pointer back to the RenderRoot method and the doc comment that will be there which can contain the more complete explanation.

///
/// Somewhat experimental.
fn is_passthrough(&self) -> bool {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the semantic difference between this and accepts_pointer_interaction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is_passthrough doesn't affect children.

There's probably a way to design these features to be more orthogonal and principled, but this is meant to be a quick-and-easy fix.

false
}

// TODO - Write a generic default implementation once
// `const std::any::type_name` is stable.
// See https://github.com/rust-lang/rust/issues/63084
Expand Down Expand Up @@ -467,6 +474,10 @@ impl Widget for Box<dyn Widget> {
self.deref().accepts_text_input()
}

fn is_passthrough(&self) -> bool {
self.deref().is_passthrough()
}

fn make_trace_span(&self) -> Span {
self.deref().make_trace_span()
}
Expand Down