1
0
Fork 0
forked from wry/wry

autocommit 2022-04-13 12:58:04 CEST

This commit is contained in:
Julian Orth 2022-04-13 12:58:04 +02:00
parent 8924936079
commit 661a28e5b0
23 changed files with 165 additions and 143 deletions

View file

@ -8,7 +8,7 @@ use {
render::RenderError, render::RenderError,
utils::buffd::{MsgParser, MsgParserError}, utils::buffd::{MsgParser, MsgParserError},
video::{ video::{
dma::{DmaBuf, DmaBufPlane}, dmabuf::{DmaBuf, DmaBufPlane},
INVALID_MODIFIER, INVALID_MODIFIER,
}, },
wire::{wl_drm::*, WlDrmId}, wire::{wl_drm::*, WlDrmId},

View file

@ -32,7 +32,10 @@ use {
leaks::Tracker, leaks::Tracker,
object::{Object, ObjectId}, object::{Object, ObjectId},
state::State, state::State,
tree::{ContainerSplit, FloatNode, FoundNode, Node, OutputNode, ToplevelNode}, tree::{
generic_node_visitor, ContainerSplit, FloatNode, FoundNode, Node, OutputNode,
ToplevelNode,
},
utils::{ utils::{
asyncevent::AsyncEvent, asyncevent::AsyncEvent,
buffd::{MsgParser, MsgParserError}, buffd::{MsgParser, MsgParserError},
@ -51,6 +54,7 @@ use {
}, },
ahash::{AHashMap, AHashSet}, ahash::{AHashMap, AHashSet},
jay_config::{keyboard::mods::Modifiers, Direction}, jay_config::{keyboard::mods::Modifiers, Direction},
smallvec::SmallVec,
std::{ std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
collections::hash_map::Entry, collections::hash_map::Entry,
@ -422,10 +426,6 @@ impl WlSeatGlobal {
self.id self.id
} }
pub fn workspace_changed(self: &Rc<Self>, output: &Rc<OutputNode>) {
self.kb_owner.workspace_changed(self, output);
}
fn bind_( fn bind_(
self: Rc<Self>, self: Rc<Self>,
id: WlSeatId, id: WlSeatId,
@ -708,3 +708,15 @@ pub enum ReleaseError {
} }
efrom!(ReleaseError, ClientError, ClientError); efrom!(ReleaseError, ClientError, ClientError);
efrom!(ReleaseError, ParseError, MsgParserError); efrom!(ReleaseError, ParseError, MsgParserError);
pub fn collect_kb_foci2(node: Rc<dyn Node>, seats: &mut SmallVec<[Rc<WlSeatGlobal>; 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<dyn Node>) -> SmallVec<[Rc<WlSeatGlobal>; 3]> {
let mut res = SmallVec::new();
collect_kb_foci2(node, &mut res);
res
}

View file

@ -1,10 +1,6 @@
use { use {
crate::{ crate::{ifs::wl_seat::WlSeatGlobal, tree::Node, utils::clonecell::CloneCell},
ifs::wl_seat::WlSeatGlobal, std::rc::Rc,
tree::{Node, OutputNode},
utils::clonecell::CloneCell,
},
std::{ops::Deref, rc::Rc},
}; };
pub struct KbOwnerHolder { pub struct KbOwnerHolder {
@ -33,10 +29,6 @@ impl KbOwnerHolder {
pub fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) { pub fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) {
self.owner.get().set_kb_node(seat, node); self.owner.get().set_kb_node(seat, node);
} }
pub fn workspace_changed(&self, seat: &Rc<WlSeatGlobal>, output: &Rc<OutputNode>) {
self.owner.get().workspace_changed(seat, output);
}
} }
struct DefaultKbOwner; struct DefaultKbOwner;
@ -47,7 +39,6 @@ trait KbOwner {
fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool; fn grab(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>) -> bool;
fn ungrab(&self, seat: &Rc<WlSeatGlobal>); fn ungrab(&self, seat: &Rc<WlSeatGlobal>);
fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>); fn set_kb_node(&self, seat: &Rc<WlSeatGlobal>, node: Rc<dyn Node>);
fn workspace_changed(&self, seat: &Rc<WlSeatGlobal>, output: &Rc<OutputNode>);
} }
impl KbOwner for DefaultKbOwner { impl KbOwner for DefaultKbOwner {
@ -77,31 +68,6 @@ impl KbOwner for DefaultKbOwner {
node.clone().node_focus(seat); node.clone().node_focus(seat);
seat.keyboard_node.set(node.clone()); seat.keyboard_node.set(node.clone());
} }
fn workspace_changed(&self, seat: &Rc<WlSeatGlobal>, output: &Rc<OutputNode>) {
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 { impl KbOwner for GrabKbOwner {
@ -116,8 +82,4 @@ impl KbOwner for GrabKbOwner {
fn set_kb_node(&self, _seat: &Rc<WlSeatGlobal>, _node: Rc<dyn Node>) { fn set_kb_node(&self, _seat: &Rc<WlSeatGlobal>, _node: Rc<dyn Node>) {
// nothing // nothing
} }
fn workspace_changed(&self, _seat: &Rc<WlSeatGlobal>, _output: &Rc<OutputNode>) {
// nothing
}
} }

View file

@ -46,7 +46,6 @@ impl WlKeyboard {
} }
pub fn send_enter(self: &Rc<Self>, serial: u32, surface: WlSurfaceId, keys: &[u32]) { pub fn send_enter(self: &Rc<Self>, serial: u32, surface: WlSurfaceId, keys: &[u32]) {
log::info!("enter with {:?}", keys);
self.seat.client.event(Enter { self.seat.client.event(Enter {
self_id: self.id, self_id: self.id,
serial, serial,

View file

@ -309,9 +309,11 @@ impl XdgToplevel {
_ => return, _ => return,
}; };
let extents = self.xdg.extents.get(); let extents = self.xdg.extents.get();
parent parent.clone().node_child_active_changed(
.clone() self,
.node_child_active_changed(self, self.toplevel_data.active_surfaces.get() > 0); self.toplevel_data.active_surfaces.get() > 0,
1,
);
parent.node_child_size_changed(self, extents.width(), extents.height()); parent.node_child_size_changed(self, extents.width(), extents.height());
parent.node_child_title_changed(self, self.title.borrow_mut().deref()); 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) { fn set_active(&self, active: bool) {
if let Some(parent) = self.parent_node.get() { 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 changed = {
let mut states = self.states.borrow_mut(); let mut states = self.states.borrow_mut();

View file

@ -463,7 +463,7 @@ impl ToplevelNode for Xwindow {
fn set_active(&self, active: bool) { fn set_active(&self, active: bool) {
if let Some(pn) = self.parent_node.get() { if let Some(pn) = self.parent_node.get() {
pn.node_child_active_changed(self, active); pn.node_child_active_changed(self, active, 1);
} }
} }

View file

@ -374,7 +374,7 @@ impl SizedNode for ZwlrLayerSurfaceV1 {
} }
fn visit_children(&self, visitor: &mut dyn NodeVisitor) { fn visit_children(&self, visitor: &mut dyn NodeVisitor) {
self.surface.clone().node_visit(visitor); self.surface.visit(visitor);
} }
fn visible(&self) -> bool { fn visible(&self) -> bool {

View file

@ -10,7 +10,7 @@ use {
errorfmt::ErrorFmt, errorfmt::ErrorFmt,
}, },
video::{ video::{
dma::{DmaBuf, DmaBufPlane}, dmabuf::{DmaBuf, DmaBufPlane},
INVALID_MODIFIER, INVALID_MODIFIER,
}, },
wire::{zwp_linux_buffer_params_v1::*, WlBufferId, ZwpLinuxBufferParamsV1Id}, wire::{zwp_linux_buffer_params_v1::*, WlBufferId, ZwpLinuxBufferParamsV1Id},

View file

@ -26,7 +26,7 @@ use {
sys::{eglInitialize, EGL_PLATFORM_GBM_KHR}, sys::{eglInitialize, EGL_PLATFORM_GBM_KHR},
RenderError, RenderError,
}, },
video::{dma::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER}, video::{dmabuf::DmaBuf, drm::Drm, gbm::GbmDevice, INVALID_MODIFIER},
}, },
ahash::AHashMap, ahash::AHashMap,
std::{ptr, rc::Rc}, std::{ptr, rc::Rc},

View file

@ -10,7 +10,7 @@ use {
RenderError, Texture, RenderError, Texture,
}, },
video::{ video::{
dma::DmaBuf, dmabuf::DmaBuf,
drm::{Drm, NodeType}, drm::{Drm, NodeType},
}, },
}, },

View file

@ -28,7 +28,7 @@ use {
tree::{ContainerNode, FloatNode, OutputNode, WorkspaceNode}, tree::{ContainerNode, FloatNode, OutputNode, WorkspaceNode},
utils::rc_eq::rc_eq, utils::rc_eq::rc_eq,
}, },
std::{ops::Deref, rc::Rc}, std::{ops::Deref, rc::Rc, slice},
}; };
pub struct Renderer<'a> { pub struct Renderer<'a> {
@ -58,8 +58,12 @@ impl Renderer<'_> {
let th = theme.title_height.get(); let th = theme.title_height.get();
{ {
let rd = output.render_data.borrow_mut(); let rd = output.render_data.borrow_mut();
let c = theme.active_title_color.get(); if let Some(aw) = &rd.active_workspace {
self.fill_boxes(std::slice::from_ref(&rd.active_workspace), &c); 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(); let c = theme.title_color.get();
self.fill_boxes(&rd.inactive_workspaces, &c); self.fill_boxes(&rd.inactive_workspaces, &c);
for title in &rd.titles { for title in &rd.titles {
@ -70,7 +74,7 @@ impl Renderer<'_> {
} }
} }
if let Some(ws) = output.workspace.get() { 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() { for stacked in self.state.root.stacked.iter() {
if stacked.node_visible() { if stacked.node_visible() {
@ -152,6 +156,10 @@ impl Renderer<'_> {
self.fill_boxes2(&rd.underline_rects, &c, x, y); self.fill_boxes2(&rd.underline_rects, &c, x, y);
let c = self.state.theme.border_color.get(); let c = self.state.theme.border_color.get();
self.fill_boxes2(&rd.border_rects, &c, x, y); 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 { for title in &rd.titles {
self.render_texture(&title.tex, x + title.x, y + title.y, ARGB8888); self.render_texture(&title.tex, x + title.x, y + title.y, ARGB8888);
} }

View file

@ -22,7 +22,7 @@ use {
theme::Theme, theme::Theme,
tree::{ tree::{
ContainerNode, ContainerSplit, DisplayNode, FloatNode, Node, NodeIds, NodeVisitorBase, ContainerNode, ContainerSplit, DisplayNode, FloatNode, Node, NodeIds, NodeVisitorBase,
OutputNode, WorkspaceNode, OutputNode, SizedNode, WorkspaceNode,
}, },
utils::{ utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, fdcloser::FdCloser, clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, fdcloser::FdCloser,
@ -32,6 +32,7 @@ use {
xkbcommon::{XkbContext, XkbKeymap}, xkbcommon::{XkbContext, XkbKeymap},
}, },
ahash::AHashMap, ahash::AHashMap,
jay_config::Direction,
std::{ std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
rc::Rc, rc::Rc,
@ -131,7 +132,7 @@ impl State {
node.node_visit_children(self); node.node_visit_children(self);
} }
} }
self.root.clone().node_visit(&mut Walker); self.root.visit(&mut Walker);
let seats = self.globals.seats.lock(); let seats = self.globals.seats.lock();
for seat in seats.values() { for seat in seats.values() {
@ -227,12 +228,12 @@ impl State {
let output = match self.workspaces.get(name) { let output = match self.workspaces.get(name) {
Some(ws) => { Some(ws) => {
let output = ws.output.get(); let output = ws.output.get();
if let Some(old) = output.workspace.get() { let did_change = output.show_workspace(&ws);
if old.id == ws.id { ws.last_active_child()
return; .node_do_focus(seat, Direction::Unspecified);
} if !did_change {
return;
} }
output.show_workspace(&ws);
output output
} }
_ => { _ => {
@ -262,10 +263,10 @@ impl State {
}; };
output.update_render_data(); output.update_render_data();
self.tree_changed(); self.tree_changed();
let seats = self.globals.seats.lock(); // let seats = self.globals.seats.lock();
for seat in seats.values() { // for seat in seats.values() {
seat.workspace_changed(&output); // seat.workspace_changed(&output);
} // }
} }
pub fn float_map_ws(&self) -> Rc<WorkspaceNode> { pub fn float_map_ws(&self) -> Rc<WorkspaceNode> {

View file

@ -2,7 +2,6 @@ use {
crate::{ crate::{
backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo}, backend::{Connector, ConnectorEvent, ConnectorId, MonitorInfo},
ifs::wl_output::WlOutputGlobal, ifs::wl_output::WlOutputGlobal,
rect::Rect,
state::{ConnectorData, OutputData, State}, state::{ConnectorData, OutputData, State},
tree::{OutputNode, OutputRenderData}, tree::{OutputNode, OutputRenderData},
utils::{asyncevent::AsyncEvent, clonecell::CloneCell}, utils::{asyncevent::AsyncEvent, clonecell::CloneCell},
@ -95,7 +94,8 @@ impl ConnectorHandler {
global: global.clone(), global: global.clone(),
layers: Default::default(), layers: Default::default(),
render_data: RefCell::new(OutputRenderData { render_data: RefCell::new(OutputRenderData {
active_workspace: Rect::new_empty(0, 0), active_workspace: None,
underline: Default::default(),
inactive_workspaces: Default::default(), inactive_workspaces: Default::default(),
titles: Default::default(), titles: Default::default(),
status: None, status: None,

View file

@ -49,6 +49,7 @@ pub struct Theme {
pub active_title_color: Cell<Color>, pub active_title_color: Cell<Color>,
pub underline_color: Cell<Color>, pub underline_color: Cell<Color>,
pub border_color: Cell<Color>, pub border_color: Cell<Color>,
pub last_active_color: Cell<Color>,
pub title_height: Cell<i32>, pub title_height: Cell<i32>,
pub border_width: Cell<i32>, pub border_width: Cell<i32>,
pub font: RefCell<String>, pub font: RefCell<String>,
@ -57,11 +58,12 @@ pub struct Theme {
impl Default for Theme { impl Default for Theme {
fn default() -> Self { fn default() -> Self {
Self { Self {
background_color: Cell::new(Color::from_rgba(0, 0, 0, 255)), background_color: Cell::new(Color::from_rgba(0x00, 0x10, 0x19, 255)),
title_color: Cell::new(Color::from_rgba(0x46, 0x04, 0x17, 255)), last_active_color: Cell::new(Color::from_rgba(0x5f, 0x67, 0x6a, 255)),
active_title_color: Cell::new(Color::from_rgba(0x17, 0x04, 0x46, 255)), title_color: Cell::new(Color::from_rgba(0x22, 0x22, 0x22, 255)),
underline_color: Cell::new(Color::from_rgba(0x66, 0x24, 0x37, 255)), active_title_color: Cell::new(Color::from_rgba(0x28, 0x55, 0x77, 255)),
border_color: Cell::new(Color::from_rgba(0x36, 0x00, 0x07, 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), title_height: Cell::new(17),
border_width: Cell::new(4), border_width: Cell::new(4),
font: RefCell::new("monospace 8".to_string()), font: RefCell::new("monospace 8".to_string()),

View file

@ -242,8 +242,8 @@ pub trait SizedNode: Sized + 'static {
let _ = (child, width, height); let _ = (child, width, height);
} }
fn child_active_changed(self: &Rc<Self>, child: &dyn Node, active: bool) { fn child_active_changed(self: &Rc<Self>, child: &dyn Node, active: bool, depth: u32) {
let _ = (child, active); let _ = (child, active, depth);
} }
fn leave(&self, seat: &WlSeatGlobal) { fn leave(&self, seat: &WlSeatGlobal) {
@ -407,7 +407,7 @@ pub trait Node {
fn node_replace_child(self: Rc<Self>, old: &dyn Node, new: Rc<dyn Node>); fn node_replace_child(self: Rc<Self>, old: &dyn Node, new: Rc<dyn Node>);
fn node_remove_child(self: Rc<Self>, child: &dyn Node); fn node_remove_child(self: Rc<Self>, child: &dyn Node);
fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32); fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32);
fn node_child_active_changed(self: Rc<Self>, child: &dyn Node, active: bool); fn node_child_active_changed(self: Rc<Self>, child: &dyn Node, active: bool, depth: u32);
fn node_leave(&self, seat: &WlSeatGlobal); fn node_leave(&self, seat: &WlSeatGlobal);
fn node_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed); fn node_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed);
fn node_pointer_unfocus(&self, seat: &Rc<WlSeatGlobal>); fn node_pointer_unfocus(&self, seat: &Rc<WlSeatGlobal>);
@ -567,8 +567,8 @@ impl<T: SizedNode> Node for T {
fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32) { fn node_child_size_changed(&self, child: &dyn Node, width: i32, height: i32) {
<Self as SizedNode>::child_size_changed(self, child, width, height) <Self as SizedNode>::child_size_changed(self, child, width, height)
} }
fn node_child_active_changed(self: Rc<Self>, child: &dyn Node, active: bool) { fn node_child_active_changed(self: Rc<Self>, child: &dyn Node, active: bool, depth: u32) {
<Self as SizedNode>::child_active_changed(&self, child, active) <Self as SizedNode>::child_active_changed(&self, child, active, depth)
} }
fn node_leave(&self, seat: &WlSeatGlobal) { fn node_leave(&self, seat: &WlSeatGlobal) {
<Self as SizedNode>::leave(self, seat) <Self as SizedNode>::leave(self, seat)

View file

@ -4,6 +4,7 @@ use {
cursor::KnownCursor, cursor::KnownCursor,
fixed::Fixed, fixed::Fixed,
ifs::wl_seat::{ ifs::wl_seat::{
collect_kb_foci, collect_kb_foci2,
wl_pointer::{PendingScroll, VERTICAL_SCROLL}, wl_pointer::{PendingScroll, VERTICAL_SCROLL},
NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT, PX_PER_SCROLL, NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT, PX_PER_SCROLL,
}, },
@ -13,8 +14,7 @@ use {
text, text,
theme::Color, theme::Color,
tree::{ tree::{
generic_node_visitor, walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, SizedNode, WorkspaceNode,
SizedNode, WorkspaceNode,
}, },
utils::{ utils::{
clonecell::CloneCell, clonecell::CloneCell,
@ -25,6 +25,7 @@ use {
}, },
}, },
ahash::AHashMap, ahash::AHashMap,
isnt::std_1::vec::IsntVecExt,
jay_config::{Axis, Direction}, jay_config::{Axis, Direction},
smallvec::SmallVec, smallvec::SmallVec,
std::{ std::{
@ -81,6 +82,7 @@ pub struct ContainerTitle {
pub struct ContainerRenderData { pub struct ContainerRenderData {
pub title_rects: Vec<Rect>, pub title_rects: Vec<Rect>,
pub active_title_rects: Vec<Rect>, pub active_title_rects: Vec<Rect>,
pub last_active_rect: Option<Rect>,
pub border_rects: Vec<Rect>, pub border_rects: Vec<Rect>,
pub underline_rects: Vec<Rect>, pub underline_rects: Vec<Rect>,
pub titles: Vec<ContainerTitle>, pub titles: Vec<ContainerTitle>,
@ -336,6 +338,9 @@ impl ContainerNode {
} }
fn perform_layout(self: &Rc<Self>) { fn perform_layout(self: &Rc<Self>) {
if self.num_children.get() == 0 {
return;
}
self.layout_scheduled.set(false); self.layout_scheduled.set(false);
if let Some(child) = self.mono_child.get() { if let Some(child) = self.mono_child.get() {
self.perform_mono_layout(&child); self.perform_mono_layout(&child);
@ -582,25 +587,20 @@ impl ContainerNode {
fn update_title(self: &Rc<Self>) { fn update_title(self: &Rc<Self>) {
let mut title = self.title.borrow_mut(); let mut title = self.title.borrow_mut();
title.clear(); title.clear();
if let Some(mc) = self.mono_child.get() { let split = match (self.mono_child.get().is_some(), self.split.get()) {
title.push_str("M["); (true, _) => "T",
title.push_str(mc.title.borrow_mut().deref()); (_, ContainerSplit::Horizontal) => "H",
title.push_str("]"); (_, ContainerSplit::Vertical) => "V",
} else { };
let split = match self.split.get() { title.push_str(split);
ContainerSplit::Horizontal => "H", title.push_str("[");
ContainerSplit::Vertical => "V", for (i, c) in self.children.iter().enumerate() {
}; if i > 0 {
title.push_str(split); title.push_str(", ");
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());
} }
title.push_str("]"); title.push_str(c.title.borrow_mut().deref());
} }
title.push_str("]");
self.parent.get().node_child_title_changed(&**self, &title); self.parent.get().node_child_title_changed(&**self, &title);
} }
@ -626,6 +626,7 @@ impl ContainerNode {
rd.active_title_rects.clear(); rd.active_title_rects.clear();
rd.border_rects.clear(); rd.border_rects.clear();
rd.underline_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 mono = self.mono_child.get().is_some();
let split = self.split.get(); let split = self.split.get();
for (i, child) in self.children.iter().enumerate() { for (i, child) in self.children.iter().enumerate() {
@ -645,6 +646,9 @@ impl ContainerNode {
} else { } else {
rd.title_rects.push(rect); rd.title_rects.push(rect);
} }
if last_active == Some(child.node.node_id()) {
rd.last_active_rect = Some(rect);
}
if !mono { if !mono {
let rect = Rect::new_sized(rect.x1(), rect.y2(), rect.width(), 1).unwrap(); let rect = Rect::new_sized(rect.x1(), rect.y2(), rect.width(), 1).unwrap();
rd.underline_rects.push(rect); rd.underline_rects.push(rect);
@ -672,6 +676,9 @@ impl ContainerNode {
rd.underline_rects rd.underline_rects
.push(Rect::new_sized(0, th, cwidth, 1).unwrap()); .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<Self>, child: &NodeRef<ContainerChild>) { fn activate_child(self: &Rc<Self>, child: &NodeRef<ContainerChild>) {
@ -679,13 +686,7 @@ impl ContainerNode {
if mc.node.node_id() == child.node.node_id() { if mc.node.node_id() == child.node.node_id() {
return; return;
} }
let mut seats = SmallVec::<[_; 3]>::new(); let seats = collect_kb_foci(mc.node.clone());
mc.node
.node_visit_children(&mut generic_node_visitor(|node| {
node.node_seat_state().for_each_kb_focus(|s| {
seats.push(s);
});
}));
mc.node.node_set_visible(false); mc.node.node_set_visible(false);
for seat in seats { for seat in seats {
child child
@ -765,6 +766,13 @@ impl SizedNode for ContainerNode {
self.visible.get() self.visible.get()
} }
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
if let Some(last) = self.focus_history.last() {
return last.node.clone().node_last_active_child();
}
self.clone()
}
fn set_visible(&self, visible: bool) { fn set_visible(&self, visible: bool) {
self.visible.set(visible); self.visible.set(visible);
for child in self.children.iter() { for child in self.children.iter() {
@ -833,13 +841,7 @@ impl SizedNode for ContainerNode {
let mut seats = SmallVec::<[_; 3]>::new(); let mut seats = SmallVec::<[_; 3]>::new();
for other in self.children.iter() { for other in self.children.iter() {
if other.node.node_id() != child_id { if other.node.node_id() != child_id {
other collect_kb_foci2(other.node.clone(), &mut seats);
.node
.node_visit_children(&mut generic_node_visitor(|node| {
node.node_seat_state().for_each_kb_focus(|s| {
seats.push(s);
});
}));
other.node.node_set_visible(false); other.node.node_set_visible(false);
} }
} }
@ -906,7 +908,7 @@ impl SizedNode for ContainerNode {
} }
self.parent self.parent
.get() .get()
.node_move_focus_from_child(seat, &**self, direction); .node_move_focus_from_child(seat, self.deref(), direction);
} }
fn move_self(self: &Rc<Self>, direction: Direction) { fn move_self(self: &Rc<Self>, direction: Direction) {
@ -1035,7 +1037,7 @@ impl SizedNode for ContainerNode {
fn active_changed(&self, active: bool) { fn active_changed(&self, active: bool) {
self.active.set(active); 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<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) { fn button(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState) {
@ -1282,15 +1284,22 @@ impl SizedNode for ContainerNode {
} }
} }
fn child_active_changed(self: &Rc<Self>, child: &dyn Node, active: bool) { fn child_active_changed(self: &Rc<Self>, child: &dyn Node, active: bool, depth: u32) {
let node = match self.child_nodes.borrow_mut().get(&child.node_id()) { let node = match self.child_nodes.borrow_mut().get(&child.node_id()) {
Some(l) => l.to_ref(), Some(l) => l.to_ref(),
None => return, None => return,
}; };
node.active.set(active); if depth == 1 {
node.focus_history node.active.set(active);
.set(Some(self.focus_history.add_last(node.clone()))); }
if active {
node.focus_history
.set(Some(self.focus_history.add_last(node.clone())));
}
self.schedule_compute_render_data(); self.schedule_compute_render_data();
self.parent
.get()
.node_child_active_changed(self.deref(), active, depth + 1);
} }
fn pointer_enter(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) { fn pointer_enter(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
@ -1381,7 +1390,7 @@ impl SizedNode for ContainerNode {
self.parent.set(parent.clone()); self.parent.set(parent.clone());
parent parent
.clone() .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.node_child_size_changed(self.deref(), self.width.get(), self.height.get());
parent parent
.clone() .clone()

View file

@ -461,7 +461,7 @@ impl SizedNode for FloatNode {
self.workspace_link.set(None); self.workspace_link.set(None);
} }
fn child_active_changed(self: &Rc<Self>, _child: &dyn Node, active: bool) { fn child_active_changed(self: &Rc<Self>, _child: &dyn Node, active: bool, _depth: u32) {
self.active.set(active); self.active.set(active);
} }

View file

@ -4,7 +4,7 @@ use {
cursor::KnownCursor, cursor::KnownCursor,
ifs::{ ifs::{
wl_output::WlOutputGlobal, wl_output::WlOutputGlobal,
wl_seat::{NodeSeatState, WlSeatGlobal}, wl_seat::{collect_kb_foci2, NodeSeatState, WlSeatGlobal},
wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, wl_surface::zwlr_layer_surface_v1::ZwlrLayerSurfaceV1,
zwlr_layer_shell_v1::{BACKGROUND, BOTTOM}, zwlr_layer_shell_v1::{BACKGROUND, BOTTOM},
}, },
@ -18,6 +18,8 @@ use {
}, },
utils::{clonecell::CloneCell, errorfmt::ErrorFmt, linkedlist::LinkedList}, utils::{clonecell::CloneCell, errorfmt::ErrorFmt, linkedlist::LinkedList},
}, },
jay_config::Direction,
smallvec::SmallVec,
std::{ std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
fmt::{Debug, Formatter}, fmt::{Debug, Formatter},
@ -45,11 +47,14 @@ impl OutputNode {
let mut rd = self.render_data.borrow_mut(); let mut rd = self.render_data.borrow_mut();
rd.titles.clear(); rd.titles.clear();
rd.inactive_workspaces.clear(); rd.inactive_workspaces.clear();
rd.active_workspace = None;
rd.status = None; rd.status = None;
let mut pos = 0; let mut pos = 0;
let font = self.state.theme.font.borrow_mut(); let font = self.state.theme.font.borrow_mut();
let th = self.state.theme.title_height.get(); let th = self.state.theme.title_height.get();
let active_id = self.workspace.get().map(|w| w.id); 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() { for ws in self.workspaces.iter() {
let mut title_width = th; let mut title_width = th;
'create_texture: { 'create_texture: {
@ -80,7 +85,7 @@ impl OutputNode {
} }
let rect = Rect::new_sized(pos, 0, title_width, th).unwrap(); let rect = Rect::new_sized(pos, 0, title_width, th).unwrap();
if Some(ws.id) == active_id { if Some(ws.id) == active_id {
rd.active_workspace = rect; rd.active_workspace = Some(rect);
} else { } else {
rd.inactive_workspaces.push(rect); rd.inactive_workspaces.push(rect);
} }
@ -102,7 +107,7 @@ impl OutputNode {
break 'set_status; break 'set_status;
} }
}; };
let pos = self.global.pos.get().width() - title.width() - 1; let pos = width - title.width() - 1;
rd.status = Some(OutputTitle { rd.status = Some(OutputTitle {
x: pos, x: pos,
y: 0, y: 0,
@ -144,15 +149,22 @@ impl OutputNode {
workspace workspace
} }
pub fn show_workspace(&self, ws: &Rc<WorkspaceNode>) { pub fn show_workspace(&self, ws: &Rc<WorkspaceNode>) -> bool {
let mut seats = SmallVec::new();
if let Some(old) = self.workspace.set(Some(ws.clone())) { if let Some(old) = self.workspace.set(Some(ws.clone())) {
if old.id == ws.id { if old.id == ws.id {
return; return false;
} }
collect_kb_foci2(old.clone(), &mut seats);
old.node_set_visible(false); old.node_set_visible(false);
} }
ws.node_set_visible(true); 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 { fn workspace_rect(&self) -> Rect {
@ -160,9 +172,9 @@ impl OutputNode {
let th = self.state.theme.title_height.get(); let th = self.state.theme.title_height.get();
Rect::new_sized( Rect::new_sized(
rect.x1(), rect.x1(),
rect.y1() + th, rect.y1() + th + 1,
rect.width(), rect.width(),
rect.height().sub(th).max(0), rect.height().sub(th + 1).max(0),
) )
.unwrap() .unwrap()
} }
@ -237,7 +249,8 @@ pub struct OutputTitle {
#[derive(Default)] #[derive(Default)]
pub struct OutputRenderData { pub struct OutputRenderData {
pub active_workspace: Rect, pub active_workspace: Option<Rect>,
pub underline: Rect,
pub inactive_workspaces: Vec<Rect>, pub inactive_workspaces: Vec<Rect>,
pub titles: Vec<OutputTitle>, pub titles: Vec<OutputTitle>,
pub status: Option<OutputTitle>, pub status: Option<OutputTitle>,
@ -260,7 +273,7 @@ impl SizedNode for OutputNode {
fn destroy_node(&self, detach: bool) { fn destroy_node(&self, detach: bool) {
if detach { if detach {
self.state.root.clone().node_remove_child(self); self.state.root.remove_child(self);
} }
self.workspace.set(None); self.workspace.set(None);
let workspaces: Vec<_> = self.workspaces.iter().map(|e| e.deref().clone()).collect(); let workspaces: Vec<_> = self.workspaces.iter().map(|e| e.deref().clone()).collect();
@ -289,14 +302,21 @@ impl SizedNode for OutputNode {
true true
} }
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
if let Some(ws) = self.workspace.get() {
return ws.last_active_child();
}
self.clone()
}
fn absolute_position(&self) -> Rect { fn absolute_position(&self) -> Rect {
self.global.pos.get() self.global.pos.get()
} }
fn find_tree_at(&self, x: i32, mut y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult { fn find_tree_at(&self, x: i32, mut y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
let th = self.state.theme.title_height.get(); let bar_height = self.state.theme.title_height.get() + 1;
if y > th { if y > bar_height {
y -= th; y -= bar_height;
let len = tree.len(); let len = tree.len();
if let Some(ws) = self.workspace.get() { if let Some(ws) = self.workspace.get() {
tree.push(FoundNode { tree.push(FoundNode {

View file

@ -33,9 +33,9 @@ pub struct WorkspaceNode {
impl WorkspaceNode { impl WorkspaceNode {
pub fn set_container(self: &Rc<Self>, container: &Rc<ContainerNode>) { pub fn set_container(self: &Rc<Self>, container: &Rc<ContainerNode>) {
let pos = self.position.get(); let pos = self.position.get();
container.clone().node_change_extents(&pos); container.change_extents(&pos);
container.clone().node_set_workspace(self); container.set_workspace(self);
container.node_set_visible(self.visible.get()); container.set_visible(self.visible.get());
self.container.set(Some(container.clone())); self.container.set(Some(container.clone()));
} }
} }
@ -74,6 +74,13 @@ impl SizedNode for WorkspaceNode {
self.visible.get() self.visible.get()
} }
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
if let Some(c) = self.container.get() {
return c.last_active_child();
}
self.clone()
}
fn set_visible(&self, visible: bool) { fn set_visible(&self, visible: bool) {
self.visible.set(visible); self.visible.set(visible);
if let Some(container) = self.container.get() { if let Some(container) = self.container.get() {

View file

@ -1,6 +1,6 @@
use crate::format::Format; use crate::format::Format;
pub mod dma; pub mod dmabuf;
pub mod drm; pub mod drm;
pub mod gbm; pub mod gbm;

View file

@ -32,7 +32,7 @@ use {
use crate::{ use crate::{
backend, backend,
utils::{errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt}, utils::{errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt},
video::{dma::DmaBuf, INVALID_MODIFIER}, video::{dmabuf::DmaBuf, INVALID_MODIFIER},
}; };
pub use sys::{ pub use sys::{
drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET, drm_mode_modeinfo, DRM_CLIENT_CAP_ATOMIC, DRM_MODE_ATOMIC_ALLOW_MODESET,

View file

@ -2,7 +2,7 @@ use {
crate::{ crate::{
format::formats, format::formats,
video::{ video::{
dma::{DmaBuf, DmaBufPlane}, dmabuf::{DmaBuf, DmaBufPlane},
drm::{Drm, DrmError}, drm::{Drm, DrmError},
ModifiedFormat, INVALID_MODIFIER, ModifiedFormat, INVALID_MODIFIER,
}, },