fix(sixel): report pixel size in winsize change ioctl (#2212)
* fix(sixel): report pixel size in winsize change ioctl * style(fmt): rustfmt
This commit is contained in:
parent
d670c29649
commit
a8b5bce9d9
8 changed files with 246 additions and 44 deletions
|
|
@ -43,16 +43,24 @@ use std::{
|
||||||
pub use async_trait::async_trait;
|
pub use async_trait::async_trait;
|
||||||
pub use nix::unistd::Pid;
|
pub use nix::unistd::Pid;
|
||||||
|
|
||||||
fn set_terminal_size_using_fd(fd: RawFd, columns: u16, rows: u16) {
|
fn set_terminal_size_using_fd(
|
||||||
|
fd: RawFd,
|
||||||
|
columns: u16,
|
||||||
|
rows: u16,
|
||||||
|
width_in_pixels: Option<u16>,
|
||||||
|
height_in_pixels: Option<u16>,
|
||||||
|
) {
|
||||||
// TODO: do this with the nix ioctl
|
// TODO: do this with the nix ioctl
|
||||||
use libc::ioctl;
|
use libc::ioctl;
|
||||||
use libc::TIOCSWINSZ;
|
use libc::TIOCSWINSZ;
|
||||||
|
|
||||||
|
let ws_xpixel = width_in_pixels.unwrap_or(0);
|
||||||
|
let ws_ypixel = height_in_pixels.unwrap_or(0);
|
||||||
let winsize = Winsize {
|
let winsize = Winsize {
|
||||||
ws_col: columns,
|
ws_col: columns,
|
||||||
ws_row: rows,
|
ws_row: rows,
|
||||||
ws_xpixel: 0,
|
ws_xpixel,
|
||||||
ws_ypixel: 0,
|
ws_ypixel,
|
||||||
};
|
};
|
||||||
// TIOCGWINSZ is an u32, but the second argument to ioctl is u64 on
|
// TIOCGWINSZ is an u32, but the second argument to ioctl is u64 on
|
||||||
// some platforms. When checked on Linux, clippy will complain about
|
// some platforms. When checked on Linux, clippy will complain about
|
||||||
|
|
@ -414,7 +422,7 @@ pub struct ServerOsInputOutput {
|
||||||
// not connected to an fd (eg.
|
// not connected to an fd (eg.
|
||||||
// a command pane with a
|
// a command pane with a
|
||||||
// non-existing command)
|
// non-existing command)
|
||||||
cached_resizes: Arc<Mutex<Option<BTreeMap<u32, (u16, u16)>>>>, // <terminal_id, (cols, rows)>
|
cached_resizes: Arc<Mutex<Option<BTreeMap<u32, (u16, u16, Option<u16>, Option<u16>)>>>>, // <terminal_id, (cols, rows, width_in_pixels, height_in_pixels)>
|
||||||
}
|
}
|
||||||
|
|
||||||
// async fn in traits is not supported by rust, so dtolnay's excellent async_trait macro is being
|
// async fn in traits is not supported by rust, so dtolnay's excellent async_trait macro is being
|
||||||
|
|
@ -448,7 +456,14 @@ impl AsyncReader for RawFdAsyncReader {
|
||||||
/// The `ServerOsApi` trait represents an abstract interface to the features of an operating system that
|
/// The `ServerOsApi` trait represents an abstract interface to the features of an operating system that
|
||||||
/// Zellij server requires.
|
/// Zellij server requires.
|
||||||
pub trait ServerOsApi: Send + Sync {
|
pub trait ServerOsApi: Send + Sync {
|
||||||
fn set_terminal_size_using_terminal_id(&self, id: u32, cols: u16, rows: u16) -> Result<()>;
|
fn set_terminal_size_using_terminal_id(
|
||||||
|
&self,
|
||||||
|
id: u32,
|
||||||
|
cols: u16,
|
||||||
|
rows: u16,
|
||||||
|
width_in_pixels: Option<u16>,
|
||||||
|
height_in_pixels: Option<u16>,
|
||||||
|
) -> Result<()>;
|
||||||
/// Spawn a new terminal, with a terminal action. The returned tuple contains the master file
|
/// Spawn a new terminal, with a terminal action. The returned tuple contains the master file
|
||||||
/// descriptor of the forked pseudo terminal and a [ChildId] struct containing process id's for
|
/// descriptor of the forked pseudo terminal and a [ChildId] struct containing process id's for
|
||||||
/// the forked child process.
|
/// the forked child process.
|
||||||
|
|
@ -501,7 +516,14 @@ pub trait ServerOsApi: Send + Sync {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerOsApi for ServerOsInputOutput {
|
impl ServerOsApi for ServerOsInputOutput {
|
||||||
fn set_terminal_size_using_terminal_id(&self, id: u32, cols: u16, rows: u16) -> Result<()> {
|
fn set_terminal_size_using_terminal_id(
|
||||||
|
&self,
|
||||||
|
id: u32,
|
||||||
|
cols: u16,
|
||||||
|
rows: u16,
|
||||||
|
width_in_pixels: Option<u16>,
|
||||||
|
height_in_pixels: Option<u16>,
|
||||||
|
) -> Result<()> {
|
||||||
let err_context = || {
|
let err_context = || {
|
||||||
format!(
|
format!(
|
||||||
"failed to set terminal id {} to size ({}, {})",
|
"failed to set terminal id {} to size ({}, {})",
|
||||||
|
|
@ -509,7 +531,7 @@ impl ServerOsApi for ServerOsInputOutput {
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
if let Some(cached_resizes) = self.cached_resizes.lock().unwrap().as_mut() {
|
if let Some(cached_resizes) = self.cached_resizes.lock().unwrap().as_mut() {
|
||||||
cached_resizes.insert(id, (cols, rows));
|
cached_resizes.insert(id, (cols, rows, width_in_pixels, height_in_pixels));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -522,7 +544,7 @@ impl ServerOsApi for ServerOsInputOutput {
|
||||||
{
|
{
|
||||||
Some(Some(fd)) => {
|
Some(Some(fd)) => {
|
||||||
if cols > 0 && rows > 0 {
|
if cols > 0 && rows > 0 {
|
||||||
set_terminal_size_using_fd(*fd, cols, rows);
|
set_terminal_size_using_fd(*fd, cols, rows, width_in_pixels, height_in_pixels);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
|
|
@ -785,8 +807,16 @@ impl ServerOsApi for ServerOsInputOutput {
|
||||||
fn apply_cached_resizes(&mut self) {
|
fn apply_cached_resizes(&mut self) {
|
||||||
let mut cached_resizes = self.cached_resizes.lock().unwrap().take();
|
let mut cached_resizes = self.cached_resizes.lock().unwrap().take();
|
||||||
if let Some(cached_resizes) = cached_resizes.as_mut() {
|
if let Some(cached_resizes) = cached_resizes.as_mut() {
|
||||||
for (terminal_id, (cols, rows)) in cached_resizes.iter() {
|
for (terminal_id, (cols, rows, width_in_pixels, height_in_pixels)) in
|
||||||
let _ = self.set_terminal_size_using_terminal_id(*terminal_id, *cols, *rows);
|
cached_resizes.iter()
|
||||||
|
{
|
||||||
|
let _ = self.set_terminal_size_using_terminal_id(
|
||||||
|
*terminal_id,
|
||||||
|
*cols,
|
||||||
|
*rows,
|
||||||
|
width_in_pixels.clone(),
|
||||||
|
height_in_pixels.clone(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ use zellij_utils::{
|
||||||
errors::prelude::*,
|
errors::prelude::*,
|
||||||
input::command::RunCommand,
|
input::command::RunCommand,
|
||||||
input::layout::FloatingPaneLayout,
|
input::layout::FloatingPaneLayout,
|
||||||
pane_size::{Dimension, Offset, PaneGeom, Size, Viewport},
|
pane_size::{Dimension, Offset, PaneGeom, Size, SizeInPixels, Viewport},
|
||||||
};
|
};
|
||||||
|
|
||||||
const RESIZE_INCREMENT_WIDTH: usize = 5;
|
const RESIZE_INCREMENT_WIDTH: usize = 5;
|
||||||
|
|
@ -39,6 +39,7 @@ pub struct FloatingPanes {
|
||||||
connected_clients: Rc<RefCell<HashSet<ClientId>>>,
|
connected_clients: Rc<RefCell<HashSet<ClientId>>>,
|
||||||
connected_clients_in_app: Rc<RefCell<HashSet<ClientId>>>,
|
connected_clients_in_app: Rc<RefCell<HashSet<ClientId>>>,
|
||||||
mode_info: Rc<RefCell<HashMap<ClientId, ModeInfo>>>,
|
mode_info: Rc<RefCell<HashMap<ClientId, ModeInfo>>>,
|
||||||
|
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
|
||||||
default_mode_info: ModeInfo,
|
default_mode_info: ModeInfo,
|
||||||
style: Style,
|
style: Style,
|
||||||
session_is_mirrored: bool,
|
session_is_mirrored: bool,
|
||||||
|
|
@ -59,6 +60,7 @@ impl FloatingPanes {
|
||||||
connected_clients: Rc<RefCell<HashSet<ClientId>>>,
|
connected_clients: Rc<RefCell<HashSet<ClientId>>>,
|
||||||
connected_clients_in_app: Rc<RefCell<HashSet<ClientId>>>,
|
connected_clients_in_app: Rc<RefCell<HashSet<ClientId>>>,
|
||||||
mode_info: Rc<RefCell<HashMap<ClientId, ModeInfo>>>,
|
mode_info: Rc<RefCell<HashMap<ClientId, ModeInfo>>>,
|
||||||
|
character_cell_size: Rc<RefCell<Option<SizeInPixels>>>,
|
||||||
session_is_mirrored: bool,
|
session_is_mirrored: bool,
|
||||||
default_mode_info: ModeInfo,
|
default_mode_info: ModeInfo,
|
||||||
style: Style,
|
style: Style,
|
||||||
|
|
@ -72,6 +74,7 @@ impl FloatingPanes {
|
||||||
connected_clients,
|
connected_clients,
|
||||||
connected_clients_in_app,
|
connected_clients_in_app,
|
||||||
mode_info,
|
mode_info,
|
||||||
|
character_cell_size,
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
default_mode_info,
|
default_mode_info,
|
||||||
style,
|
style,
|
||||||
|
|
@ -304,7 +307,8 @@ impl FloatingPanes {
|
||||||
} else {
|
} else {
|
||||||
pane.set_content_offset(Offset::default());
|
pane.set_content_offset(Offset::default());
|
||||||
}
|
}
|
||||||
resize_pty!(pane, os_api, self.senders).with_context(|| err_context(&pane.pid()))?;
|
resize_pty!(pane, os_api, self.senders, self.character_cell_size)
|
||||||
|
.with_context(|| err_context(&pane.pid()))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +394,7 @@ impl FloatingPanes {
|
||||||
|
|
||||||
pub fn resize_pty_all_panes(&mut self, os_api: &mut Box<dyn ServerOsApi>) -> Result<()> {
|
pub fn resize_pty_all_panes(&mut self, os_api: &mut Box<dyn ServerOsApi>) -> Result<()> {
|
||||||
for pane in self.panes.values_mut() {
|
for pane in self.panes.values_mut() {
|
||||||
resize_pty!(pane, os_api, self.senders)
|
resize_pty!(pane, os_api, self.senders, self.character_cell_size)
|
||||||
.with_context(|| format!("failed to resize PTY in pane {:?}", pane.pid()))?;
|
.with_context(|| format!("failed to resize PTY in pane {:?}", pane.pid()))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -424,7 +428,8 @@ impl FloatingPanes {
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
|
|
||||||
for pane in self.panes.values_mut() {
|
for pane in self.panes.values_mut() {
|
||||||
resize_pty!(pane, os_api, self.senders).with_context(err_context)?;
|
resize_pty!(pane, os_api, self.senders, self.character_cell_size)
|
||||||
|
.with_context(err_context)?;
|
||||||
}
|
}
|
||||||
self.set_force_render();
|
self.set_force_render();
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
|
|
@ -833,7 +838,7 @@ impl FloatingPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, os_api, self.senders).unwrap();
|
resize_pty!(new_position, os_api, self.senders, self.character_cell_size).unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
||||||
|
|
@ -841,7 +846,13 @@ impl FloatingPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.focus_pane_for_all_clients(active_pane_id);
|
self.focus_pane_for_all_clients(active_pane_id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ impl TiledPanes {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resize_pty!(pane, self.os_api, self.senders).unwrap();
|
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size).unwrap();
|
||||||
}
|
}
|
||||||
self.reset_boundaries();
|
self.reset_boundaries();
|
||||||
}
|
}
|
||||||
|
|
@ -781,7 +781,7 @@ impl TiledPanes {
|
||||||
}
|
}
|
||||||
|
|
||||||
for pane in self.panes.values_mut() {
|
for pane in self.panes.values_mut() {
|
||||||
resize_pty!(pane, self.os_api, self.senders).unwrap();
|
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size).unwrap();
|
||||||
}
|
}
|
||||||
self.reset_boundaries();
|
self.reset_boundaries();
|
||||||
}
|
}
|
||||||
|
|
@ -1071,7 +1071,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
new_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
||||||
|
|
@ -1079,7 +1085,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.focus_pane_for_all_clients(active_pane_id);
|
self.focus_pane_for_all_clients(active_pane_id);
|
||||||
self.set_pane_frames(self.draw_pane_frames);
|
self.set_pane_frames(self.draw_pane_frames);
|
||||||
|
|
@ -1123,7 +1135,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
new_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
||||||
|
|
@ -1131,7 +1149,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.set_pane_frames(self.draw_pane_frames);
|
self.set_pane_frames(self.draw_pane_frames);
|
||||||
}
|
}
|
||||||
|
|
@ -1159,7 +1183,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
new_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||||
|
|
@ -1167,7 +1197,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.set_pane_frames(self.draw_pane_frames);
|
self.set_pane_frames(self.draw_pane_frames);
|
||||||
}
|
}
|
||||||
|
|
@ -1195,7 +1231,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
new_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||||
|
|
@ -1203,7 +1245,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.set_pane_frames(self.draw_pane_frames);
|
self.set_pane_frames(self.draw_pane_frames);
|
||||||
}
|
}
|
||||||
|
|
@ -1231,7 +1279,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
new_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||||
|
|
@ -1239,7 +1293,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.set_pane_frames(self.draw_pane_frames);
|
self.set_pane_frames(self.draw_pane_frames);
|
||||||
}
|
}
|
||||||
|
|
@ -1269,7 +1329,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = prev_geom_override {
|
if let Some(geom) = prev_geom_override {
|
||||||
new_position.set_geom_override(geom);
|
new_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(new_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
new_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
new_position.set_should_render(true);
|
new_position.set_should_render(true);
|
||||||
|
|
||||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||||
|
|
@ -1277,7 +1343,13 @@ impl TiledPanes {
|
||||||
if let Some(geom) = next_geom_override {
|
if let Some(geom) = next_geom_override {
|
||||||
current_position.set_geom_override(geom);
|
current_position.set_geom_override(geom);
|
||||||
}
|
}
|
||||||
resize_pty!(current_position, self.os_api, self.senders).unwrap();
|
resize_pty!(
|
||||||
|
current_position,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
current_position.set_should_render(true);
|
current_position.set_should_render(true);
|
||||||
self.set_pane_frames(self.draw_pane_frames);
|
self.set_pane_frames(self.draw_pane_frames);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ impl<'a> LayoutApplier<'a> {
|
||||||
Some(position_and_size),
|
Some(position_and_size),
|
||||||
);
|
);
|
||||||
pane_focuser.set_pane_id_in_focused_location(layout.focus, &pane);
|
pane_focuser.set_pane_id_in_focused_location(layout.focus, &pane);
|
||||||
resize_pty!(pane, self.os_api, self.senders)?;
|
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size)?;
|
||||||
self.tiled_panes
|
self.tiled_panes
|
||||||
.add_pane_with_existing_geom(pane.pid(), pane);
|
.add_pane_with_existing_geom(pane.pid(), pane);
|
||||||
}
|
}
|
||||||
|
|
@ -305,7 +305,12 @@ impl<'a> LayoutApplier<'a> {
|
||||||
);
|
);
|
||||||
new_pane.set_borderless(false);
|
new_pane.set_borderless(false);
|
||||||
new_pane.set_content_offset(Offset::frame(1));
|
new_pane.set_content_offset(Offset::frame(1));
|
||||||
resize_pty!(new_pane, self.os_api, self.senders)?;
|
resize_pty!(
|
||||||
|
new_pane,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)?;
|
||||||
self.floating_panes
|
self.floating_panes
|
||||||
.add_pane(PaneId::Plugin(pid), Box::new(new_pane));
|
.add_pane(PaneId::Plugin(pid), Box::new(new_pane));
|
||||||
if floating_pane_layout.focus.unwrap_or(false) {
|
if floating_pane_layout.focus.unwrap_or(false) {
|
||||||
|
|
@ -340,7 +345,12 @@ impl<'a> LayoutApplier<'a> {
|
||||||
if let Some(held_command) = hold_for_command {
|
if let Some(held_command) = hold_for_command {
|
||||||
new_pane.hold(None, true, held_command.clone());
|
new_pane.hold(None, true, held_command.clone());
|
||||||
}
|
}
|
||||||
resize_pty!(new_pane, self.os_api, self.senders)?;
|
resize_pty!(
|
||||||
|
new_pane,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)?;
|
||||||
self.floating_panes
|
self.floating_panes
|
||||||
.add_pane(PaneId::Terminal(*pid), Box::new(new_pane));
|
.add_pane(PaneId::Terminal(*pid), Box::new(new_pane));
|
||||||
if floating_pane_layout.focus.unwrap_or(false) {
|
if floating_pane_layout.focus.unwrap_or(false) {
|
||||||
|
|
@ -398,7 +408,7 @@ impl<'a> LayoutApplier<'a> {
|
||||||
.focus
|
.focus
|
||||||
.or(Some(!layout_has_focused_pane));
|
.or(Some(!layout_has_focused_pane));
|
||||||
pane_focuser.set_pane_id_in_focused_location(pane_is_focused, &pane);
|
pane_focuser.set_pane_id_in_focused_location(pane_is_focused, &pane);
|
||||||
resize_pty!(pane, self.os_api, self.senders)?;
|
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size)?;
|
||||||
self.floating_panes.add_pane(pane.pid(), pane);
|
self.floating_panes.add_pane(pane.pid(), pane);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -415,7 +425,7 @@ impl<'a> LayoutApplier<'a> {
|
||||||
);
|
);
|
||||||
pane_focuser
|
pane_focuser
|
||||||
.set_pane_id_in_focused_location(Some(!layout_has_focused_pane), &pane);
|
.set_pane_id_in_focused_location(Some(!layout_has_focused_pane), &pane);
|
||||||
resize_pty!(pane, self.os_api, self.senders)?;
|
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size)?;
|
||||||
self.floating_panes.add_pane(pane.pid(), pane);
|
self.floating_panes.add_pane(pane.pid(), pane);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,42 @@ macro_rules! resize_pty {
|
||||||
*pid,
|
*pid,
|
||||||
$pane.get_content_columns() as u16,
|
$pane.get_content_columns() as u16,
|
||||||
$pane.get_content_rows() as u16,
|
$pane.get_content_rows() as u16,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
PaneId::Plugin(ref pid) => {
|
||||||
|
let err_context = || format!("failed to resize plugin {pid}");
|
||||||
|
$senders
|
||||||
|
.send_to_plugin(PluginInstruction::Resize(
|
||||||
|
*pid,
|
||||||
|
$pane.get_content_columns(),
|
||||||
|
$pane.get_content_rows(),
|
||||||
|
))
|
||||||
|
.with_context(err_context)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
($pane:expr, $os_input:expr, $senders:expr, $character_cell_size:expr) => {{
|
||||||
|
let (width_in_pixels, height_in_pixels) = {
|
||||||
|
let character_cell_size = $character_cell_size.borrow();
|
||||||
|
match *character_cell_size {
|
||||||
|
Some(size_in_pixels) => {
|
||||||
|
let width_in_pixels =
|
||||||
|
(size_in_pixels.width * $pane.get_content_columns()) as u16;
|
||||||
|
let height_in_pixels =
|
||||||
|
(size_in_pixels.height * $pane.get_content_rows()) as u16;
|
||||||
|
(Some(width_in_pixels), Some(height_in_pixels))
|
||||||
|
},
|
||||||
|
None => (None, None),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match $pane.pid() {
|
||||||
|
PaneId::Terminal(ref pid) => $os_input.set_terminal_size_using_terminal_id(
|
||||||
|
*pid,
|
||||||
|
$pane.get_content_columns() as u16,
|
||||||
|
$pane.get_content_rows() as u16,
|
||||||
|
width_in_pixels,
|
||||||
|
height_in_pixels,
|
||||||
),
|
),
|
||||||
PaneId::Plugin(ref pid) => {
|
PaneId::Plugin(ref pid) => {
|
||||||
let err_context = || format!("failed to resize plugin {pid}");
|
let err_context = || format!("failed to resize plugin {pid}");
|
||||||
|
|
@ -490,6 +526,7 @@ impl Tab {
|
||||||
connected_clients.clone(),
|
connected_clients.clone(),
|
||||||
connected_clients_in_app,
|
connected_clients_in_app,
|
||||||
mode_info.clone(),
|
mode_info.clone(),
|
||||||
|
character_cell_size.clone(),
|
||||||
session_is_mirrored,
|
session_is_mirrored,
|
||||||
default_mode_info.clone(),
|
default_mode_info.clone(),
|
||||||
style,
|
style,
|
||||||
|
|
@ -900,7 +937,12 @@ impl Tab {
|
||||||
embedded_pane_to_float.set_content_offset(Offset::frame(1));
|
embedded_pane_to_float.set_content_offset(Offset::frame(1));
|
||||||
}
|
}
|
||||||
embedded_pane_to_float.set_geom(new_pane_geom);
|
embedded_pane_to_float.set_geom(new_pane_geom);
|
||||||
resize_pty!(embedded_pane_to_float, self.os_api, self.senders)
|
resize_pty!(
|
||||||
|
embedded_pane_to_float,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
embedded_pane_to_float.set_active_at(Instant::now());
|
embedded_pane_to_float.set_active_at(Instant::now());
|
||||||
self.floating_panes
|
self.floating_panes
|
||||||
|
|
@ -1001,7 +1043,13 @@ impl Tab {
|
||||||
);
|
);
|
||||||
new_pane.set_active_at(Instant::now());
|
new_pane.set_active_at(Instant::now());
|
||||||
new_pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame
|
new_pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame
|
||||||
resize_pty!(new_pane, self.os_api, self.senders).with_context(err_context)?;
|
resize_pty!(
|
||||||
|
new_pane,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
|
.with_context(err_context)?;
|
||||||
self.floating_panes.add_pane(pid, Box::new(new_pane));
|
self.floating_panes.add_pane(pid, Box::new(new_pane));
|
||||||
self.floating_panes.focus_pane_for_all_clients(pid);
|
self.floating_panes.focus_pane_for_all_clients(pid);
|
||||||
}
|
}
|
||||||
|
|
@ -1101,7 +1149,12 @@ impl Tab {
|
||||||
self.get_active_pane(client_id)
|
self.get_active_pane(client_id)
|
||||||
.with_context(|| format!("no active pane found for client {client_id}"))
|
.with_context(|| format!("no active pane found for client {client_id}"))
|
||||||
.and_then(|current_active_pane| {
|
.and_then(|current_active_pane| {
|
||||||
resize_pty!(current_active_pane, self.os_api, self.senders)
|
resize_pty!(
|
||||||
|
current_active_pane,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
},
|
},
|
||||||
|
|
@ -1375,7 +1428,12 @@ impl Tab {
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
if self.pids_waiting_resize.remove(&pid) {
|
if self.pids_waiting_resize.remove(&pid) {
|
||||||
resize_pty!(terminal_output, self.os_api, self.senders)
|
resize_pty!(
|
||||||
|
terminal_output,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
}
|
}
|
||||||
terminal_output.handle_pty_bytes(bytes);
|
terminal_output.handle_pty_bytes(bytes);
|
||||||
|
|
@ -2212,7 +2270,12 @@ impl Tab {
|
||||||
// the pane there we replaced. Now, we need to update its pty about its new size.
|
// the pane there we replaced. Now, we need to update its pty about its new size.
|
||||||
// We couldn't do that before, and we can't use the original moved item now - so we
|
// We couldn't do that before, and we can't use the original moved item now - so we
|
||||||
// need to refetch it
|
// need to refetch it
|
||||||
resize_pty!(suppressed_pane, self.os_api, self.senders)?;
|
resize_pty!(
|
||||||
|
suppressed_pane,
|
||||||
|
self.os_api,
|
||||||
|
self.senders,
|
||||||
|
self.character_cell_size
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
Ok(replaced_pane)
|
Ok(replaced_pane)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,14 @@ struct FakeInputOutput {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerOsApi for FakeInputOutput {
|
impl ServerOsApi for FakeInputOutput {
|
||||||
fn set_terminal_size_using_terminal_id(&self, _id: u32, _cols: u16, _rows: u16) -> Result<()> {
|
fn set_terminal_size_using_terminal_id(
|
||||||
|
&self,
|
||||||
|
_id: u32,
|
||||||
|
_cols: u16,
|
||||||
|
_rows: u16,
|
||||||
|
_width_in_pixels: Option<u16>,
|
||||||
|
_height_in_pixels: Option<u16>,
|
||||||
|
) -> Result<()> {
|
||||||
// noop
|
// noop
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,14 @@ use zellij_utils::{
|
||||||
struct FakeInputOutput {}
|
struct FakeInputOutput {}
|
||||||
|
|
||||||
impl ServerOsApi for FakeInputOutput {
|
impl ServerOsApi for FakeInputOutput {
|
||||||
fn set_terminal_size_using_terminal_id(&self, _id: u32, _cols: u16, _rows: u16) -> Result<()> {
|
fn set_terminal_size_using_terminal_id(
|
||||||
|
&self,
|
||||||
|
_id: u32,
|
||||||
|
_cols: u16,
|
||||||
|
_rows: u16,
|
||||||
|
_width_in_pixels: Option<u16>,
|
||||||
|
_height_in_pixels: Option<u16>,
|
||||||
|
) -> Result<()> {
|
||||||
// noop
|
// noop
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,8 @@ impl ServerOsApi for FakeInputOutput {
|
||||||
_terminal_id: u32,
|
_terminal_id: u32,
|
||||||
_cols: u16,
|
_cols: u16,
|
||||||
_rows: u16,
|
_rows: u16,
|
||||||
|
_width_in_pixels: Option<u16>,
|
||||||
|
_height_in_pixels: Option<u16>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// noop
|
// noop
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue