diff --git a/wezterm-gui/src/scripting/guiwin.rs b/wezterm-gui/src/scripting/guiwin.rs index 9361238d4b98..043ebdcdc245 100644 --- a/wezterm-gui/src/scripting/guiwin.rs +++ b/wezterm-gui/src/scripting/guiwin.rs @@ -54,6 +54,22 @@ impl UserData for GuiWin { Ok(()) }, ); + methods.add_async_method("get_position", |_, this, _: ()| async move { + let p = this + .window + .get_window_position() + .await + .map_err(|e| anyhow::anyhow!("{:#}", e)) + .map_err(luaerr)?; + #[derive(FromDynamic, ToDynamic)] + struct Point { + x: isize, + y: isize, + } + impl_lua_conversion_dynamic!(Point); + let p = Point { x: p.x, y: p.y }; + Ok(p) + }); methods.add_method("set_position", |_, this, (x, y): (isize, isize)| { this.window.set_window_position(euclid::point2(x, y)); Ok(()) diff --git a/window/src/lib.rs b/window/src/lib.rs index 869a71e2475e..224784b5326c 100644 --- a/window/src/lib.rs +++ b/window/src/lib.rs @@ -270,6 +270,14 @@ pub trait WindowOps { /// click before forwarding the event (Windows). fn set_window_drag_position(&self, _coords: ScreenPoint) {} + /// Returns the location of the window on the screen. + /// The coordinates are of the top left pixel of the + /// client area. + /// + /// This is only implemented on backends that allow + /// windows to move themselves (not Wayland). + fn get_window_position(&self) -> Future; + /// Changes the location of the window on the screen. /// The coordinates are of the top left pixel of the /// client area. diff --git a/window/src/os/macos/window.rs b/window/src/os/macos/window.rs index 6bc4164677c4..9aa11a3cdf0e 100644 --- a/window/src/os/macos/window.rs +++ b/window/src/os/macos/window.rs @@ -708,6 +708,10 @@ impl WindowOps for Window { ); } + fn get_window_position(&self) -> Future { + Connection::with_window_inner(self.id, move |inner| Ok(inner.get_window_position())) + } + fn set_window_position(&self, coords: ScreenPoint) { Connection::with_window_inner(self.id, move |inner| { inner.set_window_position(coords); @@ -1106,6 +1110,20 @@ impl WindowInner { } } + fn get_window_position(&self) -> ScreenPoint { + unsafe { + let frame = NSWindow::frame(*self.window); + let content_frame = NSWindow::contentRectForFrameRect_(*self.window, frame); + let delta_x = content_frame.origin.x - frame.origin.x; + let delta_y = content_frame.origin.y - frame.origin.y; + let cartesian = NSPoint::new( + frame.origin.x as f64 + delta_x, + frame.origin.y as f64 + delta_y + content_frame.size.height, + ); + cartesian_to_screen_point(cartesian) + } + } + fn set_text_cursor_position(&mut self, cursor: Rect) { if let Some(window_view) = WindowView::get_this(unsafe { &**self.view }) { window_view.inner.borrow_mut().text_cursor_position = cursor;