Spawn new alacritty processes in CWD on macOS
On macOS we can use 'proc_pidinfo' to determine the working directory of the terminal foreground process. Fixes #1979.
This commit is contained in:
parent
43d1afbeeb
commit
4fc35f6038
|
@ -31,7 +31,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Cursors are now inverted when their fixed color is similar to the cell's background
|
- Cursors are now inverted when their fixed color is similar to the cell's background
|
||||||
- Use working directory of active process instead of shell for SpawnNewInstance action
|
- Use the working directory of the terminal foreground process, instead of the shell's working
|
||||||
|
directory, for `SpawnNewInstance` action
|
||||||
- Fallback to normal underline for unsupported underline types in `CSI 4 : ? m` escapes
|
- Fallback to normal underline for unsupported underline types in `CSI 4 : ? m` escapes
|
||||||
- The user's background color is now used as the foreground for the render timer
|
- The user's background color is now used as the foreground for the render timer
|
||||||
- Use yellow/red from the config for error and warning messages instead of fixed colors
|
- Use yellow/red from the config for error and warning messages instead of fixed colors
|
||||||
|
@ -39,6 +40,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Wayland's Client side decorations now use the search bar colors
|
- Wayland's Client side decorations now use the search bar colors
|
||||||
- Reduce memory usage by up to at least 30% with a full scrollback buffer
|
- Reduce memory usage by up to at least 30% with a full scrollback buffer
|
||||||
- The number of zerowidth characters per cell is no longer limited to 5
|
- The number of zerowidth characters per cell is no longer limited to 5
|
||||||
|
- `SpawnNewInstance` is now using the working directory of the terminal foreground process on macOS
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::borrow::Cow;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
#[cfg(unix)]
|
#[cfg(not(any(target_os = "macos", windows)))]
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
@ -45,6 +45,8 @@ use crate::config::Config;
|
||||||
use crate::daemon::start_daemon;
|
use crate::daemon::start_daemon;
|
||||||
use crate::display::{Display, DisplayUpdate};
|
use crate::display::{Display, DisplayUpdate};
|
||||||
use crate::input::{self, ActionContext as _, FONT_SIZE_STEP};
|
use crate::input::{self, ActionContext as _, FONT_SIZE_STEP};
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use crate::macos;
|
||||||
use crate::message_bar::{Message, MessageBuffer};
|
use crate::message_bar::{Message, MessageBuffer};
|
||||||
use crate::scheduler::{Scheduler, TimerId};
|
use crate::scheduler::{Scheduler, TimerId};
|
||||||
use crate::url::{Url, Urls};
|
use crate::url::{Url, Urls};
|
||||||
|
@ -309,15 +311,17 @@ impl<'a, N: Notify + 'a, T: EventListener> input::ActionContext<T> for ActionCon
|
||||||
pid = tty::child_pid();
|
pid = tty::child_pid();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "freebsd"))]
|
#[cfg(not(any(target_os = "macos", target_os = "freebsd")))]
|
||||||
let link_path = format!("/proc/{}/cwd", pid);
|
let link_path = format!("/proc/{}/cwd", pid);
|
||||||
#[cfg(target_os = "freebsd")]
|
#[cfg(target_os = "freebsd")]
|
||||||
let link_path = format!("/compat/linux/proc/{}/cwd", pid);
|
let link_path = format!("/compat/linux/proc/{}/cwd", pid);
|
||||||
|
#[cfg(not(target_os = "macos"))]
|
||||||
|
let cwd = fs::read_link(link_path);
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
let cwd = macos::proc::cwd(pid);
|
||||||
|
|
||||||
// Add the current working directory as parameter.
|
// Add the current working directory as parameter.
|
||||||
fs::read_link(link_path)
|
cwd.map(|path| vec!["--working-directory".into(), path]).unwrap_or_default()
|
||||||
.map(|path| vec!["--working-directory".into(), path])
|
|
||||||
.unwrap_or_default()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
#[cfg(not(unix))]
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod locale;
|
||||||
|
pub mod proc;
|
|
@ -0,0 +1,160 @@
|
||||||
|
use std::ffi::{CStr, CString, IntoStringError};
|
||||||
|
use std::fmt::{self, Display, Formatter};
|
||||||
|
use std::io;
|
||||||
|
use std::mem::{self, MaybeUninit};
|
||||||
|
use std::os::raw::{c_int, c_void};
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
/// Error during working directory retrieval.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
Io(io::Error),
|
||||||
|
|
||||||
|
/// Error converting into utf8 string.
|
||||||
|
IntoString(IntoStringError),
|
||||||
|
|
||||||
|
/// Expected return size didn't match libproc's.
|
||||||
|
InvalidSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
|
match self {
|
||||||
|
Error::InvalidSize => None,
|
||||||
|
Error::Io(err) => err.source(),
|
||||||
|
Error::IntoString(err) => err.source(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Error {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Error::InvalidSize => write!(f, "Invalid proc_pidinfo return size"),
|
||||||
|
Error::Io(err) => write!(f, "Error getting current working directory: {}", err),
|
||||||
|
Error::IntoString(err) => {
|
||||||
|
write!(f, "Error when parsing current working directory: {}", err)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<io::Error> for Error {
|
||||||
|
fn from(val: io::Error) -> Self {
|
||||||
|
Error::Io(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<IntoStringError> for Error {
|
||||||
|
fn from(val: IntoStringError) -> Self {
|
||||||
|
Error::IntoString(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cwd(pid: c_int) -> Result<PathBuf, Error> {
|
||||||
|
let mut info = MaybeUninit::<sys::proc_vnodepathinfo>::uninit();
|
||||||
|
let info_ptr = info.as_mut_ptr() as *mut c_void;
|
||||||
|
let size = mem::size_of::<sys::proc_vnodepathinfo>() as c_int;
|
||||||
|
|
||||||
|
let c_str = unsafe {
|
||||||
|
let pidinfo_size = sys::proc_pidinfo(pid, sys::PROC_PIDVNODEPATHINFO, 0, info_ptr, size);
|
||||||
|
match pidinfo_size {
|
||||||
|
c if c < 0 => return Err(io::Error::last_os_error().into()),
|
||||||
|
s if s != size => return Err(Error::InvalidSize),
|
||||||
|
_ => CStr::from_ptr(info.assume_init().pvi_cdir.vip_path.as_ptr()),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(CString::from(c_str).into_string().map(PathBuf::from)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bindings for libproc.
|
||||||
|
#[allow(non_camel_case_types)]
|
||||||
|
mod sys {
|
||||||
|
use std::os::raw::{c_char, c_int, c_longlong, c_void};
|
||||||
|
|
||||||
|
pub const PROC_PIDVNODEPATHINFO: c_int = 9;
|
||||||
|
|
||||||
|
type gid_t = c_int;
|
||||||
|
type off_t = c_longlong;
|
||||||
|
type uid_t = c_int;
|
||||||
|
type fsid_t = fsid;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct fsid {
|
||||||
|
pub val: [i32; 2usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct vinfo_stat {
|
||||||
|
pub vst_dev: u32,
|
||||||
|
pub vst_mode: u16,
|
||||||
|
pub vst_nlink: u16,
|
||||||
|
pub vst_ino: u64,
|
||||||
|
pub vst_uid: uid_t,
|
||||||
|
pub vst_gid: gid_t,
|
||||||
|
pub vst_atime: i64,
|
||||||
|
pub vst_atimensec: i64,
|
||||||
|
pub vst_mtime: i64,
|
||||||
|
pub vst_mtimensec: i64,
|
||||||
|
pub vst_ctime: i64,
|
||||||
|
pub vst_ctimensec: i64,
|
||||||
|
pub vst_birthtime: i64,
|
||||||
|
pub vst_birthtimensec: i64,
|
||||||
|
pub vst_size: off_t,
|
||||||
|
pub vst_blocks: i64,
|
||||||
|
pub vst_blksize: i32,
|
||||||
|
pub vst_flags: u32,
|
||||||
|
pub vst_gen: u32,
|
||||||
|
pub vst_rdev: u32,
|
||||||
|
pub vst_qspare: [i64; 2usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct vnode_info {
|
||||||
|
pub vi_stat: vinfo_stat,
|
||||||
|
pub vi_type: c_int,
|
||||||
|
pub vi_pad: c_int,
|
||||||
|
pub vi_fsid: fsid_t,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct vnode_info_path {
|
||||||
|
pub vip_vi: vnode_info,
|
||||||
|
pub vip_path: [c_char; 1024usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct proc_vnodepathinfo {
|
||||||
|
pub pvi_cdir: vnode_info_path,
|
||||||
|
pub pvi_rdir: vnode_info_path,
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub fn proc_pidinfo(
|
||||||
|
pid: c_int,
|
||||||
|
flavor: c_int,
|
||||||
|
arg: u64,
|
||||||
|
buffer: *mut c_void,
|
||||||
|
buffersize: c_int,
|
||||||
|
) -> c_int;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
use std::process;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cwd_matches_current_dir() {
|
||||||
|
assert_eq!(cwd(process::id() as i32).ok(), env::current_dir().ok());
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,9 +38,9 @@ mod daemon;
|
||||||
mod display;
|
mod display;
|
||||||
mod event;
|
mod event;
|
||||||
mod input;
|
mod input;
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
mod locale;
|
|
||||||
mod logging;
|
mod logging;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
mod macos;
|
||||||
mod message_bar;
|
mod message_bar;
|
||||||
mod meter;
|
mod meter;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -63,6 +63,8 @@ use crate::config::monitor;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::display::Display;
|
use crate::display::Display;
|
||||||
use crate::event::{Event, EventProxy, Processor};
|
use crate::event::{Event, EventProxy, Processor};
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use crate::macos::locale;
|
||||||
use crate::message_bar::MessageBuffer;
|
use crate::message_bar::MessageBuffer;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
Loading…
Reference in New Issue