1
0
Fork 0
forked from wry/wry

Restore focus after backend visibility resumes

This commit is contained in:
atagen 2026-05-31 17:12:49 +10:00
parent 466da3da88
commit f22749db2f
2 changed files with 58 additions and 5 deletions

View file

@ -8,18 +8,25 @@ use {
renderer::Renderer,
state::State,
tree::{
FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeLayerLink, NodeLocation,
OutputNode, StackedNode, TileDragDestination, WorkspaceDragDestination,
Direction, FindTreeResult, FindTreeUsecase, FoundNode, Node, NodeId, NodeLayerLink,
NodeLocation, OutputNode, StackedNode, TileDragDestination, WorkspaceDragDestination,
WorkspaceNodeId, walker::NodeVisitor,
},
utils::{copyhashmap::CopyHashMap, linkedlist::LinkedList},
},
std::{cell::Cell, ops::Deref, rc::Rc},
std::{
cell::{Cell, RefCell},
mem,
ops::Deref,
rc::{Rc, Weak},
},
};
pub struct DisplayNode {
pub id: NodeId,
pub extents: Cell<Rect>,
visible: Cell<bool>,
suspend_restore_kb_foci: RefCell<Vec<(Rc<WlSeatGlobal>, Weak<dyn Node>)>>,
pub outputs: CopyHashMap<ConnectorId, Rc<OutputNode>>,
pub stacked: Rc<LinkedList<Rc<dyn StackedNode>>>,
pub stacked_above_layers: Rc<LinkedList<Rc<dyn StackedNode>>>,
@ -31,6 +38,8 @@ impl DisplayNode {
let slf = Self {
id,
extents: Default::default(),
visible: Default::default(),
suspend_restore_kb_foci: Default::default(),
outputs: Default::default(),
stacked: Default::default(),
stacked_above_layers: Default::default(),
@ -71,6 +80,17 @@ impl DisplayNode {
pub fn update_visible(&self, state: &State) {
let visible = state.root_visible();
let was_visible = self.visible.replace(visible);
if !visible && was_visible {
let mut foci = self.suspend_restore_kb_foci.borrow_mut();
foci.clear();
for seat in state.globals.seats.lock().values() {
let node = seat.get_keyboard_node();
if node.node_id() != self.id {
foci.push((seat.clone(), Rc::downgrade(&node)));
}
}
}
for output in self.outputs.lock().values() {
output.update_visible();
}
@ -82,6 +102,20 @@ impl DisplayNode {
for seat in state.globals.seats.lock().values() {
seat.set_visible(visible);
}
if visible && !was_visible {
for (seat, node) in mem::take(&mut *self.suspend_restore_kb_foci.borrow_mut()) {
if seat.get_keyboard_node().node_id() == self.id {
if let Some(node) = node.upgrade()
&& node.node_visible()
{
seat.focus_node(node);
} else {
seat.get_fallback_output()
.take_keyboard_navigation_focus(&seat, Direction::Unspecified);
}
}
}
}
if visible {
state.damage(self.extents.get());
}