tree: make surface visibility tracking more robust
This commit is contained in:
parent
be0935c8dd
commit
ba98103233
26 changed files with 313 additions and 144 deletions
|
|
@ -5,6 +5,7 @@ use {
|
|||
ifs::wl_seat::{NodeSeatState, WlSeatGlobal},
|
||||
rect::Rect,
|
||||
renderer::Renderer,
|
||||
state::State,
|
||||
tree::{
|
||||
walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, OutputNode, StackedNode,
|
||||
},
|
||||
|
|
@ -60,6 +61,21 @@ impl DisplayNode {
|
|||
}
|
||||
self.extents.set(Rect::new(x1, y1, x2, y2).unwrap());
|
||||
}
|
||||
|
||||
pub fn update_visible(&self, state: &State) {
|
||||
let visible = state.root_visible();
|
||||
for output in self.outputs.lock().values() {
|
||||
output.update_visible();
|
||||
}
|
||||
for stacked in self.stacked.iter() {
|
||||
if !stacked.stacked_has_workspace_link() {
|
||||
stacked.stacked_set_visible(visible);
|
||||
}
|
||||
}
|
||||
for seat in state.globals.seats.lock().values() {
|
||||
seat.set_visible(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for DisplayNode {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ impl FloatNode {
|
|||
let floater = Rc::new(FloatNode {
|
||||
id: state.node_ids.next(),
|
||||
state: state.clone(),
|
||||
visible: Cell::new(ws.stacked_visible()),
|
||||
visible: Cell::new(ws.container_visible()),
|
||||
position: Cell::new(position),
|
||||
display_link: RefCell::new(None),
|
||||
workspace_link: Cell::new(None),
|
||||
|
|
@ -346,7 +346,7 @@ impl FloatNode {
|
|||
self.workspace_link
|
||||
.set(Some(ws.stacked.add_last(self.clone())));
|
||||
self.workspace.set(ws.clone());
|
||||
self.stacked_set_visible(ws.stacked_visible());
|
||||
self.stacked_set_visible(ws.container_visible());
|
||||
}
|
||||
|
||||
fn update_child_title(self: &Rc<Self>, title: &str) {
|
||||
|
|
@ -625,4 +625,8 @@ impl StackedNode for FloatNode {
|
|||
}
|
||||
self.seat_state.set_visible(self, visible);
|
||||
}
|
||||
|
||||
fn stacked_has_workspace_link(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ impl OutputNode {
|
|||
old.flush_jay_workspaces();
|
||||
}
|
||||
}
|
||||
ws.set_visible(true);
|
||||
self.update_visible();
|
||||
if let Some(fs) = ws.fullscreen.get() {
|
||||
fs.tl_change_extents(&self.global.pos.get());
|
||||
}
|
||||
|
|
@ -502,6 +502,44 @@ impl OutputNode {
|
|||
.map(|w| w.fullscreen.is_some())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn set_lock_surface(
|
||||
&self,
|
||||
surface: Option<Rc<ExtSessionLockSurfaceV1>>,
|
||||
) -> Option<Rc<ExtSessionLockSurfaceV1>> {
|
||||
let prev = self.lock_surface.set(surface);
|
||||
self.update_visible();
|
||||
prev
|
||||
}
|
||||
|
||||
pub fn update_visible(&self) {
|
||||
let mut visible = self.state.root_visible();
|
||||
if self.state.lock.locked.get() {
|
||||
if let Some(surface) = self.lock_surface.get() {
|
||||
surface.surface.set_visible(visible);
|
||||
}
|
||||
visible = false;
|
||||
}
|
||||
macro_rules! set_layer_visible {
|
||||
($layer:expr, $visible:expr) => {
|
||||
for ls in $layer.iter() {
|
||||
ls.surface.set_visible($visible);
|
||||
}
|
||||
};
|
||||
}
|
||||
let mut have_fullscreen = false;
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
have_fullscreen = ws.fullscreen.is_some();
|
||||
}
|
||||
let lower_visible = visible && have_fullscreen;
|
||||
set_layer_visible!(self.layers[0], lower_visible);
|
||||
set_layer_visible!(self.layers[1], lower_visible);
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
ws.set_visible(visible);
|
||||
}
|
||||
set_layer_visible!(self.layers[2], visible);
|
||||
set_layer_visible!(self.layers[3], visible);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OutputTitle {
|
||||
|
|
@ -607,16 +645,6 @@ impl Node for OutputNode {
|
|||
return res;
|
||||
}
|
||||
}
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
if let Some(fs) = ws.fullscreen.get() {
|
||||
tree.push(FoundNode {
|
||||
node: fs.clone().tl_into_node(),
|
||||
x,
|
||||
y,
|
||||
});
|
||||
return fs.tl_as_node().node_find_tree_at(x, y, tree);
|
||||
}
|
||||
}
|
||||
{
|
||||
let (x_abs, y_abs) = self.global.pos.get().translate_inv(x, y);
|
||||
for stacked in self.state.root.stacked.rev_iter() {
|
||||
|
|
@ -647,23 +675,36 @@ impl Node for OutputNode {
|
|||
}
|
||||
}
|
||||
}
|
||||
let bar_height = self.state.theme.sizes.title_height.get() + 1;
|
||||
if y >= bar_height {
|
||||
y -= bar_height;
|
||||
let len = tree.len();
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
tree.push(FoundNode {
|
||||
node: ws.clone(),
|
||||
x,
|
||||
y,
|
||||
});
|
||||
ws.node_find_tree_at(x, y, tree);
|
||||
}
|
||||
if tree.len() == len {
|
||||
self.find_layer_surface_at(x, y, &[BOTTOM, BACKGROUND], tree);
|
||||
}
|
||||
let mut fullscreen = None;
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
fullscreen = ws.fullscreen.get();
|
||||
}
|
||||
if let Some(fs) = fullscreen {
|
||||
tree.push(FoundNode {
|
||||
node: fs.clone().tl_into_node(),
|
||||
x,
|
||||
y,
|
||||
});
|
||||
fs.tl_as_node().node_find_tree_at(x, y, tree)
|
||||
} else {
|
||||
let bar_height = self.state.theme.sizes.title_height.get() + 1;
|
||||
if y >= bar_height {
|
||||
y -= bar_height;
|
||||
let len = tree.len();
|
||||
if let Some(ws) = self.workspace.get() {
|
||||
tree.push(FoundNode {
|
||||
node: ws.clone(),
|
||||
x,
|
||||
y,
|
||||
});
|
||||
ws.node_find_tree_at(x, y, tree);
|
||||
}
|
||||
if tree.len() == len {
|
||||
self.find_layer_surface_at(x, y, &[BOTTOM, BACKGROUND], tree);
|
||||
}
|
||||
}
|
||||
FindTreeResult::AcceptsInput
|
||||
}
|
||||
FindTreeResult::AcceptsInput
|
||||
}
|
||||
|
||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32, _bounds: Option<&Rect>) {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,14 @@ pub trait StackedNode: Node {
|
|||
fn stacked_as_node(&self) -> &dyn Node;
|
||||
fn stacked_into_node(self: Rc<Self>) -> Rc<dyn Node>;
|
||||
fn stacked_into_dyn(self: Rc<Self>) -> Rc<dyn StackedNode>;
|
||||
fn stacked_prepare_set_visible(&self) {
|
||||
// nothing
|
||||
}
|
||||
fn stacked_needs_set_visible(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn stacked_set_visible(&self, visible: bool);
|
||||
fn stacked_has_workspace_link(&self) -> bool;
|
||||
|
||||
fn stacked_absolute_position_constrains_input(&self) -> bool {
|
||||
true
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ impl WorkspaceNode {
|
|||
let pos = self.position.get();
|
||||
container.clone().tl_change_extents(&pos);
|
||||
container.tl_set_parent(self.clone());
|
||||
container.tl_set_visible(self.stacked_visible());
|
||||
container.tl_set_visible(self.container_visible());
|
||||
self.container.set(Some(container.clone()));
|
||||
}
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ impl WorkspaceNode {
|
|||
self.stacked.is_empty() && self.fullscreen.is_none() && self.container.is_none()
|
||||
}
|
||||
|
||||
pub fn stacked_visible(&self) -> bool {
|
||||
pub fn container_visible(&self) -> bool {
|
||||
self.visible.get() && self.fullscreen.is_none()
|
||||
}
|
||||
|
||||
|
|
@ -113,39 +113,37 @@ impl WorkspaceNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn plane_set_visible(&self, visible: bool) {
|
||||
if let Some(container) = self.container.get() {
|
||||
container.tl_set_visible(visible);
|
||||
}
|
||||
for stacked in self.stacked.iter() {
|
||||
stacked.stacked_set_visible(visible);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_visible(&self, visible: bool) {
|
||||
self.visible.set(visible);
|
||||
for jw in self.jay_workspaces.lock().values() {
|
||||
jw.send_visible(visible);
|
||||
}
|
||||
self.visible.set(visible);
|
||||
for stacked in self.stacked.iter() {
|
||||
stacked.stacked_prepare_set_visible();
|
||||
}
|
||||
if let Some(fs) = self.fullscreen.get() {
|
||||
fs.tl_set_visible(visible);
|
||||
} else {
|
||||
self.plane_set_visible(visible);
|
||||
}
|
||||
if let Some(container) = self.container.get() {
|
||||
container.tl_set_visible(self.container_visible());
|
||||
}
|
||||
for stacked in self.stacked.iter() {
|
||||
if stacked.stacked_needs_set_visible() {
|
||||
stacked.stacked_set_visible(self.container_visible());
|
||||
}
|
||||
}
|
||||
self.seat_state.set_visible(self, visible);
|
||||
}
|
||||
|
||||
pub fn set_fullscreen_node(&self, node: &Rc<dyn ToplevelNode>) {
|
||||
let visible = self.visible.get();
|
||||
let mut plane_was_visible = visible;
|
||||
if let Some(prev) = self.fullscreen.set(Some(node.clone())) {
|
||||
plane_was_visible = false;
|
||||
self.discard_child_properties(&*prev);
|
||||
}
|
||||
self.pull_child_properties(&**node);
|
||||
node.tl_set_visible(visible);
|
||||
if plane_was_visible {
|
||||
self.plane_set_visible(false);
|
||||
if self.visible.get() {
|
||||
self.output.get().update_visible();
|
||||
} else {
|
||||
node.tl_set_visible(false);
|
||||
}
|
||||
if let Some(surface) = node.tl_scanout_surface() {
|
||||
if let Some(fb) = self.output.get().global.connector.connector.drm_feedback() {
|
||||
|
|
@ -158,7 +156,7 @@ impl WorkspaceNode {
|
|||
if let Some(node) = self.fullscreen.take() {
|
||||
self.discard_child_properties(&*node);
|
||||
if self.visible.get() {
|
||||
self.plane_set_visible(true);
|
||||
self.output.get().update_visible();
|
||||
}
|
||||
if let Some(surface) = node.tl_scanout_surface() {
|
||||
if let Some(fb) = surface.client.state.drm_feedback.get() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue