From 661a28e5b07a389b8f527708f32e9619427fc1be Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Wed, 13 Apr 2022 12:58:04 +0200 Subject: [PATCH] autocommit 2022-04-13 12:58:04 CEST --- src/ifs/wl_drm.rs | 2 +- src/ifs/wl_seat.rs | 22 +++-- src/ifs/wl_seat/kb_owner.rs | 42 +-------- src/ifs/wl_seat/wl_keyboard.rs | 1 - .../wl_surface/xdg_surface/xdg_toplevel.rs | 10 ++- src/ifs/wl_surface/xwindow.rs | 2 +- src/ifs/wl_surface/zwlr_layer_surface_v1.rs | 2 +- src/ifs/zwp_linux_buffer_params_v1.rs | 2 +- src/render/egl/display.rs | 2 +- src/render/renderer/context.rs | 2 +- src/render/renderer/renderer.rs | 16 +++- src/state.rs | 23 ++--- src/tasks/connector.rs | 4 +- src/theme.rs | 12 +-- src/tree.rs | 10 +-- src/tree/container.rs | 89 ++++++++++--------- src/tree/float.rs | 2 +- src/tree/output.rs | 46 +++++++--- src/tree/workspace.rs | 13 ++- src/video.rs | 2 +- src/video/{dma.rs => dmabuf.rs} | 0 src/video/drm.rs | 2 +- src/video/gbm.rs | 2 +- 23 files changed, 165 insertions(+), 143 deletions(-) rename src/video/{dma.rs => dmabuf.rs} (100%) diff --git a/src/ifs/wl_drm.rs b/src/ifs/wl_drm.rs index 0bcfaa10..cd23f39f 100644 --- a/src/ifs/wl_drm.rs +++ b/src/ifs/wl_drm.rs @@ -8,7 +8,7 @@ use { render::RenderError, utils::buffd::{MsgParser, MsgParserError}, video::{ - dma::{DmaBuf, DmaBufPlane}, + dmabuf::{DmaBuf, DmaBufPlane}, INVALID_MODIFIER, }, wire::{wl_drm::*, WlDrmId}, diff --git a/src/ifs/wl_seat.rs b/src/ifs/wl_seat.rs index 5ebc19a8..70aa36d1 100644 --- a/src/ifs/wl_seat.rs +++ b/src/ifs/wl_seat.rs @@ -32,7 +32,10 @@ use { leaks::Tracker, object::{Object, ObjectId}, state::State, - tree::{ContainerSplit, FloatNode, FoundNode, Node, OutputNode, ToplevelNode}, + tree::{ + generic_node_visitor, ContainerSplit, FloatNode, FoundNode, Node, OutputNode, + ToplevelNode, + }, utils::{ asyncevent::AsyncEvent, buffd::{MsgParser, MsgParserError}, @@ -51,6 +54,7 @@ use { }, ahash::{AHashMap, AHashSet}, jay_config::{keyboard::mods::Modifiers, Direction}, + smallvec::SmallVec, std::{ cell::{Cell, RefCell}, collections::hash_map::Entry, @@ -422,10 +426,6 @@ impl WlSeatGlobal { self.id } - pub fn workspace_changed(self: &Rc, output: &Rc) { - self.kb_owner.workspace_changed(self, output); - } - fn bind_( self: Rc, id: WlSeatId, @@ -708,3 +708,15 @@ pub enum ReleaseError { } efrom!(ReleaseError, ClientError, ClientError); efrom!(ReleaseError, ParseError, MsgParserError); + +pub fn collect_kb_foci2(node: Rc, seats: &mut SmallVec<[Rc; 3]>) { + node.node_visit(&mut generic_node_visitor(|node| { + node.node_seat_state().for_each_kb_focus(|s| seats.push(s)); + })); +} + +pub fn collect_kb_foci(node: Rc) -> SmallVec<[Rc; 3]> { + let mut res = SmallVec::new(); + collect_kb_foci2(node, &mut res); + res +} diff --git a/src/ifs/wl_seat/kb_owner.rs b/src/ifs/wl_seat/kb_owner.rs index bb40025c..b000c3dd 100644 --- a/src/ifs/wl_seat/kb_owner.rs +++ b/src/ifs/wl_seat/kb_owner.rs @@ -1,10 +1,6 @@ use { - crate::{ - ifs::wl_seat::WlSeatGlobal, - tree::{Node, OutputNode}, - utils::clonecell::CloneCell, - }, - std::{ops::Deref, rc::Rc}, + crate::{ifs::wl_seat::WlSeatGlobal, tree::Node, utils::clonecell::CloneCell}, + std::rc::Rc, }; pub struct KbOwnerHolder { @@ -33,10 +29,6 @@ impl KbOwnerHolder { pub fn set_kb_node(&self, seat: &Rc, node: Rc) { self.owner.get().set_kb_node(seat, node); } - - pub fn workspace_changed(&self, seat: &Rc, output: &Rc) { - self.owner.get().workspace_changed(seat, output); - } } struct DefaultKbOwner; @@ -47,7 +39,6 @@ trait KbOwner { fn grab(&self, seat: &Rc, node: Rc) -> bool; fn ungrab(&self, seat: &Rc); fn set_kb_node(&self, seat: &Rc, node: Rc); - fn workspace_changed(&self, seat: &Rc, output: &Rc); } impl KbOwner for DefaultKbOwner { @@ -77,31 +68,6 @@ impl KbOwner for DefaultKbOwner { node.clone().node_focus(seat); seat.keyboard_node.set(node.clone()); } - - fn workspace_changed(&self, seat: &Rc, output: &Rc) { - let new_ws = match output.workspace.get() { - Some(ws) => ws, - _ => return, - }; - let node = seat.keyboard_node.get(); - let ws = match node.node_get_workspace() { - None => return, - Some(ws) => ws, - }; - let ws_output = ws.output.get(); - if ws_output.id != output.id { - return; - } - for tl in seat.toplevel_focus_history.rev_iter() { - if let Some(tl_ws) = tl.as_node().node_get_workspace() { - if tl_ws.id == new_ws.id { - self.set_kb_node(seat, tl.deref().clone().into_node()); - return; - } - } - } - self.set_kb_node(seat, seat.state.root.clone()); - } } impl KbOwner for GrabKbOwner { @@ -116,8 +82,4 @@ impl KbOwner for GrabKbOwner { fn set_kb_node(&self, _seat: &Rc, _node: Rc) { // nothing } - - fn workspace_changed(&self, _seat: &Rc, _output: &Rc) { - // nothing - } } diff --git a/src/ifs/wl_seat/wl_keyboard.rs b/src/ifs/wl_seat/wl_keyboard.rs index d1681a8d..250cf14d 100644 --- a/src/ifs/wl_seat/wl_keyboard.rs +++ b/src/ifs/wl_seat/wl_keyboard.rs @@ -46,7 +46,6 @@ impl WlKeyboard { } pub fn send_enter(self: &Rc, serial: u32, surface: WlSurfaceId, keys: &[u32]) { - log::info!("enter with {:?}", keys); self.seat.client.event(Enter { self_id: self.id, serial, diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index ca7c3828..cf062ffa 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -309,9 +309,11 @@ impl XdgToplevel { _ => return, }; let extents = self.xdg.extents.get(); - parent - .clone() - .node_child_active_changed(self, self.toplevel_data.active_surfaces.get() > 0); + parent.clone().node_child_active_changed( + self, + self.toplevel_data.active_surfaces.get() > 0, + 1, + ); parent.node_child_size_changed(self, extents.width(), extents.height()); parent.node_child_title_changed(self, self.title.borrow_mut().deref()); } @@ -501,7 +503,7 @@ impl ToplevelNode for XdgToplevel { fn set_active(&self, active: bool) { if let Some(parent) = self.parent_node.get() { - parent.node_child_active_changed(self, active); + parent.node_child_active_changed(self, active, 1); } let changed = { let mut states = self.states.borrow_mut(); diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index 50893bb9..8577fe29 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -463,7 +463,7 @@ impl ToplevelNode for Xwindow { fn set_active(&self, active: bool) { if let Some(pn) = self.parent_node.get() { - pn.node_child_active_changed(self, active); + pn.node_child_active_changed(self, active, 1); } } diff --git a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs index d0872199..f9478344 100644 --- a/src/ifs/wl_surface/zwlr_layer_surface_v1.rs +++ b/src/ifs/wl_surface/zwlr_layer_surface_v1.rs @@ -374,7 +374,7 @@ impl SizedNode for ZwlrLayerSurfaceV1 { } fn visit_children(&self, visitor: &mut dyn NodeVisitor) { - self.surface.clone().node_visit(visitor); + self.surface.visit(visitor); } fn visible(&self) -> bool { diff --git a/src/ifs/zwp_linux_buffer_params_v1.rs b/src/ifs/zwp_linux_buffer_params_v1.rs index 68aeba29..38c73a7f 100644 --- a/src/ifs/zwp_linux_buffer_params_v1.rs +++ b/src/ifs/zwp_linux_buffer_params_v1.rs @@ -10,7 +10,7 @@ use { errorfmt::ErrorFmt, }, video::{ - dma::{DmaBuf, DmaBufPlane}, + dmabuf::{DmaBuf, DmaBufPlane}, INVALID_MODIFIER, }, wire::{zwp_linux_buffer_params_v1::*, WlBufferId, ZwpLinuxBufferParamsV1Id}, diff --git a/src/render/egl/display.rs b/src/render/egl/display.rs index 663a3f0f..4b4e703b 100644 --- a/src/render/egl/display.rs +++ b/src/render/egl/display.rs @@ -26,7 +26,7 @@ use { sys::{eglInitialize, EGL_PLATFORM_GBM_KHR}, RenderError, }, - video::{dma::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER}, + video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER}, }, ahash::AHashMap, std::{ptr, rc::Rc}, diff --git a/src/render/renderer/context.rs b/src/render/renderer/context.rs index 61374582..a76a3be8 100644 --- a/src/render/renderer/context.rs +++ b/src/render/renderer/context.rs @@ -10,7 +10,7 @@ use { RenderError, Texture, }, video::{ - dma::DmaBuf, + dmabuf::DmaBuf, drm::{Drm, NodeType}, }, }, diff --git a/src/render/renderer/renderer.rs b/src/render/renderer/renderer.rs index f32d9709..65533516 100644 --- a/src/render/renderer/renderer.rs +++ b/src/render/renderer/renderer.rs @@ -28,7 +28,7 @@ use { tree::{ContainerNode, FloatNode, OutputNode, WorkspaceNode}, utils::rc_eq::rc_eq, }, - std::{ops::Deref, rc::Rc}, + std::{ops::Deref, rc::Rc, slice}, }; pub struct Renderer<'a> { @@ -58,8 +58,12 @@ impl Renderer<'_> { let th = theme.title_height.get(); { let rd = output.render_data.borrow_mut(); - let c = theme.active_title_color.get(); - self.fill_boxes(std::slice::from_ref(&rd.active_workspace), &c); + if let Some(aw) = &rd.active_workspace { + let c = theme.active_title_color.get(); + self.fill_boxes(slice::from_ref(aw), &c); + } + let c = theme.underline_color.get(); + self.fill_boxes(slice::from_ref(&rd.underline), &c); let c = theme.title_color.get(); self.fill_boxes(&rd.inactive_workspaces, &c); for title in &rd.titles { @@ -70,7 +74,7 @@ impl Renderer<'_> { } } if let Some(ws) = output.workspace.get() { - self.render_workspace(&ws, x, y + th); + self.render_workspace(&ws, x, y + th + 1); } for stacked in self.state.root.stacked.iter() { if stacked.node_visible() { @@ -152,6 +156,10 @@ impl Renderer<'_> { self.fill_boxes2(&rd.underline_rects, &c, x, y); let c = self.state.theme.border_color.get(); self.fill_boxes2(&rd.border_rects, &c, x, y); + if let Some(lar) = &rd.last_active_rect { + let c = self.state.theme.last_active_color.get(); + self.fill_boxes2(std::slice::from_ref(lar), &c, x, y); + } for title in &rd.titles { self.render_texture(&title.tex, x + title.x, y + title.y, ARGB8888); } diff --git a/src/state.rs b/src/state.rs index a4f01734..0dd002b9 100644 --- a/src/state.rs +++ b/src/state.rs @@ -22,7 +22,7 @@ use { theme::Theme, tree::{ ContainerNode, ContainerSplit, DisplayNode, FloatNode, Node, NodeIds, NodeVisitorBase, - OutputNode, WorkspaceNode, + OutputNode, SizedNode, WorkspaceNode, }, utils::{ clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, fdcloser::FdCloser, @@ -32,6 +32,7 @@ use { xkbcommon::{XkbContext, XkbKeymap}, }, ahash::AHashMap, + jay_config::Direction, std::{ cell::{Cell, RefCell}, rc::Rc, @@ -131,7 +132,7 @@ impl State { node.node_visit_children(self); } } - self.root.clone().node_visit(&mut Walker); + self.root.visit(&mut Walker); let seats = self.globals.seats.lock(); for seat in seats.values() { @@ -227,12 +228,12 @@ impl State { let output = match self.workspaces.get(name) { Some(ws) => { let output = ws.output.get(); - if let Some(old) = output.workspace.get() { - if old.id == ws.id { - return; - } + let did_change = output.show_workspace(&ws); + ws.last_active_child() + .node_do_focus(seat, Direction::Unspecified); + if !did_change { + return; } - output.show_workspace(&ws); output } _ => { @@ -262,10 +263,10 @@ impl State { }; output.update_render_data(); self.tree_changed(); - let seats = self.globals.seats.lock(); - for seat in seats.values() { - seat.workspace_changed(&output); - } + // let seats = self.globals.seats.lock(); + // for seat in seats.values() { + // seat.workspace_changed(&output); + // } } pub fn float_map_ws(&self) -> Rc { diff --git a/src/tasks/connector.rs b/src/tasks/connector.rs index 473a351c..4fd047a5 100644 --- a/src/tasks/connector.rs +++ b/src/tasks/connector.rs @@ -2,7 +2,6 @@ use { crate::{ backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo}, ifs::wl_output::WlOutputGlobal, - rect::Rect, state::{ConnectorData, OutputData, State}, tree::{OutputNode, OutputRenderData}, utils::{asyncevent::AsyncEvent, clonecell::CloneCell}, @@ -95,7 +94,8 @@ impl ConnectorHandler { global: global.clone(), layers: Default::default(), render_data: RefCell::new(OutputRenderData { - active_workspace: Rect::new_empty(0, 0), + active_workspace: None, + underline: Default::default(), inactive_workspaces: Default::default(), titles: Default::default(), status: None, diff --git a/src/theme.rs b/src/theme.rs index 0a9df6fb..e912fbfd 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -49,6 +49,7 @@ pub struct Theme { pub active_title_color: Cell, pub underline_color: Cell, pub border_color: Cell, + pub last_active_color: Cell, pub title_height: Cell, pub border_width: Cell, pub font: RefCell, @@ -57,11 +58,12 @@ pub struct Theme { impl Default for Theme { fn default() -> Self { Self { - background_color: Cell::new(Color::from_rgba(0, 0, 0, 255)), - title_color: Cell::new(Color::from_rgba(0x46, 0x04, 0x17, 255)), - active_title_color: Cell::new(Color::from_rgba(0x17, 0x04, 0x46, 255)), - underline_color: Cell::new(Color::from_rgba(0x66, 0x24, 0x37, 255)), - border_color: Cell::new(Color::from_rgba(0x36, 0x00, 0x07, 255)), + background_color: Cell::new(Color::from_rgba(0x00, 0x10, 0x19, 255)), + last_active_color: Cell::new(Color::from_rgba(0x5f, 0x67, 0x6a, 255)), + title_color: Cell::new(Color::from_rgba(0x22, 0x22, 0x22, 255)), + active_title_color: Cell::new(Color::from_rgba(0x28, 0x55, 0x77, 255)), + underline_color: Cell::new(Color::from_rgba(0x33, 0x33, 0x33, 255)), + border_color: Cell::new(Color::from_rgba(0x3f, 0x47, 0x4a, 255)), title_height: Cell::new(17), border_width: Cell::new(4), font: RefCell::new("monospace 8".to_string()), diff --git a/src/tree.rs b/src/tree.rs index 4502d74c..d1b22524 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -242,8 +242,8 @@ pub trait SizedNode: Sized + 'static { let _ = (child, width, height); } - fn child_active_changed(self: &Rc, child: &dyn Node, active: bool) { - let _ = (child, active); + fn child_active_changed(self: &Rc, child: &dyn Node, active: bool, depth: u32) { + let _ = (child, active, depth); } fn leave(&self, seat: &WlSeatGlobal) { @@ -407,7 +407,7 @@ pub trait Node { fn node_replace_child(self: Rc, old: &dyn Node, new: Rc); fn node_remove_child(self: Rc, child: &dyn Node); fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32); - fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool); + fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool, depth: u32); fn node_leave(&self, seat: &WlSeatGlobal); fn node_pointer_enter(self: Rc, seat: &Rc, x: Fixed, y: Fixed); fn node_pointer_unfocus(&self, seat: &Rc); @@ -567,8 +567,8 @@ impl Node for T { fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32) { ::child_size_changed(self, child, width, height) } - fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool) { - ::child_active_changed(&self, child, active) + fn node_child_active_changed(self: Rc, child: &dyn Node, active: bool, depth: u32) { + ::child_active_changed(&self, child, active, depth) } fn node_leave(&self, seat: &WlSeatGlobal) { ::leave(self, seat) diff --git a/src/tree/container.rs b/src/tree/container.rs index 7bec52ee..939b8b89 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -4,6 +4,7 @@ use { cursor::KnownCursor, fixed::Fixed, ifs::wl_seat::{ + collect_kb_foci, collect_kb_foci2, wl_pointer::{PendingScroll, VERTICAL_SCROLL}, NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT, PX_PER_SCROLL, }, @@ -13,8 +14,7 @@ use { text, theme::Color, tree::{ - generic_node_visitor, walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, - SizedNode, WorkspaceNode, + walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, SizedNode, WorkspaceNode, }, utils::{ clonecell::CloneCell, @@ -25,6 +25,7 @@ use { }, }, ahash::AHashMap, + isnt::std_1::vec::IsntVecExt, jay_config::{Axis, Direction}, smallvec::SmallVec, std::{ @@ -81,6 +82,7 @@ pub struct ContainerTitle { pub struct ContainerRenderData { pub title_rects: Vec, pub active_title_rects: Vec, + pub last_active_rect: Option, pub border_rects: Vec, pub underline_rects: Vec, pub titles: Vec, @@ -336,6 +338,9 @@ impl ContainerNode { } fn perform_layout(self: &Rc) { + if self.num_children.get() == 0 { + return; + } self.layout_scheduled.set(false); if let Some(child) = self.mono_child.get() { self.perform_mono_layout(&child); @@ -582,25 +587,20 @@ impl ContainerNode { fn update_title(self: &Rc) { let mut title = self.title.borrow_mut(); title.clear(); - if let Some(mc) = self.mono_child.get() { - title.push_str("M["); - title.push_str(mc.title.borrow_mut().deref()); - title.push_str("]"); - } else { - let split = match self.split.get() { - ContainerSplit::Horizontal => "H", - ContainerSplit::Vertical => "V", - }; - title.push_str(split); - title.push_str("["); - for (i, c) in self.children.iter().enumerate() { - if i > 0 { - title.push_str(", "); - } - title.push_str(c.title.borrow_mut().deref()); + let split = match (self.mono_child.get().is_some(), self.split.get()) { + (true, _) => "T", + (_, ContainerSplit::Horizontal) => "H", + (_, ContainerSplit::Vertical) => "V", + }; + title.push_str(split); + title.push_str("["); + for (i, c) in self.children.iter().enumerate() { + if i > 0 { + title.push_str(", "); } - title.push_str("]"); + title.push_str(c.title.borrow_mut().deref()); } + title.push_str("]"); self.parent.get().node_child_title_changed(&**self, &title); } @@ -626,6 +626,7 @@ impl ContainerNode { rd.active_title_rects.clear(); rd.border_rects.clear(); rd.underline_rects.clear(); + let last_active = self.focus_history.last().map(|v| v.node.node_id()); let mono = self.mono_child.get().is_some(); let split = self.split.get(); for (i, child) in self.children.iter().enumerate() { @@ -645,6 +646,9 @@ impl ContainerNode { } else { rd.title_rects.push(rect); } + if last_active == Some(child.node.node_id()) { + rd.last_active_rect = Some(rect); + } if !mono { let rect = Rect::new_sized(rect.x1(), rect.y2(), rect.width(), 1).unwrap(); rd.underline_rects.push(rect); @@ -672,6 +676,9 @@ impl ContainerNode { rd.underline_rects .push(Rect::new_sized(0, th, cwidth, 1).unwrap()); } + if rd.active_title_rects.is_not_empty() { + rd.last_active_rect.take(); + } } fn activate_child(self: &Rc, child: &NodeRef) { @@ -679,13 +686,7 @@ impl ContainerNode { if mc.node.node_id() == child.node.node_id() { return; } - let mut seats = SmallVec::<[_; 3]>::new(); - mc.node - .node_visit_children(&mut generic_node_visitor(|node| { - node.node_seat_state().for_each_kb_focus(|s| { - seats.push(s); - }); - })); + let seats = collect_kb_foci(mc.node.clone()); mc.node.node_set_visible(false); for seat in seats { child @@ -765,6 +766,13 @@ impl SizedNode for ContainerNode { self.visible.get() } + fn last_active_child(self: &Rc) -> Rc { + if let Some(last) = self.focus_history.last() { + return last.node.clone().node_last_active_child(); + } + self.clone() + } + fn set_visible(&self, visible: bool) { self.visible.set(visible); for child in self.children.iter() { @@ -833,13 +841,7 @@ impl SizedNode for ContainerNode { let mut seats = SmallVec::<[_; 3]>::new(); for other in self.children.iter() { if other.node.node_id() != child_id { - other - .node - .node_visit_children(&mut generic_node_visitor(|node| { - node.node_seat_state().for_each_kb_focus(|s| { - seats.push(s); - }); - })); + collect_kb_foci2(other.node.clone(), &mut seats); other.node.node_set_visible(false); } } @@ -906,7 +908,7 @@ impl SizedNode for ContainerNode { } self.parent .get() - .node_move_focus_from_child(seat, &**self, direction); + .node_move_focus_from_child(seat, self.deref(), direction); } fn move_self(self: &Rc, direction: Direction) { @@ -1035,7 +1037,7 @@ impl SizedNode for ContainerNode { fn active_changed(&self, active: bool) { self.active.set(active); - self.parent.get().node_child_active_changed(self, active); + self.parent.get().node_child_active_changed(self, active, 1); } fn button(self: &Rc, seat: &Rc, button: u32, state: KeyState) { @@ -1282,15 +1284,22 @@ impl SizedNode for ContainerNode { } } - fn child_active_changed(self: &Rc, child: &dyn Node, active: bool) { + fn child_active_changed(self: &Rc, child: &dyn Node, active: bool, depth: u32) { let node = match self.child_nodes.borrow_mut().get(&child.node_id()) { Some(l) => l.to_ref(), None => return, }; - node.active.set(active); - node.focus_history - .set(Some(self.focus_history.add_last(node.clone()))); + if depth == 1 { + node.active.set(active); + } + if active { + node.focus_history + .set(Some(self.focus_history.add_last(node.clone()))); + } self.schedule_compute_render_data(); + self.parent + .get() + .node_child_active_changed(self.deref(), active, depth + 1); } fn pointer_enter(self: &Rc, seat: &Rc, x: Fixed, y: Fixed) { @@ -1381,7 +1390,7 @@ impl SizedNode for ContainerNode { self.parent.set(parent.clone()); parent .clone() - .node_child_active_changed(self.deref(), self.active.get()); + .node_child_active_changed(self.deref(), self.active.get(), 1); parent.node_child_size_changed(self.deref(), self.width.get(), self.height.get()); parent .clone() diff --git a/src/tree/float.rs b/src/tree/float.rs index f0f43a80..dcdfc45a 100644 --- a/src/tree/float.rs +++ b/src/tree/float.rs @@ -461,7 +461,7 @@ impl SizedNode for FloatNode { self.workspace_link.set(None); } - fn child_active_changed(self: &Rc, _child: &dyn Node, active: bool) { + fn child_active_changed(self: &Rc, _child: &dyn Node, active: bool, _depth: u32) { self.active.set(active); } diff --git a/src/tree/output.rs b/src/tree/output.rs index 6860a79f..0d132837 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -4,7 +4,7 @@ use { cursor::KnownCursor, ifs::{ wl_output::WlOutputGlobal, - wl_seat::{NodeSeatState, WlSeatGlobal}, + wl_seat::{collect_kb_foci2, NodeSeatState, WlSeatGlobal}, wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, zwlr_layer_shell_v1::{BACKGROUND, BOTTOM}, }, @@ -18,6 +18,8 @@ use { }, utils::{clonecell::CloneCell, errorfmt::ErrorFmt, linkedlist::LinkedList}, }, + jay_config::Direction, + smallvec::SmallVec, std::{ cell::{Cell, RefCell}, fmt::{Debug, Formatter}, @@ -45,11 +47,14 @@ impl OutputNode { let mut rd = self.render_data.borrow_mut(); rd.titles.clear(); rd.inactive_workspaces.clear(); + rd.active_workspace = None; rd.status = None; let mut pos = 0; let font = self.state.theme.font.borrow_mut(); let th = self.state.theme.title_height.get(); let active_id = self.workspace.get().map(|w| w.id); + let width = self.global.pos.get().width(); + rd.underline = Rect::new_sized(0, th, width, 1).unwrap(); for ws in self.workspaces.iter() { let mut title_width = th; 'create_texture: { @@ -80,7 +85,7 @@ impl OutputNode { } let rect = Rect::new_sized(pos, 0, title_width, th).unwrap(); if Some(ws.id) == active_id { - rd.active_workspace = rect; + rd.active_workspace = Some(rect); } else { rd.inactive_workspaces.push(rect); } @@ -102,7 +107,7 @@ impl OutputNode { break 'set_status; } }; - let pos = self.global.pos.get().width() - title.width() - 1; + let pos = width - title.width() - 1; rd.status = Some(OutputTitle { x: pos, y: 0, @@ -144,15 +149,22 @@ impl OutputNode { workspace } - pub fn show_workspace(&self, ws: &Rc) { + pub fn show_workspace(&self, ws: &Rc) -> bool { + let mut seats = SmallVec::new(); if let Some(old) = self.workspace.set(Some(ws.clone())) { if old.id == ws.id { - return; + return false; } + collect_kb_foci2(old.clone(), &mut seats); old.node_set_visible(false); } ws.node_set_visible(true); - ws.clone().node_change_extents(&self.workspace_rect()); + ws.change_extents(&self.workspace_rect()); + let node = ws.last_active_child(); + for seat in seats { + node.clone().node_do_focus(&seat, Direction::Unspecified); + } + true } fn workspace_rect(&self) -> Rect { @@ -160,9 +172,9 @@ impl OutputNode { let th = self.state.theme.title_height.get(); Rect::new_sized( rect.x1(), - rect.y1() + th, + rect.y1() + th + 1, rect.width(), - rect.height().sub(th).max(0), + rect.height().sub(th + 1).max(0), ) .unwrap() } @@ -237,7 +249,8 @@ pub struct OutputTitle { #[derive(Default)] pub struct OutputRenderData { - pub active_workspace: Rect, + pub active_workspace: Option, + pub underline: Rect, pub inactive_workspaces: Vec, pub titles: Vec, pub status: Option, @@ -260,7 +273,7 @@ impl SizedNode for OutputNode { fn destroy_node(&self, detach: bool) { if detach { - self.state.root.clone().node_remove_child(self); + self.state.root.remove_child(self); } self.workspace.set(None); let workspaces: Vec<_> = self.workspaces.iter().map(|e| e.deref().clone()).collect(); @@ -289,14 +302,21 @@ impl SizedNode for OutputNode { true } + fn last_active_child(self: &Rc) -> Rc { + if let Some(ws) = self.workspace.get() { + return ws.last_active_child(); + } + self.clone() + } + fn absolute_position(&self) -> Rect { self.global.pos.get() } fn find_tree_at(&self, x: i32, mut y: i32, tree: &mut Vec) -> FindTreeResult { - let th = self.state.theme.title_height.get(); - if y > th { - y -= th; + let bar_height = self.state.theme.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 { diff --git a/src/tree/workspace.rs b/src/tree/workspace.rs index 4d4bc01e..70522010 100644 --- a/src/tree/workspace.rs +++ b/src/tree/workspace.rs @@ -33,9 +33,9 @@ pub struct WorkspaceNode { impl WorkspaceNode { pub fn set_container(self: &Rc, container: &Rc) { let pos = self.position.get(); - container.clone().node_change_extents(&pos); - container.clone().node_set_workspace(self); - container.node_set_visible(self.visible.get()); + container.change_extents(&pos); + container.set_workspace(self); + container.set_visible(self.visible.get()); self.container.set(Some(container.clone())); } } @@ -74,6 +74,13 @@ impl SizedNode for WorkspaceNode { self.visible.get() } + fn last_active_child(self: &Rc) -> Rc { + if let Some(c) = self.container.get() { + return c.last_active_child(); + } + self.clone() + } + fn set_visible(&self, visible: bool) { self.visible.set(visible); if let Some(container) = self.container.get() { diff --git a/src/video.rs b/src/video.rs index 15947931..647f4358 100644 --- a/src/video.rs +++ b/src/video.rs @@ -1,6 +1,6 @@ use crate::format::Format; -pub mod dma; +pub mod dmabuf; pub mod drm; pub mod gbm; diff --git a/src/video/dma.rs b/src/video/dmabuf.rs similarity index 100% rename from src/video/dma.rs rename to src/video/dmabuf.rs diff --git a/src/video/drm.rs b/src/video/drm.rs index 80771d37..18d9455e 100644 --- a/src/video/drm.rs +++ b/src/video/drm.rs @@ -32,7 +32,7 @@ use { use crate::{ backend, utils::{errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt}, - video::{dma::DmaBuf, INVALID_MODIFIER}, + video::{dmabuf::DmaBuf, INVALID_MODIFIER}, }; pub use sys::{ drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, diff --git a/src/video/gbm.rs b/src/video/gbm.rs index 45db93fe..142e0844 100644 --- a/src/video/gbm.rs +++ b/src/video/gbm.rs @@ -2,7 +2,7 @@ use { crate::{ format::formats, video::{ - dma::{DmaBuf, DmaBufPlane}, + dmabuf::{DmaBuf, DmaBufPlane}, drm::{Drm, DrmError}, ModifiedFormat, INVALID_MODIFIER, },