Commit 7caafe71a560
tarball1 file changed+58-31
@@ -3,7 +3,7 @@
33
44
use crate::state::{Input, State};55
use crate::wm::Resizing;6
-use monolith_layout::{Dir, Layout, MIN_FLOAT_SIZE, Rect, WindowId, clamp_float};6
+use monolith_layout::{Dir, Layout, MIN_FLOAT_SIZE, OutputId, Rect, WindowId, clamp_float};77
use smithay::input::pointer::CursorIcon;88
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;99
use smithay::utils::{Logical, Point};@@ -159,6 +159,8 @@ pub struct Drag {
159159
bounds: Rect,160160
/// A tiled window, whose splits follow the pointer instead of a rect.161161
tiled: bool,162
+ /// A scratchpad, which is always centred so a resize grows both sides.163
+ centred: bool,162164
/// None moves the window.163165
edges: Option<Edges>,164166
/// The button the drag started with, whose release ends it.@@ -275,8 +277,24 @@ pub(crate) fn start_drag(state: &mut State, button: u32) -> bool {
275277
begin_drag(state, id, edges, button, false)276278
}277279
280
+/// The output a window sits on, which for a scratchpad is wherever it is shown.281
+fn output_of(layout: &Layout, id: WindowId) -> Option<OutputId> {282
+ let win = layout.window(id)?;283
+ win.scratchpad284
+ .and_then(|s| layout.scratchpads().get(s)?.output)285
+ .or(win.output)286
+}287
+278288
fn window_rect(layout: &Layout, id: WindowId) -> Option<Rect> {279289
let win = layout.window(id)?;290
+ if win.scratchpad.is_some() {291
+ return layout292
+ .arrange(output_of(layout, id)?)293
+ .floating294
+ .iter()295
+ .find(|f| f.0 == id)296
+ .map(|f| f.1);297
+ }280298
if win.floating {281299
return win.float_rect;282300
}@@ -320,29 +338,27 @@ fn begin_drag(
320338
} else {321339
edges322340
};323
- if tiled && edges.is_none() {341
+ let centred = win.scratchpad.is_some();342
+ if (tiled || centred) && edges.is_none() {324343
return false;325344
}326
- let (Some(rect), Some(out)) = (327
- window_rect(layout, id),328
- win.output.and_then(|o| layout.output(o)),329
- ) else {345
+ let home = output_of(layout, id);346
+ let (Some(rect), Some(out)) = (window_rect(layout, id), home.and_then(|o| layout.output(o)))347
+ else {330348
return false;331349
};332
- state.wm.resizing = win333
- .output334
- .filter(|_| edges.is_some())335
- .map(|output| Resizing {336
- output,337
- window: id,338
- tiled,339
- });350
+ state.wm.resizing = home.filter(|_| edges.is_some()).map(|output| Resizing {351
+ output,352
+ window: id,353
+ tiled,354
+ });340355
state.input.drag = Some(Drag {341356
window: id,342357
from: state.input.pointer_pos,343358
rect,344359
bounds: out.usable(),345360
tiled,361
+ centred,346362
edges,347363
button,348364
client,@@ -413,23 +429,34 @@ pub(crate) fn drag_to(state: &mut State, pos: Point<f64, Logical>) -> bool {
413429
r.clamp_size(f64::INFINITY, f64::INFINITY)414430
});415431
let min = (min_w.max(MIN_FLOAT_SIZE), min_h.max(MIN_FLOAT_SIZE));416
- let (x, w) = resized(417
- r.x,418
- r.w,419
- dx,420
- (e.left, e.right),421
- (b.x, b.right()),422
- (min.0, max_w),423
- );424
- let (y, h) = resized(425
- r.y,426
- r.h,427
- dy,428
- (e.top, e.bottom),429
- (b.y, b.bottom()),430
- (min.1, max_h),431
- );432
- Rect::new(x, y, w, h)432
+ if d.centred {433
+ let both = (f64::NEG_INFINITY, f64::INFINITY);434
+ let grown = |start, len, delta, edges, limits: (f64, f64), room: f64| {435
+ let (_, len) = resized(start, len, 2.0 * delta, edges, both, limits);436
+ len.min(room).max(limits.0)437
+ };438
+ let w = grown(r.x, r.w, dx, (e.left, e.right), (min.0, max_w), b.w);439
+ let h = grown(r.y, r.h, dy, (e.top, e.bottom), (min.1, max_h), b.h);440
+ Rect::new(r.x + (r.w - w) / 2.0, r.y + (r.h - h) / 2.0, w, h)441
+ } else {442
+ let (x, w) = resized(443
+ r.x,444
+ r.w,445
+ dx,446
+ (e.left, e.right),447
+ (b.x, b.right()),448
+ (min.0, max_w),449
+ );450
+ let (y, h) = resized(451
+ r.y,452
+ r.h,453
+ dy,454
+ (e.top, e.bottom),455
+ (b.y, b.bottom()),456
+ (min.1, max_h),457
+ );458
+ Rect::new(x, y, w, h)459
+ }433460
}434461
None => clamp_float(Rect::new(r.x + dx, r.y + dy, r.w, r.h), d.bounds),435462
};