Skip to content

Commit 2c0099a

Browse files
author
Maxim Sokolov
committed
add lua methods to access position and pane in the direction
1 parent 9d7e613 commit 2c0099a

File tree

5 files changed

+89
-11
lines changed

5 files changed

+89
-11
lines changed

lua-api-crates/mux/src/tab.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use config::keyassignment::PaneDirection;
2+
13
use super::*;
24
use luahelper::to_lua;
35
use std::sync::Arc;
@@ -53,6 +55,23 @@ impl UserData for MuxTab {
5355
.collect::<Vec<MuxPane>>())
5456
});
5557

58+
methods.add_method("get_pane_direction", |_, this, direction: String| {
59+
let mux = get_mux()?;
60+
let tab = this.resolve(&mux)?;
61+
let panes = tab.iter_panes_ignoring_zoom();
62+
63+
let dir = PaneDirection::direction_from_str(&direction).map_err(|err| {
64+
mlua::Error::external(format!(
65+
"Unable to convert direction '{}'. Error: {}",
66+
direction, err
67+
))
68+
})?;
69+
let pane = tab
70+
.get_pane_direction(dir, true)
71+
.map(|pane_index| MuxPane(panes[pane_index].pane.pane_id()));
72+
Ok(pane)
73+
});
74+
5675
methods.add_method("set_zoomed", |_, this, zoomed: bool| {
5776
let mux = get_mux()?;
5877
let tab = this.resolve(&mux)?;

mux/src/tab.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,14 @@ impl Tab {
644644
self.inner.lock().activate_pane_direction(direction)
645645
}
646646

647+
/// Returns an adjacent pane in the specified direction.
648+
/// In cases where there are multiple adjacent panes in the
649+
/// intended direction, we take the pane that has the largest
650+
/// edge intersection.
651+
pub fn get_pane_direction(&self, direction: PaneDirection, ignore_zoom: bool) -> Option<usize> {
652+
self.inner.lock().get_pane_direction(direction, ignore_zoom)
653+
}
654+
647655
pub fn prune_dead_panes(&self) -> bool {
648656
self.inner.lock().prune_dead_panes()
649657
}
@@ -1410,34 +1418,42 @@ impl TabInner {
14101418
}
14111419
self.toggle_zoom();
14121420
}
1413-
let panes = self.iter_panes();
1421+
if let Some(panel_idx) = self.get_pane_direction(direction, false) {
1422+
self.set_active_idx(panel_idx);
1423+
}
1424+
}
1425+
1426+
fn get_pane_direction(&mut self, direction: PaneDirection, ignore_zoom: bool) -> Option<usize> {
1427+
let panes = if ignore_zoom {
1428+
self.iter_panes_ignoring_zoom()
1429+
} else {
1430+
self.iter_panes()
1431+
};
14141432

14151433
let active = match panes.iter().find(|pane| pane.is_active) {
14161434
Some(p) => p,
14171435
None => {
14181436
// No active pane somehow...
1419-
self.set_active_idx(0);
1420-
return;
1437+
return Some(0);
14211438
}
14221439
};
14231440

14241441
if matches!(direction, PaneDirection::Next | PaneDirection::Prev) {
14251442
let max_pane_id = panes.iter().map(|p| p.index).max().unwrap_or(active.index);
14261443

1427-
if direction == PaneDirection::Next {
1428-
self.set_active_idx(if active.index == max_pane_id {
1444+
return Some(if direction == PaneDirection::Next {
1445+
if active.index == max_pane_id {
14291446
0
14301447
} else {
14311448
active.index + 1
1432-
});
1449+
}
14331450
} else {
1434-
self.set_active_idx(if active.index == 0 {
1451+
if active.index == 0 {
14351452
max_pane_id
14361453
} else {
14371454
active.index - 1
1438-
});
1439-
}
1440-
return;
1455+
}
1456+
});
14411457
}
14421458

14431459
let mut best = None;
@@ -1508,8 +1524,9 @@ impl TabInner {
15081524
drop(recency);
15091525

15101526
if let Some((_, target)) = best.take() {
1511-
self.set_active_idx(target.index);
1527+
return Some(target.index);
15121528
}
1529+
None
15131530
}
15141531

15151532
fn prune_dead_panes(&mut self) -> bool {

wezterm-gui/src/scripting/guiwin.rs

+16
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,22 @@ impl UserData for GuiWin {
5454
Ok(())
5555
},
5656
);
57+
methods.add_async_method("get_position", |_, this, _: ()| async move {
58+
let p = this
59+
.window
60+
.get_window_position()
61+
.await
62+
.map_err(|e| anyhow::anyhow!("{:#}", e))
63+
.map_err(luaerr)?;
64+
#[derive(FromDynamic, ToDynamic)]
65+
struct Point {
66+
x: isize,
67+
y: isize,
68+
}
69+
impl_lua_conversion_dynamic!(Point);
70+
let p = Point { x: p.x, y: p.y };
71+
Ok(p)
72+
});
5773
methods.add_method("set_position", |_, this, (x, y): (isize, isize)| {
5874
this.window.set_window_position(euclid::point2(x, y));
5975
Ok(())

window/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@ pub trait WindowOps {
270270
/// click before forwarding the event (Windows).
271271
fn set_window_drag_position(&self, _coords: ScreenPoint) {}
272272

273+
/// Returns the location of the window on the screen.
274+
/// The coordinates are of the top left pixel of the
275+
/// client area.
276+
///
277+
/// This is only implemented on backends that allow
278+
/// windows to move themselves (not Wayland).
279+
fn get_window_position(&self) -> Future<ScreenPoint>;
280+
273281
/// Changes the location of the window on the screen.
274282
/// The coordinates are of the top left pixel of the
275283
/// client area.

window/src/os/macos/window.rs

+18
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,10 @@ impl WindowOps for Window {
686686
);
687687
}
688688

689+
fn get_window_position(&self) -> Future<ScreenPoint> {
690+
Connection::with_window_inner(self.id, move |inner| Ok(inner.get_window_position()))
691+
}
692+
689693
fn set_window_position(&self, coords: ScreenPoint) {
690694
Connection::with_window_inner(self.id, move |inner| {
691695
inner.set_window_position(coords);
@@ -1084,6 +1088,20 @@ impl WindowInner {
10841088
}
10851089
}
10861090

1091+
fn get_window_position(&self) -> ScreenPoint {
1092+
unsafe {
1093+
let frame = NSWindow::frame(*self.window);
1094+
let content_frame = NSWindow::contentRectForFrameRect_(*self.window, frame);
1095+
let delta_x = content_frame.origin.x - frame.origin.x;
1096+
let delta_y = content_frame.origin.y - frame.origin.y;
1097+
let cartesian = NSPoint::new(
1098+
frame.origin.x as f64 + delta_x,
1099+
frame.origin.y as f64 + delta_y + content_frame.size.height,
1100+
);
1101+
cartesian_to_screen_point(cartesian)
1102+
}
1103+
}
1104+
10871105
fn set_text_cursor_position(&mut self, cursor: Rect) {
10881106
if let Some(window_view) = WindowView::get_this(unsafe { &**self.view }) {
10891107
window_view.inner.borrow_mut().text_cursor_position = cursor;

0 commit comments

Comments
 (0)