mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2024-12-26 21:58:10 +01:00
Make tiled windows move like tiled windows
This commit is contained in:
parent
e701334538
commit
9df450843c
3 changed files with 80 additions and 17 deletions
|
@ -10,10 +10,14 @@ use smithay::{
|
|||
},
|
||||
SeatHandler,
|
||||
},
|
||||
utils::{IsAlive, Logical, Point},
|
||||
utils::{IsAlive, Logical, Point, Rectangle},
|
||||
};
|
||||
|
||||
use crate::{backend::Backend, state::State};
|
||||
use crate::{
|
||||
backend::Backend,
|
||||
state::State,
|
||||
window::window_state::{Float, WindowState},
|
||||
};
|
||||
|
||||
pub struct MoveSurfaceGrab<S: SeatHandler> {
|
||||
pub start_data: GrabStartData<S>,
|
||||
|
@ -36,11 +40,47 @@ impl<B: Backend> PointerGrab<State<B>> for MoveSurfaceGrab<State<B>> {
|
|||
return;
|
||||
}
|
||||
|
||||
let delta = event.location - self.start_data.location;
|
||||
let new_loc = self.initial_window_loc.to_f64() + delta;
|
||||
data.space
|
||||
.map_element(self.window.clone(), new_loc.to_i32_round(), true);
|
||||
data.focus_state.set_focus(self.window.clone());
|
||||
let tiled = WindowState::with_state(&self.window, |state| {
|
||||
matches!(state.floating, Float::Tiled(_))
|
||||
});
|
||||
|
||||
if tiled {
|
||||
let window_under = data
|
||||
.space
|
||||
.elements()
|
||||
.find(|&win| {
|
||||
if let Some(loc) = data.space.element_location(win) {
|
||||
let size = win.geometry().size;
|
||||
let rect = Rectangle { size, loc };
|
||||
rect.contains(event.location.to_i32_round())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
.cloned();
|
||||
|
||||
if let Some(window_under) = window_under {
|
||||
if window_under == self.window {
|
||||
return;
|
||||
}
|
||||
|
||||
let window_under_floating = WindowState::with_state(&window_under, |state| {
|
||||
matches!(state.floating, Float::Floating)
|
||||
});
|
||||
|
||||
if window_under_floating {
|
||||
return;
|
||||
}
|
||||
|
||||
tracing::info!("{:?}, {:?}", self.window.geometry(), self.window.bbox());
|
||||
data.swap_window_positions(&self.window, &window_under);
|
||||
}
|
||||
} else {
|
||||
let delta = event.location - self.start_data.location;
|
||||
let new_loc = self.initial_window_loc.to_f64() + delta;
|
||||
data.space
|
||||
.map_element(self.window.clone(), new_loc.to_i32_round(), true);
|
||||
}
|
||||
}
|
||||
|
||||
fn relative_motion(
|
||||
|
|
|
@ -379,14 +379,6 @@ impl<B: Backend> State<B> {
|
|||
popup_manager: PopupManager::default(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the [Window] associated with a given [WlSurface].
|
||||
pub fn window_for_surface(&self, surface: &WlSurface) -> Option<Window> {
|
||||
self.space
|
||||
.elements()
|
||||
.find(|window| window.wl_surface().map(|s| s == *surface).unwrap_or(false))
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CalloopData<B: Backend> {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use smithay::{
|
||||
desktop::Window, reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
wayland::compositor,
|
||||
desktop::Window,
|
||||
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||
wayland::{compositor, seat::WaylandFocus},
|
||||
};
|
||||
|
||||
use crate::{backend::Backend, layout::Layout, state::State};
|
||||
|
@ -26,6 +27,36 @@ pub trait SurfaceState: Default + 'static {
|
|||
}
|
||||
}
|
||||
|
||||
impl<B: Backend> State<B> {
|
||||
/// Returns the [Window] associated with a given [WlSurface].
|
||||
pub fn window_for_surface(&self, surface: &WlSurface) -> Option<Window> {
|
||||
self.space
|
||||
.elements()
|
||||
.find(|window| window.wl_surface().map(|s| s == *surface).unwrap_or(false))
|
||||
.cloned()
|
||||
}
|
||||
|
||||
pub fn swap_window_positions(&mut self, win1: &Window, win2: &Window) {
|
||||
let win1_loc = self.space.element_location(win1).unwrap(); // TODO: handle unwraps
|
||||
let win2_loc = self.space.element_location(win2).unwrap();
|
||||
let win1_geo = self.space.element_geometry(win1).unwrap();
|
||||
let win2_geo = self.space.element_geometry(win2).unwrap();
|
||||
|
||||
win1.toplevel().with_pending_state(|state| {
|
||||
state.size = Some(win2_geo.size);
|
||||
});
|
||||
win2.toplevel().with_pending_state(|state| {
|
||||
state.size = Some(win1_geo.size);
|
||||
});
|
||||
|
||||
self.space.map_element(win1.clone(), win2_loc, false);
|
||||
self.space.map_element(win2.clone(), win1_loc, false);
|
||||
|
||||
win1.toplevel().send_pending_configure();
|
||||
win2.toplevel().send_pending_configure();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &Window) {
|
||||
WindowState::with_state(window, |window_state| {
|
||||
match window_state.floating {
|
||||
|
|
Loading…
Reference in a new issue