From befd5e99b2401c9e2f2ca4ecf06e9a273532d81a Mon Sep 17 00:00:00 2001 From: Julian Orth Date: Sun, 10 Apr 2022 01:35:15 +0200 Subject: [PATCH] autocommit 2022-04-10 01:35:15 CEST --- default-config/src/lib.rs | 9 ++-- src/backend.rs | 24 +++++++-- src/backends/metal.rs | 2 - src/backends/metal/input.rs | 43 ++++++++++------ src/backends/metal/monitor.rs | 2 - src/backends/x.rs | 19 ++++--- src/config/handler.rs | 4 +- src/ifs/wl_seat/event_handling.rs | 50 +++++++++++++++---- src/ifs/wl_seat/pointer_owner.rs | 45 ++++++++++++----- src/ifs/wl_seat/wl_keyboard.rs | 1 + src/ifs/wl_seat/wl_pointer.rs | 49 ++++++++++++++---- src/ifs/wl_surface.rs | 19 +++++-- src/ifs/wl_surface/xdg_surface.rs | 7 +++ src/ifs/wl_surface/xdg_surface/xdg_popup.rs | 2 +- .../wl_surface/xdg_surface/xdg_toplevel.rs | 11 ++-- src/ifs/wl_surface/xwindow.rs | 12 ++++- src/libinput/event.rs | 9 +++- src/libinput/sys.rs | 11 ++++ src/tree.rs | 9 ++-- src/tree/container.rs | 46 ++++++++++------- src/tree/walker.rs | 6 +-- src/xwayland/xwm.rs | 14 ++++-- 22 files changed, 280 insertions(+), 114 deletions(-) diff --git a/default-config/src/lib.rs b/default-config/src/lib.rs index 8aa121cc..315979be 100644 --- a/default-config/src/lib.rs +++ b/default-config/src/lib.rs @@ -10,10 +10,10 @@ use jay_config::{ keyboard::{ mods::{Modifiers, ALT, CTRL, SHIFT}, 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_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F13, SYM_F14, SYM_F15, - SYM_F16, SYM_F17, SYM_F18, SYM_F19, SYM_F2, SYM_F20, SYM_F21, SYM_F22, SYM_F23, - SYM_F24, SYM_F25, SYM_F3, SYM_F4, SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9, + SYM_Super_L, SYM_b, SYM_c, SYM_d, SYM_f, SYM_h, SYM_j, SYM_k, SYM_l, SYM_m, SYM_p, + SYM_q, SYM_t, SYM_v, SYM_y, SYM_F1, SYM_F10, SYM_F11, SYM_F12, SYM_F13, SYM_F14, + SYM_F15, SYM_F16, SYM_F17, SYM_F18, SYM_F19, SYM_F2, SYM_F20, SYM_F21, SYM_F22, + SYM_F23, SYM_F24, SYM_F25, SYM_F3, SYM_F4, SYM_F5, SYM_F6, SYM_F7, SYM_F8, SYM_F9, }, }, quit, switch_to_vt, @@ -21,7 +21,6 @@ use jay_config::{ Command, Direction::{Down, Left, Right, Up}, }; -use jay_config::keyboard::syms::SYM_c; const MOD: Modifiers = ALT; diff --git a/src/backend.rs b/src/backend.rs index f61becc7..e6dd2489 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -1,5 +1,9 @@ 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::{ fmt::{Debug, Display, Formatter}, rc::Rc, @@ -101,8 +105,15 @@ pub enum KeyState { #[derive(Debug, Copy, Clone, Eq, PartialEq)] pub enum ScrollAxis { - Horizontal, - Vertical, + Horizontal = HORIZONTAL_SCROLL as _, + Vertical = VERTICAL_SCROLL as _, +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq)] +pub enum AxisSource { + Wheel = WHEEL as _, + Finger = FINGER as _, + Continuous = CONTINUOUS as _, } #[derive(Debug)] @@ -112,5 +123,10 @@ pub enum InputEvent { #[allow(dead_code)] Motion(Fixed, Fixed), Button(u32, KeyState), - Scroll(i32, ScrollAxis), + + Axis(Fixed, ScrollAxis), + AxisSource(AxisSource), + AxisStop(ScrollAxis), + AxisDiscrete(i32, ScrollAxis), + Frame, } diff --git a/src/backends/metal.rs b/src/backends/metal.rs index d00e2f4b..39348bca 100644 --- a/src/backends/metal.rs +++ b/src/backends/metal.rs @@ -207,8 +207,6 @@ struct MetalInputDevice { removed: Cell, events: SyncQueue, cb: CloneCell>>, - hscroll: Cell, - vscroll: Cell, name: CloneCell>, // state diff --git a/src/backends/metal/input.rs b/src/backends/metal/input.rs index 44d1f710..e31bd625 100644 --- a/src/backends/metal/input.rs +++ b/src/backends/metal/input.rs @@ -1,7 +1,7 @@ use { crate::{ async_engine::FdStatus, - backend::{InputEvent, KeyState, ScrollAxis}, + backend::{AxisSource, InputEvent, KeyState, ScrollAxis}, backends::metal::MetalBackend, libinput::{ consts::{ @@ -81,7 +81,15 @@ impl MetalBackend { c::LIBINPUT_EVENT_KEYBOARD_KEY => self.handle_keyboard_key(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_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)); } - fn handle_pointer_scroll_wheel(self: &Rc, event: LibInputEvent) { + fn handle_pointer_axis(self: &Rc, event: LibInputEvent, source: AxisSource) { const PX_PER_SCROLL: f64 = 15.0; const ONE_TWENTRY: f64 = 120.0; let (event, dev) = unpack!(self, event, pointer_event); let axes = [ ( LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, - &dev.hscroll, ScrollAxis::Horizontal, ), - ( - LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, - &dev.vscroll, - ScrollAxis::Vertical, - ), + (LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, ScrollAxis::Vertical), ]; - for (axis, val, sa) in axes { + dev.event(InputEvent::AxisSource(source)); + for (axis, sa) in axes { if !event.has_axis(axis) { continue; } - let scroll = event.scroll_value_v120(axis) / ONE_TWENTRY + val.get(); - let scroll_used = (PX_PER_SCROLL * scroll).round(); - val.set(scroll - scroll_used / PX_PER_SCROLL); - if scroll_used != 0.0 { - dev.event(InputEvent::Scroll(scroll_used as i32, sa)); + let mut scroll = match source { + AxisSource::Wheel => event.scroll_value_v120(axis), + _ => event.scroll_value(axis), + }; + 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, event: LibInputEvent) { diff --git a/src/backends/metal/monitor.rs b/src/backends/metal/monitor.rs index 5bd8aee5..281baf1c 100644 --- a/src/backends/metal/monitor.rs +++ b/src/backends/metal/monitor.rs @@ -286,8 +286,6 @@ impl MetalBackend { removed: Cell::new(false), events: Default::default(), cb: Default::default(), - hscroll: Cell::new(0.0), - vscroll: Cell::new(0.0), name: Default::default(), pressed_keys: Default::default(), pressed_buttons: Default::default(), diff --git a/src/backends/x.rs b/src/backends/x.rs index b8589b20..8016864e 100644 --- a/src/backends/x.rs +++ b/src/backends/x.rs @@ -2,9 +2,9 @@ use { crate::{ async_engine::{Phase, SpawnedFuture}, backend::{ - Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, ConnectorKernelId, - InputDevice, InputDeviceAccelProfile, InputDeviceCapability, InputDeviceId, InputEvent, - KeyState, Mode, MonitorInfo, ScrollAxis, + AxisSource, Backend, BackendEvent, Connector, ConnectorEvent, ConnectorId, + ConnectorKernelId, InputDevice, InputDeviceAccelProfile, InputDeviceCapability, + InputDeviceId, InputEvent, KeyState, Mode, MonitorInfo, ScrollAxis, }, fixed::Fixed, format::XRGB8888, @@ -721,13 +721,16 @@ impl XBackendData { if matches!(button, 4..=7) { if state == KeyState::Pressed { let (axis, val) = match button { - 4 => (ScrollAxis::Vertical, -15), - 5 => (ScrollAxis::Vertical, 15), - 6 => (ScrollAxis::Horizontal, -15), - 7 => (ScrollAxis::Horizontal, 15), + 4 => (ScrollAxis::Vertical, -1), + 5 => (ScrollAxis::Vertical, 1), + 6 => (ScrollAxis::Horizontal, -1), + 7 => (ScrollAxis::Horizontal, 1), _ => 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 { const BTN_LEFT: u32 = 0x110; diff --git a/src/config/handler.rs b/src/config/handler.rs index 2f1ea492..e7003386 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -769,9 +769,7 @@ impl ConfigProxyHandler { ClientMessage::ConnectorSetPosition { connector, x, y } => self .handle_connector_set_position(connector, x, y) .wrn("connector_set_position")?, - ClientMessage::Close { seat } => self - .handle_close(seat) - .wrn("close")?, + ClientMessage::Close { seat } => self.handle_close(seat).wrn("close")?, } Ok(()) } diff --git a/src/ifs/wl_seat/event_handling.rs b/src/ifs/wl_seat/event_handling.rs index c75f0ecc..119a7508 100644 --- a/src/ifs/wl_seat/event_handling.rs +++ b/src/ifs/wl_seat/event_handling.rs @@ -1,6 +1,6 @@ use { crate::{ - backend::{ConnectorId, InputEvent, KeyState, ScrollAxis}, + backend::{ConnectorId, InputEvent, KeyState}, client::{Client, ClientId}, fixed::Fixed, ifs::{ @@ -11,7 +11,11 @@ use { }, wl_seat::{ 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, }, wl_surface::{xdg_surface::xdg_popup::XdgPopup, WlSurface}, @@ -100,6 +104,10 @@ impl NodeSeatState { self.kb_foci.iter().for_each(|(_, s)| f(s)); } + pub fn for_each_pointer_focus)>(&self, mut f: F) { + self.pointer_foci.iter().for_each(|(_, s)| f(s)); + } + pub fn destroy_node(&self, node: &dyn Node) { self.destroy_node2(node, true); } @@ -145,7 +153,12 @@ impl WlSeatGlobal { InputEvent::ConnectorPosition(o, x, y) => self.connector_position_event(o, x, y), InputEvent::Motion(dx, dy) => self.motion_event(dx, dy), 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) { let (state, xkb_dir) = { + log::info!("{} {:?}", key, state); let mut pk = self.pressed_keys.borrow_mut(); match state { KeyState::Released => { @@ -455,12 +469,30 @@ impl WlSeatGlobal { // Scroll callbacks impl WlSeatGlobal { - pub fn scroll_surface(&self, surface: &WlSurface, delta: i32, axis: ScrollAxis) { - let axis = match axis { - ScrollAxis::Horizontal => wl_pointer::HORIZONTAL_SCROLL, - ScrollAxis::Vertical => wl_pointer::VERTICAL_SCROLL, - }; - self.surface_pointer_event(0, surface, |p| p.send_axis(0, axis, Fixed::from_int(delta))); + pub fn scroll_surface(&self, surface: &WlSurface, event: &PendingScroll) { + if let Some(source) = event.source.get() { + let since = if source >= WHEEL_TILT { + WHEEL_TILT_SINCE_VERSION + } else { + 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); } } diff --git a/src/ifs/wl_seat/pointer_owner.rs b/src/ifs/wl_seat/pointer_owner.rs index 2585f9b4..a70b9c40 100644 --- a/src/ifs/wl_seat/pointer_owner.rs +++ b/src/ifs/wl_seat/pointer_owner.rs @@ -1,11 +1,11 @@ use { crate::{ - backend::{KeyState, ScrollAxis}, + backend::{AxisSource, KeyState, ScrollAxis}, fixed::Fixed, ifs::{ ipc, 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, }, tree::{FoundNode, Node}, @@ -17,6 +17,7 @@ use { pub struct PointerOwnerHolder { default: Rc, owner: CloneCell>, + pending_scroll: PendingScroll, } impl Default for PointerOwnerHolder { @@ -24,6 +25,7 @@ impl Default for PointerOwnerHolder { Self { default: 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) } - pub fn scroll(&self, seat: &Rc, delta: i32, axis: ScrollAxis) { - self.owner.get().scroll(seat, delta, axis) + pub fn axis_source(&self, axis_source: AxisSource) { + 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) { + 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) { @@ -74,7 +95,7 @@ impl PointerOwnerHolder { trait PointerOwner { fn button(&self, seat: &Rc, button: u32, state: KeyState); - fn scroll(&self, seat: &Rc, delta: i32, axis: ScrollAxis); + fn axis_node(&self, seat: &Rc) -> Option>; fn handle_pointer_position(&self, seat: &Rc); fn start_drag( &self, @@ -123,10 +144,8 @@ impl PointerOwner for DefaultPointerOwner { pn.button(seat, button, state); } - fn scroll(&self, seat: &Rc, delta: i32, axis: ScrollAxis) { - if let Some(pn) = seat.pointer_node() { - pn.scroll(seat, delta, axis); - } + fn axis_node(&self, seat: &Rc) -> Option> { + seat.pointer_node() } fn handle_pointer_position(&self, seat: &Rc) { @@ -244,8 +263,8 @@ impl PointerOwner for GrabPointerOwner { self.node.clone().button(seat, button, state); } - fn scroll(&self, seat: &Rc, delta: i32, axis: ScrollAxis) { - self.node.scroll(seat, delta, axis); + fn axis_node(&self, _seat: &Rc) -> Option> { + Some(self.node.clone()) } fn handle_pointer_position(&self, seat: &Rc) { @@ -367,8 +386,8 @@ impl PointerOwner for DndPointerOwner { seat.tree_changed.trigger(); } - fn scroll(&self, _seat: &Rc, _delta: i32, _axis: ScrollAxis) { - // nothing + fn axis_node(&self, _seat: &Rc) -> Option> { + None } fn handle_pointer_position(&self, seat: &Rc) { diff --git a/src/ifs/wl_seat/wl_keyboard.rs b/src/ifs/wl_seat/wl_keyboard.rs index 250cf14d..d1681a8d 100644 --- a/src/ifs/wl_seat/wl_keyboard.rs +++ b/src/ifs/wl_seat/wl_keyboard.rs @@ -46,6 +46,7 @@ impl WlKeyboard { } pub fn send_enter(self: &Rc, serial: u32, surface: WlSurfaceId, keys: &[u32]) { + log::info!("enter with {:?}", keys); self.seat.client.event(Enter { self_id: self.id, serial, diff --git a/src/ifs/wl_seat/wl_pointer.rs b/src/ifs/wl_seat/wl_pointer.rs index f9b69309..19f999b9 100644 --- a/src/ifs/wl_seat/wl_pointer.rs +++ b/src/ifs/wl_seat/wl_pointer.rs @@ -9,7 +9,7 @@ use { utils::buffd::{MsgParser, MsgParserError}, wire::{wl_pointer::*, WlPointerId, WlSurfaceId}, }, - std::rc::Rc, + std::{cell::Cell, rc::Rc}, thiserror::Error, }; @@ -19,19 +19,48 @@ const ROLE: u32 = 0; pub(super) const RELEASED: u32 = 0; pub(super) const PRESSED: u32 = 1; -pub(super) const VERTICAL_SCROLL: u32 = 0; -pub(super) const HORIZONTAL_SCROLL: u32 = 1; +pub const VERTICAL_SCROLL: u32 = 0; +pub const HORIZONTAL_SCROLL: u32 = 1; +pub const WHEEL: u32 = 0; +pub const FINGER: u32 = 1; +pub const CONTINUOUS: u32 = 2; #[allow(dead_code)] -const WHEEL: u32 = 0; -#[allow(dead_code)] -const FINGER: u32 = 1; -#[allow(dead_code)] -const CONTINUOUS: u32 = 2; -#[allow(dead_code)] -const WHEEL_TILT: u32 = 3; +pub const WHEEL_TILT: u32 = 3; 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>; 2], + pub axis: [Cell>; 2], + pub stop: [Cell; 2], + pub source: Cell>, +} + +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 { id: WlPointerId, diff --git a/src/ifs/wl_surface.rs b/src/ifs/wl_surface.rs index 8fb80662..074f7bd7 100644 --- a/src/ifs/wl_surface.rs +++ b/src/ifs/wl_surface.rs @@ -6,13 +6,13 @@ pub mod zwlr_layer_surface_v1; use { crate::{ - backend::{KeyState, ScrollAxis}, + backend::KeyState, client::{Client, ClientError, RequestParser}, fixed::Fixed, ifs::{ wl_buffer::WlBuffer, wl_callback::WlCallback, - wl_seat::{Dnd, NodeSeatState, SeatId, WlSeatGlobal}, + wl_seat::{wl_pointer::PendingScroll, Dnd, NodeSeatState, SeatId, WlSeatGlobal}, wl_surface::{ cursor::CursorSurface, wl_subsurface::WlSubsurface, xdg_surface::XdgSurfaceError, zwlr_layer_surface_v1::ZwlrLayerSurfaceV1Error, @@ -584,6 +584,13 @@ impl WlSurface { _ => 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! { @@ -644,6 +651,9 @@ impl Node for WlSurface { child.surface.set_visible(visible); } } + if !visible { + self.send_seat_release_events(); + } self.seat_state.set_visible(self, visible); } @@ -673,6 +683,7 @@ impl Node for WlSurface { tl.surface_active_changed(false); } } + self.send_seat_release_events(); self.seat_state.destroy_node(self); } @@ -788,8 +799,8 @@ impl Node for WlSurface { seat.button_surface(&self, button, state); } - fn scroll(&self, seat: &WlSeatGlobal, delta: i32, axis: ScrollAxis) { - seat.scroll_surface(self, delta, axis); + fn axis_event(&self, seat: &WlSeatGlobal, event: &PendingScroll) { + seat.scroll_surface(self, event); } fn focus(self: Rc, seat: &Rc) { diff --git a/src/ifs/wl_surface/xdg_surface.rs b/src/ifs/wl_surface/xdg_surface.rs index 7ac86860..48fac2b1 100644 --- a/src/ifs/wl_surface/xdg_surface.rs +++ b/src/ifs/wl_surface/xdg_surface.rs @@ -299,6 +299,13 @@ impl XdgSurface { 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! { diff --git a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs index 3c50a29b..1607abfc 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_popup.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_popup.rs @@ -293,7 +293,7 @@ impl Node for XdgPopup { } 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); } diff --git a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs index f5aaeec4..cecc9480 100644 --- a/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs +++ b/src/ifs/wl_surface/xdg_surface/xdg_toplevel.rs @@ -144,9 +144,8 @@ impl XdgToplevel { } fn send_close(&self) { - self.xdg.surface.client.event(Close { - self_id: self.id, - }); + self.xdg.surface.client.event(Close { self_id: self.id }); + self.xdg.surface.client.flush(); } fn send_configure(&self, width: i32, height: i32) { @@ -366,6 +365,10 @@ impl Node for XdgToplevel { self.node_id.into() } + fn close(&self) { + self.send_close(); + } + fn seat_state(&self) -> &NodeSeatState { &self.xdg.seat_state } @@ -395,7 +398,7 @@ impl Node for XdgToplevel { } 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); } diff --git a/src/ifs/wl_surface/xwindow.rs b/src/ifs/wl_surface/xwindow.rs index 43e60b61..2070cf04 100644 --- a/src/ifs/wl_surface/xwindow.rs +++ b/src/ifs/wl_surface/xwindow.rs @@ -270,7 +270,8 @@ impl Xwindow { } pub fn map_status_changed(self: &Rc) { - match self.map_change() { + let map_change = self.map_change(); + match map_change { Change::None => return, Change::Unmap => self.destroy_node(true), Change::Map if self.data.info.override_redirect.get() => { @@ -300,6 +301,11 @@ impl Xwindow { 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(); } } @@ -329,6 +335,10 @@ impl Node for Xwindow { self.id.into() } + fn close(&self) { + self.events.push(XWaylandEvent::Close(self.data.clone())); + } + fn visible(&self) -> bool { self.surface.visible.get() } diff --git a/src/libinput/event.rs b/src/libinput/event.rs index d2a01ec2..0f9ec764 100644 --- a/src/libinput/event.rs +++ b/src/libinput/event.rs @@ -9,8 +9,9 @@ use { libinput_event_keyboard_get_key_state, libinput_event_keyboard_get_time_usec, libinput_event_pointer, libinput_event_pointer_get_button, 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_time_usec, libinput_event_pointer_has_axis, + libinput_event_pointer_get_dy, libinput_event_pointer_get_scroll_value, + libinput_event_pointer_get_scroll_value_v120, libinput_event_pointer_get_time_usec, + libinput_event_pointer_has_axis, }, }, std::marker::PhantomData, @@ -108,6 +109,10 @@ impl<'a> LibInputEventPointer<'a> { 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 { unsafe { libinput_event_pointer_get_scroll_value_v120(self.event, axis.raw() as _) } } diff --git a/src/libinput/sys.rs b/src/libinput/sys.rs index 890b1220..494eb884 100644 --- a/src/libinput/sys.rs +++ b/src/libinput/sys.rs @@ -78,6 +78,10 @@ extern "C" { pub fn libinput_event_pointer_get_button_state( event: *mut libinput_event_pointer, ) -> 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( event: *mut libinput_event_pointer, axis: libinput_pointer_axis, @@ -86,6 +90,13 @@ extern "C" { event: *mut libinput_event_pointer, axis: libinput_pointer_axis, ) -> 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)] diff --git a/src/tree.rs b/src/tree.rs index bf7ee157..76da4973 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -1,10 +1,10 @@ use { crate::{ - backend::{KeyState, ScrollAxis}, + backend::KeyState, client::{Client, ClientId}, fixed::Fixed, ifs::{ - wl_seat::{Dnd, NodeSeatState, WlSeatGlobal}, + wl_seat::{wl_pointer::PendingScroll, Dnd, NodeSeatState, WlSeatGlobal}, wl_surface::WlSurface, }, rect::Rect, @@ -197,10 +197,9 @@ pub trait Node { let _ = state; } - fn scroll(&self, seat: &WlSeatGlobal, delta: i32, axis: ScrollAxis) { + fn axis_event(&self, seat: &WlSeatGlobal, event: &PendingScroll) { let _ = seat; - let _ = delta; - let _ = axis; + let _ = event; } fn focus(self: Rc, seat: &Rc) { diff --git a/src/tree/container.rs b/src/tree/container.rs index e76416ee..5d39be37 100644 --- a/src/tree/container.rs +++ b/src/tree/container.rs @@ -6,33 +6,32 @@ use { ifs::wl_seat::{NodeSeatState, SeatId, WlSeatGlobal, BTN_LEFT}, rect::Rect, render::{Renderer, Texture}, + state::State, + text, theme::Color, - tree::{walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, WorkspaceNode}, + tree::{ + generic_node_visitor, walker::NodeVisitor, FindTreeResult, FoundNode, Node, NodeId, + WorkspaceNode, + }, utils::{ clonecell::CloneCell, + errorfmt::ErrorFmt, linkedlist::{LinkedList, LinkedNode, NodeRef}, + numcell::NumCell, + rc_eq::rc_eq, }, }, ahash::AHashMap, jay_config::{Axis, Direction}, - std::cell::{Cell, RefCell}, -}; - -use { - crate::{ - state::State, - text, - utils::{errorfmt::ErrorFmt, numcell::NumCell, rc_eq::rc_eq}, - }, + smallvec::SmallVec, std::{ + cell::{Cell, RefCell}, fmt::{Debug, Formatter}, mem, ops::{Deref, DerefMut, Sub}, rc::Rc, }, }; -use crate::tree::{generic_node_visitor}; -use crate::utils::smallmap::SmallMap; #[allow(dead_code)] #[derive(Copy, Clone, Debug, Eq, PartialEq)] @@ -282,7 +281,7 @@ impl ContainerNode { focus_history: Default::default(), }); let r = link.to_ref(); - links.insert( new.id(), link, ); + links.insert(new.id(), link); r }; new.clone().set_workspace(&self.workspace.get()); @@ -379,6 +378,9 @@ impl ContainerNode { ContainerSplit::Vertical => (self.content_height.get(), self.content_width.get()), }; let num_children = self.num_children.get(); + if num_children == 0 { + return; + } let mut pos = 0; let mut remaining_content_size = content_size; for child in self.children.iter() { @@ -671,20 +673,19 @@ impl ContainerNode { if mc.node.id() == child.node.id() { return; } - let seats = SmallMap::, 3>::new(); + let mut seats = SmallVec::<[_; 3]>::new(); mc.node.visit_children(&mut generic_node_visitor(|node| { node.seat_state().for_each_kb_focus(|s| { - seats.insert(s.id(), s); + seats.push(s); }); })); mc.node.set_visible(false); - for (_, seat) in seats.take() { + for seat in seats { child.node.clone().do_focus(&seat, Direction::Unspecified); } self.mono_child.set(Some(child.clone())); self.schedule_layout(); } else { - } } } @@ -839,7 +840,7 @@ impl Node for ContainerNode { _ => match self.focus_history.last() { Some(n) => Some(n.deref().clone()), None => self.children.last(), - } + }, } }; if let Some(node) = node { @@ -1184,7 +1185,8 @@ impl Node for ContainerNode { None => return, }; 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(); } @@ -1282,6 +1284,12 @@ impl Node for ContainerNode { .clone() .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) { diff --git a/src/tree/walker.rs b/src/tree/walker.rs index 0d547480..758cea85 100644 --- a/src/tree/walker.rs +++ b/src/tree/walker.rs @@ -112,10 +112,8 @@ pub struct GenericNodeVisitor { f: F, } -pub fn generic_node_visitor)>(f: F) -> GenericNodeVisitor { - GenericNodeVisitor { - f, - } +pub fn generic_node_visitor)>(f: F) -> GenericNodeVisitor { + GenericNodeVisitor { f } } impl)> NodeVisitor for GenericNodeVisitor { diff --git a/src/xwayland/xwm.rs b/src/xwayland/xwm.rs index caad89ef..cea92e01 100644 --- a/src/xwayland/xwm.rs +++ b/src/xwayland/xwm.rs @@ -536,7 +536,8 @@ impl Wm { Ok(ty) if ty == ATOM_STRING => {} Ok(ty) if ty == self.atoms.UTF8_STRING => {} 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; } Err(XconError::PropertyUnavailable) => { @@ -616,7 +617,13 @@ impl Wm { if let Ok(res) = &res { 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) { @@ -798,7 +805,8 @@ impl Wm { Ok(ty) if ty == ATOM_STRING => {} Ok(ty) if ty == self.atoms.UTF8_STRING => {} 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; } Err(XconError::PropertyUnavailable) => return,