Don't pass pointer button events to client when moving or resizing
This commit is contained in:
parent
3c24934f48
commit
66695482d0
2 changed files with 90 additions and 49 deletions
131
src/input/mod.rs
131
src/input/mod.rs
|
|
@ -78,6 +78,7 @@ use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
cell::RefCell,
|
cell::RefCell,
|
||||||
|
collections::HashSet,
|
||||||
os::unix::process::CommandExt,
|
os::unix::process::CommandExt,
|
||||||
thread,
|
thread,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
|
|
@ -87,6 +88,8 @@ pub mod gestures;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct SupressedKeys(RefCell<Vec<(Keycode, Option<RegistrationToken>)>>);
|
pub struct SupressedKeys(RefCell<Vec<(Keycode, Option<RegistrationToken>)>>);
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct SupressedButtons(RefCell<HashSet<u32>>);
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct ModifiersShortcutQueue(RefCell<Option<shortcuts::Binding>>);
|
pub struct ModifiersShortcutQueue(RefCell<Option<shortcuts::Binding>>);
|
||||||
|
|
||||||
|
|
@ -116,6 +119,16 @@ impl SupressedKeys {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SupressedButtons {
|
||||||
|
fn add(&self, button: u32) {
|
||||||
|
self.0.borrow_mut().insert(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remove(&self, button: u32) -> bool {
|
||||||
|
self.0.borrow_mut().remove(&button)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ModifiersShortcutQueue {
|
impl ModifiersShortcutQueue {
|
||||||
pub fn set(&self, binding: shortcuts::Binding) {
|
pub fn set(&self, binding: shortcuts::Binding) {
|
||||||
let mut set = self.0.borrow_mut();
|
let mut set = self.0.borrow_mut();
|
||||||
|
|
@ -773,6 +786,7 @@ impl State {
|
||||||
|
|
||||||
let serial = SERIAL_COUNTER.next_serial();
|
let serial = SERIAL_COUNTER.next_serial();
|
||||||
let button = event.button_code();
|
let button = event.button_code();
|
||||||
|
let mut pass_event = !seat.supressed_buttons().remove(button);
|
||||||
if event.state() == ButtonState::Pressed {
|
if event.state() == ButtonState::Pressed {
|
||||||
// change the keyboard focus unless the pointer is grabbed
|
// change the keyboard focus unless the pointer is grabbed
|
||||||
// We test for any matching surface type here but always use the root
|
// We test for any matching surface type here but always use the root
|
||||||
|
|
@ -850,35 +864,45 @@ impl State {
|
||||||
target.toplevel().map(Cow::into_owned)
|
target.toplevel().map(Cow::into_owned)
|
||||||
{
|
{
|
||||||
let seat_clone = seat.clone();
|
let seat_clone = seat.clone();
|
||||||
let button = PointerButtonEvent::button(&event);
|
let mouse_button =
|
||||||
self.common.event_loop_handle.insert_idle(
|
PointerButtonEvent::button(&event);
|
||||||
move |state| {
|
|
||||||
fn dispatch_grab<G: PointerGrab<State> + 'static>(
|
|
||||||
grab: Option<(G, smithay::input::pointer::Focus)>,
|
|
||||||
seat: Seat<State>,
|
|
||||||
serial: Serial,
|
|
||||||
state: &mut State)
|
|
||||||
{
|
|
||||||
if let Some((target, focus)) = grab {
|
|
||||||
seat
|
|
||||||
.modifiers_shortcut_queue()
|
|
||||||
.clear();
|
|
||||||
|
|
||||||
seat
|
let mut supress_button = || {
|
||||||
.get_pointer()
|
// If the logo is held then the pointer event is
|
||||||
.unwrap()
|
// aimed at the compositor and shouldn't be passed
|
||||||
.set_grab(
|
// to the application.
|
||||||
state, target, serial,
|
pass_event = false;
|
||||||
focus,
|
seat.supressed_buttons().add(button);
|
||||||
);
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut shell =
|
fn dispatch_grab<
|
||||||
state.common.shell.write().unwrap();
|
G: PointerGrab<State> + 'static,
|
||||||
if let Some(button) = button {
|
>(
|
||||||
match button {
|
grab: Option<(
|
||||||
smithay::backend::input::MouseButton::Left => {
|
G,
|
||||||
|
smithay::input::pointer::Focus,
|
||||||
|
)>,
|
||||||
|
seat: Seat<State>,
|
||||||
|
serial: Serial,
|
||||||
|
state: &mut State,
|
||||||
|
) {
|
||||||
|
if let Some((target, focus)) = grab {
|
||||||
|
seat.modifiers_shortcut_queue().clear();
|
||||||
|
|
||||||
|
seat.get_pointer()
|
||||||
|
.unwrap()
|
||||||
|
.set_grab(state, target, serial, focus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mouse_button) = mouse_button {
|
||||||
|
match mouse_button {
|
||||||
|
smithay::backend::input::MouseButton::Left => {
|
||||||
|
supress_button();
|
||||||
|
self.common.event_loop_handle.insert_idle(
|
||||||
|
move |state| {
|
||||||
|
let mut shell =
|
||||||
|
state.common.shell.write().unwrap();
|
||||||
let res = shell.move_request(
|
let res = shell.move_request(
|
||||||
&surface,
|
&surface,
|
||||||
&seat_clone,
|
&seat_clone,
|
||||||
|
|
@ -888,12 +912,19 @@ impl State {
|
||||||
&state.common.config,
|
&state.common.config,
|
||||||
&state.common.event_loop_handle,
|
&state.common.event_loop_handle,
|
||||||
&state.common.xdg_activation_state,
|
&state.common.xdg_activation_state,
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
drop(shell);
|
drop(shell);
|
||||||
dispatch_grab(res, seat_clone, serial, state);
|
dispatch_grab(res, seat_clone, serial, state);
|
||||||
},
|
}
|
||||||
smithay::backend::input::MouseButton::Right => {
|
);
|
||||||
|
},
|
||||||
|
smithay::backend::input::MouseButton::Right => {
|
||||||
|
supress_button();
|
||||||
|
self.common.event_loop_handle.insert_idle(
|
||||||
|
move |state| {
|
||||||
|
let mut shell =
|
||||||
|
state.common.shell.write().unwrap();
|
||||||
let Some(target_elem) = shell.element_for_surface(&surface) else { return };
|
let Some(target_elem) = shell.element_for_surface(&surface) else { return };
|
||||||
let Some(geom) = shell
|
let Some(geom) = shell
|
||||||
.space_for(target_elem)
|
.space_for(target_elem)
|
||||||
|
|
@ -912,17 +943,16 @@ impl State {
|
||||||
&seat_clone,
|
&seat_clone,
|
||||||
serial,
|
serial,
|
||||||
edge,
|
edge,
|
||||||
false
|
false,
|
||||||
);
|
);
|
||||||
drop(shell);
|
drop(shell);
|
||||||
dispatch_grab(res, seat_clone, serial, state);
|
dispatch_grab(res, seat_clone, serial, state);
|
||||||
},
|
}
|
||||||
_ => {},
|
);
|
||||||
}
|
},
|
||||||
|
_ => {},
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
under = Some(target);
|
under = Some(target);
|
||||||
|
|
@ -971,20 +1001,25 @@ impl State {
|
||||||
.set_overview_mode(None, self.common.event_loop_handle.clone());
|
.set_overview_mode(None, self.common.event_loop_handle.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mem::drop(shell);
|
std::mem::drop(shell);
|
||||||
};
|
};
|
||||||
|
|
||||||
let ptr = seat.get_pointer().unwrap();
|
let ptr = seat.get_pointer().unwrap();
|
||||||
ptr.button(
|
if pass_event {
|
||||||
self,
|
ptr.button(
|
||||||
&ButtonEvent {
|
self,
|
||||||
button,
|
&ButtonEvent {
|
||||||
state: event.state(),
|
button,
|
||||||
serial,
|
state: event.state(),
|
||||||
time: event.time_msec(),
|
serial,
|
||||||
},
|
time: event.time_msec(),
|
||||||
);
|
},
|
||||||
ptr.frame(self);
|
);
|
||||||
|
ptr.frame(self);
|
||||||
|
} else if event.state() == ButtonState::Released {
|
||||||
|
ptr.unset_grab(self, serial, event.time_msec())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InputEvent::PointerAxis { event, .. } => {
|
InputEvent::PointerAxis { event, .. } => {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ use std::{any::Any, cell::RefCell, collections::HashMap, sync::Mutex, time::Dura
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::render::cursor::{CursorShape, CursorState},
|
backend::render::cursor::{CursorShape, CursorState},
|
||||||
config::{xkb_config_to_wl, Config},
|
config::{xkb_config_to_wl, Config},
|
||||||
input::{ModifiersShortcutQueue, SupressedKeys},
|
input::{ModifiersShortcutQueue, SupressedButtons, SupressedKeys},
|
||||||
state::State,
|
state::State,
|
||||||
};
|
};
|
||||||
use smithay::{
|
use smithay::{
|
||||||
|
|
@ -169,6 +169,7 @@ pub fn create_seat(
|
||||||
userdata.insert_if_missing_threadsafe(SeatId::default);
|
userdata.insert_if_missing_threadsafe(SeatId::default);
|
||||||
userdata.insert_if_missing(Devices::default);
|
userdata.insert_if_missing(Devices::default);
|
||||||
userdata.insert_if_missing(SupressedKeys::default);
|
userdata.insert_if_missing(SupressedKeys::default);
|
||||||
|
userdata.insert_if_missing(SupressedButtons::default);
|
||||||
userdata.insert_if_missing(ModifiersShortcutQueue::default);
|
userdata.insert_if_missing(ModifiersShortcutQueue::default);
|
||||||
userdata.insert_if_missing_threadsafe(SeatMoveGrabState::default);
|
userdata.insert_if_missing_threadsafe(SeatMoveGrabState::default);
|
||||||
userdata.insert_if_missing_threadsafe(SeatMenuGrabState::default);
|
userdata.insert_if_missing_threadsafe(SeatMenuGrabState::default);
|
||||||
|
|
@ -215,6 +216,7 @@ pub trait SeatExt {
|
||||||
fn set_active_output(&self, output: &Output);
|
fn set_active_output(&self, output: &Output);
|
||||||
fn devices(&self) -> &Devices;
|
fn devices(&self) -> &Devices;
|
||||||
fn supressed_keys(&self) -> &SupressedKeys;
|
fn supressed_keys(&self) -> &SupressedKeys;
|
||||||
|
fn supressed_buttons(&self) -> &SupressedButtons;
|
||||||
fn modifiers_shortcut_queue(&self) -> &ModifiersShortcutQueue;
|
fn modifiers_shortcut_queue(&self) -> &ModifiersShortcutQueue;
|
||||||
|
|
||||||
fn cursor_geometry(
|
fn cursor_geometry(
|
||||||
|
|
@ -254,6 +256,10 @@ impl SeatExt for Seat<State> {
|
||||||
self.user_data().get::<SupressedKeys>().unwrap()
|
self.user_data().get::<SupressedKeys>().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supressed_buttons(&self) -> &SupressedButtons {
|
||||||
|
self.user_data().get::<SupressedButtons>().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
fn modifiers_shortcut_queue(&self) -> &ModifiersShortcutQueue {
|
fn modifiers_shortcut_queue(&self) -> &ModifiersShortcutQueue {
|
||||||
self.user_data().get::<ModifiersShortcutQueue>().unwrap()
|
self.user_data().get::<ModifiersShortcutQueue>().unwrap()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue