autocommit 2022-04-18 14:14:25 CEST
This commit is contained in:
parent
085ca95835
commit
54cf01f745
20 changed files with 155 additions and 109 deletions
|
|
@ -2,13 +2,11 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
cli::{GlobalArgs, IdleArgs, IdleCmd, IdleSetArgs},
|
cli::{GlobalArgs, IdleArgs, IdleCmd, IdleSetArgs},
|
||||||
tools::tool_client::{Handle, ToolClient},
|
tools::tool_client::{Handle, ToolClient},
|
||||||
utils::errorfmt::ErrorFmt,
|
utils::{errorfmt::ErrorFmt, stack::Stack},
|
||||||
wire::{jay_compositor, jay_idle, JayIdleId},
|
wire::{jay_compositor, jay_idle, JayIdleId, WlSurfaceId},
|
||||||
},
|
},
|
||||||
std::{cell::Cell, collections::VecDeque, rc::Rc, str::FromStr},
|
std::{cell::Cell, collections::VecDeque, rc::Rc, str::FromStr},
|
||||||
};
|
};
|
||||||
use crate::utils::stack::Stack;
|
|
||||||
use crate::wire::WlSurfaceId;
|
|
||||||
|
|
||||||
pub fn main(global: GlobalArgs, args: IdleArgs) {
|
pub fn main(global: GlobalArgs, args: IdleArgs) {
|
||||||
let tc = ToolClient::new(global.log_level.into());
|
let tc = ToolClient::new(global.log_level.into());
|
||||||
|
|
@ -81,10 +79,13 @@ impl Idle {
|
||||||
let mut inhibitors = inhibitors.take();
|
let mut inhibitors = inhibitors.take();
|
||||||
inhibitors.sort_by_key(|i| i.pid);
|
inhibitors.sort_by_key(|i| i.pid);
|
||||||
inhibitors.sort_by_key(|i| i.surface);
|
inhibitors.sort_by_key(|i| i.surface);
|
||||||
if inhibitors.len() > 0{
|
if inhibitors.len() > 0 {
|
||||||
println!("Inhibitors:");
|
println!("Inhibitors:");
|
||||||
for inhibitor in inhibitors {
|
for inhibitor in inhibitors {
|
||||||
println!(" {}, surface {}, pid {}", inhibitor.comm, inhibitor.surface, inhibitor.pid);
|
println!(
|
||||||
|
" {}, surface {}, pid {}",
|
||||||
|
inhibitor.comm, inhibitor.surface, inhibitor.pid
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use std::collections::VecDeque;
|
|
||||||
use bstr::ByteSlice;
|
|
||||||
pub use error::{ClientError, MethodError, ObjectError};
|
pub use error::{ClientError, MethodError, ObjectError};
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
|
|
@ -16,12 +14,15 @@ use {
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
queue::AsyncQueue,
|
queue::AsyncQueue,
|
||||||
|
trim::AsciiTrim,
|
||||||
},
|
},
|
||||||
wire::WlRegistryId,
|
wire::WlRegistryId,
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
|
bstr::ByteSlice,
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
|
collections::VecDeque,
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Debug, Display, Formatter},
|
fmt::{Debug, Display, Formatter},
|
||||||
mem,
|
mem,
|
||||||
|
|
@ -30,7 +31,6 @@ use {
|
||||||
},
|
},
|
||||||
uapi::{c, OwnedFd},
|
uapi::{c, OwnedFd},
|
||||||
};
|
};
|
||||||
use crate::utils::trim::AsciiTrim;
|
|
||||||
|
|
||||||
mod error;
|
mod error;
|
||||||
mod objects;
|
mod objects;
|
||||||
|
|
@ -459,9 +459,5 @@ fn get_pid_info(uid: c::uid_t, pid: c::pid_t) -> PidInfo {
|
||||||
"Unknown".to_string()
|
"Unknown".to_string()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
PidInfo {
|
PidInfo { uid, pid, comm }
|
||||||
uid,
|
|
||||||
pid,
|
|
||||||
comm,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -283,8 +283,15 @@ enum ServerMessage {
|
||||||
|
|
||||||
#[derive(Encode, Decode)]
|
#[derive(Encode, Decode)]
|
||||||
enum ForkerMessage {
|
enum ForkerMessage {
|
||||||
Log { level: usize, msg: String },
|
Log {
|
||||||
PidFd { id: u32, success: bool, pid: c::pid_t },
|
level: usize,
|
||||||
|
msg: String,
|
||||||
|
},
|
||||||
|
PidFd {
|
||||||
|
id: u32,
|
||||||
|
success: bool,
|
||||||
|
pid: c::pid_t,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Forker {
|
struct Forker {
|
||||||
|
|
@ -413,8 +420,11 @@ impl Forker {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if let Some(id) = pidfd_id {
|
if let Some(id) = pidfd_id {
|
||||||
self.outgoing
|
self.outgoing.push(ForkerMessage::PidFd {
|
||||||
.push(ForkerMessage::PidFd { id, success: false, pid: 0 });
|
id,
|
||||||
|
success: false,
|
||||||
|
pid: 0,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
self.outgoing.push(ForkerMessage::Log {
|
self.outgoing.push(ForkerMessage::Log {
|
||||||
level: log::Level::Error as usize,
|
level: log::Level::Error as usize,
|
||||||
|
|
@ -427,8 +437,11 @@ impl Forker {
|
||||||
Forked::Parent { pid, pidfd } => {
|
Forked::Parent { pid, pidfd } => {
|
||||||
if let Some(id) = pidfd_id {
|
if let Some(id) = pidfd_id {
|
||||||
self.fds.borrow_mut().push(Rc::new(pidfd));
|
self.fds.borrow_mut().push(Rc::new(pidfd));
|
||||||
self.outgoing
|
self.outgoing.push(ForkerMessage::PidFd {
|
||||||
.push(ForkerMessage::PidFd { id, success: true, pid });
|
id,
|
||||||
|
success: true,
|
||||||
|
pid,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
drop(write);
|
drop(write);
|
||||||
let slf = self.clone();
|
let slf = self.clone();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
client::{Client, ClientError},
|
client::{Client, ClientError},
|
||||||
|
ifs::wl_surface::zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1,
|
||||||
leaks::Tracker,
|
leaks::Tracker,
|
||||||
object::Object,
|
object::Object,
|
||||||
utils::buffd::{MsgParser, MsgParserError},
|
utils::buffd::{MsgParser, MsgParserError},
|
||||||
|
|
@ -9,7 +10,6 @@ use {
|
||||||
std::{rc::Rc, time::Duration},
|
std::{rc::Rc, time::Duration},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
use crate::ifs::wl_surface::zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1;
|
|
||||||
|
|
||||||
pub struct JayIdle {
|
pub struct JayIdle {
|
||||||
pub id: JayIdleId,
|
pub id: JayIdleId,
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ use {
|
||||||
state::State,
|
state::State,
|
||||||
tree::{
|
tree::{
|
||||||
generic_node_visitor, ContainerSplit, FloatNode, FoundNode, Node, OutputNode,
|
generic_node_visitor, ContainerSplit, FloatNode, FoundNode, Node, OutputNode,
|
||||||
ToplevelNode,
|
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{
|
||||||
asyncevent::AsyncEvent,
|
asyncevent::AsyncEvent,
|
||||||
|
|
@ -42,7 +41,7 @@ use {
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
copyhashmap::CopyHashMap,
|
copyhashmap::CopyHashMap,
|
||||||
errorfmt::ErrorFmt,
|
errorfmt::ErrorFmt,
|
||||||
linkedlist::{LinkedList, LinkedNode},
|
linkedlist::{LinkedNode},
|
||||||
rc_eq::rc_eq,
|
rc_eq::rc_eq,
|
||||||
},
|
},
|
||||||
wire::{
|
wire::{
|
||||||
|
|
@ -111,7 +110,6 @@ pub struct WlSeatGlobal {
|
||||||
pos: Cell<(Fixed, Fixed)>,
|
pos: Cell<(Fixed, Fixed)>,
|
||||||
pointer_stack: RefCell<Vec<Rc<dyn Node>>>,
|
pointer_stack: RefCell<Vec<Rc<dyn Node>>>,
|
||||||
found_tree: RefCell<Vec<FoundNode>>,
|
found_tree: RefCell<Vec<FoundNode>>,
|
||||||
toplevel_focus_history: LinkedList<Rc<dyn ToplevelNode>>,
|
|
||||||
keyboard_node: CloneCell<Rc<dyn Node>>,
|
keyboard_node: CloneCell<Rc<dyn Node>>,
|
||||||
pressed_keys: RefCell<AHashSet<u32>>,
|
pressed_keys: RefCell<AHashSet<u32>>,
|
||||||
bindings: RefCell<AHashMap<ClientId, AHashMap<WlSeatId, Rc<WlSeat>>>>,
|
bindings: RefCell<AHashMap<ClientId, AHashMap<WlSeatId, Rc<WlSeat>>>>,
|
||||||
|
|
@ -154,7 +152,6 @@ impl WlSeatGlobal {
|
||||||
pos: Cell::new((Fixed(0), Fixed(0))),
|
pos: Cell::new((Fixed(0), Fixed(0))),
|
||||||
pointer_stack: RefCell::new(vec![]),
|
pointer_stack: RefCell::new(vec![]),
|
||||||
found_tree: RefCell::new(vec![]),
|
found_tree: RefCell::new(vec![]),
|
||||||
toplevel_focus_history: Default::default(),
|
|
||||||
keyboard_node: CloneCell::new(state.root.clone()),
|
keyboard_node: CloneCell::new(state.root.clone()),
|
||||||
pressed_keys: RefCell::new(Default::default()),
|
pressed_keys: RefCell::new(Default::default()),
|
||||||
bindings: Default::default(),
|
bindings: Default::default(),
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,17 @@ use {
|
||||||
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
|
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
|
||||||
},
|
},
|
||||||
object::ObjectId,
|
object::ObjectId,
|
||||||
tree::{FloatNode, Node, ToplevelNode},
|
tree::{FloatNode, Node, SizedNode, ToplevelNode},
|
||||||
utils::{clonecell::CloneCell, smallmap::SmallMap},
|
utils::{clonecell::CloneCell, smallmap::SmallMap},
|
||||||
wire::WlDataOfferId,
|
wire::WlDataOfferId,
|
||||||
xkbcommon::{ModifierState, XKB_KEY_DOWN, XKB_KEY_UP},
|
xkbcommon::{ModifierState, XKB_KEY_DOWN, XKB_KEY_UP},
|
||||||
},
|
},
|
||||||
jay_config::keyboard::{mods::Modifiers, syms::KeySym, ModifiedKeySym},
|
jay_config::{
|
||||||
|
keyboard::{mods::Modifiers, syms::KeySym, ModifiedKeySym},
|
||||||
|
Direction,
|
||||||
|
},
|
||||||
smallvec::SmallVec,
|
smallvec::SmallVec,
|
||||||
std::{ops::Deref, rc::Rc},
|
std::rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -94,9 +97,7 @@ impl NodeSeatState {
|
||||||
seat.keyboard_node.set(seat.state.root.clone());
|
seat.keyboard_node.set(seat.state.root.clone());
|
||||||
// log::info!("keyboard_node = root");
|
// log::info!("keyboard_node = root");
|
||||||
if focus_last {
|
if focus_last {
|
||||||
if let Some(tl) = seat.toplevel_focus_history.last() {
|
seat.output.get().do_focus(&seat, Direction::Unspecified);
|
||||||
seat.focus_node(tl.focus_surface(seat.id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -269,30 +270,6 @@ impl WlSeatGlobal {
|
||||||
self.pointer_stack.borrow().last().cloned()
|
self.pointer_stack.borrow().last().cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn last_tiled_keyboard_toplevel(&self, new: &dyn Node) -> Option<Rc<dyn ToplevelNode>> {
|
|
||||||
let workspace = match self.output.get().workspace.get() {
|
|
||||||
Some(ws) => ws,
|
|
||||||
_ => return None,
|
|
||||||
};
|
|
||||||
let is_container = new.node_is_container();
|
|
||||||
for tl in self.toplevel_focus_history.rev_iter() {
|
|
||||||
match tl.as_node().node_get_workspace() {
|
|
||||||
Some(ws) if ws.id == workspace.id => {}
|
|
||||||
_ => continue,
|
|
||||||
};
|
|
||||||
let parent_is_float = match tl.parent() {
|
|
||||||
Some(pn) => pn.node_is_float(),
|
|
||||||
_ => false,
|
|
||||||
};
|
|
||||||
if !parent_is_float
|
|
||||||
&& (!is_container || !tl.as_node().node_is_contained_in(new.node_id()))
|
|
||||||
{
|
|
||||||
return Some(tl.deref().clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn move_(&self, node: &Rc<FloatNode>) {
|
pub fn move_(&self, node: &Rc<FloatNode>) {
|
||||||
self.move_.set(true);
|
self.move_.set(true);
|
||||||
self.move_start_pos.set(self.pos.get());
|
self.move_start_pos.set(self.pos.get());
|
||||||
|
|
@ -301,8 +278,6 @@ impl WlSeatGlobal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_toplevel(self: &Rc<Self>, n: Rc<dyn ToplevelNode>) {
|
pub fn focus_toplevel(self: &Rc<Self>, n: Rc<dyn ToplevelNode>) {
|
||||||
let node = self.toplevel_focus_history.add_last(n.clone());
|
|
||||||
n.data().toplevel_history.insert(self.id, node);
|
|
||||||
self.focus_node(n.focus_surface(self.id));
|
self.focus_node(n.focus_surface(self.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,12 @@ use {
|
||||||
utils::{
|
utils::{
|
||||||
buffd::{MsgParser, MsgParserError},
|
buffd::{MsgParser, MsgParserError},
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
|
copyhashmap::CopyHashMap,
|
||||||
linkedlist::LinkedList,
|
linkedlist::LinkedList,
|
||||||
numcell::NumCell,
|
numcell::NumCell,
|
||||||
smallmap::SmallMap,
|
smallmap::SmallMap,
|
||||||
},
|
},
|
||||||
wire::{wl_surface::*, WlOutputId, WlSurfaceId},
|
wire::{wl_surface::*, WlOutputId, WlSurfaceId, ZwpIdleInhibitorV1Id},
|
||||||
xkbcommon::ModifierState,
|
xkbcommon::ModifierState,
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
|
|
@ -49,8 +50,6 @@ use {
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1,
|
zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1,
|
||||||
};
|
};
|
||||||
use crate::utils::copyhashmap::CopyHashMap;
|
|
||||||
use crate::wire::ZwpIdleInhibitorV1Id;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const INVALID_SCALE: u32 = 0;
|
const INVALID_SCALE: u32 = 0;
|
||||||
|
|
@ -691,6 +690,10 @@ impl SizedNode for WlSurface {
|
||||||
self.visible.get()
|
self.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
self.toplevel.get().map(|tl| tl.into_node())
|
||||||
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
self.visible.set(visible);
|
self.visible.set(visible);
|
||||||
for inhibitor in self.idle_inhibitors.lock().values() {
|
for inhibitor in self.idle_inhibitors.lock().values() {
|
||||||
|
|
|
||||||
|
|
@ -292,6 +292,10 @@ impl SizedNode for XdgPopup {
|
||||||
self.xdg.surface.visible.get()
|
self.xdg.surface.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
self.parent.get().and_then(|x| x.workspace.get().map(|w| w as Rc<dyn Node>))
|
||||||
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
log::info!("set visible = {}", visible);
|
log::info!("set visible = {}", visible);
|
||||||
self.xdg.set_visible(visible);
|
self.xdg.set_visible(visible);
|
||||||
|
|
|
||||||
|
|
@ -403,6 +403,10 @@ impl SizedNode for XdgToplevel {
|
||||||
self.xdg.surface.visible.get()
|
self.xdg.surface.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
self.parent_node.get()
|
||||||
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
self.xdg.set_visible(visible);
|
self.xdg.set_visible(visible);
|
||||||
self.xdg.seat_state.set_visible(self, visible);
|
self.xdg.seat_state.set_visible(self, visible);
|
||||||
|
|
@ -481,10 +485,6 @@ impl ToplevelNode for XdgToplevel {
|
||||||
&self.toplevel_data
|
&self.toplevel_data
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent(&self) -> Option<Rc<dyn Node>> {
|
|
||||||
self.parent_node.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_node(&self) -> &dyn Node {
|
fn as_node(&self) -> &dyn Node {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -366,6 +366,10 @@ impl SizedNode for Xwindow {
|
||||||
self.surface.visible.get()
|
self.surface.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
self.parent_node.get()
|
||||||
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
self.surface.node_set_visible(visible);
|
self.surface.node_set_visible(visible);
|
||||||
self.seat_state.set_visible(self, visible);
|
self.seat_state.set_visible(self, visible);
|
||||||
|
|
@ -463,10 +467,6 @@ impl ToplevelNode for Xwindow {
|
||||||
&self.toplevel_data
|
&self.toplevel_data
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parent(&self) -> Option<Rc<dyn Node>> {
|
|
||||||
self.parent_node.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_node(&self) -> &dyn Node {
|
fn as_node(&self) -> &dyn Node {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -381,6 +381,10 @@ impl SizedNode for ZwlrLayerSurfaceV1 {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
Some(self.output.clone())
|
||||||
|
}
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
fn absolute_position(&self) -> Rect {
|
||||||
self.pos.get()
|
self.pos.get()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
69
src/state.rs
69
src/state.rs
|
|
@ -6,7 +6,7 @@ use {
|
||||||
InputDeviceId, InputDeviceIds, MonitorInfo,
|
InputDeviceId, InputDeviceIds, MonitorInfo,
|
||||||
},
|
},
|
||||||
cli::RunArgs,
|
cli::RunArgs,
|
||||||
client::{Client, Clients},
|
client::{Client, Clients, SerialRange, NUM_CACHED_SERIAL_RANGES},
|
||||||
config::ConfigProxy,
|
config::ConfigProxy,
|
||||||
cursor::ServerCursors,
|
cursor::ServerCursors,
|
||||||
dbus::Dbus,
|
dbus::Dbus,
|
||||||
|
|
@ -42,12 +42,12 @@ use {
|
||||||
std::{
|
std::{
|
||||||
cell::{Cell, RefCell},
|
cell::{Cell, RefCell},
|
||||||
num::Wrapping,
|
num::Wrapping,
|
||||||
|
ops::Deref,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::client::{NUM_CACHED_SERIAL_RANGES, SerialRange};
|
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
pub xkb_ctx: XkbContext,
|
pub xkb_ctx: XkbContext,
|
||||||
|
|
@ -209,39 +209,44 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_tiled(self: &Rc<Self>, node: Rc<dyn Node>) {
|
pub fn map_tiled(self: &Rc<Self>, node: Rc<dyn Node>) {
|
||||||
let seat = self.seat_queue.last();
|
let output = self
|
||||||
if let Some(seat) = &seat {
|
.seat_queue
|
||||||
if let Some(prev) = seat.last_tiled_keyboard_toplevel(&*node) {
|
.last()
|
||||||
if let Some(container) = prev.parent() {
|
.map(|s| s.get_output())
|
||||||
if let Some(container) = container.node_into_container() {
|
.or_else(|| self.root.outputs.lock().values().next().cloned())
|
||||||
container.add_child_after(prev.as_node(), node);
|
.or_else(|| self.dummy_output.get())
|
||||||
return;
|
.unwrap();
|
||||||
}
|
let last_active = output.last_active_child();
|
||||||
}
|
let last_active_parent = last_active.node_parent();
|
||||||
|
if let Some(lap) = last_active_parent {
|
||||||
|
if lap.node_is_container() {
|
||||||
|
let container = lap.node_into_container().unwrap();
|
||||||
|
container.add_child_after(last_active.deref(), node);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if lap.node_is_workspace() {
|
||||||
|
let workspace = lap.node_into_workspace().unwrap();
|
||||||
|
let container = ContainerNode::new(
|
||||||
|
self,
|
||||||
|
&workspace,
|
||||||
|
workspace.clone(),
|
||||||
|
last_active.clone(),
|
||||||
|
ContainerSplit::Horizontal,
|
||||||
|
);
|
||||||
|
workspace.set_container(&container);
|
||||||
|
container.add_child_after(last_active.deref(), node);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut output = seat.map(|s| s.get_output());
|
|
||||||
if output.is_none() {
|
|
||||||
let outputs = self.root.outputs.lock();
|
|
||||||
output = outputs.values().next().cloned();
|
|
||||||
}
|
|
||||||
let output = match output {
|
|
||||||
Some(output) => output,
|
|
||||||
_ => self.dummy_output.get().unwrap(),
|
|
||||||
};
|
|
||||||
let workspace = output.ensure_workspace();
|
let workspace = output.ensure_workspace();
|
||||||
if let Some(container) = workspace.container.get() {
|
let container = ContainerNode::new(
|
||||||
container.append_child(node);
|
self,
|
||||||
} else {
|
&workspace,
|
||||||
let container = ContainerNode::new(
|
workspace.clone(),
|
||||||
self,
|
node,
|
||||||
&workspace,
|
ContainerSplit::Horizontal,
|
||||||
workspace.clone(),
|
);
|
||||||
node,
|
workspace.set_container(&container);
|
||||||
ContainerSplit::Horizontal,
|
|
||||||
);
|
|
||||||
workspace.set_container(&container);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_floating(
|
pub fn map_floating(
|
||||||
|
|
|
||||||
13
src/tree.rs
13
src/tree.rs
|
|
@ -75,6 +75,7 @@ pub trait SizedNode: Sized + 'static {
|
||||||
fn visit(self: &Rc<Self>, visitor: &mut dyn NodeVisitor);
|
fn visit(self: &Rc<Self>, visitor: &mut dyn NodeVisitor);
|
||||||
fn visit_children(&self, visitor: &mut dyn NodeVisitor);
|
fn visit_children(&self, visitor: &mut dyn NodeVisitor);
|
||||||
fn visible(&self) -> bool;
|
fn visible(&self) -> bool;
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>>;
|
||||||
|
|
||||||
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
||||||
self.clone()
|
self.clone()
|
||||||
|
|
@ -285,6 +286,10 @@ pub trait SizedNode: Sized + 'static {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_workspace(self: &Rc<Self>) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn is_container(&self) -> bool {
|
fn is_container(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
@ -372,6 +377,7 @@ pub trait Node {
|
||||||
fn node_visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor);
|
fn node_visit(self: Rc<Self>, visitor: &mut dyn NodeVisitor);
|
||||||
fn node_visit_children(&self, visitor: &mut dyn NodeVisitor);
|
fn node_visit_children(&self, visitor: &mut dyn NodeVisitor);
|
||||||
fn node_visible(&self) -> bool;
|
fn node_visible(&self) -> bool;
|
||||||
|
fn node_parent(&self) -> Option<Rc<dyn Node>>;
|
||||||
fn node_last_active_child(self: Rc<Self>) -> Rc<dyn Node>;
|
fn node_last_active_child(self: Rc<Self>) -> Rc<dyn Node>;
|
||||||
fn node_set_visible(&self, visible: bool);
|
fn node_set_visible(&self, visible: bool);
|
||||||
fn node_get_workspace(&self) -> Option<Rc<WorkspaceNode>>;
|
fn node_get_workspace(&self) -> Option<Rc<WorkspaceNode>>;
|
||||||
|
|
@ -428,6 +434,7 @@ pub trait Node {
|
||||||
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32);
|
fn node_render(&self, renderer: &mut Renderer, x: i32, y: i32);
|
||||||
fn node_into_float(self: Rc<Self>) -> Option<Rc<FloatNode>>;
|
fn node_into_float(self: Rc<Self>) -> Option<Rc<FloatNode>>;
|
||||||
fn node_into_container(self: Rc<Self>) -> Option<Rc<ContainerNode>>;
|
fn node_into_container(self: Rc<Self>) -> Option<Rc<ContainerNode>>;
|
||||||
|
fn node_into_workspace(self: Rc<Self>) -> Option<Rc<WorkspaceNode>>;
|
||||||
fn node_is_container(&self) -> bool;
|
fn node_is_container(&self) -> bool;
|
||||||
fn node_is_output(&self) -> bool;
|
fn node_is_output(&self) -> bool;
|
||||||
fn node_into_output(self: Rc<Self>) -> Option<Rc<OutputNode>>;
|
fn node_into_output(self: Rc<Self>) -> Option<Rc<OutputNode>>;
|
||||||
|
|
@ -467,6 +474,9 @@ impl<T: SizedNode> Node for T {
|
||||||
fn node_visible(&self) -> bool {
|
fn node_visible(&self) -> bool {
|
||||||
<Self as SizedNode>::visible(self)
|
<Self as SizedNode>::visible(self)
|
||||||
}
|
}
|
||||||
|
fn node_parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
<Self as SizedNode>::parent(self)
|
||||||
|
}
|
||||||
fn node_last_active_child(self: Rc<Self>) -> Rc<dyn Node> {
|
fn node_last_active_child(self: Rc<Self>) -> Rc<dyn Node> {
|
||||||
<Self as SizedNode>::last_active_child(&self)
|
<Self as SizedNode>::last_active_child(&self)
|
||||||
}
|
}
|
||||||
|
|
@ -613,6 +623,9 @@ impl<T: SizedNode> Node for T {
|
||||||
fn node_into_container(self: Rc<Self>) -> Option<Rc<ContainerNode>> {
|
fn node_into_container(self: Rc<Self>) -> Option<Rc<ContainerNode>> {
|
||||||
<Self as SizedNode>::into_container(&self)
|
<Self as SizedNode>::into_container(&self)
|
||||||
}
|
}
|
||||||
|
fn node_into_workspace(self: Rc<Self>) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
<Self as SizedNode>::into_workspace(&self)
|
||||||
|
}
|
||||||
fn node_is_container(&self) -> bool {
|
fn node_is_container(&self) -> bool {
|
||||||
<Self as SizedNode>::is_container(self)
|
<Self as SizedNode>::is_container(self)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -766,6 +766,10 @@ impl SizedNode for ContainerNode {
|
||||||
self.visible.get()
|
self.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
Some(self.parent.get())
|
||||||
|
}
|
||||||
|
|
||||||
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
||||||
if let Some(last) = self.focus_history.last() {
|
if let Some(last) = self.focus_history.last() {
|
||||||
return last.node.clone().node_last_active_child();
|
return last.node.clone().node_last_active_child();
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,10 @@ impl SizedNode for DisplayNode {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
fn find_tree_at(&self, x: i32, y: i32, tree: &mut Vec<FoundNode>) -> FindTreeResult {
|
||||||
let outputs = self.outputs.lock();
|
let outputs = self.outputs.lock();
|
||||||
for output in outputs.values() {
|
for output in outputs.values() {
|
||||||
|
|
|
||||||
|
|
@ -352,6 +352,10 @@ impl SizedNode for FloatNode {
|
||||||
self.visible.get()
|
self.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
Some(self.workspace.get())
|
||||||
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
self.visible.set(visible);
|
self.visible.set(visible);
|
||||||
if let Some(child) = self.child.get() {
|
if let Some(child) = self.child.get() {
|
||||||
|
|
|
||||||
|
|
@ -303,6 +303,10 @@ impl SizedNode for OutputNode {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
Some(self.state.root.clone())
|
||||||
|
}
|
||||||
|
|
||||||
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
||||||
if let Some(ws) = self.workspace.get() {
|
if let Some(ws) = self.workspace.get() {
|
||||||
return ws.last_active_child();
|
return ws.last_active_child();
|
||||||
|
|
@ -310,6 +314,12 @@ impl SizedNode for OutputNode {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn do_focus(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||||
|
if let Some(ws) = self.workspace.get() {
|
||||||
|
ws.do_focus(seat, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
fn absolute_position(&self) -> Rect {
|
||||||
self.global.pos.get()
|
self.global.pos.get()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
ifs::{wl_seat::SeatId, wl_surface::WlSurface},
|
ifs::{wl_seat::SeatId, wl_surface::WlSurface},
|
||||||
tree::Node,
|
tree::Node,
|
||||||
utils::{linkedlist::LinkedNode, numcell::NumCell, smallmap::SmallMap},
|
utils::{numcell::NumCell, smallmap::SmallMap},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::rc::Rc,
|
||||||
};
|
};
|
||||||
|
|
@ -10,7 +10,6 @@ use {
|
||||||
tree_id!(ToplevelNodeId);
|
tree_id!(ToplevelNodeId);
|
||||||
pub trait ToplevelNode {
|
pub trait ToplevelNode {
|
||||||
fn data(&self) -> &ToplevelData;
|
fn data(&self) -> &ToplevelData;
|
||||||
fn parent(&self) -> Option<Rc<dyn Node>>;
|
|
||||||
fn as_node(&self) -> &dyn Node;
|
fn as_node(&self) -> &dyn Node;
|
||||||
fn into_node(self: Rc<Self>) -> Rc<dyn Node>;
|
fn into_node(self: Rc<Self>) -> Rc<dyn Node>;
|
||||||
fn accepts_keyboard_focus(&self) -> bool;
|
fn accepts_keyboard_focus(&self) -> bool;
|
||||||
|
|
@ -25,13 +24,11 @@ pub trait ToplevelNode {
|
||||||
pub struct ToplevelData {
|
pub struct ToplevelData {
|
||||||
pub active_surfaces: NumCell<u32>,
|
pub active_surfaces: NumCell<u32>,
|
||||||
pub focus_surface: SmallMap<SeatId, Rc<WlSurface>, 1>,
|
pub focus_surface: SmallMap<SeatId, Rc<WlSurface>, 1>,
|
||||||
pub toplevel_history: SmallMap<SeatId, LinkedNode<Rc<dyn ToplevelNode>>, 1>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToplevelData {
|
impl ToplevelData {
|
||||||
pub fn clear(&self) {
|
pub fn clear(&self) {
|
||||||
self.focus_surface.clear();
|
self.focus_surface.clear();
|
||||||
self.toplevel_history.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,4 +51,8 @@ impl<'a> dyn ToplevelNode + 'a {
|
||||||
.get(&seat)
|
.get(&seat)
|
||||||
.unwrap_or_else(|| self.default_surface())
|
.unwrap_or_else(|| self.default_surface())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
self.as_node().node_parent()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use {
|
||||||
linkedlist::{LinkedList, LinkedNode},
|
linkedlist::{LinkedList, LinkedNode},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
jay_config::Direction,
|
||||||
std::{cell::Cell, fmt::Debug, rc::Rc},
|
std::{cell::Cell, fmt::Debug, rc::Rc},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -74,6 +75,10 @@ impl SizedNode for WorkspaceNode {
|
||||||
self.visible.get()
|
self.visible.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parent(&self) -> Option<Rc<dyn Node>> {
|
||||||
|
Some(self.output.get())
|
||||||
|
}
|
||||||
|
|
||||||
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
fn last_active_child(self: &Rc<Self>) -> Rc<dyn Node> {
|
||||||
if let Some(c) = self.container.get() {
|
if let Some(c) = self.container.get() {
|
||||||
return c.last_active_child();
|
return c.last_active_child();
|
||||||
|
|
@ -89,6 +94,12 @@ impl SizedNode for WorkspaceNode {
|
||||||
self.seat_state.set_visible(self, visible);
|
self.seat_state.set_visible(self, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn do_focus(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||||
|
if let Some(container) = self.container.get() {
|
||||||
|
container.do_focus(seat, direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn absolute_position(&self) -> Rect {
|
fn absolute_position(&self) -> Rect {
|
||||||
self.position.get()
|
self.position.get()
|
||||||
}
|
}
|
||||||
|
|
@ -117,6 +128,10 @@ impl SizedNode for WorkspaceNode {
|
||||||
renderer.render_workspace(self, x, y);
|
renderer.render_workspace(self, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_workspace(self: &Rc<Self>) -> Option<Rc<WorkspaceNode>> {
|
||||||
|
Some(self.clone())
|
||||||
|
}
|
||||||
|
|
||||||
fn accepts_child(&self, node: &dyn Node) -> bool {
|
fn accepts_child(&self, node: &dyn Node) -> bool {
|
||||||
node.node_is_container()
|
node.node_is_container()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use std::mem;
|
|
||||||
use {
|
use {
|
||||||
crate::utils::ptr_ext::{MutPtrExt, PtrExt},
|
crate::utils::ptr_ext::{MutPtrExt, PtrExt},
|
||||||
std::cell::UnsafeCell,
|
std::{cell::UnsafeCell, mem},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct Stack<T> {
|
pub struct Stack<T> {
|
||||||
|
|
@ -38,8 +37,6 @@ impl<T> Stack<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take(&self) -> Vec<T> {
|
pub fn take(&self) -> Vec<T> {
|
||||||
unsafe {
|
unsafe { mem::take(self.vec.get().deref_mut()) }
|
||||||
mem::take(self.vec.get().deref_mut())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue