autocommit 2022-02-20 15:31:54 CET
This commit is contained in:
parent
0f2fbcc5e7
commit
26fab1e3e2
10 changed files with 198 additions and 19 deletions
|
|
@ -120,6 +120,12 @@ impl ConfigProxyHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_move(&self, seat: Seat, direction: Direction) -> Result<(), MoveError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
seat.move_focused(direction);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle_get_repeat_rate(&self, seat: Seat) -> Result<(), SeatGetRepeatRateError> {
|
||||
let seat = self.get_seat(seat)?;
|
||||
let (rate, delay) = seat.get_rate();
|
||||
|
|
@ -426,7 +432,7 @@ impl ConfigProxyHandler {
|
|||
self.handle_remove_shortcut(seat, mods, sym)?
|
||||
}
|
||||
ClientMessage::Focus { seat, direction } => self.handle_focus(seat, direction)?,
|
||||
ClientMessage::Move { seat, direction } => {}
|
||||
ClientMessage::Move { seat, direction } => self.handle_move(seat, direction)?,
|
||||
ClientMessage::GetInputDevices { seat } => self.handle_get_input_devices(seat),
|
||||
ClientMessage::GetSeats => self.handle_get_seats(),
|
||||
ClientMessage::RemoveSeat { .. } => {}
|
||||
|
|
@ -467,6 +473,8 @@ enum CphError {
|
|||
SeatSetRepeatRateError(#[from] SeatSetRepeatRateError),
|
||||
#[error("Could not process a `focus` request")]
|
||||
FocusError(#[from] FocusError),
|
||||
#[error("Could not process a `move` request")]
|
||||
MoveError(#[from] MoveError),
|
||||
#[error("Could not process a `set_split` request")]
|
||||
SetSplitError(#[from] SetSplitError),
|
||||
#[error("Could not process a `get_split` request")]
|
||||
|
|
@ -554,6 +562,13 @@ enum FocusError {
|
|||
}
|
||||
efrom!(FocusError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum MoveError {
|
||||
#[error(transparent)]
|
||||
CphError(#[from] Box<CphError>),
|
||||
}
|
||||
efrom!(MoveError, CphError);
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum SetSplitError {
|
||||
#[error(transparent)]
|
||||
|
|
|
|||
|
|
@ -227,6 +227,11 @@ impl WlSeatGlobal {
|
|||
kb_node.move_focus(self, direction);
|
||||
}
|
||||
|
||||
pub fn move_focused(self: &Rc<Self>, direction: Direction) {
|
||||
let kb_node = self.keyboard_node.get();
|
||||
kb_node.move_self(direction);
|
||||
}
|
||||
|
||||
fn set_selection_<T: ipc::Vtable>(
|
||||
self: &Rc<Self>,
|
||||
field: &CloneCell<Option<Rc<T::Source>>>,
|
||||
|
|
|
|||
|
|
@ -637,6 +637,14 @@ impl Node for WlSurface {
|
|||
xdg.move_focus(seat, direction);
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
let xdg = match self.xdg.get() {
|
||||
Some(x) => x,
|
||||
_ => return,
|
||||
};
|
||||
xdg.move_self(direction);
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
self.buffer_abs_pos.get()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,10 @@ pub trait XdgSurfaceExt: Debug {
|
|||
let _ = direction;
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
let _ = direction;
|
||||
}
|
||||
|
||||
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -171,11 +175,15 @@ impl XdgSurface {
|
|||
}
|
||||
|
||||
pub fn move_focus(&self, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
let ext = match self.ext.get() {
|
||||
None => return,
|
||||
Some(e) => e,
|
||||
};
|
||||
ext.move_focus(seat, direction);
|
||||
if let Some(ext)= self.ext.get() {
|
||||
ext.move_focus(seat, direction);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_self(&self, direction: Direction) {
|
||||
if let Some(ext)= self.ext.get() {
|
||||
ext.move_self(direction);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn role(&self) -> XdgSurfaceRole {
|
||||
|
|
|
|||
|
|
@ -510,6 +510,11 @@ impl Node for XdgToplevel {
|
|||
self.xdg.set_workspace(ws);
|
||||
}
|
||||
|
||||
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
|
||||
self.parent_node.set(Some(parent));
|
||||
self.notify_parent();
|
||||
}
|
||||
|
||||
fn client(&self) -> Option<Rc<Client>> {
|
||||
Some(self.xdg.surface.client.clone())
|
||||
}
|
||||
|
|
@ -546,15 +551,18 @@ impl XdgSurfaceExt for XdgToplevel {
|
|||
));
|
||||
self.parent_node.set(Some(cn.clone()));
|
||||
pn.replace_child(&*self, cn);
|
||||
self.notify_parent();
|
||||
}
|
||||
|
||||
fn move_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
let pn = match self.parent_node.get() {
|
||||
Some(pn) => pn,
|
||||
_ => return,
|
||||
};
|
||||
pn.move_focus_from_child(seat, &*self, direction);
|
||||
if let Some(pn) = self.parent_node.get() {
|
||||
pn.move_focus_from_child(seat, &*self, direction);
|
||||
}
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
if let Some(pn) = self.parent_node.get() {
|
||||
pn.move_child(self, direction);
|
||||
}
|
||||
}
|
||||
|
||||
fn initial_configure(self: Rc<Self>) -> Result<(), XdgSurfaceError> {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ macro_rules! object_base {
|
|||
) -> Result<(), $ename> {
|
||||
match request {
|
||||
$(
|
||||
$code => slf.$f(parser)?,
|
||||
$code => $oname::$f(&slf, parser)?,
|
||||
)*
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::cursor::KnownCursor;
|
||||
use crate::fixed::Fixed;
|
||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT};
|
||||
use crate::ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT, Dnd};
|
||||
use crate::rect::Rect;
|
||||
use crate::render::{Renderer, Texture};
|
||||
use crate::theme::Color;
|
||||
|
|
@ -12,6 +12,7 @@ use crate::{text, ErrorFmt, NumCell, State};
|
|||
use ahash::AHashMap;
|
||||
use i4config::{Axis, Direction};
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::mem;
|
||||
use std::ops::{Deref, DerefMut, Sub};
|
||||
|
|
@ -85,6 +86,7 @@ impl Debug for ContainerNode {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ContainerChild {
|
||||
pub node: Rc<dyn Node>,
|
||||
pub active: Cell<bool>,
|
||||
|
|
@ -185,13 +187,23 @@ impl ContainerNode {
|
|||
}
|
||||
|
||||
pub fn add_child_after(self: &Rc<Self>, prev: &dyn Node, new: Rc<dyn Node>) {
|
||||
self.add_child_x(prev, new, |prev, new| self.add_child_after_(prev, new));
|
||||
}
|
||||
|
||||
pub fn add_child_before(self: &Rc<Self>, prev: &dyn Node, new: Rc<dyn Node>) {
|
||||
self.add_child_x(prev, new, |prev, new| self.add_child_before_(prev, new));
|
||||
}
|
||||
|
||||
fn add_child_x<F>(self: &Rc<Self>, prev: &dyn Node, new: Rc<dyn Node>, f: F)
|
||||
where F: FnOnce(&NodeRef<ContainerChild>, Rc<dyn Node>),
|
||||
{
|
||||
let node = self
|
||||
.child_nodes
|
||||
.borrow()
|
||||
.get(&prev.id())
|
||||
.map(|n| n.to_ref());
|
||||
if let Some(node) = node {
|
||||
self.add_child_after_(&node, new);
|
||||
f(&node, new);
|
||||
return;
|
||||
}
|
||||
log::error!(
|
||||
|
|
@ -200,6 +212,16 @@ impl ContainerNode {
|
|||
}
|
||||
|
||||
fn add_child_after_(self: &Rc<Self>, prev: &NodeRef<ContainerChild>, new: Rc<dyn Node>) {
|
||||
self.add_child(|cc| prev.append(cc), new);
|
||||
}
|
||||
|
||||
fn add_child_before_(self: &Rc<Self>, prev: &NodeRef<ContainerChild>, new: Rc<dyn Node>) {
|
||||
self.add_child(|cc| prev.prepend(cc), new);
|
||||
}
|
||||
|
||||
fn add_child<F>(self: &Rc<Self>, f: F, new: Rc<dyn Node>)
|
||||
where F: FnOnce(ContainerChild) -> LinkedNode<ContainerChild>,
|
||||
{
|
||||
{
|
||||
let mut links = self.child_nodes.borrow_mut();
|
||||
if links.contains_key(&new.id()) {
|
||||
|
|
@ -208,7 +230,7 @@ impl ContainerNode {
|
|||
}
|
||||
links.insert(
|
||||
new.id(),
|
||||
prev.append(ContainerChild {
|
||||
f(ContainerChild {
|
||||
node: new.clone(),
|
||||
active: Cell::new(false),
|
||||
body: Default::default(),
|
||||
|
|
@ -221,6 +243,7 @@ impl ContainerNode {
|
|||
);
|
||||
}
|
||||
new.clone().set_workspace(&self.workspace.get());
|
||||
new.clone().set_parent(self.clone());
|
||||
let num_children = self.num_children.fetch_add(1) + 1;
|
||||
self.update_content_size();
|
||||
let new_child_factor = 1.0 / num_children as f64;
|
||||
|
|
@ -456,6 +479,7 @@ impl ContainerNode {
|
|||
title.push_str("]");
|
||||
self.parent.get().child_title_changed(&**self, &title);
|
||||
self.schedule_render_titles();
|
||||
log::info!("num children: {}", self.num_children.get());
|
||||
}
|
||||
|
||||
fn schedule_render_titles(self: &Rc<Self>) {
|
||||
|
|
@ -593,6 +617,10 @@ impl Node for ContainerNode {
|
|||
self.parent.get().move_focus_from_child(seat, &*self, direction);
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
self.parent.get().move_child(self, direction);
|
||||
}
|
||||
|
||||
fn do_focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, direction: Direction) {
|
||||
let node = match direction {
|
||||
Direction::Left => self.children.last(),
|
||||
|
|
@ -646,6 +674,62 @@ impl Node for ContainerNode {
|
|||
};
|
||||
sibling.node.clone().do_focus(seat, direction);
|
||||
}
|
||||
//
|
||||
fn move_child(
|
||||
self: Rc<Self>,
|
||||
child: Rc<dyn Node>,
|
||||
direction: Direction,
|
||||
) {
|
||||
// CASE 1: This is the only child of the container. Replace the container by the child.
|
||||
if self.num_children.get() == 1 {
|
||||
if let Some(parent) = self.parent.get().into_container() {
|
||||
parent.replace_child(&*self, child.clone());
|
||||
}
|
||||
return;
|
||||
}
|
||||
let (split, prev) = direction_to_split(direction);
|
||||
// CASE 2: We're moving the child within the container.
|
||||
if split == self.split.get() {
|
||||
let mut cn = self.child_nodes.borrow_mut();
|
||||
let mut child = match cn.entry(child.id()) {
|
||||
Entry::Occupied(o) => o,
|
||||
Entry::Vacant(_) => return,
|
||||
};
|
||||
let neighbor = match prev {
|
||||
true => child.get().prev(),
|
||||
false => child.get().next(),
|
||||
};
|
||||
if let Some(neighbor) = neighbor {
|
||||
let cc = child.get().deref().deref().clone();
|
||||
let link = match prev {
|
||||
true => neighbor.prepend(cc),
|
||||
false => neighbor.append(cc),
|
||||
};
|
||||
child.insert(link);
|
||||
self.schedule_layout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// CASE 3: We're moving the child out of the container.
|
||||
let mut neighbor = self.clone();
|
||||
let mut parent_opt = self.parent.get().into_container();
|
||||
while let Some(parent) = &parent_opt {
|
||||
if parent.split.get() == split {
|
||||
break;
|
||||
}
|
||||
neighbor = parent.clone();
|
||||
parent_opt = parent.parent.get().into_container();
|
||||
}
|
||||
let parent = match parent_opt {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
self.clone().remove_child(&*child);
|
||||
match prev {
|
||||
true => parent.add_child_before(&*neighbor, child.clone()),
|
||||
false => parent.add_child_after(&*neighbor, child.clone()),
|
||||
}
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
Rect::new_sized(
|
||||
|
|
@ -762,7 +846,7 @@ impl Node for ContainerNode {
|
|||
FindTreeResult::AcceptsInput
|
||||
}
|
||||
|
||||
fn replace_child(&self, old: &dyn Node, new: Rc<dyn Node>) {
|
||||
fn replace_child(self: Rc<Self>, old: &dyn Node, new: Rc<dyn Node>) {
|
||||
let node = match self.child_nodes.borrow_mut().remove(&old.id()) {
|
||||
Some(c) => c,
|
||||
None => return,
|
||||
|
|
@ -777,9 +861,12 @@ impl Node for ContainerNode {
|
|||
title: Default::default(),
|
||||
title_texture: Default::default(),
|
||||
});
|
||||
let body = link.body.get();
|
||||
drop(node);
|
||||
self.child_nodes.borrow_mut().insert(new.id(), link);
|
||||
new.clone().set_parent(self.clone());
|
||||
new.clone().set_workspace(&self.workspace.get());
|
||||
let body = node.body.get().move_(self.abs_x1.get(), self.abs_y1.get());
|
||||
let body = body.move_(self.abs_x1.get(), self.abs_y1.get());
|
||||
new.clone().change_extents(&body);
|
||||
}
|
||||
|
||||
|
|
@ -890,4 +977,19 @@ impl Node for ContainerNode {
|
|||
}
|
||||
self.workspace.set(ws.clone());
|
||||
}
|
||||
|
||||
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
|
||||
self.parent.set(parent.clone());
|
||||
parent.child_size_changed(&*self, self.width.get(), self.height.get());
|
||||
parent.clone().child_title_changed(&*self, self.title.borrow_mut().deref());
|
||||
}
|
||||
}
|
||||
|
||||
fn direction_to_split(dir: Direction) -> (ContainerSplit, bool) {
|
||||
match dir {
|
||||
Direction::Left => (ContainerSplit::Horizontal, true),
|
||||
Direction::Down => (ContainerSplit::Vertical, false),
|
||||
Direction::Up => (ContainerSplit::Vertical, true),
|
||||
Direction::Right => (ContainerSplit::Horizontal, false),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,6 +110,10 @@ pub trait Node {
|
|||
let _ = direction;
|
||||
}
|
||||
|
||||
fn move_self(self: Rc<Self>, direction: Direction) {
|
||||
let _ = direction;
|
||||
}
|
||||
|
||||
fn move_focus_from_child(
|
||||
&self,
|
||||
seat: &Rc<WlSeatGlobal>,
|
||||
|
|
@ -121,6 +125,15 @@ pub trait Node {
|
|||
let _ = child;
|
||||
}
|
||||
|
||||
fn move_child(
|
||||
self: Rc<Self>,
|
||||
child: Rc<dyn Node>,
|
||||
direction: Direction,
|
||||
) {
|
||||
let _ = direction;
|
||||
let _ = child;
|
||||
}
|
||||
|
||||
fn absolute_position(&self) -> Rect {
|
||||
Rect::new_empty(0, 0)
|
||||
}
|
||||
|
|
@ -175,7 +188,7 @@ pub trait Node {
|
|||
FindTreeResult::Other
|
||||
}
|
||||
|
||||
fn replace_child(&self, old: &dyn Node, new: Rc<dyn Node>) {
|
||||
fn replace_child(self: Rc<Self>, old: &dyn Node, new: Rc<dyn Node>) {
|
||||
let _ = old;
|
||||
let _ = new;
|
||||
}
|
||||
|
|
@ -234,6 +247,10 @@ pub trait Node {
|
|||
false
|
||||
}
|
||||
|
||||
fn is_workspace(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||
let _ = rect;
|
||||
}
|
||||
|
|
@ -242,6 +259,10 @@ pub trait Node {
|
|||
let _ = ws;
|
||||
}
|
||||
|
||||
fn set_parent(self: Rc<Self>, parent: Rc<dyn Node>) {
|
||||
let _ = parent;
|
||||
}
|
||||
|
||||
fn client(&self) -> Option<Rc<Client>> {
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ impl Node for WorkspaceNode {
|
|||
renderer.render_workspace(self, x, y);
|
||||
}
|
||||
|
||||
fn is_workspace(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn change_extents(self: Rc<Self>, rect: &Rect) {
|
||||
if let Some(c) = self.container.get() {
|
||||
c.change_extents(rect);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ pub struct CloneCell<T: UnsafeCellCloneSafe> {
|
|||
data: UnsafeCell<T>,
|
||||
}
|
||||
|
||||
impl<T: UnsafeCellCloneSafe> Clone for CloneCell<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
data: UnsafeCell::new(self.get()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: UnsafeCellCloneSafe + Debug> Debug for CloneCell<T> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
unsafe { self.data.get().deref().fmt(f) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue