autocommit 2022-04-10 01:35:15 CEST
This commit is contained in:
parent
21e2216ce5
commit
befd5e99b2
22 changed files with 280 additions and 114 deletions
|
|
@ -10,10 +10,10 @@ use jay_config::{
|
||||||
keyboard::{
|
keyboard::{
|
||||||
mods::{Modifiers, ALT, CTRL, SHIFT},
|
mods::{Modifiers, ALT, CTRL, SHIFT},
|
||||||
syms::{
|
syms::{
|
||||||
SYM_Super_L, SYM_b, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p, SYM_q,
|
SYM_Super_L, SYM_b, SYM_c, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p,
|
||||||
SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F13, SYM_F14, SYM_F15,
|
SYM_q, SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F13, SYM_F14,
|
||||||
SYM_F16, SYM_F17, SYM_F18, SYM_F19, SYM_F2, SYM_F20, SYM_F21, SYM_F22, SYM_F23,
|
SYM_F15, SYM_F16, SYM_F17, SYM_F18, SYM_F19, SYM_F2, SYM_F20, SYM_F21, SYM_F22,
|
||||||
SYM_F24, SYM_F25, SYM_F3, SYM_F4, SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9,
|
SYM_F23, SYM_F24, SYM_F25, SYM_F3, SYM_F4, SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
quit, switch_to_vt,
|
quit, switch_to_vt,
|
||||||
|
|
@ -21,7 +21,6 @@ use jay_config::{
|
||||||
Command,
|
Command,
|
||||||
Direction::{Down, Left, Right, Up},
|
Direction::{Down, Left, Right, Up},
|
||||||
};
|
};
|
||||||
use jay_config::keyboard::syms::SYM_c;
|
|
||||||
|
|
||||||
const MOD: Modifiers = ALT;
|
const MOD: Modifiers = ALT;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
use {
|
use {
|
||||||
crate::{fixed::Fixed, video::drm::ConnectorType},
|
crate::{
|
||||||
|
fixed::Fixed,
|
||||||
|
ifs::wl_seat::wl_pointer::{CONTINUOUS, FINGER, HORIZONTAL_SCROLL, VERTICAL_SCROLL, WHEEL},
|
||||||
|
video::drm::ConnectorType,
|
||||||
|
},
|
||||||
std::{
|
std::{
|
||||||
fmt::{Debug, Display, Formatter},
|
fmt::{Debug, Display, Formatter},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
|
@ -101,8 +105,15 @@ pub enum KeyState {
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
pub enum ScrollAxis {
|
pub enum ScrollAxis {
|
||||||
Horizontal,
|
Horizontal = HORIZONTAL_SCROLL as _,
|
||||||
Vertical,
|
Vertical = VERTICAL_SCROLL as _,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
||||||
|
pub enum AxisSource {
|
||||||
|
Wheel = WHEEL as _,
|
||||||
|
Finger = FINGER as _,
|
||||||
|
Continuous = CONTINUOUS as _,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -112,5 +123,10 @@ pub enum InputEvent {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
Motion(Fixed, Fixed),
|
Motion(Fixed, Fixed),
|
||||||
Button(u32, KeyState),
|
Button(u32, KeyState),
|
||||||
Scroll(i32, ScrollAxis),
|
|
||||||
|
Axis(Fixed, ScrollAxis),
|
||||||
|
AxisSource(AxisSource),
|
||||||
|
AxisStop(ScrollAxis),
|
||||||
|
AxisDiscrete(i32, ScrollAxis),
|
||||||
|
Frame,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,8 +207,6 @@ struct MetalInputDevice {
|
||||||
removed: Cell<bool>,
|
removed: Cell<bool>,
|
||||||
events: SyncQueue<InputEvent>,
|
events: SyncQueue<InputEvent>,
|
||||||
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
cb: CloneCell<Option<Rc<dyn Fn()>>>,
|
||||||
hscroll: Cell<f64>,
|
|
||||||
vscroll: Cell<f64>,
|
|
||||||
name: CloneCell<Rc<String>>,
|
name: CloneCell<Rc<String>>,
|
||||||
|
|
||||||
// state
|
// state
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::FdStatus,
|
async_engine::FdStatus,
|
||||||
backend::{InputEvent, KeyState, ScrollAxis},
|
backend::{AxisSource, InputEvent, KeyState, ScrollAxis},
|
||||||
backends::metal::MetalBackend,
|
backends::metal::MetalBackend,
|
||||||
libinput::{
|
libinput::{
|
||||||
consts::{
|
consts::{
|
||||||
|
|
@ -81,7 +81,15 @@ impl MetalBackend {
|
||||||
c::LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_key(event),
|
c::LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_key(event),
|
||||||
c::LIBINPUT_EVENT_POINTER_MOTION => self.handle_pointer_motion(event),
|
c::LIBINPUT_EVENT_POINTER_MOTION => self.handle_pointer_motion(event),
|
||||||
c::LIBINPUT_EVENT_POINTER_BUTTON => self.handle_pointer_button(event),
|
c::LIBINPUT_EVENT_POINTER_BUTTON => self.handle_pointer_button(event),
|
||||||
c::LIBINPUT_EVENT_POINTER_SCROLL_WHEEL => self.handle_pointer_scroll_wheel(event),
|
c::LIBINPUT_EVENT_POINTER_SCROLL_WHEEL => {
|
||||||
|
self.handle_pointer_axis(event, AxisSource::Wheel)
|
||||||
|
}
|
||||||
|
c::LIBINPUT_EVENT_POINTER_SCROLL_FINGER => {
|
||||||
|
self.handle_pointer_axis(event, AxisSource::Finger)
|
||||||
|
}
|
||||||
|
c::LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS => {
|
||||||
|
self.handle_pointer_axis(event, AxisSource::Continuous)
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -112,33 +120,38 @@ impl MetalBackend {
|
||||||
dev.event(InputEvent::Key(event.key(), state));
|
dev.event(InputEvent::Key(event.key(), state));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_pointer_scroll_wheel(self: &Rc<Self>, event: LibInputEvent) {
|
fn handle_pointer_axis(self: &Rc<Self>, event: LibInputEvent, source: AxisSource) {
|
||||||
const PX_PER_SCROLL: f64 = 15.0;
|
const PX_PER_SCROLL: f64 = 15.0;
|
||||||
const ONE_TWENTRY: f64 = 120.0;
|
const ONE_TWENTRY: f64 = 120.0;
|
||||||
let (event, dev) = unpack!(self, event, pointer_event);
|
let (event, dev) = unpack!(self, event, pointer_event);
|
||||||
let axes = [
|
let axes = [
|
||||||
(
|
(
|
||||||
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
|
||||||
&dev.hscroll,
|
|
||||||
ScrollAxis::Horizontal,
|
ScrollAxis::Horizontal,
|
||||||
),
|
),
|
||||||
(
|
(LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical),
|
||||||
LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL,
|
|
||||||
&dev.vscroll,
|
|
||||||
ScrollAxis::Vertical,
|
|
||||||
),
|
|
||||||
];
|
];
|
||||||
for (axis, val, sa) in axes {
|
dev.event(InputEvent::AxisSource(source));
|
||||||
|
for (axis, sa) in axes {
|
||||||
if !event.has_axis(axis) {
|
if !event.has_axis(axis) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let scroll = event.scroll_value_v120(axis) / ONE_TWENTRY + val.get();
|
let mut scroll = match source {
|
||||||
let scroll_used = (PX_PER_SCROLL * scroll).round();
|
AxisSource::Wheel => event.scroll_value_v120(axis),
|
||||||
val.set(scroll - scroll_used / PX_PER_SCROLL);
|
_ => event.scroll_value(axis),
|
||||||
if scroll_used != 0.0 {
|
};
|
||||||
dev.event(InputEvent::Scroll(scroll_used as i32, sa));
|
if scroll == 0.0 {
|
||||||
|
dev.event(InputEvent::AxisStop(sa));
|
||||||
|
} else {
|
||||||
|
if source == AxisSource::Wheel {
|
||||||
|
let scroll_discrete = scroll / ONE_TWENTRY;
|
||||||
|
dev.event(InputEvent::AxisDiscrete(scroll_discrete as _, sa));
|
||||||
|
scroll = PX_PER_SCROLL * scroll_discrete;
|
||||||
|
}
|
||||||
|
dev.event(InputEvent::Axis(scroll.into(), sa));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dev.event(InputEvent::Frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_pointer_button(self: &Rc<Self>, event: LibInputEvent) {
|
fn handle_pointer_button(self: &Rc<Self>, event: LibInputEvent) {
|
||||||
|
|
|
||||||
|
|
@ -286,8 +286,6 @@ impl MetalBackend {
|
||||||
removed: Cell::new(false),
|
removed: Cell::new(false),
|
||||||
events: Default::default(),
|
events: Default::default(),
|
||||||
cb: Default::default(),
|
cb: Default::default(),
|
||||||
hscroll: Cell::new(0.0),
|
|
||||||
vscroll: Cell::new(0.0),
|
|
||||||
name: Default::default(),
|
name: Default::default(),
|
||||||
pressed_keys: Default::default(),
|
pressed_keys: Default::default(),
|
||||||
pressed_buttons: Default::default(),
|
pressed_buttons: Default::default(),
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ use {
|
||||||
crate::{
|
crate::{
|
||||||
async_engine::{Phase, SpawnedFuture},
|
async_engine::{Phase, SpawnedFuture},
|
||||||
backend::{
|
backend::{
|
||||||
Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId,
|
AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId,
|
||||||
InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent,
|
ConnectorKernelId, InputDevice, InputDeviceAccelProfile, InputDeviceCapability,
|
||||||
KeyState, Mode, MonitorInfo, ScrollAxis,
|
InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, ScrollAxis,
|
||||||
},
|
},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
format::XRGB8888,
|
format::XRGB8888,
|
||||||
|
|
@ -721,13 +721,16 @@ impl XBackendData {
|
||||||
if matches!(button, 4..=7) {
|
if matches!(button, 4..=7) {
|
||||||
if state == KeyState::Pressed {
|
if state == KeyState::Pressed {
|
||||||
let (axis, val) = match button {
|
let (axis, val) = match button {
|
||||||
4 => (ScrollAxis::Vertical, -15),
|
4 => (ScrollAxis::Vertical, -1),
|
||||||
5 => (ScrollAxis::Vertical, 15),
|
5 => (ScrollAxis::Vertical, 1),
|
||||||
6 => (ScrollAxis::Horizontal, -15),
|
6 => (ScrollAxis::Horizontal, -1),
|
||||||
7 => (ScrollAxis::Horizontal, 15),
|
7 => (ScrollAxis::Horizontal, 1),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
seat.mouse_event(InputEvent::Scroll(val, axis));
|
seat.mouse_event(InputEvent::AxisSource(AxisSource::Wheel));
|
||||||
|
seat.mouse_event(InputEvent::AxisDiscrete(val, axis));
|
||||||
|
seat.mouse_event(InputEvent::Axis(Fixed::from_int(val * 15), axis));
|
||||||
|
seat.mouse_event(InputEvent::Frame);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const BTN_LEFT: u32 = 0x110;
|
const BTN_LEFT: u32 = 0x110;
|
||||||
|
|
|
||||||
|
|
@ -769,9 +769,7 @@ impl ConfigProxyHandler {
|
||||||
ClientMessage::ConnectorSetPosition { connector, x, y } => self
|
ClientMessage::ConnectorSetPosition { connector, x, y } => self
|
||||||
.handle_connector_set_position(connector, x, y)
|
.handle_connector_set_position(connector, x, y)
|
||||||
.wrn("connector_set_position")?,
|
.wrn("connector_set_position")?,
|
||||||
ClientMessage::Close { seat } => self
|
ClientMessage::Close { seat } => self.handle_close(seat).wrn("close")?,
|
||||||
.handle_close(seat)
|
|
||||||
.wrn("close")?,
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::{ConnectorId, InputEvent, KeyState, ScrollAxis},
|
backend::{ConnectorId, InputEvent, KeyState},
|
||||||
client::{Client, ClientId},
|
client::{Client, ClientId},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
ifs::{
|
ifs::{
|
||||||
|
|
@ -11,7 +11,11 @@ use {
|
||||||
},
|
},
|
||||||
wl_seat::{
|
wl_seat::{
|
||||||
wl_keyboard::{self, WlKeyboard},
|
wl_keyboard::{self, WlKeyboard},
|
||||||
wl_pointer::{self, WlPointer, POINTER_FRAME_SINCE_VERSION},
|
wl_pointer::{
|
||||||
|
self, PendingScroll, WlPointer, AXIS_DISCRETE_SINCE_VERSION,
|
||||||
|
AXIS_SOURCE_SINCE_VERSION, AXIS_STOP_SINCE_VERSION,
|
||||||
|
POINTER_FRAME_SINCE_VERSION, WHEEL_TILT, WHEEL_TILT_SINCE_VERSION,
|
||||||
|
},
|
||||||
Dnd, SeatId, WlSeat, WlSeatGlobal,
|
Dnd, SeatId, WlSeat, WlSeatGlobal,
|
||||||
},
|
},
|
||||||
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
|
wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface},
|
||||||
|
|
@ -100,6 +104,10 @@ impl NodeSeatState {
|
||||||
self.kb_foci.iter().for_each(|(_, s)| f(s));
|
self.kb_foci.iter().for_each(|(_, s)| f(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn for_each_pointer_focus<F: FnMut(Rc<WlSeatGlobal>)>(&self, mut f: F) {
|
||||||
|
self.pointer_foci.iter().for_each(|(_, s)| f(s));
|
||||||
|
}
|
||||||
|
|
||||||
pub fn destroy_node(&self, node: &dyn Node) {
|
pub fn destroy_node(&self, node: &dyn Node) {
|
||||||
self.destroy_node2(node, true);
|
self.destroy_node2(node, true);
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +153,12 @@ impl WlSeatGlobal {
|
||||||
InputEvent::ConnectorPosition(o, x, y) => self.connector_position_event(o, x, y),
|
InputEvent::ConnectorPosition(o, x, y) => self.connector_position_event(o, x, y),
|
||||||
InputEvent::Motion(dx, dy) => self.motion_event(dx, dy),
|
InputEvent::Motion(dx, dy) => self.motion_event(dx, dy),
|
||||||
InputEvent::Button(b, s) => self.pointer_owner.button(self, b, s),
|
InputEvent::Button(b, s) => self.pointer_owner.button(self, b, s),
|
||||||
InputEvent::Scroll(d, a) => self.pointer_owner.scroll(self, d, a),
|
|
||||||
|
InputEvent::AxisSource(s) => self.pointer_owner.axis_source(s),
|
||||||
|
InputEvent::AxisDiscrete(d, a) => self.pointer_owner.axis_discrete(d, a),
|
||||||
|
InputEvent::Axis(d, a) => self.pointer_owner.axis(d, a),
|
||||||
|
InputEvent::AxisStop(d) => self.pointer_owner.axis_stop(d),
|
||||||
|
InputEvent::Frame => self.pointer_owner.frame(self),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,6 +213,7 @@ impl WlSeatGlobal {
|
||||||
|
|
||||||
fn key_event(&self, key: u32, state: KeyState) {
|
fn key_event(&self, key: u32, state: KeyState) {
|
||||||
let (state, xkb_dir) = {
|
let (state, xkb_dir) = {
|
||||||
|
log::info!("{} {:?}", key, state);
|
||||||
let mut pk = self.pressed_keys.borrow_mut();
|
let mut pk = self.pressed_keys.borrow_mut();
|
||||||
match state {
|
match state {
|
||||||
KeyState::Released => {
|
KeyState::Released => {
|
||||||
|
|
@ -455,12 +469,30 @@ impl WlSeatGlobal {
|
||||||
|
|
||||||
// Scroll callbacks
|
// Scroll callbacks
|
||||||
impl WlSeatGlobal {
|
impl WlSeatGlobal {
|
||||||
pub fn scroll_surface(&self, surface: &WlSurface, delta: i32, axis: ScrollAxis) {
|
pub fn scroll_surface(&self, surface: &WlSurface, event: &PendingScroll) {
|
||||||
let axis = match axis {
|
if let Some(source) = event.source.get() {
|
||||||
ScrollAxis::Horizontal => wl_pointer::HORIZONTAL_SCROLL,
|
let since = if source >= WHEEL_TILT {
|
||||||
ScrollAxis::Vertical => wl_pointer::VERTICAL_SCROLL,
|
WHEEL_TILT_SINCE_VERSION
|
||||||
};
|
} else {
|
||||||
self.surface_pointer_event(0, surface, |p| p.send_axis(0, axis, Fixed::from_int(delta)));
|
AXIS_SOURCE_SINCE_VERSION
|
||||||
|
};
|
||||||
|
self.surface_pointer_event(since, surface, |p| p.send_axis_source(source));
|
||||||
|
}
|
||||||
|
for i in 0..1 {
|
||||||
|
if let Some(delta) = event.discrete[i].get() {
|
||||||
|
self.surface_pointer_event(AXIS_DISCRETE_SINCE_VERSION, surface, |p| {
|
||||||
|
p.send_axis_discrete(i as _, delta)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if let Some(delta) = event.axis[i].get() {
|
||||||
|
self.surface_pointer_event(0, surface, |p| p.send_axis(0, i as _, delta));
|
||||||
|
}
|
||||||
|
if event.stop[i].get() {
|
||||||
|
self.surface_pointer_event(AXIS_STOP_SINCE_VERSION, surface, |p| {
|
||||||
|
p.send_axis_stop(0, i as _)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
self.surface_pointer_frame(surface);
|
self.surface_pointer_frame(surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::{KeyState, ScrollAxis},
|
backend::{AxisSource, KeyState, ScrollAxis},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
ifs::{
|
ifs::{
|
||||||
ipc,
|
ipc,
|
||||||
ipc::{wl_data_device::WlDataDevice, wl_data_source::WlDataSource},
|
ipc::{wl_data_device::WlDataDevice, wl_data_source::WlDataSource},
|
||||||
wl_seat::{Dnd, DroppedDnd, WlSeatError, WlSeatGlobal},
|
wl_seat::{wl_pointer::PendingScroll, Dnd, DroppedDnd, WlSeatError, WlSeatGlobal},
|
||||||
wl_surface::WlSurface,
|
wl_surface::WlSurface,
|
||||||
},
|
},
|
||||||
tree::{FoundNode, Node},
|
tree::{FoundNode, Node},
|
||||||
|
|
@ -17,6 +17,7 @@ use {
|
||||||
pub struct PointerOwnerHolder {
|
pub struct PointerOwnerHolder {
|
||||||
default: Rc<DefaultPointerOwner>,
|
default: Rc<DefaultPointerOwner>,
|
||||||
owner: CloneCell<Rc<dyn PointerOwner>>,
|
owner: CloneCell<Rc<dyn PointerOwner>>,
|
||||||
|
pending_scroll: PendingScroll,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PointerOwnerHolder {
|
impl Default for PointerOwnerHolder {
|
||||||
|
|
@ -24,6 +25,7 @@ impl Default for PointerOwnerHolder {
|
||||||
Self {
|
Self {
|
||||||
default: Rc::new(DefaultPointerOwner),
|
default: Rc::new(DefaultPointerOwner),
|
||||||
owner: CloneCell::new(Rc::new(DefaultPointerOwner)),
|
owner: CloneCell::new(Rc::new(DefaultPointerOwner)),
|
||||||
|
pending_scroll: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -33,8 +35,27 @@ impl PointerOwnerHolder {
|
||||||
self.owner.get().button(seat, button, state)
|
self.owner.get().button(seat, button, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll(&self, seat: &Rc<WlSeatGlobal>, delta: i32, axis: ScrollAxis) {
|
pub fn axis_source(&self, axis_source: AxisSource) {
|
||||||
self.owner.get().scroll(seat, delta, axis)
|
self.pending_scroll.source.set(Some(axis_source as _));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn axis_discrete(&self, delta: i32, axis: ScrollAxis) {
|
||||||
|
self.pending_scroll.discrete[axis as usize].set(Some(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn axis(&self, delta: Fixed, axis: ScrollAxis) {
|
||||||
|
self.pending_scroll.axis[axis as usize].set(Some(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn axis_stop(&self, axis: ScrollAxis) {
|
||||||
|
self.pending_scroll.stop[axis as usize].set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn frame(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
let pending = self.pending_scroll.take();
|
||||||
|
if let Some(node) = self.owner.get().axis_node(seat) {
|
||||||
|
node.axis_event(seat, &pending);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
pub fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
@ -74,7 +95,7 @@ impl PointerOwnerHolder {
|
||||||
|
|
||||||
trait PointerOwner {
|
trait PointerOwner {
|
||||||
fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState);
|
fn button(&self, seat: &Rc<WlSeatGlobal>, button: u32, state: KeyState);
|
||||||
fn scroll(&self, seat: &Rc<WlSeatGlobal>, delta: i32, axis: ScrollAxis);
|
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>>;
|
||||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>);
|
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>);
|
||||||
fn start_drag(
|
fn start_drag(
|
||||||
&self,
|
&self,
|
||||||
|
|
@ -123,10 +144,8 @@ impl PointerOwner for DefaultPointerOwner {
|
||||||
pn.button(seat, button, state);
|
pn.button(seat, button, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scroll(&self, seat: &Rc<WlSeatGlobal>, delta: i32, axis: ScrollAxis) {
|
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||||
if let Some(pn) = seat.pointer_node() {
|
seat.pointer_node()
|
||||||
pn.scroll(seat, delta, axis);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
@ -244,8 +263,8 @@ impl PointerOwner for GrabPointerOwner {
|
||||||
self.node.clone().button(seat, button, state);
|
self.node.clone().button(seat, button, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scroll(&self, seat: &Rc<WlSeatGlobal>, delta: i32, axis: ScrollAxis) {
|
fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||||
self.node.scroll(seat, delta, axis);
|
Some(self.node.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
@ -367,8 +386,8 @@ impl PointerOwner for DndPointerOwner {
|
||||||
seat.tree_changed.trigger();
|
seat.tree_changed.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scroll(&self, _seat: &Rc<WlSeatGlobal>, _delta: i32, _axis: ScrollAxis) {
|
fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||||
// nothing
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ 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,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use {
|
||||||
utils::buffd::{MsgParser, MsgParserError},
|
utils::buffd::{MsgParser, MsgParserError},
|
||||||
wire::{wl_pointer::*, WlPointerId, WlSurfaceId},
|
wire::{wl_pointer::*, WlPointerId, WlSurfaceId},
|
||||||
},
|
},
|
||||||
std::rc::Rc,
|
std::{cell::Cell, rc::Rc},
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -19,19 +19,48 @@ const ROLE: u32 = 0;
|
||||||
pub(super) const RELEASED: u32 = 0;
|
pub(super) const RELEASED: u32 = 0;
|
||||||
pub(super) const PRESSED: u32 = 1;
|
pub(super) const PRESSED: u32 = 1;
|
||||||
|
|
||||||
pub(super) const VERTICAL_SCROLL: u32 = 0;
|
pub const VERTICAL_SCROLL: u32 = 0;
|
||||||
pub(super) const HORIZONTAL_SCROLL: u32 = 1;
|
pub const HORIZONTAL_SCROLL: u32 = 1;
|
||||||
|
|
||||||
|
pub const WHEEL: u32 = 0;
|
||||||
|
pub const FINGER: u32 = 1;
|
||||||
|
pub const CONTINUOUS: u32 = 2;
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
const WHEEL: u32 = 0;
|
pub const WHEEL_TILT: u32 = 3;
|
||||||
#[allow(dead_code)]
|
|
||||||
const FINGER: u32 = 1;
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const CONTINUOUS: u32 = 2;
|
|
||||||
#[allow(dead_code)]
|
|
||||||
const WHEEL_TILT: u32 = 3;
|
|
||||||
|
|
||||||
pub const POINTER_FRAME_SINCE_VERSION: u32 = 5;
|
pub const POINTER_FRAME_SINCE_VERSION: u32 = 5;
|
||||||
|
pub const AXIS_SOURCE_SINCE_VERSION: u32 = 5;
|
||||||
|
pub const AXIS_DISCRETE_SINCE_VERSION: u32 = 5;
|
||||||
|
pub const AXIS_STOP_SINCE_VERSION: u32 = 5;
|
||||||
|
pub const WHEEL_TILT_SINCE_VERSION: u32 = 6;
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct PendingScroll {
|
||||||
|
pub discrete: [Cell<Option<i32>>; 2],
|
||||||
|
pub axis: [Cell<Option<Fixed>>; 2],
|
||||||
|
pub stop: [Cell<bool>; 2],
|
||||||
|
pub source: Cell<Option<u32>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PendingScroll {
|
||||||
|
pub fn take(&self) -> Self {
|
||||||
|
Self {
|
||||||
|
discrete: [
|
||||||
|
Cell::new(self.discrete[0].take()),
|
||||||
|
Cell::new(self.discrete[1].take()),
|
||||||
|
],
|
||||||
|
axis: [
|
||||||
|
Cell::new(self.axis[0].take()),
|
||||||
|
Cell::new(self.axis[1].take()),
|
||||||
|
],
|
||||||
|
stop: [
|
||||||
|
Cell::new(self.stop[0].take()),
|
||||||
|
Cell::new(self.stop[1].take()),
|
||||||
|
],
|
||||||
|
source: Cell::new(self.source.take()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WlPointer {
|
pub struct WlPointer {
|
||||||
id: WlPointerId,
|
id: WlPointerId,
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,13 @@ pub mod zwlr_layer_surface_v1;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::{KeyState, ScrollAxis},
|
backend::KeyState,
|
||||||
client::{Client, ClientError, RequestParser},
|
client::{Client, ClientError, RequestParser},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
ifs::{
|
ifs::{
|
||||||
wl_buffer::WlBuffer,
|
wl_buffer::WlBuffer,
|
||||||
wl_callback::WlCallback,
|
wl_callback::WlCallback,
|
||||||
wl_seat::{Dnd, NodeSeatState, SeatId, WlSeatGlobal},
|
wl_seat::{wl_pointer::PendingScroll, Dnd, NodeSeatState, SeatId, WlSeatGlobal},
|
||||||
wl_surface::{
|
wl_surface::{
|
||||||
cursor::CursorSurface, wl_subsurface::WlSubsurface, xdg_surface::XdgSurfaceError,
|
cursor::CursorSurface, wl_subsurface::WlSubsurface, xdg_surface::XdgSurfaceError,
|
||||||
zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error,
|
zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error,
|
||||||
|
|
@ -584,6 +584,13 @@ impl WlSurface {
|
||||||
_ => FindTreeResult::Other,
|
_ => FindTreeResult::Other,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_seat_release_events(&self) {
|
||||||
|
self.seat_state
|
||||||
|
.for_each_pointer_focus(|s| s.leave_surface(self));
|
||||||
|
self.seat_state
|
||||||
|
.for_each_kb_focus(|s| s.unfocus_surface(self));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_base! {
|
object_base! {
|
||||||
|
|
@ -644,6 +651,9 @@ impl Node for WlSurface {
|
||||||
child.surface.set_visible(visible);
|
child.surface.set_visible(visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !visible {
|
||||||
|
self.send_seat_release_events();
|
||||||
|
}
|
||||||
self.seat_state.set_visible(self, visible);
|
self.seat_state.set_visible(self, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -673,6 +683,7 @@ impl Node for WlSurface {
|
||||||
tl.surface_active_changed(false);
|
tl.surface_active_changed(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.send_seat_release_events();
|
||||||
self.seat_state.destroy_node(self);
|
self.seat_state.destroy_node(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -788,8 +799,8 @@ impl Node for WlSurface {
|
||||||
seat.button_surface(&self, button, state);
|
seat.button_surface(&self, button, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scroll(&self, seat: &WlSeatGlobal, delta: i32, axis: ScrollAxis) {
|
fn axis_event(&self, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||||
seat.scroll_surface(self, delta, axis);
|
seat.scroll_surface(self, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
fn focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
|
||||||
|
|
@ -299,6 +299,13 @@ impl XdgSurface {
|
||||||
popup.update_absolute_position();
|
popup.update_absolute_position();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_visible(&self, visible: bool) {
|
||||||
|
self.surface.set_visible(visible);
|
||||||
|
for popup in self.popups.lock().values() {
|
||||||
|
popup.set_visible(visible);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object_base! {
|
object_base! {
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ impl Node for XdgPopup {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
self.xdg.surface.set_visible(visible);
|
self.xdg.set_visible(visible);
|
||||||
self.xdg.seat_state.set_visible(self, visible);
|
self.xdg.seat_state.set_visible(self, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,9 +144,8 @@ impl XdgToplevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_close(&self) {
|
fn send_close(&self) {
|
||||||
self.xdg.surface.client.event(Close {
|
self.xdg.surface.client.event(Close { self_id: self.id });
|
||||||
self_id: self.id,
|
self.xdg.surface.client.flush();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_configure(&self, width: i32, height: i32) {
|
fn send_configure(&self, width: i32, height: i32) {
|
||||||
|
|
@ -366,6 +365,10 @@ impl Node for XdgToplevel {
|
||||||
self.node_id.into()
|
self.node_id.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close(&self) {
|
||||||
|
self.send_close();
|
||||||
|
}
|
||||||
|
|
||||||
fn seat_state(&self) -> &NodeSeatState {
|
fn seat_state(&self) -> &NodeSeatState {
|
||||||
&self.xdg.seat_state
|
&self.xdg.seat_state
|
||||||
}
|
}
|
||||||
|
|
@ -395,7 +398,7 @@ impl Node for XdgToplevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_visible(&self, visible: bool) {
|
fn set_visible(&self, visible: bool) {
|
||||||
self.xdg.surface.set_visible(visible);
|
self.xdg.set_visible(visible);
|
||||||
self.xdg.seat_state.set_visible(self, visible);
|
self.xdg.seat_state.set_visible(self, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,8 @@ impl Xwindow {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn map_status_changed(self: &Rc<Self>) {
|
pub fn map_status_changed(self: &Rc<Self>) {
|
||||||
match self.map_change() {
|
let map_change = self.map_change();
|
||||||
|
match map_change {
|
||||||
Change::None => return,
|
Change::None => return,
|
||||||
Change::Unmap => self.destroy_node(true),
|
Change::Unmap => self.destroy_node(true),
|
||||||
Change::Map if self.data.info.override_redirect.get() => {
|
Change::Map if self.data.info.override_redirect.get() => {
|
||||||
|
|
@ -300,6 +301,11 @@ impl Xwindow {
|
||||||
self.data.title_changed();
|
self.data.title_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
match map_change {
|
||||||
|
Change::Unmap => self.set_visible(false),
|
||||||
|
Change::Map => self.set_visible(true),
|
||||||
|
Change::None => {}
|
||||||
|
}
|
||||||
self.data.state.tree_changed();
|
self.data.state.tree_changed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -329,6 +335,10 @@ impl Node for Xwindow {
|
||||||
self.id.into()
|
self.id.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close(&self) {
|
||||||
|
self.events.push(XWaylandEvent::Close(self.data.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
fn visible(&self) -> bool {
|
fn visible(&self) -> bool {
|
||||||
self.surface.visible.get()
|
self.surface.visible.get()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ use {
|
||||||
libinput_event_keyboard_get_key_state, libinput_event_keyboard_get_time_usec,
|
libinput_event_keyboard_get_key_state, libinput_event_keyboard_get_time_usec,
|
||||||
libinput_event_pointer, libinput_event_pointer_get_button,
|
libinput_event_pointer, libinput_event_pointer_get_button,
|
||||||
libinput_event_pointer_get_button_state, libinput_event_pointer_get_dx,
|
libinput_event_pointer_get_button_state, libinput_event_pointer_get_dx,
|
||||||
libinput_event_pointer_get_dy, libinput_event_pointer_get_scroll_value_v120,
|
libinput_event_pointer_get_dy, libinput_event_pointer_get_scroll_value,
|
||||||
libinput_event_pointer_get_time_usec, libinput_event_pointer_has_axis,
|
libinput_event_pointer_get_scroll_value_v120, libinput_event_pointer_get_time_usec,
|
||||||
|
libinput_event_pointer_has_axis,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
std::marker::PhantomData,
|
std::marker::PhantomData,
|
||||||
|
|
@ -108,6 +109,10 @@ impl<'a> LibInputEventPointer<'a> {
|
||||||
unsafe { ButtonState(libinput_event_pointer_get_button_state(self.event)) }
|
unsafe { ButtonState(libinput_event_pointer_get_button_state(self.event)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn scroll_value(&self, axis: PointerAxis) -> f64 {
|
||||||
|
unsafe { libinput_event_pointer_get_scroll_value(self.event, axis.raw() as _) }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn scroll_value_v120(&self, axis: PointerAxis) -> f64 {
|
pub fn scroll_value_v120(&self, axis: PointerAxis) -> f64 {
|
||||||
unsafe { libinput_event_pointer_get_scroll_value_v120(self.event, axis.raw() as _) }
|
unsafe { libinput_event_pointer_get_scroll_value_v120(self.event, axis.raw() as _) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,10 @@ extern "C" {
|
||||||
pub fn libinput_event_pointer_get_button_state(
|
pub fn libinput_event_pointer_get_button_state(
|
||||||
event: *mut libinput_event_pointer,
|
event: *mut libinput_event_pointer,
|
||||||
) -> libinput_button_state;
|
) -> libinput_button_state;
|
||||||
|
pub fn libinput_event_pointer_get_scroll_value(
|
||||||
|
event: *mut libinput_event_pointer,
|
||||||
|
axis: libinput_pointer_axis,
|
||||||
|
) -> f64;
|
||||||
pub fn libinput_event_pointer_get_scroll_value_v120(
|
pub fn libinput_event_pointer_get_scroll_value_v120(
|
||||||
event: *mut libinput_event_pointer,
|
event: *mut libinput_event_pointer,
|
||||||
axis: libinput_pointer_axis,
|
axis: libinput_pointer_axis,
|
||||||
|
|
@ -86,6 +90,13 @@ extern "C" {
|
||||||
event: *mut libinput_event_pointer,
|
event: *mut libinput_event_pointer,
|
||||||
axis: libinput_pointer_axis,
|
axis: libinput_pointer_axis,
|
||||||
) -> c::c_int;
|
) -> c::c_int;
|
||||||
|
// pub fn libinput_event_pointer_get_axis_source(
|
||||||
|
// event: *mut libinput_event_pointer,
|
||||||
|
// ) -> libinput_pointer_axis_source;
|
||||||
|
// pub fn libinput_event_pointer_get_axis_value_discrete(
|
||||||
|
// event: *mut libinput_event_pointer,
|
||||||
|
// axis: libinput_pointer_axis,
|
||||||
|
// ) -> f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use {
|
use {
|
||||||
crate::{
|
crate::{
|
||||||
backend::{KeyState, ScrollAxis},
|
backend::KeyState,
|
||||||
client::{Client, ClientId},
|
client::{Client, ClientId},
|
||||||
fixed::Fixed,
|
fixed::Fixed,
|
||||||
ifs::{
|
ifs::{
|
||||||
wl_seat::{Dnd, NodeSeatState, WlSeatGlobal},
|
wl_seat::{wl_pointer::PendingScroll, Dnd, NodeSeatState, WlSeatGlobal},
|
||||||
wl_surface::WlSurface,
|
wl_surface::WlSurface,
|
||||||
},
|
},
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
|
|
@ -197,10 +197,9 @@ pub trait Node {
|
||||||
let _ = state;
|
let _ = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scroll(&self, seat: &WlSeatGlobal, delta: i32, axis: ScrollAxis) {
|
fn axis_event(&self, seat: &WlSeatGlobal, event: &PendingScroll) {
|
||||||
let _ = seat;
|
let _ = seat;
|
||||||
let _ = delta;
|
let _ = event;
|
||||||
let _ = axis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
fn focus(self: Rc<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||||
|
|
|
||||||
|
|
@ -6,33 +6,32 @@ use {
|
||||||
ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT},
|
ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT},
|
||||||
rect::Rect,
|
rect::Rect,
|
||||||
render::{Renderer, Texture},
|
render::{Renderer, Texture},
|
||||||
|
state::State,
|
||||||
|
text,
|
||||||
theme::Color,
|
theme::Color,
|
||||||
tree::{walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode},
|
tree::{
|
||||||
|
generic_node_visitor, walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId,
|
||||||
|
WorkspaceNode,
|
||||||
|
},
|
||||||
utils::{
|
utils::{
|
||||||
clonecell::CloneCell,
|
clonecell::CloneCell,
|
||||||
|
errorfmt::ErrorFmt,
|
||||||
linkedlist::{LinkedList, LinkedNode, NodeRef},
|
linkedlist::{LinkedList, LinkedNode, NodeRef},
|
||||||
|
numcell::NumCell,
|
||||||
|
rc_eq::rc_eq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ahash::AHashMap,
|
ahash::AHashMap,
|
||||||
jay_config::{Axis, Direction},
|
jay_config::{Axis, Direction},
|
||||||
std::cell::{Cell, RefCell},
|
smallvec::SmallVec,
|
||||||
};
|
|
||||||
|
|
||||||
use {
|
|
||||||
crate::{
|
|
||||||
state::State,
|
|
||||||
text,
|
|
||||||
utils::{errorfmt::ErrorFmt, numcell::NumCell, rc_eq::rc_eq},
|
|
||||||
},
|
|
||||||
std::{
|
std::{
|
||||||
|
cell::{Cell, RefCell},
|
||||||
fmt::{Debug, Formatter},
|
fmt::{Debug, Formatter},
|
||||||
mem,
|
mem,
|
||||||
ops::{Deref, DerefMut, Sub},
|
ops::{Deref, DerefMut, Sub},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use crate::tree::{generic_node_visitor};
|
|
||||||
use crate::utils::smallmap::SmallMap;
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
|
@ -282,7 +281,7 @@ impl ContainerNode {
|
||||||
focus_history: Default::default(),
|
focus_history: Default::default(),
|
||||||
});
|
});
|
||||||
let r = link.to_ref();
|
let r = link.to_ref();
|
||||||
links.insert( new.id(), link, );
|
links.insert(new.id(), link);
|
||||||
r
|
r
|
||||||
};
|
};
|
||||||
new.clone().set_workspace(&self.workspace.get());
|
new.clone().set_workspace(&self.workspace.get());
|
||||||
|
|
@ -379,6 +378,9 @@ impl ContainerNode {
|
||||||
ContainerSplit::Vertical => (self.content_height.get(), self.content_width.get()),
|
ContainerSplit::Vertical => (self.content_height.get(), self.content_width.get()),
|
||||||
};
|
};
|
||||||
let num_children = self.num_children.get();
|
let num_children = self.num_children.get();
|
||||||
|
if num_children == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
let mut remaining_content_size = content_size;
|
let mut remaining_content_size = content_size;
|
||||||
for child in self.children.iter() {
|
for child in self.children.iter() {
|
||||||
|
|
@ -671,20 +673,19 @@ impl ContainerNode {
|
||||||
if mc.node.id() == child.node.id() {
|
if mc.node.id() == child.node.id() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let seats = SmallMap::<SeatId, Rc<WlSeatGlobal>, 3>::new();
|
let mut seats = SmallVec::<[_; 3]>::new();
|
||||||
mc.node.visit_children(&mut generic_node_visitor(|node| {
|
mc.node.visit_children(&mut generic_node_visitor(|node| {
|
||||||
node.seat_state().for_each_kb_focus(|s| {
|
node.seat_state().for_each_kb_focus(|s| {
|
||||||
seats.insert(s.id(), s);
|
seats.push(s);
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
mc.node.set_visible(false);
|
mc.node.set_visible(false);
|
||||||
for (_, seat) in seats.take() {
|
for seat in seats {
|
||||||
child.node.clone().do_focus(&seat, Direction::Unspecified);
|
child.node.clone().do_focus(&seat, Direction::Unspecified);
|
||||||
}
|
}
|
||||||
self.mono_child.set(Some(child.clone()));
|
self.mono_child.set(Some(child.clone()));
|
||||||
self.schedule_layout();
|
self.schedule_layout();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -839,7 +840,7 @@ impl Node for ContainerNode {
|
||||||
_ => match self.focus_history.last() {
|
_ => match self.focus_history.last() {
|
||||||
Some(n) => Some(n.deref().clone()),
|
Some(n) => Some(n.deref().clone()),
|
||||||
None => self.children.last(),
|
None => self.children.last(),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(node) = node {
|
if let Some(node) = node {
|
||||||
|
|
@ -1184,7 +1185,8 @@ impl Node for ContainerNode {
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
node.active.set(active);
|
node.active.set(active);
|
||||||
node.focus_history.set(Some(self.focus_history.add_last(node.clone())));
|
node.focus_history
|
||||||
|
.set(Some(self.focus_history.add_last(node.clone())));
|
||||||
self.schedule_compute_render_data();
|
self.schedule_compute_render_data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1282,6 +1284,12 @@ impl Node for ContainerNode {
|
||||||
.clone()
|
.clone()
|
||||||
.child_title_changed(&*self, self.title.borrow_mut().deref());
|
.child_title_changed(&*self, self.title.borrow_mut().deref());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn close(&self) {
|
||||||
|
for child in self.children.iter() {
|
||||||
|
child.node.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn direction_to_split(dir: Direction) -> (ContainerSplit, bool) {
|
fn direction_to_split(dir: Direction) -> (ContainerSplit, bool) {
|
||||||
|
|
|
||||||
|
|
@ -112,10 +112,8 @@ pub struct GenericNodeVisitor<F> {
|
||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generic_node_visitor<F: FnMut(Rc<dyn Node>)>(f: F) -> GenericNodeVisitor<F> {
|
pub fn generic_node_visitor<F: FnMut(Rc<dyn Node>)>(f: F) -> GenericNodeVisitor<F> {
|
||||||
GenericNodeVisitor {
|
GenericNodeVisitor { f }
|
||||||
f,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: FnMut(Rc<dyn Node>)> NodeVisitor for GenericNodeVisitor<F> {
|
impl<F: FnMut(Rc<dyn Node>)> NodeVisitor for GenericNodeVisitor<F> {
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,8 @@ impl Wm {
|
||||||
Ok(ty) if ty == ATOM_STRING => {}
|
Ok(ty) if ty == ATOM_STRING => {}
|
||||||
Ok(ty) if ty == self.atoms.UTF8_STRING => {}
|
Ok(ty) if ty == self.atoms.UTF8_STRING => {}
|
||||||
Ok(ty) => {
|
Ok(ty) => {
|
||||||
self.unexpected_type(data.window_id, "WM_WINDOW_ROLE", ty).await;
|
self.unexpected_type(data.window_id, "WM_WINDOW_ROLE", ty)
|
||||||
|
.await;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Err(XconError::PropertyUnavailable) => {
|
Err(XconError::PropertyUnavailable) => {
|
||||||
|
|
@ -616,7 +617,13 @@ impl Wm {
|
||||||
if let Ok(res) = &res {
|
if let Ok(res) = &res {
|
||||||
ty_name = res.get().name;
|
ty_name = res.get().name;
|
||||||
}
|
}
|
||||||
log::error!("Property {} of window {} has unexpected type {} ({})", prop, window, ty_name, ty);
|
log::error!(
|
||||||
|
"Property {} of window {} has unexpected type {} ({})",
|
||||||
|
prop,
|
||||||
|
window,
|
||||||
|
ty_name,
|
||||||
|
ty
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn load_window_wm_name(&self, data: &Rc<XwindowData>) {
|
async fn load_window_wm_name(&self, data: &Rc<XwindowData>) {
|
||||||
|
|
@ -798,7 +805,8 @@ impl Wm {
|
||||||
Ok(ty) if ty == ATOM_STRING => {}
|
Ok(ty) if ty == ATOM_STRING => {}
|
||||||
Ok(ty) if ty == self.atoms.UTF8_STRING => {}
|
Ok(ty) if ty == self.atoms.UTF8_STRING => {}
|
||||||
Ok(ty) => {
|
Ok(ty) => {
|
||||||
self.unexpected_type(data.window_id, "_NET_STARTUP_ID", ty).await;
|
self.unexpected_type(data.window_id, "_NET_STARTUP_ID", ty)
|
||||||
|
.await;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Err(XconError::PropertyUnavailable) => return,
|
Err(XconError::PropertyUnavailable) => return,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue