aboutsummaryrefslogtreecommitdiff
path: root/src/input.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-05-11 10:02:48 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-05-11 10:02:48 +0400
commite454cd6282eb52709a397e72abec01ed65f6c4c1 (patch)
tree318698c6e877fb73e6a4564bdc9ff4c1a6d7e20a /src/input.rs
parent1c14a0a2a97867878c65ea33fa8b927618efb555 (diff)
downloadniri-e454cd6282eb52709a397e72abec01ed65f6c4c1.tar.gz
niri-e454cd6282eb52709a397e72abec01ed65f6c4c1.tar.bz2
niri-e454cd6282eb52709a397e72abec01ed65f6c4c1.zip
Implement double-resize-click to reset height/toggle full width
Diffstat (limited to 'src/input.rs')
-rw-r--r--src/input.rs47
1 files changed, 40 insertions, 7 deletions
diff --git a/src/input.rs b/src/input.rs
index 208d48f0..cacbaaca 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -31,7 +31,9 @@ use crate::niri::State;
use crate::resize_grab::ResizeGrab;
use crate::ui::screenshot_ui::ScreenshotUi;
use crate::utils::spawning::spawn;
-use crate::utils::{center, get_monotonic_time};
+use crate::utils::{center, get_monotonic_time, ResizeEdge};
+
+pub const DOUBLE_CLICK_TIME: Duration = Duration::from_millis(400);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CompositorMod {
@@ -1076,7 +1078,6 @@ impl State {
if ButtonState::Pressed == button_state {
if let Some(mapped) = self.niri.window_under_cursor() {
let window = mapped.window.clone();
- self.niri.layout.activate_window(&window);
// Check if we need to start an interactive resize.
if event.button() == Some(MouseButton::Right) && !pointer.is_grabbed() {
@@ -1093,23 +1094,55 @@ impl State {
.layout
.resize_edges_under(output, pos_within_output)
.unwrap();
- if self
- .niri
- .layout
- .interactive_resize_begin(window.clone(), edges)
+
+ // See if we got a double resize-click gesture.
+ // FIXME: deduplicate with resize_request in xdg-shell somehow.
+ let time = get_monotonic_time();
+ let last_cell = mapped.last_interactive_resize_start();
+ let last = last_cell.get();
+ last_cell.set(Some((time, edges)));
+ let mut did_gesture = false;
+ if let Some((last_time, last_edges)) = last {
+ if time.saturating_sub(last_time) <= DOUBLE_CLICK_TIME {
+ let intersection = edges.intersection(last_edges);
+ if intersection.intersects(ResizeEdge::LEFT_RIGHT) {
+ // FIXME: don't activate once we can pass specific windows to
+ // actions.
+ self.niri.layout.activate_window(&window);
+ self.niri.layout.toggle_full_width();
+ }
+ if intersection.intersects(ResizeEdge::TOP_BOTTOM) {
+ // FIXME: don't activate once we can pass specific windows to
+ // actions.
+ self.niri.layout.activate_window(&window);
+ self.niri.layout.reset_window_height();
+ }
+ did_gesture = true;
+ }
+ }
+
+ self.niri.layout.activate_window(&window);
+
+ if !did_gesture
+ && self
+ .niri
+ .layout
+ .interactive_resize_begin(window.clone(), edges)
{
let start_data = PointerGrabStartData {
focus: None,
button: event.button_code(),
location,
};
- let grab = ResizeGrab::new(start_data, window);
+ let grab = ResizeGrab::new(start_data, window.clone());
pointer.set_grab(self, grab, serial, Focus::Clear);
self.niri.interactive_resize_ongoing = true;
}
}
}
+ self.niri.layout.activate_window(&window);
+
// FIXME: granular.
self.niri.queue_redraw_all();
} else if let Some(output) = self.niri.output_under_cursor() {