aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-06-11 21:04:49 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-06-12 08:56:52 +0300
commit2f18d8e32831a1e6000ca0d56dba05727088bb52 (patch)
treed04bf894e8e0ceb507db1bd36a5094fad8316e11 /src/ui
parent7aec37f5c97a2b38553472d786a95f8a7f4324fb (diff)
downloadniri-2f18d8e32831a1e6000ca0d56dba05727088bb52.tar.gz
niri-2f18d8e32831a1e6000ca0d56dba05727088bb52.tar.bz2
niri-2f18d8e32831a1e6000ca0d56dba05727088bb52.zip
Implement move-column/window-to-monitor actions for the screenshot UI
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/screenshot_ui.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/ui/screenshot_ui.rs b/src/ui/screenshot_ui.rs
index e3b0ee89..c87dc637 100644
--- a/src/ui/screenshot_ui.rs
+++ b/src/ui/screenshot_ui.rs
@@ -347,6 +347,75 @@ impl ScreenshotUi {
self.update_buffers();
}
+ /// Moves the screenshot selection to a different output.
+ ///
+ /// This preserves the relative position while keeping logical size. It is (intentionally) very
+ /// similar to how floating windows move across monitors, but with one difference: floating
+ /// windows can go partially outside the view, while the screenshot selection cannot. So, we
+ /// clamp it to new output bounds, trying to preserve the size if possible.
+ pub fn move_to_output(&mut self, new_output: Output) {
+ let Self::Open {
+ selection,
+ output_data,
+ ..
+ } = self
+ else {
+ return;
+ };
+
+ let (current_output, current_a, current_b) = selection;
+
+ if current_output == &new_output {
+ return;
+ }
+
+ let Some(target_data) = output_data.get(&new_output) else {
+ return;
+ };
+
+ let current_data = &output_data[current_output];
+
+ let current_rect: Rectangle<_, Physical> = Rectangle::new(
+ Point::from((current_a.x.min(current_b.x), current_a.y.min(current_b.y))),
+ Size::from((
+ (current_a.x.max(current_b.x) - current_a.x.min(current_b.x) + 1),
+ (current_a.y.max(current_b.y) - current_a.y.min(current_b.y) + 1),
+ )),
+ );
+ let current_rect = current_rect.to_f64();
+
+ let rel_x = current_rect.loc.x / current_data.size.w as f64;
+ let rel_y = current_rect.loc.y / current_data.size.h as f64;
+
+ let factor = target_data.scale / current_data.scale;
+ let mut new_width = (current_rect.size.w * factor).round() as i32;
+ let mut new_height = (current_rect.size.h * factor).round() as i32;
+
+ new_width = new_width.clamp(1, target_data.size.w);
+ new_height = new_height.clamp(1, target_data.size.h);
+
+ let new_x = (rel_x * target_data.size.w as f64).round() as i32;
+ let new_y = (rel_y * target_data.size.h as f64).round() as i32;
+
+ let max_x = target_data.size.w - new_width;
+ let max_y = target_data.size.h - new_height;
+ let new_x = new_x.clamp(0, max_x);
+ let new_y = new_y.clamp(0, max_y);
+
+ let new_rect = Rectangle::new(
+ Point::from((new_x, new_y)),
+ Size::from((new_width, new_height)),
+ );
+
+ *selection = (
+ new_output,
+ new_rect.loc,
+ new_rect.loc + new_rect.size - Size::from((1, 1)),
+ );
+
+ self.update_buffers();
+ }
+
pub fn set_width(&mut self, change: SizeChange) {
let Self::Open {
selection: (output, a, b),