1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-11 03:27:05 +03:00

lua: make gui_window() reconcile workspace

reconciling causes gui windows to be created and allows for stuff like
this, that would otherwise fail because the gui window hadn't been
created yet.

```lua
local wezterm = require 'wezterm'

local mux = wezterm.mux

wezterm.on("gui-startup", function()
  local tab, pane, window = mux.spawn_window{}
  window:gui_window():set_inner_size(1200, 1200)
end)

return {
}
```
This commit is contained in:
Wez Furlong 2022-07-06 18:52:14 -07:00
parent 3e01d44ece
commit 533e52c589
3 changed files with 13 additions and 5 deletions

View File

@ -334,14 +334,14 @@ impl_lua_conversion_dynamic!(MuxTabInfo);
impl UserData for MuxWindow {
fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
methods.add_method("window_id", |_, this, _: ()| Ok(this.0));
methods.add_method("gui_window", |lua, this, _: ()| {
methods.add_async_method("gui_window", |lua, this, _: ()| async move {
// Weakly bound to the gui module; mux cannot hard-depend
// on wezterm-gui, but we can runtime resolve the appropriate module
let wezterm_mod = get_or_create_module(lua, "wezterm")
.map_err(|err| mlua::Error::external(format!("{err:#}")))?;
let gui: mlua::Table = wezterm_mod.get("gui")?;
let func: mlua::Function = gui.get("gui_window_for_mux_window")?;
func.call::<_, mlua::Value>(this.0)
func.call_async::<_, mlua::Value>(this.0).await
});
methods.add_method("get_workspace", |_, this, _: ()| {
let mux = get_mux()?;

View File

@ -7,6 +7,7 @@ pub use config::FrontEndSelection;
use mux::client::ClientId;
use mux::window::WindowId as MuxWindowId;
use mux::{Mux, MuxNotification};
use promise::{Future, Promise};
use std::cell::RefCell;
use std::collections::{BTreeMap, HashSet};
use std::rc::Rc;
@ -151,7 +152,8 @@ impl GuiFrontEnd {
.context("running message loop")
}
pub fn reconcile_workspace(&self) {
pub fn reconcile_workspace(&self) -> Future<()> {
let mut promise = Promise::new();
let mux = Mux::get().expect("mux started and running on main thread");
let workspace = mux.active_workspace_for_client(&self.client_id);
@ -160,7 +162,8 @@ impl GuiFrontEnd {
// be running in other workspaces, so let's pick one
// and activate it
if self.is_switching_workspace() {
return;
promise.ok(());
return promise.get_future().unwrap();
}
for workspace in mux.iter_workspaces() {
if !mux.is_workspace_empty(&workspace) {
@ -211,6 +214,8 @@ impl GuiFrontEnd {
log::trace!("reconcile: windows -> {:?}", windows);
*self.known_windows.borrow_mut() = windows;
let future = promise.get_future().unwrap();
// then spawn any new windows that are needed
promise::spawn::spawn(async move {
while let Some(mux_window_id) = mux_windows.next() {
@ -238,8 +243,10 @@ impl GuiFrontEnd {
}
}
*front_end().switching_workspaces.borrow_mut() = false;
promise.ok(());
})
.detach();
future
}
fn has_mux_window(&self, mux_window_id: MuxWindowId) -> bool {

View File

@ -15,9 +15,10 @@ pub fn register(lua: &Lua) -> anyhow::Result<()> {
window_mod.set(
"gui_window_for_mux_window",
lua.create_function(|_, mux_window_id: MuxWindowId| {
lua.create_async_function(|_, mux_window_id: MuxWindowId| async move {
let fe =
try_front_end().ok_or_else(|| mlua::Error::external("not called on gui thread"))?;
let _ = fe.reconcile_workspace().await;
let win = fe.gui_window_for_mux_window(mux_window_id).ok_or_else(|| {
mlua::Error::external(format!(
"mux window id {mux_window_id} is not currently associated with a gui window"