Compare commits

..

No commits in common. "6fc750369872f3cb3bfca720cdad0ed25ad8887e" and "d04a999bf810c59bfb85252c285ea55eefd5ca54" have entirely different histories.

8 changed files with 124 additions and 165 deletions

View File

@ -5,7 +5,6 @@ on:
branches: branches:
- master - master
pull_request: pull_request:
workflow_dispatch:
jobs: jobs:
format: format:

View File

@ -112,7 +112,18 @@ 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 => wl_pointer::ButtonState::Pressed, input::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());
@ -225,15 +236,7 @@ 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; let under = self.window_map.borrow().get_surface_under(pos);
// 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());
} }
} }
@ -355,18 +358,7 @@ 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; let under = self.window_map.borrow().get_surface_under(self.pointer_location);
// 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());
} }
@ -529,8 +521,9 @@ enum KeyAction {
} }
fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> Option<KeyAction> { fn process_keyboard_shortcut(modifiers: ModifiersState, keysym: Keysym) -> Option<KeyAction> {
let modkey = modifiers.ctrl; if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
if modkey && keysym == xkb::KEY_q { || modifiers.logo && keysym == xkb::KEY_q
{
// ctrl+alt+backspace = quit // ctrl+alt+backspace = quit
// logo + q = quit // logo + q = quit
Some(KeyAction::Quit) Some(KeyAction::Quit)
@ -539,14 +532,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 modkey && keysym == xkb::KEY_Return { } else if modifiers.logo && keysym == xkb::KEY_Return {
// run terminal // run terminal
Some(KeyAction::Run("alacritty".into())) Some(KeyAction::Run("weston-terminal".into()))
} else if modkey && keysym >= xkb::KEY_1 && keysym <= xkb::KEY_9 { } else if modifiers.logo && 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 modkey && modifiers.shift && keysym == xkb::KEY_M { } else if modifiers.logo && modifiers.shift && keysym == xkb::KEY_M {
Some(KeyAction::ScaleDown) Some(KeyAction::ScaleDown)
} else if modkey && modifiers.shift && keysym == xkb::KEY_P { } else if modifiers.logo && modifiers.shift && keysym == xkb::KEY_P {
Some(KeyAction::ScaleUp) Some(KeyAction::ScaleUp)
} else { } else {
None None

View File

@ -48,15 +48,12 @@ 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;
@ -155,9 +152,6 @@ 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;
@ -485,7 +479,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
initial_window_location, initial_window_location,
}; };
pointer.set_grab(grab, serial, 0); pointer.set_grab(grab, serial);
} }
XdgRequest::Resize { XdgRequest::Resize {
@ -545,7 +539,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, 0); pointer.set_grab(grab, serial);
} }
XdgRequest::AckConfigure { XdgRequest::AckConfigure {
@ -812,7 +806,7 @@ pub fn init_shell<BackendData: 'static>(display: Rc<RefCell<Display>>, log: ::sl
initial_window_location, initial_window_location,
}; };
pointer.set_grab(grab, serial, 0); pointer.set_grab(grab, serial);
} }
ShellRequest::Resize { ShellRequest::Resize {
@ -872,7 +866,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, 0); pointer.set_grab(grab, serial);
} }
_ => (), _ => (),
} }

View File

@ -10,6 +10,7 @@ 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},
@ -17,7 +18,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, shell::xdg::decoration::{init_xdg_decoration_manager, XdgDecorationRequest},
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},
@ -121,7 +122,25 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
log.clone(), log.clone(),
); );
init_xdg_decoration_manager(&mut display.borrow_mut(), |_, _| {}, log.clone()); init_xdg_decoration_manager(
&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
@ -148,7 +167,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;
} }
_ => {} _ => {}

View File

@ -7,7 +7,7 @@ use libc::dev_t;
use std::{ use std::{
fmt::{self, Display, Formatter}, fmt::{self, Display, Formatter},
fs, io, mem, fs, io,
os::unix::prelude::{AsRawFd, IntoRawFd, RawFd}, os::unix::prelude::{AsRawFd, IntoRawFd, RawFd},
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -20,7 +20,8 @@ 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 {
fd: RawFd, // Always `Some`, None variant is used when taking ownership
fd: Option<RawFd>,
dev: dev_t, dev: dev_t,
ty: NodeType, ty: NodeType,
} }
@ -55,7 +56,11 @@ impl DrmNode {
_ => return Err(CreateDrmNodeError::NotDrmNode), _ => return Err(CreateDrmNodeError::NotDrmNode),
}; };
Ok(DrmNode { fd, dev, ty }) Ok(DrmNode {
fd: Some(fd),
dev,
ty,
})
} }
/// Returns the type of the DRM node. /// Returns the type of the DRM node.
@ -115,22 +120,22 @@ impl Display for DrmNode {
} }
impl IntoRawFd for DrmNode { impl IntoRawFd for DrmNode {
fn into_raw_fd(self) -> RawFd { fn into_raw_fd(mut self) -> RawFd {
let fd = self.fd; self.fd.take().unwrap()
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 self.fd.unwrap()
} }
} }
impl Drop for DrmNode { impl Drop for DrmNode {
fn drop(&mut self) { fn drop(&mut self) {
let _ = close(self.fd); if let Some(fd) = self.fd {
let _ = close(fd);
}
} }
} }

View File

@ -53,15 +53,12 @@ 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()
@ -212,9 +209,7 @@ 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

View File

@ -88,18 +88,13 @@ 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
@ -361,7 +356,6 @@ pub fn start_dnd<C>(
Rc::new(RefCell::new(callback)), Rc::new(RefCell::new(callback)),
), ),
serial, serial,
0,
); );
} }
} }
@ -451,7 +445,6 @@ 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(
@ -464,7 +457,6 @@ where
callback.clone(), callback.clone(),
), ),
serial, serial,
0,
); );
return; return;
} }

View File

@ -91,76 +91,6 @@ 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),
@ -230,13 +160,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, time: u32) { pub fn set_grab<G: PointerGrab + 'static>(&self, grab: G, serial: Serial) {
self.inner.borrow_mut().set_grab(serial, grab, time); self.inner.borrow_mut().grab = GrabStatus::Active(serial, Box::new(grab));
} }
/// 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, serial: Serial, time: u32) { pub fn unset_grab(&self) {
self.inner.borrow_mut().unset_grab(serial, time); self.inner.borrow_mut().grab = GrabStatus::None;
} }
/// Check if this pointer is currently grabbed with this serial /// Check if this pointer is currently grabbed with this serial
@ -353,13 +283,6 @@ 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<'_>,
@ -369,10 +292,6 @@ 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<'_>,
@ -382,10 +301,6 @@ 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;
@ -402,15 +317,19 @@ 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, time: u32) { pub fn set_grab<G: PointerGrab + 'static>(&mut self, serial: Serial, grab: G) {
self.inner.set_grab(serial, grab, time); self.inner.grab = GrabStatus::Active(serial, Box::new(grab));
} }
/// 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.unset_grab(serial, time); self.inner.grab = GrabStatus::None;
// 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
@ -449,7 +368,51 @@ impl<'a> PointerInnerHandle<'a> {
serial: Serial, serial: Serial,
time: u32, time: u32,
) { ) {
self.inner.motion(location, focus, serial, time); // do we leave a surface ?
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
@ -724,7 +687,6 @@ impl PointerGrab for DefaultGrab {
location: handle.current_location(), location: handle.current_location(),
}, },
}, },
time,
); );
} }
} }