diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index fdc14f55..35f69d5b 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -134,7 +134,7 @@ pub struct WlSurface { visible: Cell, role: Cell, pending: PendingState, - input_region: Cell>>, + input_region: CloneCell>>, opaque_region: Cell>>, buffer_points: RefCell, pub buffer_points_norm: RefCell, @@ -894,13 +894,25 @@ impl WlSurface { Ok(()) } - fn find_surface_at(self: &Rc, x: i32, y: i32) -> Option<(Rc, i32, i32)> { + fn accepts_input_at(&self, x: i32, y: i32) -> bool { let rect = self.buffer_abs_pos.get().at_point(0, 0); + if !rect.contains(x, y) { + return false; + } + if let Some(ir) = self.input_region.get() { + if !ir.contains(x, y) { + return false; + } + } + true + } + + fn find_surface_at(self: &Rc, x: i32, y: i32) -> Option<(Rc, i32, i32)> { let children = self.children.borrow(); let children = match children.deref() { Some(c) => c, _ => { - return if rect.contains(x, y) { + return if self.accepts_input_at(x, y) { Some((self.clone(), x, y)) } else { None @@ -925,7 +937,7 @@ impl WlSurface { if let Some(res) = ss(&children.above) { return Some(res); } - if rect.contains(x, y) { + if self.accepts_input_at(x, y) { return Some((self.clone(), x, y)); } if let Some(res) = ss(&children.below) { diff --git a/src/ifs/wl_surface/x_surface/xwindow.rs b/src/ifs/wl_surface/x_surface/xwindow.rs index bbee02aa..b6685335 100644 --- a/src/ifs/wl_surface/x_surface/xwindow.rs +++ b/src/ifs/wl_surface/x_surface/xwindow.rs @@ -322,6 +322,10 @@ impl Node for Xwindow { seat.focus_toplevel(self.clone()); } + fn node_active_changed(&self, active: bool) { + self.toplevel_data.update_self_active(self, active); + } + fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { let rect = self.x.surface.buffer_abs_pos.get(); if x < rect.width() && y < rect.height() { diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index f1321176..4083bdda 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -511,6 +511,10 @@ impl Node for XdgToplevel { seat.focus_toplevel(self.clone()); } + fn node_active_changed(&self, active: bool) { + self.toplevel_data.update_self_active(self, active); + } + fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { self.xdg.find_tree_at(x, y, tree) } diff --git a/src/tree/container.rs b/src/tree/container.rs index 20f5ed9d..cde675cb 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -758,7 +758,9 @@ impl ContainerNode { } } self.mono_child.set(Some(child.clone())); - child.node.tl_set_visible(true); + if self.toplevel_data.visible.get() { + child.node.tl_set_visible(true); + } child.node.tl_restack_popups(); // log::info!("activate_child2"); self.schedule_layout(); @@ -1126,10 +1128,7 @@ impl Node for ContainerNode { } fn node_active_changed(&self, active: bool) { - self.toplevel_data.active.set(active); - if let Some(parent) = self.toplevel_data.parent.get() { - parent.node_child_active_changed(self, active, 1); - } + self.toplevel_data.update_self_active(self, active); } fn node_find_tree_at(&self, x: i32, y: i32, tree: &mut Vec) -> FindTreeResult { diff --git a/src/tree/float.rs b/src/tree/float.rs index 7ac868d0..7f191216 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -10,8 +10,8 @@ use { state::State, text::{self, TextTexture}, tree::{ - walker::NodeVisitor, ContainingNode, FindTreeResult, FoundNode, Node, NodeId, - StackedNode, ToplevelNode, WorkspaceNode, + walker::NodeVisitor, ContainingNode, Direction, FindTreeResult, FoundNode, Node, + NodeId, StackedNode, ToplevelNode, WorkspaceNode, }, utils::{ clonecell::CloneCell, copyhashmap::CopyHashMap, double_click_state::DoubleClickState, @@ -490,6 +490,11 @@ impl Node for FloatNode { if state != KeyState::Pressed { return; } + if seat_data.op_type == OpType::Move { + if let Some(tl) = self.child.get() { + tl.node_do_focus(seat, Direction::Unspecified); + } + } if seat_data .double_click_state .click(&self.state, time_usec, seat_data.x, seat_data.y) diff --git a/src/tree/placeholder.rs b/src/tree/placeholder.rs index 4882608a..b43a1888 100644 --- a/src/tree/placeholder.rs +++ b/src/tree/placeholder.rs @@ -113,10 +113,7 @@ impl Node for PlaceholderNode { } fn node_active_changed(&self, active: bool) { - self.toplevel.active.set(active); - if let Some(parent) = self.toplevel.parent.get() { - parent.node_child_active_changed(self, active, 1); - } + self.toplevel.update_self_active(self, active); } fn node_find_tree_at(&self, _x: i32, _y: i32, _tree: &mut Vec) -> FindTreeResult { diff --git a/src/tree/toplevel.rs b/src/tree/toplevel.rs index ad7c050d..c2708227 100644 --- a/src/tree/toplevel.rs +++ b/src/tree/toplevel.rs @@ -58,21 +58,9 @@ impl ToplevelNode for T { fn tl_surface_active_changed(&self, active: bool) { let data = self.tl_data(); - if active { - if data.active_surfaces.inc() { - self.tl_set_active(true); - if let Some(parent) = data.parent.get() { - parent.node_child_active_changed(self.tl_as_node(), true, 1); - } - } - } else { - if data.active_surfaces.dec() { - self.tl_set_active(false); - if let Some(parent) = data.parent.get() { - parent.node_child_active_changed(self.tl_as_node(), false, 1); - } - } - } + data.update_active(self, || { + data.active_surfaces.adj(active); + }); } fn tl_set_fullscreen(self: Rc, fullscreen: bool) { @@ -193,7 +181,7 @@ pub struct FullscreenedData { } pub struct ToplevelData { - pub active: Cell, + pub self_active: Cell, pub client: Option>, pub state: Rc, pub active_surfaces: ThresholdCounter, @@ -220,7 +208,7 @@ pub struct ToplevelData { impl ToplevelData { pub fn new(state: &Rc, title: String, client: Option>) -> Self { Self { - active: Cell::new(false), + self_active: Cell::new(false), client, state: state.clone(), active_surfaces: Default::default(), @@ -245,7 +233,23 @@ impl ToplevelData { } pub fn active(&self) -> bool { - self.active_surfaces.active() || self.active.get() + self.active_surfaces.active() || self.self_active.get() + } + + fn update_active(&self, tl: &T, f: F) { + let active_old = self.active(); + f(); + let active_new = self.active(); + if active_old != active_new { + tl.tl_set_active(active_new); + if let Some(parent) = self.parent.get() { + parent.node_child_active_changed(tl.tl_as_node(), active_new, 1); + } + } + } + + pub fn update_self_active(&self, node: &T, active: bool) { + self.update_active(node, || self.self_active.set(active)); } pub fn float_size(&self, ws: &WorkspaceNode) -> (i32, i32) {