Commit c1b89405f8fd
tarball5 files changed+52-3
@@ -2,6 +2,7 @@
22
//! into these calls, with pointer positions in global logical coordinates.33
44
use crate::state::{Input, State};5
+use crate::wm::Resizing;56
use monolith_layout::{Axis, Dir, Layout, MIN_FLOAT_SIZE, Rect, WindowId, clamp_float};67
use smithay::backend::input::{ButtonState, InputTime, KeyState};78
use smithay::backend::session::Session;@@ -55,6 +56,9 @@ impl State {
5556
.drag5657
.take_if(|d| d.button.is_none_or(|b| b == button));5758
if ended.is_some() {59
+ if self.wm.resizing.take().is_some() {60
+ self.apply_layout();61
+ }5862
let pos = self.input.pointer_pos;5963
let over = self.surface_under(pos).is_some();6064
self.input.hover = self.edge_at(pos, over).map(|(_, e)| e);@@ -551,6 +555,14 @@ fn begin_drag(state: &mut State, id: WindowId, edges: Option<Edges>, button: Opt
551555
) else {552556
return false;553557
};558
+ state.wm.resizing = win559
+ .output560
+ .filter(|_| edges.is_some())561
+ .map(|output| Resizing {562
+ output,563
+ window: id,564
+ tiled,565
+ });554566
state.input.drag = Some(Drag {555567
window: id,556568
from: state.input.pointer_pos,@@ -78,6 +78,7 @@ impl SessionLockHandler for State {
7878
self.services.lock.pending = Some(confirmation);7979
self.services.lock.blanked.clear();8080
self.input.drag = None;81
+ self.wm.resizing = None;8182
self.sync_focus();8283
self.dirty.redraw = true;8384
}@@ -47,7 +47,9 @@ pub fn build(
4747
anim,4848
windows,4949
last_frames,50
+ resizing,5051
} = wm.parts();52
+ let stretched = |w, tiled| resizing.is_some_and(|r| r.holds(w, tiled, o));5153
let Some(area) = layout.output(o).map(|out| out.area) else {5254
return Vec::new();5355
};@@ -82,13 +84,18 @@ pub fn build(
8284
Some(r) => above.push((p.window, local(r), true, true)),8385
None => {8486
let r = anim.tiled(o, p.window, now).unwrap_or(p.rect);85
- tiled.push((p.window, local(r), true, false));87
+ tiled.push((p.window, local(r), true, stretched(p.window, true)));8688
}8789
}8890
}8991
let float = |&(w, r): &(WindowId, Rect)| {9092
let glide = anim.gliding(w, now);91
- (w, local(glide.unwrap_or(r)), true, glide.is_some())93
+ (94
+ w,95
+ local(glide.unwrap_or(r)),96
+ true,97
+ glide.is_some() || stretched(w, false),98
+ )9299
};93100
let (over, under): (Vec<_>, Vec<_>) =94101
arr.floating.iter().partition(|f| arr.over.contains(&f.0));@@ -396,12 +396,20 @@ impl State {
396396
let mut mapped = Vec::new();397397
for (id, rect, kind, o) in shown {398398
let free = kind == Kind::Floating && self.wm.get(id).is_some_and(|s| s.natural_size);399
+ let held = self400
+ .wm401
+ .resizing402
+ .is_some_and(|r| r.holds(id, kind == Kind::Tiled, o))403
+ && rect.w >= 1.0404
+ && rect.h >= 1.0;399405
let scale = self400406
.backend401407
.output(o)402408
.map_or(1.0, |o| o.current_scale().fractional_scale());403409
if let Some(window) = self.wm.window(id).cloned()404
- && (free || configure(&window, rect, kind, self.wm.layout.maximized(id), scale))410
+ && (free411
+ || held412
+ || configure(&window, rect, kind, self.wm.layout.maximized(id), scale))405413
{406414
let loc = (rect.x.round() as i32, rect.y.round() as i32);407415
self.wm.space.map_element(window, loc, false);@@ -33,6 +33,24 @@ pub struct Wm {
3333
pub layer_focus: Option<WlSurface>,3434
/// What closed windows still show while their ghost animates.3535
pub last_frames: HashMap<WindowId, LastFrame>,36
+ pub resizing: Option<Resizing>,37
+}38
+39
+/// A mouse resize in progress. The windows it reshapes keep their size and40
+/// are drawn stretched until the button is released, rather than being sent41
+/// a configure for every motion event.42
+#[derive(Clone, Copy)]43
+pub struct Resizing {44
+ pub output: OutputId,45
+ pub window: WindowId,46
+ /// Moving a split reshapes every tile on the output, not just one.47
+ pub tiled: bool,48
+}49
+50
+impl Resizing {51
+ pub fn holds(&self, id: WindowId, tiled: bool, o: OutputId) -> bool {52
+ self.output == o && if self.tiled { tiled } else { id == self.window }53
+ }3654
}3755
3856
pub struct LastFrame {@@ -51,6 +69,7 @@ pub struct Parts<'a> {
5169
pub anim: &'a Animator,5270
pub windows: &'a mut SecondaryMap<WindowId, WindowState>,5371
pub last_frames: &'a HashMap<WindowId, LastFrame>,72
+ pub resizing: Option<Resizing>,5473
}5574
5675
pub struct WindowState {@@ -120,6 +139,7 @@ impl Wm {
120139
anim,121140
layer_focus: None,122141
last_frames: HashMap::new(),142
+ resizing: None,123143
}124144
}125145
@@ -211,6 +231,7 @@ impl Wm {
211231
anim: &self.anim,212232
windows: &mut self.windows,213233
last_frames: &self.last_frames,234
+ resizing: self.resizing,214235
}215236
}