Move and resize floating windows with the Super button
This commit is contained in:
1 parent
a597d09a7a
commit
4b70cb40e0
1 file changed
+104
-4
+104
-4
@@ -11,12 +11,16 @@ use smithay::{
|
|||||||
input::{
|
input::{
|
||||||
keyboard::{FilterResult, keysyms},
|
keyboard::{FilterResult, keysyms},
|
||||||
pointer::{
|
pointer::{
|
||||||
AxisFrame, ButtonEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent,
|
AxisFrame, ButtonEvent, Focus, GestureSwipeBeginEvent, GestureSwipeEndEvent,
|
||||||
GestureSwipeUpdateEvent, MotionEvent, PointerHandle, RelativeMotionEvent,
|
GestureSwipeUpdateEvent, GrabStartData, MotionEvent, PointerHandle,
|
||||||
|
RelativeMotionEvent,
|
||||||
},
|
},
|
||||||
touch::{DownEvent, MotionEvent as TouchMotionEvent, UpEvent},
|
touch::{DownEvent, MotionEvent as TouchMotionEvent, UpEvent},
|
||||||
},
|
},
|
||||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
reexports::{
|
||||||
|
wayland_protocols::xdg::shell::server::xdg_toplevel::ResizeEdge as XdgResizeEdge,
|
||||||
|
wayland_server::protocol::wl_surface::WlSurface,
|
||||||
|
},
|
||||||
utils::{Logical, Point, SERIAL_COUNTER, Serial},
|
utils::{Logical, Point, SERIAL_COUNTER, Serial},
|
||||||
wayland::{
|
wayland::{
|
||||||
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat,
|
keyboard_shortcuts_inhibit::KeyboardShortcutsInhibitorSeat,
|
||||||
@@ -24,7 +28,14 @@ use smithay::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Ferese, config::BindingAction};
|
use crate::{
|
||||||
|
Ferese,
|
||||||
|
config::BindingAction,
|
||||||
|
grabs::{MoveSurfaceGrab, ResizeEdge, ResizeSurfaceGrab},
|
||||||
|
};
|
||||||
|
|
||||||
|
const BTN_LEFT: u32 = 0x110;
|
||||||
|
const BTN_RIGHT: u32 = 0x111;
|
||||||
|
|
||||||
impl Ferese {
|
impl Ferese {
|
||||||
pub fn process_input_event<I: InputBackend>(&mut self, event: InputEvent<I>) {
|
pub fn process_input_event<I: InputBackend>(&mut self, event: InputEvent<I>) {
|
||||||
@@ -336,6 +347,22 @@ impl Ferese {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if event.state() == ButtonState::Pressed
|
||||||
|
&& self.start_floating_pointer_grab(&pointer, event.button_code(), serial)
|
||||||
|
{
|
||||||
|
pointer.button(
|
||||||
|
self,
|
||||||
|
&ButtonEvent {
|
||||||
|
button: event.button_code(),
|
||||||
|
state: event.state(),
|
||||||
|
serial,
|
||||||
|
time: event.time() as u32,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
pointer.frame(self);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if event.state() == ButtonState::Pressed && !pointer.is_grabbed() {
|
if event.state() == ButtonState::Pressed && !pointer.is_grabbed() {
|
||||||
self.focus_window_at(pointer.current_location(), serial, true);
|
self.focus_window_at(pointer.current_location(), serial, true);
|
||||||
}
|
}
|
||||||
@@ -457,6 +484,79 @@ impl Ferese {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn start_floating_pointer_grab(
|
||||||
|
&mut self,
|
||||||
|
pointer: &PointerHandle<Self>,
|
||||||
|
button: u32,
|
||||||
|
serial: Serial,
|
||||||
|
) -> bool {
|
||||||
|
if self.session_lock.active
|
||||||
|
|| pointer.is_grabbed()
|
||||||
|
|| !matches!(button, BTN_LEFT | BTN_RIGHT)
|
||||||
|
|| !self
|
||||||
|
.seat
|
||||||
|
.get_keyboard()
|
||||||
|
.is_some_and(|keyboard| keyboard.modifier_state().logo)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let location = pointer.current_location();
|
||||||
|
if self.layer_under(location).is_some() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let Some(window) = self.window_under_visual(location) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
if !self.is_floating_window(&window) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let Some(rect) = self.visual_rect_for_window(&window) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.focus_window_at(location, serial, true);
|
||||||
|
let start_data = GrabStartData {
|
||||||
|
focus: None,
|
||||||
|
button,
|
||||||
|
location,
|
||||||
|
};
|
||||||
|
|
||||||
|
if button == BTN_LEFT {
|
||||||
|
pointer.set_grab(
|
||||||
|
self,
|
||||||
|
MoveSurfaceGrab {
|
||||||
|
start_data,
|
||||||
|
window,
|
||||||
|
initial_location: rect.loc,
|
||||||
|
initial_size: rect.size,
|
||||||
|
finished: false,
|
||||||
|
},
|
||||||
|
serial,
|
||||||
|
Focus::Clear,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
let horizontal_right =
|
||||||
|
location.x >= f64::from(rect.loc.x) + f64::from(rect.size.w) / 2.0;
|
||||||
|
let vertical_bottom =
|
||||||
|
location.y >= f64::from(rect.loc.y) + f64::from(rect.size.h) / 2.0;
|
||||||
|
let edge = match (horizontal_right, vertical_bottom) {
|
||||||
|
(false, false) => XdgResizeEdge::TopLeft,
|
||||||
|
(true, false) => XdgResizeEdge::TopRight,
|
||||||
|
(false, true) => XdgResizeEdge::BottomLeft,
|
||||||
|
(true, true) => XdgResizeEdge::BottomRight,
|
||||||
|
};
|
||||||
|
pointer.set_grab(
|
||||||
|
self,
|
||||||
|
ResizeSurfaceGrab::new(start_data, window, ResizeEdge::from(edge), rect),
|
||||||
|
serial,
|
||||||
|
Focus::Clear,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn absolute_event_position<I, E>(&self, event: &E) -> Option<Point<f64, Logical>>
|
fn absolute_event_position<I, E>(&self, event: &E) -> Option<Point<f64, Logical>>
|
||||||
where
|
where
|
||||||
I: InputBackend,
|
I: InputBackend,
|
||||||
|
|||||||
Reference in new issue
Block a user