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

masonry: rename has_focus to subtree_has_focus #617

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
8 changes: 4 additions & 4 deletions masonry/src/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl_context_method!(
/// The focus status of a widget.
///
/// Returns `true` if this specific widget is focused.
/// To check if any descendants are focused use [`has_focus`].
/// To check if any descendants are focused use [`subtree_has_focus`].
///
/// Focus means that the widget receives keyboard events.
///
Expand All @@ -314,8 +314,8 @@ impl_context_method!(
///
/// Returns `true` if either this specific widget or any one of its descendants is focused.
/// To check if only this specific widget is focused use [`is_focused`](Self::is_focused).
pub fn has_focus(&self) -> bool {
self.widget_state.has_focus
pub fn subtree_has_focus(&self) -> bool {
self.widget_state.subtree_has_focus
}

/// Whether this specific widget is in the focus chain.
Expand Down Expand Up @@ -742,7 +742,7 @@ impl EventCtx<'_> {
/// See [`is_focused`](Self::is_focused) for more information about focus.
pub fn resign_focus(&mut self) {
trace!("resign_focus");
if self.has_focus() {
if self.subtree_has_focus() {
self.global_state.next_focused_widget = None;
} else {
warn!(
Expand Down
2 changes: 1 addition & 1 deletion masonry/src/debug_logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ impl DebugLogger {
StateTree::new("is_explicitly_disabled", w_state.is_explicitly_disabled),
StateTree::new("is_hot", w_state.is_hot),
StateTree::new("needs_layout", w_state.needs_layout),
StateTree::new("has_focus", w_state.has_focus),
StateTree::new("subtree_has_focus", w_state.subtree_has_focus),
StateTree::new("request_anim", w_state.request_anim),
StateTree::new("children_changed", w_state.children_changed),
StateTree::new("update_focus_chain", w_state.update_focus_chain),
Expand Down
38 changes: 23 additions & 15 deletions masonry/src/passes/update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,28 +214,36 @@ pub(crate) fn run_update_focus_pass(root: &mut RenderRoot, root_state: &mut Widg
focused_set: &HashSet<WidgetId>,
) {
run_targeted_update_pass(root, Some(widget_id), |widget, ctx| {
let has_focus = focused_set.contains(&ctx.widget_id());
let subtree_has_focus = focused_set.contains(&ctx.widget_id());

if ctx.widget_state.has_focus != has_focus {
widget.on_status_change(ctx, &StatusChange::ChildFocusChanged(has_focus));
if ctx.widget_state.subtree_has_focus != subtree_has_focus {
widget.on_status_change(ctx, &StatusChange::ChildFocusChanged(subtree_has_focus));
}
ctx.widget_state.has_focus = has_focus;
ctx.widget_state.subtree_has_focus = subtree_has_focus;
});
}

// TODO - Make sure widgets are iterated from the bottom up.
// TODO - Document the iteration order for update_focus pass.
for widget_id in prev_focused_path.iter().copied() {
if root.widget_arena.has(widget_id)
&& root.widget_arena.get_state_mut(widget_id).item.has_focus
&& root
.widget_arena
.get_state_mut(widget_id)
.item
.subtree_has_focus
!= focused_set.contains(&widget_id)
{
update_focused_status_of(root, widget_id, &focused_set);
}
}
for widget_id in next_focused_path.iter().copied() {
if root.widget_arena.has(widget_id)
&& root.widget_arena.get_state_mut(widget_id).item.has_focus
&& root
.widget_arena
.get_state_mut(widget_id)
.item
.subtree_has_focus
!= focused_set.contains(&widget_id)
{
update_focused_status_of(root, widget_id, &focused_set);
Expand Down Expand Up @@ -560,9 +568,9 @@ fn update_focus_chain_for_widget(
return;
}

// Replace has_focus to check if the value changed in the meantime
state.item.has_focus = global_state.focused_widget == Some(id);
let had_focus = state.item.has_focus;
// Replace subtree_has_focus to check if the value changed in the meantime
state.item.subtree_has_focus = global_state.focused_widget == Some(id);
let subtree_had_focus = state.item.subtree_has_focus;

state.item.in_focus_chain = false;
state.item.focus_chain.clear();
Expand Down Expand Up @@ -597,16 +605,16 @@ fn update_focus_chain_for_widget(
parent_focus_chain.extend(&state.item.focus_chain);
}

// had_focus is the old focus value. state.has_focus was replaced with parent_ctx.is_focused().
// Therefore if had_focus is true but state.has_focus is false then the widget which is
// currently focused is not part of the functional tree anymore
// (Lifecycle::BuildFocusChain.should_propagate_to_hidden() is false!) and should
// subtree_had_focus is the old focus value. state.subtree_has_focus was replaced with
// parent_ctx.is_focused(). Therefore if subtree_had_focus is true but state.subtree_has_focus
// is false then the widget which is currently focused is not part of the functional tree
// anymore (Lifecycle::BuildFocusChain.should_propagate_to_hidden() is false!) and should
// resign the focus.
if had_focus && !state.item.has_focus {
if subtree_had_focus && !state.item.subtree_has_focus {
// Not sure about this logic, might remove
global_state.next_focused_widget = None;
}
state.item.has_focus = had_focus;
state.item.subtree_has_focus = subtree_had_focus;
}

pub(crate) fn run_update_focus_chain_pass(root: &mut RenderRoot) {
Expand Down
6 changes: 3 additions & 3 deletions masonry/src/widget/widget_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ pub struct WidgetState {

/// In the focused path, starting from window and ending at the focused widget.
/// Descendants of the focused widget are not in the focused path.
pub(crate) has_focus: bool,
pub(crate) subtree_has_focus: bool,

/// Whether this specific widget is in the focus chain.
pub(crate) in_focus_chain: bool,
Expand Down Expand Up @@ -194,7 +194,7 @@ impl WidgetState {
needs_paint: true,
request_accessibility: true,
needs_accessibility: true,
has_focus: false,
subtree_has_focus: false,
in_focus_chain: false,
request_anim: true,
needs_anim: true,
Expand Down Expand Up @@ -260,7 +260,7 @@ impl WidgetState {
self.needs_anim |= child_state.needs_anim;
self.needs_accessibility |= child_state.needs_accessibility;
self.needs_update_disabled |= child_state.needs_update_disabled;
self.has_focus |= child_state.has_focus;
self.subtree_has_focus |= child_state.subtree_has_focus;
self.children_changed |= child_state.children_changed;
self.update_focus_chain |= child_state.update_focus_chain;
self.needs_update_stashed |= child_state.needs_update_stashed;
Expand Down