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
|
|
@ -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<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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<DefaultPointerOwner>,
|
||||
owner: CloneCell<Rc<dyn PointerOwner>>,
|
||||
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<WlSeatGlobal>, 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<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>) {
|
||||
|
|
@ -74,7 +95,7 @@ impl PointerOwnerHolder {
|
|||
|
||||
trait PointerOwner {
|
||||
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 start_drag(
|
||||
&self,
|
||||
|
|
@ -123,10 +144,8 @@ impl PointerOwner for DefaultPointerOwner {
|
|||
pn.button(seat, button, state);
|
||||
}
|
||||
|
||||
fn scroll(&self, seat: &Rc<WlSeatGlobal>, delta: i32, axis: ScrollAxis) {
|
||||
if let Some(pn) = seat.pointer_node() {
|
||||
pn.scroll(seat, delta, axis);
|
||||
}
|
||||
fn axis_node(&self, seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||
seat.pointer_node()
|
||||
}
|
||||
|
||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
|
|
@ -244,8 +263,8 @@ impl PointerOwner for GrabPointerOwner {
|
|||
self.node.clone().button(seat, button, state);
|
||||
}
|
||||
|
||||
fn scroll(&self, seat: &Rc<WlSeatGlobal>, delta: i32, axis: ScrollAxis) {
|
||||
self.node.scroll(seat, delta, axis);
|
||||
fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||
Some(self.node.clone())
|
||||
}
|
||||
|
||||
fn handle_pointer_position(&self, seat: &Rc<WlSeatGlobal>) {
|
||||
|
|
@ -367,8 +386,8 @@ impl PointerOwner for DndPointerOwner {
|
|||
seat.tree_changed.trigger();
|
||||
}
|
||||
|
||||
fn scroll(&self, _seat: &Rc<WlSeatGlobal>, _delta: i32, _axis: ScrollAxis) {
|
||||
// nothing
|
||||
fn axis_node(&self, _seat: &Rc<WlSeatGlobal>) -> Option<Rc<dyn Node>> {
|
||||
None
|
||||
}
|
||||
|
||||
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]) {
|
||||
log::info!("enter with {:?}", keys);
|
||||
self.seat.client.event(Enter {
|
||||
self_id: self.id,
|
||||
serial,
|
||||
|
|
|
|||
|
|
@ -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<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 {
|
||||
id: WlPointerId,
|
||||
|
|
|
|||
|
|
@ -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<Self>, seat: &Rc<WlSeatGlobal>) {
|
||||
|
|
|
|||
|
|
@ -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! {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -270,7 +270,8 @@ impl Xwindow {
|
|||
}
|
||||
|
||||
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::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()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue