1
0
Fork 0
forked from wry/wry

autocommit 2022-02-20 15:31:54 CET

This commit is contained in:
Julian Orth 2022-02-20 15:31:54 +01:00
parent 0f2fbcc5e7
commit 26fab1e3e2
10 changed files with 198 additions and 19 deletions

View file

@ -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)]

View file

@ -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>>>,

View file

@ -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()
}

View file

@ -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 {

View file

@ -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> {

View file

@ -31,7 +31,7 @@ macro_rules! object_base {
) -> Result<(), $ename> {
match request {
$(
$code => slf.$f(parser)?,
$code => $oname::$f(&slf, parser)?,
)*
_ => unreachable!(),
}

View file

@ -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),
}
}

View file

@ -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
}

View file

@ -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);

View file

@ -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) }