From 5a5d08080cd6d5030481425b4a323e34e2fe0d8a Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Wed, 3 Mar 2021 23:29:18 -0800 Subject: [PATCH] gui: allow dragging the window by non-tab areas in tab bar I've only tested this on macos, but it should be cross platform, with the caveat that Wayland doesn't let a window position itself, so this won't work there. --- wezterm-gui/src/termwindow/mod.rs | 3 +++ wezterm-gui/src/termwindow/mouseevent.rs | 30 +++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/wezterm-gui/src/termwindow/mod.rs b/wezterm-gui/src/termwindow/mod.rs index e3f9fefde..268461c34 100644 --- a/wezterm-gui/src/termwindow/mod.rs +++ b/wezterm-gui/src/termwindow/mod.rs @@ -114,6 +114,7 @@ pub struct TermWindow { last_mouse_terminal_coords: (usize, StableRowIndex), scroll_drag_start: Option, split_drag_start: Option, + window_drag_position: Option, prev_cursor: PrevCursorPos, last_scroll_info: RenderableDimensions, @@ -260,6 +261,7 @@ impl WindowCallbacks for TermWindow { last_mouse_terminal_coords: self.last_mouse_terminal_coords.clone(), scroll_drag_start: self.scroll_drag_start.clone(), split_drag_start: self.split_drag_start.clone(), + window_drag_position: None, prev_cursor: self.prev_cursor.clone(), last_scroll_info: self.last_scroll_info.clone(), clipboard_contents: Arc::clone(&clipboard_contents), @@ -474,6 +476,7 @@ impl TermWindow { last_mouse_terminal_coords: (0, 0), scroll_drag_start: None, split_drag_start: None, + window_drag_position: None, prev_cursor: PrevCursorPos::new(), last_scroll_info: RenderableDimensions::default(), clipboard_contents: Arc::clone(&clipboard_contents), diff --git a/wezterm-gui/src/termwindow/mouseevent.rs b/wezterm-gui/src/termwindow/mouseevent.rs index 5e5f57fd4..508ac74ed 100644 --- a/wezterm-gui/src/termwindow/mouseevent.rs +++ b/wezterm-gui/src/termwindow/mouseevent.rs @@ -62,6 +62,10 @@ impl super::TermWindow { // Completed a split drag return; } + if press == &MousePress::Left && self.window_drag_position.take().is_some() { + // Completed a window drag + return; + } } WMEK::Press(ref press) => { @@ -96,6 +100,27 @@ impl super::TermWindow { } WMEK::Move => { + if let Some(start) = self.window_drag_position.as_ref() { + // Dragging the window + // Compute the distance since the initial event + let delta_x = start.screen_coords.x - event.screen_coords.x; + let delta_y = start.screen_coords.y - event.screen_coords.y; + + // Now compute a new window position. + // We don't have a direct way to get the position, + // but we can infer it by comparing the mouse coords + // with the screen coords in the initial event. + // This computes the original top_left position, + // and applies the total drag delta to it. + let top_left = ::window::ScreenPoint::new( + (start.screen_coords.x - start.coords.x) - delta_x, + (start.screen_coords.y - start.coords.y) - delta_y, + ); + // and now tell the window to go there + context.set_window_position(top_left); + return; + } + let current_viewport = self.get_viewport(pane.pane_id()); if let Some(from_top) = self.scroll_drag_start.as_ref() { // Dragging the scroll bar @@ -171,7 +196,10 @@ impl super::TermWindow { TabBarItem::NewTabButton => { self.spawn_tab(&SpawnTabDomain::CurrentPaneDomain); } - TabBarItem::None => {} + TabBarItem::None => { + // Potentially starting a drag by the tab bar + self.window_drag_position.replace(event.clone()); + } }, WMEK::Press(MousePress::Middle) => match self.tab_bar.hit_test(x) { TabBarItem::Tab(tab_idx) => {