Skip to content

Commit

Permalink
Attempt at being able to hide the floating pane
Browse files Browse the repository at this point in the history
  • Loading branch information
e82eric committed Sep 29, 2024
1 parent 20fbe7a commit e240f67
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 27 deletions.
11 changes: 9 additions & 2 deletions codec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use config::keyassignment::{PaneDirection, ScrollbackEraseMode};
use mux::client::{ClientId, ClientInfo};
use mux::pane::PaneId;
use mux::renderable::{RenderableDimensions, StableCursorPosition};
use mux::tab::{PaneNode, SerdeUrl, SplitRequest, TabId};
use mux::tab::{PaneNode, SerdeUrl, SplitRequest, Tab, TabId};
use mux::window::WindowId;
use portable_pty::CommandBuilder;
use rangeset::*;
Expand Down Expand Up @@ -503,6 +503,7 @@ pdu! {
GetPaneDirectionResponse: 61,
AdjustPaneSize: 62,
FloatPane: 63,
FloatPaneVisibilityChanged: 64
}

impl Pdu {
Expand Down Expand Up @@ -645,7 +646,7 @@ pub struct ListPanes {}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct ListPanesResponse {
pub tabs: Vec<(PaneNode, PaneNode)>,
pub tabs: Vec<(PaneNode, (PaneNode, bool))>,
pub tab_titles: Vec<String>,
pub window_titles: HashMap<WindowId, String>,
}
Expand All @@ -658,6 +659,12 @@ pub struct FloatPane {
pub domain: config::keyassignment::SpawnTabDomain,
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct FloatPaneVisibilityChanged {
pub tab_id: TabId,
pub visible: bool
}

#[derive(Deserialize, Serialize, PartialEq, Debug)]
pub struct SplitPane {
pub pane_id: PaneId,
Expand Down
1 change: 1 addition & 0 deletions config/src/keyassignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ pub enum KeyAssignment {
SplitHorizontal(SpawnCommand),
SplitVertical(SpawnCommand),
FloatPane(SpawnCommand),
ToggleFloatingPane,
ShowLauncher,
ShowLauncherArgs(LauncherActionArgs),
ClearScrollback(ScrollbackEraseMode),
Expand Down
20 changes: 20 additions & 0 deletions mux/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ pub enum MuxNotification {
old_workspace: String,
new_workspace: String,
},
FloatPaneVisibilityChanged{
tab_id: TabId,
visible: bool,
}
}

static SUB_ID: AtomicUsize = AtomicUsize::new(0);
Expand Down Expand Up @@ -525,6 +529,16 @@ impl Mux {
}
}

pub fn set_float_pane_visibility(&self, tab_id: TabId, visible: bool) -> anyhow::Result<()> {
let tab = self
.get_tab(tab_id)
.ok_or_else(|| anyhow::anyhow!("tab {tab_id} not found"))?;

tab.set_float_pane_visibility(visible);

Ok(())
}

/// Called by PaneFocused event handlers to reconcile a remote
/// pane focus event and apply its effects locally
pub fn focus_pane_and_containing_tab(&self, pane_id: PaneId) -> anyhow::Result<()> {
Expand Down Expand Up @@ -1056,6 +1070,12 @@ impl Mux {
pub fn resolve_pane_id(&self, pane_id: PaneId) -> Option<(DomainId, WindowId, TabId)> {
let mut ids = None;
for tab in self.tabs.read().values() {
if let Some(float_pane) = tab.get_float_pane() {
if pane_id == float_pane.pane.pane_id() {
ids = Some((tab.tab_id(), float_pane.pane.domain_id()));
break;
}
}
for p in tab.iter_panes_ignoring_zoom() {
if p.pane.pane_id() == pane_id {
ids = Some((tab.tab_id(), p.pane.domain_id()));
Expand Down
83 changes: 62 additions & 21 deletions mux/src/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct TabInner {
zoomed: Option<Arc<dyn Pane>>,
title: String,
float_pane: Option<Arc<dyn Pane>>,
float_pane_visible: bool,
recency: Recency,
}

Expand Down Expand Up @@ -76,8 +77,7 @@ pub struct PositionedPane {
pub height: usize,
pub pixel_height: usize,
/// The pane instance
pub pane: Arc<dyn Pane>,
pub is_float: bool,
pub pane: Arc<dyn Pane>
}

impl std::fmt::Debug for PositionedPane {
Expand Down Expand Up @@ -546,14 +546,14 @@ impl Tab {
/// PaneEntry, or to create a new Pane from that entry.
/// make_pane is expected to add the pane to the mux if it creates
/// a new pane, otherwise the pane won't poll/update in the GUI.
pub fn sync_with_pane_tree<F>(&self, size: TerminalSize, root: (PaneNode, PaneNode), make_pane: F)
pub fn sync_with_pane_tree<F>(&self, size: TerminalSize, root: (PaneNode, (PaneNode, bool)), make_pane: F)
where
F: FnMut(PaneEntry) -> Arc<dyn Pane>,
{
self.inner.lock().sync_with_pane_tree(size, root, make_pane)
}

pub fn codec_pane_tree(&self) -> (PaneNode, PaneNode) {
pub fn codec_pane_tree(&self) -> (PaneNode, (PaneNode, bool)) {
self.inner.lock().codec_pane_tree()
}

Expand All @@ -579,6 +579,10 @@ impl Tab {
self.inner.lock().iter_panes()
}

pub fn float_pane_is_visible(&self) -> bool {
self.inner.lock().float_pane_is_visible()
}

pub fn get_float_pane(&self) -> Option<PositionedPane> {
self.inner.lock().get_float_pane()
}
Expand Down Expand Up @@ -712,6 +716,10 @@ impl Tab {
self.inner.lock().set_active_pane(pane)
}

pub fn set_float_pane_visibility(&self, visible: bool) {
self.inner.lock().set_float_pane_visibility(visible);
}

pub fn set_active_idx(&self, pane_index: usize) {
self.inner.lock().set_active_idx(pane_index)
}
Expand Down Expand Up @@ -764,6 +772,12 @@ impl Tab {
.split_and_insert(pane_index, request, pane)
}

pub fn toggle_float(&self) {
self.inner
.lock()
.toggle_float_pane();
}

pub fn insert_float(
&self,
float_size: TerminalSize,
Expand Down Expand Up @@ -791,10 +805,11 @@ impl TabInner {
title: String::new(),
recency: Recency::default(),
float_pane: None,
float_pane_visible: false
}
}

fn sync_with_pane_tree<F>(&mut self, size: TerminalSize, root: (PaneNode, PaneNode), mut make_pane: F)
fn sync_with_pane_tree<F>(&mut self, size: TerminalSize, root: (PaneNode, (PaneNode, bool)), mut make_pane: F)
where
F: FnMut(PaneEntry) -> Arc<dyn Pane>,
{
Expand Down Expand Up @@ -834,9 +849,10 @@ impl TabInner {
self.zoomed = zoomed;
self.size = size;

if let PaneNode::Leaf(entry) = root.1 {
if let PaneNode::Leaf(entry) = root.1.0 {
let float_pane = make_pane(entry);
self.float_pane.replace(float_pane);
self.float_pane_visible = root.1.1;
}

self.resize(size);
Expand All @@ -850,14 +866,14 @@ impl TabInner {
assert!(self.pane.is_some());
}

fn codec_pane_tree(&mut self) -> (PaneNode, PaneNode) {
fn codec_pane_tree(&mut self) -> (PaneNode, (PaneNode, bool)) {
let mux = Mux::get();
let tab_id = self.id;
let window_id = match mux.window_containing_tab(tab_id) {
Some(w) => w,
None => {
log::error!("no window contains tab {}", tab_id);
return (PaneNode::Empty, PaneNode::Empty);
return (PaneNode::Empty, (PaneNode::Empty, false));
}
};

Expand All @@ -868,7 +884,7 @@ impl TabInner {
Some(ws) => ws,
None => {
log::error!("window id {} doesn't have a window!?", window_id);
return (PaneNode::Empty, PaneNode::Empty);
return (PaneNode::Empty, (PaneNode::Empty, false));
}
};

Expand All @@ -881,7 +897,7 @@ impl TabInner {
let working_dir = float_pane.get_current_working_dir(CachePolicy::AllowStale);
let cursor_pos = float_pane.get_cursor_position();

PaneNode::Leaf(PaneEntry {
(PaneNode::Leaf(PaneEntry {
window_id,
tab_id,
pane_id: float_pane.pane_id(),
Expand All @@ -902,9 +918,9 @@ impl TabInner {
top_row: 0,
left_col: 0,
tty_name: float_pane.tty_name(),
})
}), self.float_pane_visible)
} else {
PaneNode::Empty
(PaneNode::Empty, false)
};

if let Some(root) = self.pane.as_ref() {
Expand Down Expand Up @@ -996,6 +1012,10 @@ impl TabInner {
self.iter_panes_impl(true)
}

fn float_pane_is_visible(&self) -> bool {
self.float_pane_visible
}

fn get_float_pane(&self) -> Option<PositionedPane> {
if let Some(float_pane) = self.float_pane.as_ref() {
let root_size = self.size;
Expand All @@ -1016,8 +1036,7 @@ impl TabInner {
height: size.rows,
pixel_width: size.pixel_width,
pixel_height: size.pixel_height,
pane: Arc::clone(float_pane),
is_float: true
pane: Arc::clone(float_pane)
})
} else {
None
Expand Down Expand Up @@ -1109,8 +1128,7 @@ impl TabInner {
pixel_width: size.pixel_width.into(),
height: size.rows.into(),
pixel_height: size.pixel_height.into(),
pane: Arc::clone(zoomed),
is_float: false
pane: Arc::clone(zoomed)
});
return panes;
}
Expand Down Expand Up @@ -1156,8 +1174,7 @@ impl TabInner {
height: dims.rows as _,
pixel_width: dims.pixel_width as _,
pixel_height: dims.pixel_height as _,
pane,
is_float: false
pane
});
}

Expand Down Expand Up @@ -1842,16 +1859,18 @@ impl TabInner {
}

fn is_float_active(&self) -> bool {
return self.float_pane.is_some();
self.float_pane.is_some() && self.float_pane_visible
}

fn get_active_pane(&mut self) -> Option<Arc<dyn Pane>> {
if let Some(zoomed) = self.zoomed.as_ref() {
return Some(Arc::clone(zoomed));
}

if let Some(float_pane) = self.float_pane.as_ref() {
return Some(Arc::clone(float_pane));
if self.float_pane_visible {
if let Some(float_pane) = self.float_pane.as_ref() {
return Some(Arc::clone(float_pane));
}
}

self.iter_panes_ignoring_zoom()
Expand Down Expand Up @@ -1884,6 +1903,17 @@ impl TabInner {
}
}

fn set_float_pane_visibility(&mut self, visible: bool) {
if visible != self.float_pane_visible {
self.float_pane_visible = visible;
let mux = Mux::get();
mux.notify(MuxNotification::FloatPaneVisibilityChanged{
tab_id: self.id,
visible,
});
}
}

fn advise_focus_change(&mut self, prior: Option<Arc<dyn Pane>>) {
let mux = Mux::get();
let current = self.get_active_pane();
Expand Down Expand Up @@ -2105,6 +2135,16 @@ impl TabInner {
})
}

fn toggle_float_pane(&mut self) {
if self.float_pane.is_some() {
if self.float_pane_visible {
self.set_float_pane_visibility(false);
} else {
self.set_float_pane_visibility(true);
}
}
}

fn add_float_pane(
&mut self,
float_size: TerminalSize,
Expand All @@ -2119,6 +2159,7 @@ impl TabInner {
}

self.float_pane = Some(Arc::clone(&pane));
self.float_pane_visible = true;

pane.resize(float_size)?;
Ok(())
Expand Down
23 changes: 23 additions & 0 deletions wezterm-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use std::path::{Path, PathBuf};
use std::thread;
use std::time::Duration;
use thiserror::Error;
use codec::FloatPaneVisibilityChanged;
use wezterm_uds::UnixStream;

#[derive(Error, Debug)]
Expand Down Expand Up @@ -297,6 +298,27 @@ fn process_unilateral(
.detach();
return Ok(());
}
Pdu::FloatPaneVisibilityChanged(FloatPaneVisibilityChanged { tab_id, visible }) => {
let tab_id = *tab_id;
let visible = visible.clone();
promise::spawn::spawn_into_main_thread(async move {
let mux = Mux::try_get().ok_or_else(|| anyhow!("no more mux"))?;
let client_domain = mux
.get_domain(local_domain_id)
.ok_or_else(|| anyhow!("no such domain {}", local_domain_id))?;
let client_domain =
client_domain
.downcast_ref::<ClientDomain>()
.ok_or_else(|| {
anyhow!("domain {} is not a ClientDomain instance", local_domain_id)
})?;

client_domain.set_float_pane_visibility(tab_id, visible);
anyhow::Result::<()>::Ok(())
})
.detach();
return Ok(());
}
Pdu::TabResized(_) | Pdu::TabAddedToWindow(_) => {
log::trace!("resync due to {:?}", decoded.pdu);
promise::spawn::spawn_into_main_thread(async move {
Expand Down Expand Up @@ -1343,6 +1365,7 @@ impl Client {
rpc!(spawn_v2, SpawnV2, SpawnResponse);
rpc!(split_pane, SplitPane, SpawnResponse);
rpc!(add_float_pane, FloatPane, SpawnResponse);
rpc!(set_float_pane_visibility, FloatPaneVisibilityChanged, UnitResponse);
rpc!(
move_pane_to_new_tab,
MovePaneToNewTab,
Expand Down
Loading

0 comments on commit e240f67

Please sign in to comment.