mirror of
https://github.com/wez/wezterm.git
synced 2024-09-19 02:37:51 +03:00
mux protocol sending alerts to client
refs: https://github.com/wez/wezterm/issues/748 refs: https://github.com/wez/wezterm/issues/489
This commit is contained in:
parent
f5f393bf2c
commit
dc4c8f07dd
@ -30,7 +30,8 @@ use std::sync::Arc;
|
||||
use termwiz::hyperlink::Hyperlink;
|
||||
use termwiz::surface::Line;
|
||||
use varbincode;
|
||||
use wezterm_term::{ClipboardSelection, StableRowIndex};
|
||||
use wezterm_term::color::ColorPalette;
|
||||
use wezterm_term::{Alert, ClipboardSelection, StableRowIndex};
|
||||
|
||||
/// Returns the encoded length of the leb128 representation of value
|
||||
fn encoded_length(value: u64) -> usize {
|
||||
@ -400,7 +401,7 @@ macro_rules! pdu {
|
||||
/// The overall version of the codec.
|
||||
/// This must be bumped when backwards incompatible changes
|
||||
/// are made to the types and protocol.
|
||||
pub const CODEC_VERSION: usize = 7;
|
||||
pub const CODEC_VERSION: usize = 8;
|
||||
|
||||
// Defines the Pdu enum.
|
||||
// Each struct has an explicit identifying number.
|
||||
@ -437,6 +438,8 @@ pdu! {
|
||||
KillPane: 35,
|
||||
SpawnV2: 36,
|
||||
PaneRemoved: 37,
|
||||
SetPalette: 38,
|
||||
NotifyAlert: 39,
|
||||
}
|
||||
|
||||
impl Pdu {
|
||||
@ -508,11 +511,11 @@ impl Pdu {
|
||||
|
||||
pub fn pane_id(&self) -> Option<PaneId> {
|
||||
match self {
|
||||
Pdu::GetPaneRenderChangesResponse(GetPaneRenderChangesResponse { pane_id, .. }) => {
|
||||
Some(*pane_id)
|
||||
}
|
||||
Pdu::SetClipboard(SetClipboard { pane_id, .. }) => Some(*pane_id),
|
||||
Pdu::PaneRemoved(PaneRemoved { pane_id }) => Some(*pane_id),
|
||||
Pdu::GetPaneRenderChangesResponse(GetPaneRenderChangesResponse { pane_id, .. })
|
||||
| Pdu::SetPalette(SetPalette { pane_id, .. })
|
||||
| Pdu::NotifyAlert(NotifyAlert { pane_id, .. })
|
||||
| Pdu::SetClipboard(SetClipboard { pane_id, .. })
|
||||
| Pdu::PaneRemoved(PaneRemoved { pane_id }) => Some(*pane_id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -675,6 +678,18 @@ pub struct SetClipboard {
|
||||
pub selection: ClipboardSelection,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Debug)]
|
||||
pub struct SetPalette {
|
||||
pub pane_id: PaneId,
|
||||
pub palette: ColorPalette,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Debug)]
|
||||
pub struct NotifyAlert {
|
||||
pub pane_id: PaneId,
|
||||
pub alert: Alert,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, PartialEq, Debug)]
|
||||
pub struct Resize {
|
||||
pub containing_tab_id: TabId,
|
||||
|
@ -1,12 +1,38 @@
|
||||
//! Colors for attributes
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::fmt;
|
||||
use std::result::Result;
|
||||
pub use termwiz::color::{AnsiColor, ColorAttribute, RgbColor, RgbaTuple};
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, PartialEq, Eq)]
|
||||
pub struct Palette256(pub [RgbColor; 256]);
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
impl Serialize for Palette256 {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
self.0.to_vec().serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "use_serde")]
|
||||
impl<'de> Deserialize<'de> for Palette256 {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Palette256, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = Vec::<RgbColor>::deserialize(deserializer)?;
|
||||
use std::convert::TryInto;
|
||||
Ok(Self(s.try_into().map_err(|_| {
|
||||
serde::de::Error::custom("Palette256 size mismatch")
|
||||
})?))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::iter::FromIterator<RgbColor> for Palette256 {
|
||||
fn from_iter<I: IntoIterator<Item = RgbColor>>(iter: I) -> Self {
|
||||
let mut colors = [RgbColor::default(); 256];
|
||||
@ -17,7 +43,8 @@ impl std::iter::FromIterator<RgbColor> for Palette256 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
|
||||
pub struct ColorPalette {
|
||||
pub colors: Palette256,
|
||||
pub foreground: RgbColor,
|
||||
|
@ -37,6 +37,7 @@ pub trait DeviceControlHandler {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "use_serde", derive(Serialize, Deserialize))]
|
||||
pub enum Alert {
|
||||
Bell,
|
||||
ToastNotification {
|
||||
|
@ -10,6 +10,7 @@ use mux::domain::DomainId;
|
||||
use mux::pane::{alloc_pane_id, Pane, PaneId, Pattern, SearchResult};
|
||||
use mux::renderable::{RenderableDimensions, StableCursorPosition};
|
||||
use mux::tab::TabId;
|
||||
use mux::{Mux, MuxNotification};
|
||||
use portable_pty::PtySize;
|
||||
use rangeset::RangeSet;
|
||||
use ratelim::RateLimiter;
|
||||
@ -21,7 +22,7 @@ use std::sync::Arc;
|
||||
use termwiz::input::KeyEvent;
|
||||
use url::Url;
|
||||
use wezterm_term::color::ColorPalette;
|
||||
use wezterm_term::{Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex};
|
||||
use wezterm_term::{Alert, Clipboard, KeyCode, KeyModifiers, Line, MouseEvent, StableRowIndex};
|
||||
|
||||
pub struct ClientPane {
|
||||
client: Arc<ClientInner>,
|
||||
@ -29,6 +30,7 @@ pub struct ClientPane {
|
||||
pub remote_pane_id: PaneId,
|
||||
pub remote_tab_id: TabId,
|
||||
pub renderable: RefCell<RenderableState>,
|
||||
palette: RefCell<ColorPalette>,
|
||||
writer: RefCell<PaneWriter>,
|
||||
reader: Pipe,
|
||||
mouse: Rc<RefCell<MouseState>>,
|
||||
@ -76,6 +78,8 @@ impl ClientPane {
|
||||
};
|
||||
|
||||
let reader = Pipe::new().expect("Pipe::new failed");
|
||||
let config = configuration();
|
||||
let palette: ColorPalette = config.resolved_palette.clone().into();
|
||||
|
||||
Self {
|
||||
client: Arc::clone(client),
|
||||
@ -85,6 +89,7 @@ impl ClientPane {
|
||||
remote_tab_id,
|
||||
renderable: RefCell::new(render),
|
||||
writer: RefCell::new(writer),
|
||||
palette: RefCell::new(palette),
|
||||
reader,
|
||||
clipboard: RefCell::new(None),
|
||||
mouse_grabbed: RefCell::new(false),
|
||||
@ -113,10 +118,25 @@ impl ClientPane {
|
||||
log::error!("ClientPane: Ignoring SetClipboard request {:?}", clipboard);
|
||||
}
|
||||
},
|
||||
Pdu::SetPalette(SetPalette { palette, .. }) => {
|
||||
*self.palette.borrow_mut() = palette;
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.notify(MuxNotification::Alert {
|
||||
pane_id: self.local_pane_id,
|
||||
alert: Alert::PaletteChanged,
|
||||
});
|
||||
}
|
||||
Pdu::NotifyAlert(NotifyAlert { alert, .. }) => {
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.notify(MuxNotification::Alert {
|
||||
pane_id: self.local_pane_id,
|
||||
alert,
|
||||
});
|
||||
}
|
||||
Pdu::PaneRemoved(PaneRemoved { pane_id }) => {
|
||||
log::trace!("remote pane {} has been removed", pane_id);
|
||||
self.renderable.borrow().inner.borrow_mut().dead = true;
|
||||
let mux = mux::Mux::get().unwrap();
|
||||
let mux = Mux::get().unwrap();
|
||||
mux.prune_dead_windows();
|
||||
}
|
||||
_ => bail!("unhandled unilateral pdu: {:?}", pdu),
|
||||
@ -333,13 +353,10 @@ impl Pane for ClientPane {
|
||||
fn palette(&self) -> ColorPalette {
|
||||
let tardy = self.renderable.borrow().inner.borrow().is_tardy();
|
||||
|
||||
let config = configuration();
|
||||
let palette: ColorPalette = config.resolved_palette.clone().into();
|
||||
|
||||
if tardy {
|
||||
palette.grey_out()
|
||||
self.palette.borrow().grey_out()
|
||||
} else {
|
||||
palette
|
||||
self.palette.borrow().clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,8 +87,12 @@ where
|
||||
.await?;
|
||||
stream.flush().await.context("flushing PDU to client")?;
|
||||
}
|
||||
Ok(Item::Notif(MuxNotification::Alert { pane_id, alert: _ })) => {
|
||||
// FIXME: queue notification to send to client!
|
||||
Ok(Item::Notif(MuxNotification::Alert { pane_id, alert })) => {
|
||||
{
|
||||
let per_pane = handler.per_pane(pane_id);
|
||||
let mut per_pane = per_pane.lock().unwrap();
|
||||
per_pane.notifications.push(alert);
|
||||
}
|
||||
handler.schedule_pane_push(pane_id);
|
||||
}
|
||||
Ok(Item::Notif(MuxNotification::WindowCreated(_window_id))) => {}
|
||||
|
@ -15,7 +15,7 @@ use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Instant;
|
||||
use url::Url;
|
||||
use wezterm_term::terminal::{Clipboard, ClipboardSelection};
|
||||
use wezterm_term::terminal::{Alert, Clipboard, ClipboardSelection};
|
||||
use wezterm_term::StableRowIndex;
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -37,13 +37,15 @@ impl PduSender {
|
||||
}
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct PerPane {
|
||||
pub(crate) struct PerPane {
|
||||
cursor_position: StableCursorPosition,
|
||||
title: String,
|
||||
working_dir: Option<Url>,
|
||||
dimensions: RenderableDimensions,
|
||||
dirty_lines: RangeSet<StableRowIndex>,
|
||||
mouse_grabbed: bool,
|
||||
sent_initial_palette: bool,
|
||||
pub(crate) notifications: Vec<Alert>,
|
||||
}
|
||||
|
||||
impl PerPane {
|
||||
@ -148,6 +150,32 @@ fn maybe_push_pane_changes(
|
||||
serial: 0,
|
||||
})?;
|
||||
}
|
||||
if !per_pane.sent_initial_palette {
|
||||
per_pane.notifications.push(Alert::PaletteChanged);
|
||||
per_pane.sent_initial_palette = true;
|
||||
}
|
||||
for alert in per_pane.notifications.drain(..) {
|
||||
match alert {
|
||||
Alert::PaletteChanged => {
|
||||
sender.send(DecodedPdu {
|
||||
pdu: Pdu::SetPalette(SetPalette {
|
||||
pane_id: pane.pane_id(),
|
||||
palette: pane.palette(),
|
||||
}),
|
||||
serial: 0,
|
||||
})?;
|
||||
}
|
||||
alert => {
|
||||
sender.send(DecodedPdu {
|
||||
pdu: Pdu::NotifyAlert(NotifyAlert {
|
||||
pane_id: pane.pane_id(),
|
||||
alert,
|
||||
}),
|
||||
serial: 0,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -174,7 +202,8 @@ impl SessionHandler {
|
||||
per_pane: HashMap::new(),
|
||||
}
|
||||
}
|
||||
fn per_pane(&mut self, pane_id: PaneId) -> Arc<Mutex<PerPane>> {
|
||||
|
||||
pub(crate) fn per_pane(&mut self, pane_id: PaneId) -> Arc<Mutex<PerPane>> {
|
||||
Arc::clone(
|
||||
self.per_pane
|
||||
.entry(pane_id)
|
||||
@ -535,6 +564,8 @@ impl SessionHandler {
|
||||
Pdu::Pong { .. }
|
||||
| Pdu::ListPanesResponse { .. }
|
||||
| Pdu::SetClipboard { .. }
|
||||
| Pdu::NotifyAlert { .. }
|
||||
| Pdu::SetPalette { .. }
|
||||
| Pdu::SpawnResponse { .. }
|
||||
| Pdu::GetPaneRenderChangesResponse { .. }
|
||||
| Pdu::UnitResponse { .. }
|
||||
|
Loading…
Reference in New Issue
Block a user