Compare commits
20 Commits
d04a999bf8
...
6fc7503698
Author | SHA1 | Date |
---|---|---|
Victor Timofei | 6fc7503698 | |
Victoria Brekenfeld | 5da3a62929 | |
Victoria Brekenfeld | 134f726dfb | |
Victoria Brekenfeld | 8c92e5f720 | |
Victor Berger | d797cdcdcb | |
i509VCB | 0c8cb49129 | |
Victoria Brekenfeld | 11ab4c7f92 | |
Victor Timofei | bf515da51a | |
Victor Timofei | 264299a6a4 | |
Victor Timofei | 2fb1f93160 | |
Victor Timofei | 77fdd1883e | |
Victor Timofei | 2a9a4decab | |
Victor Timofei | d08f9e2a98 | |
Victor Timofei | 67daf0d433 | |
Victor Timofei | 05924dc2ff | |
Victor Timofei | 51ad2d060f | |
Victor Timofei | fa14d56b2a | |
Victor Timofei | 89399181b0 | |
Victor Timofei | 44b8a88de6 | |
Victor Timofei | 145c0bc2df |
|
@ -5,6 +5,7 @@ on:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
format:
|
format:
|
||||||
|
|
|
@ -112,18 +112,7 @@ impl<Backend> AnvilState<Backend> {
|
||||||
let serial = SCOUNTER.next_serial();
|
let serial = SCOUNTER.next_serial();
|
||||||
let button = evt.button_code();
|
let button = evt.button_code();
|
||||||
let state = match evt.state() {
|
let state = match evt.state() {
|
||||||
input::ButtonState::Pressed => {
|
input::ButtonState::Pressed => wl_pointer::ButtonState::Pressed,
|
||||||
// change the keyboard focus unless the pointer is grabbed
|
|
||||||
if !self.pointer.is_grabbed() {
|
|
||||||
let under = self
|
|
||||||
.window_map
|
|
||||||
.borrow_mut()
|
|
||||||
.get_surface_and_bring_to_top(self.pointer_location);
|
|
||||||
self.keyboard
|
|
||||||
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
|
|
||||||
}
|
|
||||||
wl_pointer::ButtonState::Pressed
|
|
||||||
}
|
|
||||||
input::ButtonState::Released => wl_pointer::ButtonState::Released,
|
input::ButtonState::Released => wl_pointer::ButtonState::Released,
|
||||||
};
|
};
|
||||||
self.pointer.button(button, state, serial, evt.time());
|
self.pointer.button(button, state, serial, evt.time());
|
||||||
|
@ -236,7 +225,15 @@ impl<Backend> AnvilState<Backend> {
|
||||||
let pos = evt.position_transformed(output_size);
|
let pos = evt.position_transformed(output_size);
|
||||||
self.pointer_location = pos;
|
self.pointer_location = pos;
|
||||||
let serial = SCOUNTER.next_serial();
|
let serial = SCOUNTER.next_serial();
|
||||||
let under = self.window_map.borrow().get_surface_under(pos);
|
let under;
|
||||||
|
// set focus for this window
|
||||||
|
if !self.pointer.is_grabbed() {
|
||||||
|
under = self.window_map.borrow_mut().get_surface_and_bring_to_top(pos);
|
||||||
|
self.keyboard
|
||||||
|
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
|
||||||
|
} else {
|
||||||
|
under = self.window_map.borrow().get_surface_under(pos);
|
||||||
|
}
|
||||||
self.pointer.motion(pos, under, serial, evt.time());
|
self.pointer.motion(pos, under, serial, evt.time());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +355,18 @@ impl AnvilState<UdevData> {
|
||||||
// this event is never generated by winit
|
// this event is never generated by winit
|
||||||
self.pointer_location = self.clamp_coords(self.pointer_location);
|
self.pointer_location = self.clamp_coords(self.pointer_location);
|
||||||
|
|
||||||
let under = self.window_map.borrow().get_surface_under(self.pointer_location);
|
let under;
|
||||||
|
// set focus for this window
|
||||||
|
if !self.pointer.is_grabbed() {
|
||||||
|
under = self
|
||||||
|
.window_map
|
||||||
|
.borrow_mut()
|
||||||
|
.get_surface_and_bring_to_top(self.pointer_location);
|
||||||
|
self.keyboard
|
||||||
|
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
|
||||||
|
} else {
|
||||||
|
under = self.window_map.borrow().get_surface_under(self.pointer_location);
|
||||||
|
}
|
||||||
self.pointer
|
self.pointer
|
||||||
.motion(self.pointer_location, under, serial, evt.time());
|
.motion(self.pointer_location, under, serial, evt.time());
|
||||||
}
|
}
|
||||||
|
@ -521,9 +529,8 @@ enum KeyAction {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> Option<KeyAction> {
|
fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> Option<KeyAction> {
|
||||||
if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
|
let modkey = modifiers.ctrl;
|
||||||
|| modifiers.logo && keysym == xkb::KEY_q
|
if modkey && keysym == xkb::KEY_q {
|
||||||
{
|
|
||||||
// ctrl+alt+backspace = quit
|
// ctrl+alt+backspace = quit
|
||||||
// logo + q = quit
|
// logo + q = quit
|
||||||
Some(KeyAction::Quit)
|
Some(KeyAction::Quit)
|
||||||
|
@ -532,14 +539,14 @@ fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> Optio
|
||||||
Some(KeyAction::VtSwitch(
|
Some(KeyAction::VtSwitch(
|
||||||
(keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32,
|
(keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32,
|
||||||
))
|
))
|
||||||
} else if modifiers.logo && keysym == xkb::KEY_Return {
|
} else if modkey && keysym == xkb::KEY_Return {
|
||||||
// run terminal
|
// run terminal
|
||||||
Some(KeyAction::Run("weston-terminal".into()))
|
Some(KeyAction::Run("alacritty".into()))
|
||||||
} else if modifiers.logo && keysym >= xkb::KEY_1 && keysym <= xkb::KEY_9 {
|
} else if modkey && keysym >= xkb::KEY_1 && keysym <= xkb::KEY_9 {
|
||||||
Some(KeyAction::Screen((keysym - xkb::KEY_1) as usize))
|
Some(KeyAction::Screen((keysym - xkb::KEY_1) as usize))
|
||||||
} else if modifiers.logo && modifiers.shift && keysym == xkb::KEY_M {
|
} else if modkey && modifiers.shift && keysym == xkb::KEY_M {
|
||||||
Some(KeyAction::ScaleDown)
|
Some(KeyAction::ScaleDown)
|
||||||
} else if modifiers.logo && modifiers.shift && keysym == xkb::KEY_P {
|
} else if modkey && modifiers.shift && keysym == xkb::KEY_P {
|
||||||
Some(KeyAction::ScaleUp)
|
Some(KeyAction::ScaleUp)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -48,12 +48,15 @@ struct MoveSurfaceGrab {
|
||||||
impl PointerGrab for MoveSurfaceGrab {
|
impl PointerGrab for MoveSurfaceGrab {
|
||||||
fn motion(
|
fn motion(
|
||||||
&mut self,
|
&mut self,
|
||||||
_handle: &mut PointerInnerHandle<'_>,
|
handle: &mut PointerInnerHandle<'_>,
|
||||||
location: Point<f64, Logical>,
|
location: Point<f64, Logical>,
|
||||||
_focus: Option<(wl_surface::WlSurface, Point<i32, Logical>)>,
|
_focus: Option<(wl_surface::WlSurface, Point<i32, Logical>)>,
|
||||||
_serial: Serial,
|
serial: Serial,
|
||||||
_time: u32,
|
time: u32,
|
||||||
) {
|
) {
|
||||||
|
// While the grab is active, no client has pointer focus
|
||||||
|
handle.motion(location, None, serial, time);
|
||||||
|
|
||||||
let delta = location - self.start_data.location;
|
let delta = location - self.start_data.location;
|
||||||
let new_location = self.initial_window_location.to_f64() + delta;
|
let new_location = self.initial_window_location.to_f64() + delta;
|
||||||
|
|
||||||
|
@ -152,6 +155,9 @@ impl PointerGrab for ResizeSurfaceGrab {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// While the grab is active, no client has pointer focus
|
||||||
|
handle.motion(location, None, serial, time);
|
||||||
|
|
||||||
let (mut dx, mut dy) = (location - self.start_data.location).into();
|
let (mut dx, mut dy) = (location - self.start_data.location).into();
|
||||||
|
|
||||||
let mut new_window_width = self.initial_window_size.w;
|
let mut new_window_width = self.initial_window_size.w;
|
||||||
|
@ -479,7 +485,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
|
||||||
initial_window_location,
|
initial_window_location,
|
||||||
};
|
};
|
||||||
|
|
||||||
pointer.set_grab(grab, serial);
|
pointer.set_grab(grab, serial, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
XdgRequest::Resize {
|
XdgRequest::Resize {
|
||||||
|
@ -539,7 +545,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
|
||||||
last_window_size: initial_window_size,
|
last_window_size: initial_window_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
pointer.set_grab(grab, serial);
|
pointer.set_grab(grab, serial, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
XdgRequest::AckConfigure {
|
XdgRequest::AckConfigure {
|
||||||
|
@ -806,7 +812,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
|
||||||
initial_window_location,
|
initial_window_location,
|
||||||
};
|
};
|
||||||
|
|
||||||
pointer.set_grab(grab, serial);
|
pointer.set_grab(grab, serial, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShellRequest::Resize {
|
ShellRequest::Resize {
|
||||||
|
@ -866,7 +872,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
|
||||||
last_window_size: initial_window_size,
|
last_window_size: initial_window_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
pointer.set_grab(grab, serial);
|
pointer.set_grab(grab, serial, 0);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ use std::{
|
||||||
use smithay::{
|
use smithay::{
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{generic::Generic, Interest, LoopHandle, Mode, PostAction},
|
calloop::{generic::Generic, Interest, LoopHandle, Mode, PostAction},
|
||||||
wayland_protocols::unstable::xdg_decoration,
|
|
||||||
wayland_server::{protocol::wl_surface::WlSurface, Display},
|
wayland_server::{protocol::wl_surface::WlSurface, Display},
|
||||||
},
|
},
|
||||||
utils::{Logical, Point},
|
utils::{Logical, Point},
|
||||||
|
@ -18,7 +17,7 @@ use smithay::{
|
||||||
data_device::{default_action_chooser, init_data_device, set_data_device_focus, DataDeviceEvent},
|
data_device::{default_action_chooser, init_data_device, set_data_device_focus, DataDeviceEvent},
|
||||||
output::xdg::init_xdg_output_manager,
|
output::xdg::init_xdg_output_manager,
|
||||||
seat::{CursorImageStatus, KeyboardHandle, PointerHandle, Seat, XkbConfig},
|
seat::{CursorImageStatus, KeyboardHandle, PointerHandle, Seat, XkbConfig},
|
||||||
shell::xdg::decoration::{init_xdg_decoration_manager, XdgDecorationRequest},
|
shell::xdg::decoration::init_xdg_decoration_manager,
|
||||||
shm::init_shm_global,
|
shm::init_shm_global,
|
||||||
tablet_manager::{init_tablet_manager_global, TabletSeatTrait},
|
tablet_manager::{init_tablet_manager_global, TabletSeatTrait},
|
||||||
xdg_activation::{init_xdg_activation_global, XdgActivationEvent},
|
xdg_activation::{init_xdg_activation_global, XdgActivationEvent},
|
||||||
|
@ -122,25 +121,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
|
||||||
log.clone(),
|
log.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
init_xdg_decoration_manager(
|
init_xdg_decoration_manager(&mut display.borrow_mut(), |_, _| {}, log.clone());
|
||||||
&mut display.borrow_mut(),
|
|
||||||
|req, _ddata| match req {
|
|
||||||
XdgDecorationRequest::NewToplevelDecoration { toplevel } => {
|
|
||||||
use xdg_decoration::v1::server::zxdg_toplevel_decoration_v1::Mode;
|
|
||||||
|
|
||||||
let res = toplevel.with_pending_state(|state| {
|
|
||||||
state.decoration_mode = Some(Mode::ClientSide);
|
|
||||||
});
|
|
||||||
|
|
||||||
if res.is_ok() {
|
|
||||||
toplevel.send_configure();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
XdgDecorationRequest::SetMode { .. } => {}
|
|
||||||
XdgDecorationRequest::UnsetMode { .. } => {}
|
|
||||||
},
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let socket_name = if listen_on_socket {
|
let socket_name = if listen_on_socket {
|
||||||
let socket_name = display
|
let socket_name = display
|
||||||
|
@ -167,7 +148,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
|
||||||
DataDeviceEvent::DnDStarted { icon, .. } => {
|
DataDeviceEvent::DnDStarted { icon, .. } => {
|
||||||
*dnd_icon2.lock().unwrap() = icon;
|
*dnd_icon2.lock().unwrap() = icon;
|
||||||
}
|
}
|
||||||
DataDeviceEvent::DnDDropped => {
|
DataDeviceEvent::DnDDropped { .. } => {
|
||||||
*dnd_icon2.lock().unwrap() = None;
|
*dnd_icon2.lock().unwrap() = None;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
@ -7,7 +7,7 @@ use libc::dev_t;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
fs, io,
|
fs, io, mem,
|
||||||
os::unix::prelude::{AsRawFd, IntoRawFd, RawFd},
|
os::unix::prelude::{AsRawFd, IntoRawFd, RawFd},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
@ -20,8 +20,7 @@ use nix::{
|
||||||
/// A node which refers to a DRM device.
|
/// A node which refers to a DRM device.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DrmNode {
|
pub struct DrmNode {
|
||||||
// Always `Some`, None variant is used when taking ownership
|
fd: RawFd,
|
||||||
fd: Option<RawFd>,
|
|
||||||
dev: dev_t,
|
dev: dev_t,
|
||||||
ty: NodeType,
|
ty: NodeType,
|
||||||
}
|
}
|
||||||
|
@ -56,11 +55,7 @@ impl DrmNode {
|
||||||
_ => return Err(CreateDrmNodeError::NotDrmNode),
|
_ => return Err(CreateDrmNodeError::NotDrmNode),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(DrmNode {
|
Ok(DrmNode { fd, dev, ty })
|
||||||
fd: Some(fd),
|
|
||||||
dev,
|
|
||||||
ty,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type of the DRM node.
|
/// Returns the type of the DRM node.
|
||||||
|
@ -120,22 +115,22 @@ impl Display for DrmNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoRawFd for DrmNode {
|
impl IntoRawFd for DrmNode {
|
||||||
fn into_raw_fd(mut self) -> RawFd {
|
fn into_raw_fd(self) -> RawFd {
|
||||||
self.fd.take().unwrap()
|
let fd = self.fd;
|
||||||
|
mem::forget(self);
|
||||||
|
fd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsRawFd for DrmNode {
|
impl AsRawFd for DrmNode {
|
||||||
fn as_raw_fd(&self) -> RawFd {
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
self.fd.unwrap()
|
self.fd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for DrmNode {
|
impl Drop for DrmNode {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(fd) = self.fd {
|
let _ = close(self.fd);
|
||||||
let _ = close(fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,15 @@ impl DnDGrab {
|
||||||
impl PointerGrab for DnDGrab {
|
impl PointerGrab for DnDGrab {
|
||||||
fn motion(
|
fn motion(
|
||||||
&mut self,
|
&mut self,
|
||||||
_handle: &mut PointerInnerHandle<'_>,
|
handle: &mut PointerInnerHandle<'_>,
|
||||||
location: Point<f64, Logical>,
|
location: Point<f64, Logical>,
|
||||||
focus: Option<(wl_surface::WlSurface, Point<i32, Logical>)>,
|
focus: Option<(wl_surface::WlSurface, Point<i32, Logical>)>,
|
||||||
serial: Serial,
|
serial: Serial,
|
||||||
time: u32,
|
time: u32,
|
||||||
) {
|
) {
|
||||||
|
// While the grab is active, no client has pointer focus
|
||||||
|
handle.motion(location, None, serial, time);
|
||||||
|
|
||||||
let seat_data = self
|
let seat_data = self
|
||||||
.seat
|
.seat
|
||||||
.user_data()
|
.user_data()
|
||||||
|
@ -209,7 +212,9 @@ impl PointerGrab for DnDGrab {
|
||||||
source.cancelled();
|
source.cancelled();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&mut *self.callback.borrow_mut())(super::DataDeviceEvent::DnDDropped);
|
(&mut *self.callback.borrow_mut())(super::DataDeviceEvent::DnDDropped {
|
||||||
|
seat: self.seat.clone(),
|
||||||
|
});
|
||||||
self.icon = None;
|
self.icon = None;
|
||||||
// in all cases abandon the drop
|
// in all cases abandon the drop
|
||||||
// no more buttons are pressed, release the grab
|
// no more buttons are pressed, release the grab
|
||||||
|
|
|
@ -88,13 +88,18 @@ pub enum DataDeviceEvent {
|
||||||
/// The icon the client requested to be used to be associated with the cursor icon
|
/// The icon the client requested to be used to be associated with the cursor icon
|
||||||
/// during the drag'n'drop.
|
/// during the drag'n'drop.
|
||||||
icon: Option<wl_surface::WlSurface>,
|
icon: Option<wl_surface::WlSurface>,
|
||||||
|
/// The seat on which the DnD operation was started
|
||||||
|
seat: Seat,
|
||||||
},
|
},
|
||||||
/// The drag'n'drop action was finished by the user releasing the buttons
|
/// The drag'n'drop action was finished by the user releasing the buttons
|
||||||
///
|
///
|
||||||
/// At this point, any pointer icon should be removed.
|
/// At this point, any pointer icon should be removed.
|
||||||
///
|
///
|
||||||
/// Note that this event will only be generated for client-initiated drag'n'drop session.
|
/// Note that this event will only be generated for client-initiated drag'n'drop session.
|
||||||
DnDDropped,
|
DnDDropped {
|
||||||
|
/// The seat on which the DnD action was finished.
|
||||||
|
seat: Seat,
|
||||||
|
},
|
||||||
/// A client requested to read the server-set selection
|
/// A client requested to read the server-set selection
|
||||||
SendSelection {
|
SendSelection {
|
||||||
/// the requested mime type
|
/// the requested mime type
|
||||||
|
@ -356,6 +361,7 @@ pub fn start_dnd<C>(
|
||||||
Rc::new(RefCell::new(callback)),
|
Rc::new(RefCell::new(callback)),
|
||||||
),
|
),
|
||||||
serial,
|
serial,
|
||||||
|
0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,6 +451,7 @@ where
|
||||||
(&mut *callback.borrow_mut())(DataDeviceEvent::DnDStarted {
|
(&mut *callback.borrow_mut())(DataDeviceEvent::DnDStarted {
|
||||||
source: source.clone(),
|
source: source.clone(),
|
||||||
icon: icon.clone(),
|
icon: icon.clone(),
|
||||||
|
seat: seat.clone(),
|
||||||
});
|
});
|
||||||
let start_data = pointer.grab_start_data().unwrap();
|
let start_data = pointer.grab_start_data().unwrap();
|
||||||
pointer.set_grab(
|
pointer.set_grab(
|
||||||
|
@ -457,6 +464,7 @@ where
|
||||||
callback.clone(),
|
callback.clone(),
|
||||||
),
|
),
|
||||||
serial,
|
serial,
|
||||||
|
0,
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,76 @@ impl PointerInternal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_grab<G: PointerGrab + 'static>(&mut self, serial: Serial, grab: G, time: u32) {
|
||||||
|
self.grab = GrabStatus::Active(serial, Box::new(grab));
|
||||||
|
// generate a move to let the grab change the focus or move the pointer as result of its initialization
|
||||||
|
let location = self.location;
|
||||||
|
let focus = self.focus.clone();
|
||||||
|
self.motion(location, focus, serial, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unset_grab(&mut self, serial: Serial, time: u32) {
|
||||||
|
self.grab = GrabStatus::None;
|
||||||
|
// restore the focus
|
||||||
|
let location = self.location;
|
||||||
|
let focus = self.pending_focus.clone();
|
||||||
|
self.motion(location, focus, serial, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn motion(
|
||||||
|
&mut self,
|
||||||
|
location: Point<f64, Logical>,
|
||||||
|
focus: Option<(WlSurface, Point<i32, Logical>)>,
|
||||||
|
serial: Serial,
|
||||||
|
time: u32,
|
||||||
|
) {
|
||||||
|
// do we leave a surface ?
|
||||||
|
let mut leave = true;
|
||||||
|
self.location = location;
|
||||||
|
if let Some((ref current_focus, _)) = self.focus {
|
||||||
|
if let Some((ref surface, _)) = focus {
|
||||||
|
if current_focus.as_ref().equals(surface.as_ref()) {
|
||||||
|
leave = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if leave {
|
||||||
|
self.with_focused_pointers(|pointer, surface| {
|
||||||
|
pointer.leave(serial.into(), surface);
|
||||||
|
if pointer.as_ref().version() >= 5 {
|
||||||
|
pointer.frame();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.focus = None;
|
||||||
|
(self.image_callback)(CursorImageStatus::Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
// do we enter one ?
|
||||||
|
if let Some((surface, surface_location)) = focus {
|
||||||
|
let entered = self.focus.is_none();
|
||||||
|
// in all cases, update the focus, the coordinates of the surface
|
||||||
|
// might have changed
|
||||||
|
self.focus = Some((surface, surface_location));
|
||||||
|
let (x, y) = (location - surface_location.to_f64()).into();
|
||||||
|
if entered {
|
||||||
|
self.with_focused_pointers(|pointer, surface| {
|
||||||
|
pointer.enter(serial.into(), surface, x, y);
|
||||||
|
if pointer.as_ref().version() >= 5 {
|
||||||
|
pointer.frame();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// we were on top of a surface and remained on it
|
||||||
|
self.with_focused_pointers(|pointer, _| {
|
||||||
|
pointer.motion(time, x, y);
|
||||||
|
if pointer.as_ref().version() >= 5 {
|
||||||
|
pointer.frame();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn with_focused_pointers<F>(&self, mut f: F)
|
fn with_focused_pointers<F>(&self, mut f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(&WlPointer, &WlSurface),
|
F: FnMut(&WlPointer, &WlSurface),
|
||||||
|
@ -160,13 +230,13 @@ impl PointerHandle {
|
||||||
/// Change the current grab on this pointer to the provided grab
|
/// Change the current grab on this pointer to the provided grab
|
||||||
///
|
///
|
||||||
/// Overwrites any current grab.
|
/// Overwrites any current grab.
|
||||||
pub fn set_grab<G: PointerGrab + 'static>(&self, grab: G, serial: Serial) {
|
pub fn set_grab<G: PointerGrab + 'static>(&self, grab: G, serial: Serial, time: u32) {
|
||||||
self.inner.borrow_mut().grab = GrabStatus::Active(serial, Box::new(grab));
|
self.inner.borrow_mut().set_grab(serial, grab, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove any current grab on this pointer, resetting it to the default behavior
|
/// Remove any current grab on this pointer, resetting it to the default behavior
|
||||||
pub fn unset_grab(&self) {
|
pub fn unset_grab(&self, serial: Serial, time: u32) {
|
||||||
self.inner.borrow_mut().grab = GrabStatus::None;
|
self.inner.borrow_mut().unset_grab(serial, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if this pointer is currently grabbed with this serial
|
/// Check if this pointer is currently grabbed with this serial
|
||||||
|
@ -283,6 +353,13 @@ pub struct GrabStartData {
|
||||||
/// rather than trying to guess when the grab will end.
|
/// rather than trying to guess when the grab will end.
|
||||||
pub trait PointerGrab {
|
pub trait PointerGrab {
|
||||||
/// A motion was reported
|
/// A motion was reported
|
||||||
|
///
|
||||||
|
/// This method allows you attach additional behavior to a motion event, possibly altering it.
|
||||||
|
/// You generally will want to invoke `PointerInnerHandle::motion()` as part of your processing. If you
|
||||||
|
/// don't, the rest of the compositor will behave as if the motion event never occurred.
|
||||||
|
///
|
||||||
|
/// Some grabs (such as drag'n'drop, shell resize and motion) unset the focus while they are active,
|
||||||
|
/// this is achieved by just setting the focus to `None` when invoking `PointerInnerHandle::motion()`.
|
||||||
fn motion(
|
fn motion(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: &mut PointerInnerHandle<'_>,
|
handle: &mut PointerInnerHandle<'_>,
|
||||||
|
@ -292,6 +369,10 @@ pub trait PointerGrab {
|
||||||
time: u32,
|
time: u32,
|
||||||
);
|
);
|
||||||
/// A button press was reported
|
/// A button press was reported
|
||||||
|
///
|
||||||
|
/// This method allows you attach additional behavior to a button event, possibly altering it.
|
||||||
|
/// You generally will want to invoke `PointerInnerHandle::button()` as part of your processing. If you
|
||||||
|
/// don't, the rest of the compositor will behave as if the button event never occurred.
|
||||||
fn button(
|
fn button(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: &mut PointerInnerHandle<'_>,
|
handle: &mut PointerInnerHandle<'_>,
|
||||||
|
@ -301,6 +382,10 @@ pub trait PointerGrab {
|
||||||
time: u32,
|
time: u32,
|
||||||
);
|
);
|
||||||
/// An axis scroll was reported
|
/// An axis scroll was reported
|
||||||
|
///
|
||||||
|
/// This method allows you attach additional behavior to an axis event, possibly altering it.
|
||||||
|
/// You generally will want to invoke `PointerInnerHandle::axis()` as part of your processing. If you
|
||||||
|
/// don't, the rest of the compositor will behave as if the axis event never occurred.
|
||||||
fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame);
|
fn axis(&mut self, handle: &mut PointerInnerHandle<'_>, details: AxisFrame);
|
||||||
/// The data about the event that started the grab.
|
/// The data about the event that started the grab.
|
||||||
fn start_data(&self) -> &GrabStartData;
|
fn start_data(&self) -> &GrabStartData;
|
||||||
|
@ -317,19 +402,15 @@ impl<'a> PointerInnerHandle<'a> {
|
||||||
/// Change the current grab on this pointer to the provided grab
|
/// Change the current grab on this pointer to the provided grab
|
||||||
///
|
///
|
||||||
/// Overwrites any current grab.
|
/// Overwrites any current grab.
|
||||||
pub fn set_grab<G: PointerGrab + 'static>(&mut self, serial: Serial, grab: G) {
|
pub fn set_grab<G: PointerGrab + 'static>(&mut self, serial: Serial, grab: G, time: u32) {
|
||||||
self.inner.grab = GrabStatus::Active(serial, Box::new(grab));
|
self.inner.set_grab(serial, grab, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove any current grab on this pointer, resetting it to the default behavior
|
/// Remove any current grab on this pointer, resetting it to the default behavior
|
||||||
///
|
///
|
||||||
/// This will also restore the focus of the underlying pointer
|
/// This will also restore the focus of the underlying pointer
|
||||||
pub fn unset_grab(&mut self, serial: Serial, time: u32) {
|
pub fn unset_grab(&mut self, serial: Serial, time: u32) {
|
||||||
self.inner.grab = GrabStatus::None;
|
self.inner.unset_grab(serial, time);
|
||||||
// restore the focus
|
|
||||||
let location = self.current_location();
|
|
||||||
let focus = self.inner.pending_focus.clone();
|
|
||||||
self.motion(location, focus, serial, time);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Access the current focus of this pointer
|
/// Access the current focus of this pointer
|
||||||
|
@ -368,51 +449,7 @@ impl<'a> PointerInnerHandle<'a> {
|
||||||
serial: Serial,
|
serial: Serial,
|
||||||
time: u32,
|
time: u32,
|
||||||
) {
|
) {
|
||||||
// do we leave a surface ?
|
self.inner.motion(location, focus, serial, time);
|
||||||
let mut leave = true;
|
|
||||||
self.inner.location = location;
|
|
||||||
if let Some((ref current_focus, _)) = self.inner.focus {
|
|
||||||
if let Some((ref surface, _)) = focus {
|
|
||||||
if current_focus.as_ref().equals(surface.as_ref()) {
|
|
||||||
leave = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if leave {
|
|
||||||
self.inner.with_focused_pointers(|pointer, surface| {
|
|
||||||
pointer.leave(serial.into(), surface);
|
|
||||||
if pointer.as_ref().version() >= 5 {
|
|
||||||
pointer.frame();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
self.inner.focus = None;
|
|
||||||
(self.inner.image_callback)(CursorImageStatus::Default);
|
|
||||||
}
|
|
||||||
|
|
||||||
// do we enter one ?
|
|
||||||
if let Some((surface, surface_location)) = focus {
|
|
||||||
let entered = self.inner.focus.is_none();
|
|
||||||
// in all cases, update the focus, the coordinates of the surface
|
|
||||||
// might have changed
|
|
||||||
self.inner.focus = Some((surface, surface_location));
|
|
||||||
let (x, y) = (location - surface_location.to_f64()).into();
|
|
||||||
if entered {
|
|
||||||
self.inner.with_focused_pointers(|pointer, surface| {
|
|
||||||
pointer.enter(serial.into(), surface, x, y);
|
|
||||||
if pointer.as_ref().version() >= 5 {
|
|
||||||
pointer.frame();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
// we were on top of a surface and remained on it
|
|
||||||
self.inner.with_focused_pointers(|pointer, _| {
|
|
||||||
pointer.motion(time, x, y);
|
|
||||||
if pointer.as_ref().version() >= 5 {
|
|
||||||
pointer.frame();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Notify that a button was pressed
|
/// Notify that a button was pressed
|
||||||
|
@ -687,6 +724,7 @@ impl PointerGrab for DefaultGrab {
|
||||||
location: handle.current_location(),
|
location: handle.current_location(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
time,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue