mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-15 15:42:06 +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,
|
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 struct MoveSurfaceGrab<S: SeatHandler> {
|
||||||
pub start_data: GrabStartData<S>,
|
pub start_data: GrabStartData<S>,
|
||||||
|
@ -36,11 +40,47 @@ impl<B: Backend> PointerGrab<State<B>> for MoveSurfaceGrab<State<B>> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 delta = event.location - self.start_data.location;
|
||||||
let new_loc = self.initial_window_loc.to_f64() + delta;
|
let new_loc = self.initial_window_loc.to_f64() + delta;
|
||||||
data.space
|
data.space
|
||||||
.map_element(self.window.clone(), new_loc.to_i32_round(), true);
|
.map_element(self.window.clone(), new_loc.to_i32_round(), true);
|
||||||
data.focus_state.set_focus(self.window.clone());
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relative_motion(
|
fn relative_motion(
|
||||||
|
|
|
@ -379,14 +379,6 @@ impl<B: Backend> State<B> {
|
||||||
popup_manager: PopupManager::default(),
|
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> {
|
pub struct CalloopData<B: Backend> {
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
use smithay::{
|
use smithay::{
|
||||||
desktop::Window, reexports::wayland_server::protocol::wl_surface::WlSurface,
|
desktop::Window,
|
||||||
wayland::compositor,
|
reexports::wayland_server::protocol::wl_surface::WlSurface,
|
||||||
|
wayland::{compositor, seat::WaylandFocus},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{backend::Backend, layout::Layout, state::State};
|
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) {
|
pub fn toggle_floating<B: Backend>(state: &mut State<B>, window: &Window) {
|
||||||
WindowState::with_state(window, |window_state| {
|
WindowState::with_state(window, |window_state| {
|
||||||
match window_state.floating {
|
match window_state.floating {
|
||||||
|
|
Loading…
Reference in a new issue