wayland: implement tablet-v2
This commit is contained in:
parent
86e283d255
commit
7ed499eabd
62 changed files with 5174 additions and 318 deletions
|
|
@ -2,10 +2,13 @@ use {
|
|||
crate::{
|
||||
backend::KeyState,
|
||||
cursor::KnownCursor,
|
||||
cursor_user::CursorUser,
|
||||
fixed::Fixed,
|
||||
ifs::wl_seat::{
|
||||
collect_kb_foci, collect_kb_foci2, wl_pointer::PendingScroll, NodeSeatState, SeatId,
|
||||
WlSeatGlobal, BTN_LEFT,
|
||||
collect_kb_foci, collect_kb_foci2,
|
||||
tablet::{TabletTool, TabletToolChanges, TabletToolId},
|
||||
wl_pointer::PendingScroll,
|
||||
NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT,
|
||||
},
|
||||
rect::Rect,
|
||||
renderer::Renderer,
|
||||
|
|
@ -112,7 +115,7 @@ pub struct ContainerNode {
|
|||
focus_history: LinkedList<NodeRef<ContainerChild>>,
|
||||
child_nodes: RefCell<AHashMap<NodeId, LinkedNode<ContainerChild>>>,
|
||||
workspace: CloneCell<Rc<WorkspaceNode>>,
|
||||
seats: RefCell<AHashMap<SeatId, SeatState>>,
|
||||
cursors: RefCell<AHashMap<CursorType, CursorState>>,
|
||||
state: Rc<State>,
|
||||
pub render_data: RefCell<ContainerRenderData>,
|
||||
scroller: Scroller,
|
||||
|
|
@ -141,7 +144,13 @@ pub struct ContainerChild {
|
|||
factor: Cell<f64>,
|
||||
}
|
||||
|
||||
struct SeatState {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
enum CursorType {
|
||||
Seat(SeatId),
|
||||
TabletTool(TabletToolId),
|
||||
}
|
||||
|
||||
struct CursorState {
|
||||
cursor: KnownCursor,
|
||||
target: bool,
|
||||
x: i32,
|
||||
|
|
@ -210,7 +219,7 @@ impl ContainerNode {
|
|||
focus_history: Default::default(),
|
||||
child_nodes: RefCell::new(child_nodes),
|
||||
workspace: CloneCell::new(workspace.clone()),
|
||||
seats: RefCell::new(Default::default()),
|
||||
cursors: RefCell::new(Default::default()),
|
||||
state: state.clone(),
|
||||
render_data: Default::default(),
|
||||
scroller: Default::default(),
|
||||
|
|
@ -328,7 +337,7 @@ impl ContainerNode {
|
|||
}
|
||||
|
||||
fn cancel_seat_ops(&self) {
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
let mut seats = self.cursors.borrow_mut();
|
||||
for seat in seats.values_mut() {
|
||||
seat.op = None;
|
||||
}
|
||||
|
|
@ -514,12 +523,21 @@ impl ContainerNode {
|
|||
);
|
||||
}
|
||||
|
||||
fn pointer_move(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, mut x: i32, mut y: i32) {
|
||||
fn pointer_move(
|
||||
self: &Rc<Self>,
|
||||
id: CursorType,
|
||||
cursor: &CursorUser,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
target: bool,
|
||||
) {
|
||||
let mut x = x.round_down();
|
||||
let mut y = y.round_down();
|
||||
let title_height = self.state.theme.sizes.title_height.get();
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
let seat_state = seats.entry(seat.id()).or_insert_with(|| SeatState {
|
||||
let mut seats = self.cursors.borrow_mut();
|
||||
let seat_state = seats.entry(id).or_insert_with(|| CursorState {
|
||||
cursor: KnownCursor::Default,
|
||||
target: false,
|
||||
target,
|
||||
x,
|
||||
y,
|
||||
op: None,
|
||||
|
|
@ -601,7 +619,7 @@ impl ContainerNode {
|
|||
};
|
||||
if new_cursor != mem::replace(&mut seat_state.cursor, new_cursor) {
|
||||
if seat_state.target {
|
||||
seat.pointer_cursor().set_known(new_cursor);
|
||||
cursor.set_known(new_cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1036,6 +1054,80 @@ impl ContainerNode {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn button(
|
||||
self: Rc<Self>,
|
||||
id: CursorType,
|
||||
seat: &Rc<WlSeatGlobal>,
|
||||
time_usec: u64,
|
||||
pressed: bool,
|
||||
) {
|
||||
let mut seat_datas = self.cursors.borrow_mut();
|
||||
let seat_data = match seat_datas.get_mut(&id) {
|
||||
Some(s) => s,
|
||||
_ => return,
|
||||
};
|
||||
if seat_data.op.is_none() {
|
||||
if !pressed {
|
||||
return;
|
||||
}
|
||||
let (kind, child) = 'res: {
|
||||
let mono = self.mono_child.is_some();
|
||||
for child in self.children.iter() {
|
||||
let rect = child.title_rect.get();
|
||||
if rect.contains(seat_data.x, seat_data.y) {
|
||||
self.activate_child(&child);
|
||||
child
|
||||
.node
|
||||
.clone()
|
||||
.node_do_focus(seat, Direction::Unspecified);
|
||||
break 'res (SeatOpKind::Move, child);
|
||||
} else if !mono {
|
||||
if self.split.get() == ContainerSplit::Horizontal {
|
||||
if seat_data.x < rect.x1() {
|
||||
break 'res (
|
||||
SeatOpKind::Resize {
|
||||
dist_left: seat_data.x
|
||||
- child.prev().unwrap().body.get().x2(),
|
||||
dist_right: child.body.get().x1() - seat_data.x,
|
||||
},
|
||||
child,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if seat_data.y < rect.y1() {
|
||||
break 'res (
|
||||
SeatOpKind::Resize {
|
||||
dist_left: seat_data.y
|
||||
- child.prev().unwrap().body.get().y2(),
|
||||
dist_right: child.body.get().y1() - seat_data.y,
|
||||
},
|
||||
child,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
if seat_data
|
||||
.double_click_state
|
||||
.click(&self.state, time_usec, seat_data.x, seat_data.y)
|
||||
&& kind == SeatOpKind::Move
|
||||
{
|
||||
drop(seat_datas);
|
||||
seat.set_tl_floating(child.node.clone(), true);
|
||||
return;
|
||||
}
|
||||
seat_data.op = Some(SeatOp { child, kind })
|
||||
} else if !pressed {
|
||||
let op = seat_data.op.take().unwrap();
|
||||
drop(seat_datas);
|
||||
if op.kind == SeatOpKind::Move {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct SeatOp {
|
||||
|
|
@ -1194,76 +1286,14 @@ impl Node for ContainerNode {
|
|||
if button != BTN_LEFT {
|
||||
return;
|
||||
}
|
||||
let mut seat_datas = self.seats.borrow_mut();
|
||||
let seat_data = match seat_datas.get_mut(&seat.id()) {
|
||||
Some(s) => s,
|
||||
_ => return,
|
||||
};
|
||||
if seat_data.op.is_none() {
|
||||
if state != KeyState::Pressed {
|
||||
return;
|
||||
}
|
||||
let (kind, child) = 'res: {
|
||||
let mono = self.mono_child.is_some();
|
||||
for child in self.children.iter() {
|
||||
let rect = child.title_rect.get();
|
||||
if rect.contains(seat_data.x, seat_data.y) {
|
||||
self.activate_child(&child);
|
||||
child
|
||||
.node
|
||||
.clone()
|
||||
.node_do_focus(seat, Direction::Unspecified);
|
||||
break 'res (SeatOpKind::Move, child);
|
||||
} else if !mono {
|
||||
if self.split.get() == ContainerSplit::Horizontal {
|
||||
if seat_data.x < rect.x1() {
|
||||
break 'res (
|
||||
SeatOpKind::Resize {
|
||||
dist_left: seat_data.x
|
||||
- child.prev().unwrap().body.get().x2(),
|
||||
dist_right: child.body.get().x1() - seat_data.x,
|
||||
},
|
||||
child,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if seat_data.y < rect.y1() {
|
||||
break 'res (
|
||||
SeatOpKind::Resize {
|
||||
dist_left: seat_data.y
|
||||
- child.prev().unwrap().body.get().y2(),
|
||||
dist_right: child.body.get().y1() - seat_data.y,
|
||||
},
|
||||
child,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
if seat_data
|
||||
.double_click_state
|
||||
.click(&self.state, time_usec, seat_data.x, seat_data.y)
|
||||
&& kind == SeatOpKind::Move
|
||||
{
|
||||
drop(seat_datas);
|
||||
seat.set_tl_floating(child.node.clone(), true);
|
||||
return;
|
||||
}
|
||||
seat_data.op = Some(SeatOp { child, kind })
|
||||
} else if state == KeyState::Released {
|
||||
let op = seat_data.op.take().unwrap();
|
||||
drop(seat_datas);
|
||||
if op.kind == SeatOpKind::Move {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
let id = CursorType::Seat(seat.id());
|
||||
self.button(id, seat, time_usec, state == KeyState::Pressed);
|
||||
}
|
||||
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) {
|
||||
let mut seat_datas = self.seats.borrow_mut();
|
||||
let seat_data = match seat_datas.get_mut(&seat.id()) {
|
||||
let mut seat_datas = self.cursors.borrow_mut();
|
||||
let id = CursorType::Seat(seat.id());
|
||||
let seat_data = match seat_datas.get_mut(&id) {
|
||||
Some(s) => s,
|
||||
_ => return,
|
||||
};
|
||||
|
|
@ -1299,21 +1329,29 @@ impl Node for ContainerNode {
|
|||
|
||||
fn node_on_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
// log::info!("node_on_pointer_enter");
|
||||
self.pointer_move(seat, x.round_down(), y.round_down());
|
||||
self.pointer_move(
|
||||
CursorType::Seat(seat.id()),
|
||||
seat.pointer_cursor(),
|
||||
x,
|
||||
y,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
fn node_on_pointer_unfocus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
// log::info!("unfocus");
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
if let Some(seat_state) = seats.get_mut(&seat.id()) {
|
||||
let mut seats = self.cursors.borrow_mut();
|
||||
let id = CursorType::Seat(seat.id());
|
||||
if let Some(seat_state) = seats.get_mut(&id) {
|
||||
seat_state.target = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn node_on_pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
// log::info!("container focus");
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
if let Some(seat_state) = seats.get_mut(&seat.id()) {
|
||||
let mut seats = self.cursors.borrow_mut();
|
||||
let id = CursorType::Seat(seat.id());
|
||||
if let Some(seat_state) = seats.get_mut(&id) {
|
||||
seat_state.target = true;
|
||||
seat.pointer_cursor().set_known(seat_state.cursor);
|
||||
}
|
||||
|
|
@ -1321,7 +1359,46 @@ impl Node for ContainerNode {
|
|||
|
||||
fn node_on_pointer_motion(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
// log::info!("node_on_pointer_motion");
|
||||
self.pointer_move(seat, x.round_down(), y.round_down());
|
||||
self.pointer_move(
|
||||
CursorType::Seat(seat.id()),
|
||||
seat.pointer_cursor(),
|
||||
x,
|
||||
y,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_leave(&self, tool: &Rc<TabletTool>, _time_usec: u64) {
|
||||
let id = CursorType::TabletTool(tool.id);
|
||||
self.cursors.borrow_mut().remove(&id);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_enter(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
_time_usec: u64,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
) {
|
||||
tool.cursor().set_known(KnownCursor::Default);
|
||||
self.pointer_move(CursorType::TabletTool(tool.id), tool.cursor(), x, y, true);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_apply_changes(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
time_usec: u64,
|
||||
changes: Option<&TabletToolChanges>,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
) {
|
||||
let id = CursorType::TabletTool(tool.id);
|
||||
self.pointer_move(id, tool.cursor(), x, y, false);
|
||||
if let Some(changes) = changes {
|
||||
if let Some(pressed) = changes.down {
|
||||
self.button(id, tool.seat(), time_usec, pressed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn node_into_container(self: Rc<Self>) -> Option<Rc<ContainerNode>> {
|
||||
|
|
@ -1332,13 +1409,13 @@ impl Node for ContainerNode {
|
|||
Some(self)
|
||||
}
|
||||
|
||||
fn node_is_container(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn node_into_toplevel(self: Rc<Self>) -> Option<Rc<dyn ToplevelNode>> {
|
||||
Some(self)
|
||||
}
|
||||
|
||||
fn node_is_container(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl ContainingNode for ContainerNode {
|
||||
|
|
@ -1534,7 +1611,7 @@ impl ToplevelNodeBase for ContainerNode {
|
|||
}
|
||||
|
||||
fn tl_destroy_impl(&self) {
|
||||
mem::take(self.seats.borrow_mut().deref_mut());
|
||||
mem::take(self.cursors.borrow_mut().deref_mut());
|
||||
let mut cn = self.child_nodes.borrow_mut();
|
||||
for (_, n) in cn.drain() {
|
||||
n.node.tl_destroy();
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use {
|
|||
crate::{
|
||||
backend::ConnectorId,
|
||||
cursor::KnownCursor,
|
||||
ifs::wl_seat::{NodeSeatState, WlSeatGlobal},
|
||||
fixed::Fixed,
|
||||
ifs::wl_seat::{tablet::TabletTool, NodeSeatState, WlSeatGlobal},
|
||||
rect::Rect,
|
||||
renderer::Renderer,
|
||||
state::State,
|
||||
|
|
@ -142,4 +143,14 @@ impl Node for DisplayNode {
|
|||
// log::info!("display focus");
|
||||
seat.pointer_cursor().set_known(KnownCursor::Default);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_enter(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
_time_usec: u64,
|
||||
_x: Fixed,
|
||||
_y: Fixed,
|
||||
) {
|
||||
tool.cursor().set_known(KnownCursor::Default)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,12 @@ use {
|
|||
crate::{
|
||||
backend::KeyState,
|
||||
cursor::KnownCursor,
|
||||
cursor_user::CursorUser,
|
||||
fixed::Fixed,
|
||||
ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT},
|
||||
ifs::wl_seat::{
|
||||
tablet::{TabletTool, TabletToolChanges, TabletToolId},
|
||||
NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT,
|
||||
},
|
||||
rect::Rect,
|
||||
renderer::Renderer,
|
||||
scale::Scale,
|
||||
|
|
@ -44,11 +48,17 @@ pub struct FloatNode {
|
|||
pub render_titles_scheduled: Cell<bool>,
|
||||
pub title: RefCell<String>,
|
||||
pub title_textures: CopyHashMap<Scale, TextTexture>,
|
||||
seats: RefCell<AHashMap<SeatId, SeatState>>,
|
||||
cursors: RefCell<AHashMap<CursorType, CursorState>>,
|
||||
pub attention_requested: Cell<bool>,
|
||||
}
|
||||
|
||||
struct SeatState {
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
enum CursorType {
|
||||
Seat(SeatId),
|
||||
TabletTool(TabletToolId),
|
||||
}
|
||||
|
||||
struct CursorState {
|
||||
cursor: KnownCursor,
|
||||
target: bool,
|
||||
x: i32,
|
||||
|
|
@ -113,7 +123,7 @@ impl FloatNode {
|
|||
render_titles_scheduled: Cell::new(false),
|
||||
title: Default::default(),
|
||||
title_textures: Default::default(),
|
||||
seats: Default::default(),
|
||||
cursors: Default::default(),
|
||||
attention_requested: Cell::new(false),
|
||||
});
|
||||
floater.pull_child_properties();
|
||||
|
|
@ -214,14 +224,23 @@ impl FloatNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn pointer_move(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, x: i32, y: i32) {
|
||||
fn pointer_move(
|
||||
self: &Rc<Self>,
|
||||
id: CursorType,
|
||||
cursor: &CursorUser,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
target: bool,
|
||||
) {
|
||||
let x = x.round_down();
|
||||
let y = y.round_down();
|
||||
let theme = &self.state.theme;
|
||||
let bw = theme.sizes.border_width.get();
|
||||
let th = theme.sizes.title_height.get();
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
let seat_state = seats.entry(seat.id()).or_insert_with(|| SeatState {
|
||||
let mut seats = self.cursors.borrow_mut();
|
||||
let seat_state = seats.entry(id).or_insert_with(|| CursorState {
|
||||
cursor: KnownCursor::Default,
|
||||
target: false,
|
||||
target,
|
||||
x,
|
||||
y,
|
||||
op_type: OpType::Move,
|
||||
|
|
@ -289,6 +308,7 @@ impl FloatNode {
|
|||
}
|
||||
}
|
||||
self.position.set(Rect::new(x1, y1, x2, y2).unwrap());
|
||||
self.state.damage();
|
||||
self.schedule_layout();
|
||||
return;
|
||||
}
|
||||
|
|
@ -334,7 +354,7 @@ impl FloatNode {
|
|||
seat_state.op_type = op_type;
|
||||
if new_cursor != mem::replace(&mut seat_state.cursor, new_cursor) {
|
||||
if seat_state.target {
|
||||
seat.pointer_cursor().set_known(new_cursor);
|
||||
cursor.set_known(new_cursor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -398,6 +418,77 @@ impl FloatNode {
|
|||
self.state.tree_changed();
|
||||
}
|
||||
}
|
||||
|
||||
fn button(
|
||||
self: Rc<Self>,
|
||||
id: CursorType,
|
||||
cursor: &CursorUser,
|
||||
seat: &Rc<WlSeatGlobal>,
|
||||
time_usec: u64,
|
||||
pressed: bool,
|
||||
) {
|
||||
let mut cursors = self.cursors.borrow_mut();
|
||||
let cursor_data = match cursors.get_mut(&id) {
|
||||
Some(s) => s,
|
||||
_ => return,
|
||||
};
|
||||
if !cursor_data.op_active {
|
||||
if !pressed {
|
||||
return;
|
||||
}
|
||||
if cursor_data.op_type == OpType::Move {
|
||||
if let Some(tl) = self.child.get() {
|
||||
tl.node_do_focus(seat, Direction::Unspecified);
|
||||
}
|
||||
}
|
||||
if cursor_data.double_click_state.click(
|
||||
&self.state,
|
||||
time_usec,
|
||||
cursor_data.x,
|
||||
cursor_data.y,
|
||||
) && cursor_data.op_type == OpType::Move
|
||||
{
|
||||
if let Some(tl) = self.child.get() {
|
||||
drop(cursors);
|
||||
seat.set_tl_floating(tl, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
cursor_data.op_active = true;
|
||||
let pos = self.position.get();
|
||||
match cursor_data.op_type {
|
||||
OpType::Move => {
|
||||
self.restack();
|
||||
cursor_data.dist_hor = cursor_data.x;
|
||||
cursor_data.dist_ver = cursor_data.y;
|
||||
}
|
||||
OpType::ResizeLeft => cursor_data.dist_hor = cursor_data.x,
|
||||
OpType::ResizeTop => cursor_data.dist_ver = cursor_data.y,
|
||||
OpType::ResizeRight => cursor_data.dist_hor = pos.width() - cursor_data.x,
|
||||
OpType::ResizeBottom => cursor_data.dist_ver = pos.height() - cursor_data.y,
|
||||
OpType::ResizeTopLeft => {
|
||||
cursor_data.dist_hor = cursor_data.x;
|
||||
cursor_data.dist_ver = cursor_data.y;
|
||||
}
|
||||
OpType::ResizeTopRight => {
|
||||
cursor_data.dist_hor = pos.width() - cursor_data.x;
|
||||
cursor_data.dist_ver = cursor_data.y;
|
||||
}
|
||||
OpType::ResizeBottomLeft => {
|
||||
cursor_data.dist_hor = cursor_data.x;
|
||||
cursor_data.dist_ver = pos.height() - cursor_data.y;
|
||||
}
|
||||
OpType::ResizeBottomRight => {
|
||||
cursor_data.dist_hor = pos.width() - cursor_data.x;
|
||||
cursor_data.dist_ver = pos.height() - cursor_data.y;
|
||||
}
|
||||
}
|
||||
} else if !pressed {
|
||||
cursor_data.op_active = false;
|
||||
let ws = cursor.output().ensure_workspace();
|
||||
self.set_workspace(&ws);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for FloatNode {
|
||||
|
|
@ -487,89 +578,89 @@ impl Node for FloatNode {
|
|||
if button != BTN_LEFT {
|
||||
return;
|
||||
}
|
||||
let mut seat_datas = self.seats.borrow_mut();
|
||||
let seat_data = match seat_datas.get_mut(&seat.id()) {
|
||||
Some(s) => s,
|
||||
_ => return,
|
||||
};
|
||||
if !seat_data.op_active {
|
||||
if state != KeyState::Pressed {
|
||||
return;
|
||||
}
|
||||
if seat_data.op_type == OpType::Move {
|
||||
if let Some(tl) = self.child.get() {
|
||||
tl.node_do_focus(seat, Direction::Unspecified);
|
||||
}
|
||||
}
|
||||
if seat_data
|
||||
.double_click_state
|
||||
.click(&self.state, time_usec, seat_data.x, seat_data.y)
|
||||
&& seat_data.op_type == OpType::Move
|
||||
{
|
||||
if let Some(tl) = self.child.get() {
|
||||
drop(seat_datas);
|
||||
seat.set_tl_floating(tl, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
seat_data.op_active = true;
|
||||
let pos = self.position.get();
|
||||
match seat_data.op_type {
|
||||
OpType::Move => {
|
||||
self.restack();
|
||||
seat_data.dist_hor = seat_data.x;
|
||||
seat_data.dist_ver = seat_data.y;
|
||||
}
|
||||
OpType::ResizeLeft => seat_data.dist_hor = seat_data.x,
|
||||
OpType::ResizeTop => seat_data.dist_ver = seat_data.y,
|
||||
OpType::ResizeRight => seat_data.dist_hor = pos.width() - seat_data.x,
|
||||
OpType::ResizeBottom => seat_data.dist_ver = pos.height() - seat_data.y,
|
||||
OpType::ResizeTopLeft => {
|
||||
seat_data.dist_hor = seat_data.x;
|
||||
seat_data.dist_ver = seat_data.y;
|
||||
}
|
||||
OpType::ResizeTopRight => {
|
||||
seat_data.dist_hor = pos.width() - seat_data.x;
|
||||
seat_data.dist_ver = seat_data.y;
|
||||
}
|
||||
OpType::ResizeBottomLeft => {
|
||||
seat_data.dist_hor = seat_data.x;
|
||||
seat_data.dist_ver = pos.height() - seat_data.y;
|
||||
}
|
||||
OpType::ResizeBottomRight => {
|
||||
seat_data.dist_hor = pos.width() - seat_data.x;
|
||||
seat_data.dist_ver = pos.height() - seat_data.y;
|
||||
}
|
||||
}
|
||||
} else if state == KeyState::Released {
|
||||
seat_data.op_active = false;
|
||||
let ws = seat.get_output().ensure_workspace();
|
||||
self.set_workspace(&ws);
|
||||
}
|
||||
self.button(
|
||||
CursorType::Seat(seat.id()),
|
||||
seat.pointer_cursor(),
|
||||
seat,
|
||||
time_usec,
|
||||
state == KeyState::Pressed,
|
||||
);
|
||||
}
|
||||
|
||||
fn node_on_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
self.pointer_move(seat, x.round_down(), y.round_down());
|
||||
self.pointer_move(
|
||||
CursorType::Seat(seat.id()),
|
||||
seat.pointer_cursor(),
|
||||
x,
|
||||
y,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
fn node_on_pointer_unfocus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
if let Some(seat_state) = seats.get_mut(&seat.id()) {
|
||||
let mut cursors = self.cursors.borrow_mut();
|
||||
let id = CursorType::Seat(seat.id());
|
||||
if let Some(seat_state) = cursors.get_mut(&id) {
|
||||
seat_state.target = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn node_on_pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
// log::info!("float focus");
|
||||
let mut seats = self.seats.borrow_mut();
|
||||
if let Some(seat_state) = seats.get_mut(&seat.id()) {
|
||||
let mut cursors = self.cursors.borrow_mut();
|
||||
let id = CursorType::Seat(seat.id());
|
||||
if let Some(seat_state) = cursors.get_mut(&id) {
|
||||
seat_state.target = true;
|
||||
seat.pointer_cursor().set_known(seat_state.cursor);
|
||||
}
|
||||
}
|
||||
|
||||
fn node_on_pointer_motion(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
self.pointer_move(seat, x.round_down(), y.round_down());
|
||||
self.pointer_move(
|
||||
CursorType::Seat(seat.id()),
|
||||
seat.pointer_cursor(),
|
||||
x,
|
||||
y,
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_leave(&self, tool: &Rc<TabletTool>, _time_usec: u64) {
|
||||
let id = CursorType::TabletTool(tool.id);
|
||||
self.cursors.borrow_mut().remove(&id);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_enter(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
_time_usec: u64,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
) {
|
||||
tool.cursor().set_known(KnownCursor::Default);
|
||||
self.pointer_move(CursorType::TabletTool(tool.id), tool.cursor(), x, y, true);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_apply_changes(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
time_usec: u64,
|
||||
changes: Option<&TabletToolChanges>,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
) {
|
||||
self.pointer_move(CursorType::TabletTool(tool.id), tool.cursor(), x, y, false);
|
||||
if let Some(changes) = changes {
|
||||
if let Some(pressed) = changes.down {
|
||||
self.button(
|
||||
CursorType::TabletTool(tool.id),
|
||||
tool.cursor(),
|
||||
tool.seat(),
|
||||
time_usec,
|
||||
pressed,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn node_into_float(self: Rc<Self>) -> Option<Rc<FloatNode>> {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,10 @@ use {
|
|||
wl_buffer::WlBufferStorage,
|
||||
wl_output::WlOutputGlobal,
|
||||
wl_seat::{
|
||||
collect_kb_foci2, wl_pointer::PendingScroll, NodeSeatState, SeatId, WlSeatGlobal,
|
||||
BTN_LEFT,
|
||||
collect_kb_foci2,
|
||||
tablet::{TabletTool, TabletToolChanges, TabletToolId},
|
||||
wl_pointer::PendingScroll,
|
||||
NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT,
|
||||
},
|
||||
wl_surface::{
|
||||
ext_session_lock_surface_v1::ExtSessionLockSurfaceV1,
|
||||
|
|
@ -63,7 +65,7 @@ pub struct OutputNode {
|
|||
pub is_dummy: bool,
|
||||
pub status: CloneCell<Rc<String>>,
|
||||
pub scroll: Scroller,
|
||||
pub pointer_positions: CopyHashMap<SeatId, (i32, i32)>,
|
||||
pub pointer_positions: CopyHashMap<PointerType, (i32, i32)>,
|
||||
pub lock_surface: CloneCell<Option<Rc<ExtSessionLockSurfaceV1>>>,
|
||||
pub hardware_cursor: CloneCell<Option<Rc<dyn HardwareCursor>>>,
|
||||
pub hardware_cursor_needs_render: Cell<bool>,
|
||||
|
|
@ -72,6 +74,12 @@ pub struct OutputNode {
|
|||
pub screencopies: CopyHashMap<(ClientId, ZwlrScreencopyFrameV1Id), Rc<ZwlrScreencopyFrameV1>>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum PointerType {
|
||||
Seat(SeatId),
|
||||
TabletTool(TabletToolId),
|
||||
}
|
||||
|
||||
pub async fn output_render_data(state: Rc<State>) {
|
||||
loop {
|
||||
let container = state.pending_output_render_data.pop().await;
|
||||
|
|
@ -593,8 +601,9 @@ impl OutputNode {
|
|||
self.schedule_update_render_data();
|
||||
}
|
||||
|
||||
fn pointer_move(self: &Rc<Self>, seat: &Rc<WlSeatGlobal>, x: i32, y: i32) {
|
||||
self.pointer_positions.set(seat.id(), (x, y));
|
||||
fn pointer_move(self: &Rc<Self>, id: PointerType, x: Fixed, y: Fixed) {
|
||||
self.pointer_positions
|
||||
.set(id, (x.round_down(), y.round_down()));
|
||||
}
|
||||
|
||||
pub fn has_fullscreen(&self) -> bool {
|
||||
|
|
@ -641,6 +650,29 @@ impl OutputNode {
|
|||
set_layer_visible!(self.layers[2], visible);
|
||||
set_layer_visible!(self.layers[3], visible);
|
||||
}
|
||||
|
||||
fn button(self: Rc<Self>, id: PointerType) {
|
||||
let (x, y) = match self.pointer_positions.get(&id) {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
if y >= self.state.theme.sizes.title_height.get() {
|
||||
return;
|
||||
}
|
||||
let ws = 'ws: {
|
||||
let rd = self.render_data.borrow_mut();
|
||||
for title in &rd.titles {
|
||||
if x >= title.x1 && x < title.x2 {
|
||||
break 'ws title.ws.clone();
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
self.show_workspace(&ws);
|
||||
ws.flush_jay_workspaces();
|
||||
self.schedule_update_render_data();
|
||||
self.state.tree_changed();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OutputTitle {
|
||||
|
|
@ -844,26 +876,7 @@ impl Node for OutputNode {
|
|||
if state != KeyState::Pressed || button != BTN_LEFT {
|
||||
return;
|
||||
}
|
||||
let (x, y) = match self.pointer_positions.get(&seat.id()) {
|
||||
Some(p) => p,
|
||||
_ => return,
|
||||
};
|
||||
if y >= self.state.theme.sizes.title_height.get() {
|
||||
return;
|
||||
}
|
||||
let ws = 'ws: {
|
||||
let rd = self.render_data.borrow_mut();
|
||||
for title in &rd.titles {
|
||||
if x >= title.x1 && x < title.x2 {
|
||||
break 'ws title.ws.clone();
|
||||
}
|
||||
}
|
||||
return;
|
||||
};
|
||||
self.show_workspace(&ws);
|
||||
ws.flush_jay_workspaces();
|
||||
self.schedule_update_render_data();
|
||||
self.state.tree_changed();
|
||||
self.button(PointerType::Seat(seat.id()));
|
||||
}
|
||||
|
||||
fn node_on_axis_event(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, event: &PendingScroll) {
|
||||
|
|
@ -905,7 +918,7 @@ impl Node for OutputNode {
|
|||
}
|
||||
|
||||
fn node_on_pointer_enter(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
self.pointer_move(seat, x.round_down(), y.round_down());
|
||||
self.pointer_move(PointerType::Seat(seat.id()), x, y);
|
||||
}
|
||||
|
||||
fn node_on_pointer_focus(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
|
|
@ -914,7 +927,40 @@ impl Node for OutputNode {
|
|||
}
|
||||
|
||||
fn node_on_pointer_motion(self: Rc<Self>, seat: &Rc<WlSeatGlobal>, x: Fixed, y: Fixed) {
|
||||
self.pointer_move(seat, x.round_down(), y.round_down());
|
||||
self.pointer_move(PointerType::Seat(seat.id()), x, y);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_leave(&self, tool: &Rc<TabletTool>, _time_usec: u64) {
|
||||
self.pointer_positions
|
||||
.remove(&PointerType::TabletTool(tool.id));
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_enter(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
_time_usec: u64,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
) {
|
||||
tool.cursor().set_known(KnownCursor::Default);
|
||||
self.pointer_move(PointerType::TabletTool(tool.id), x, y);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_apply_changes(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
_time_usec: u64,
|
||||
changes: Option<&TabletToolChanges>,
|
||||
x: Fixed,
|
||||
y: Fixed,
|
||||
) {
|
||||
let id = PointerType::TabletTool(tool.id);
|
||||
self.pointer_move(id, x, y);
|
||||
if let Some(changes) = changes {
|
||||
if changes.down == Some(true) {
|
||||
self.button(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@ use {
|
|||
crate::{
|
||||
client::ClientId,
|
||||
cursor::KnownCursor,
|
||||
fixed::Fixed,
|
||||
ifs::{
|
||||
jay_workspace::JayWorkspace,
|
||||
wl_output::OutputId,
|
||||
wl_seat::{NodeSeatState, WlSeatGlobal},
|
||||
wl_seat::{tablet::TabletTool, NodeSeatState, WlSeatGlobal},
|
||||
wl_surface::WlSurface,
|
||||
},
|
||||
rect::Rect,
|
||||
|
|
@ -277,6 +278,16 @@ impl Node for WorkspaceNode {
|
|||
seat.pointer_cursor().set_known(KnownCursor::Default);
|
||||
}
|
||||
|
||||
fn node_on_tablet_tool_enter(
|
||||
self: Rc<Self>,
|
||||
tool: &Rc<TabletTool>,
|
||||
_time_usec: u64,
|
||||
_x: Fixed,
|
||||
_y: Fixed,
|
||||
) {
|
||||
tool.cursor().set_known(KnownCursor::Default)
|
||||
}
|
||||
|
||||
fn node_into_workspace(self: Rc<Self>) -> Option<Rc<WorkspaceNode>> {
|
||||
Some(self.clone())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue