alacritty

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit ea87c1546b98265332239ccf6ff7eb45d7549ee2
parent 9ba7c4fae4d927e109c7981f7e11ca7acdc14eb3
Author: David Hewitt <1939362+davidhewitt@users.noreply.github.com>
Date:   Thu,  7 Mar 2019 20:37:11 +0000

Add dynamic title support for Window



Diffstat:
MCHANGELOG.md | 1+
Msrc/term/mod.rs | 14++++++++++++++
Msrc/tty/windows/conpty.rs | 22+++++++++-------------
Msrc/tty/windows/mod.rs | 7+++++++
Msrc/window.rs | 7++-----
5 files changed, 33 insertions(+), 18 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - MSI installer for Windows is now available - New default key bindings Alt+Home, Alt+End, Alt+PageUp and Alt+PageDown +- Dynamic title support on Windows ### Fixed diff --git a/src/term/mod.rs b/src/term/mod.rs @@ -786,6 +786,7 @@ pub struct Term { /// Default style for resetting the cursor default_cursor_style: CursorStyle, + /// Whether to permit updating the terminal title dynamic_title: bool, /// Number of spaces in one tab @@ -1357,6 +1358,19 @@ impl ansi::Handler for Term { fn set_title(&mut self, title: &str) { if self.dynamic_title { self.next_title = Some(title.to_owned()); + + #[cfg(windows)] + { + // cmd.exe in winpty: winpty incorrectly sets the title to ' ' instead of + // 'Alacritty' - thus we have to substitute this back to get equivalent + // behaviour as conpty. + // + // The starts_with check is necessary because other shells e.g. bash set a + // different title and don't need Alacritty prepended. + if !tty::is_conpty() && title.starts_with(' ') { + self.next_title = Some(format!("Alacritty {}", title.trim())); + } + } } } diff --git a/src/tty/windows/conpty.rs b/src/tty/windows/conpty.rs @@ -27,7 +27,7 @@ use widestring::U16CString; use winapi::ctypes::c_void; use winapi::shared::basetsd::{PSIZE_T, SIZE_T}; use winapi::shared::minwindef::{BYTE, DWORD}; -use winapi::shared::ntdef::{HANDLE, HRESULT, LPCWSTR, LPWSTR}; +use winapi::shared::ntdef::{HANDLE, HRESULT, LPWSTR}; use winapi::shared::winerror::S_OK; use winapi::um::libloaderapi::{GetModuleHandleA, GetProcAddress}; use winapi::um::processthreadsapi::{ @@ -147,6 +147,11 @@ pub fn new<'a>( let mut size: SIZE_T = 0; let mut startup_info_ex: STARTUPINFOEXW = Default::default(); + + let title = options.title.as_ref().map(|w| w.as_str()).unwrap_or("Alacritty"); + let title = U16CString::from_str(title).unwrap(); + startup_info_ex.StartupInfo.lpTitle = title.as_ptr() as LPWSTR; + startup_info_ex.StartupInfo.cb = mem::size_of::<STARTUPINFOEXW>() as u32; // Setting this flag but leaving all the handles as default (null) ensures the @@ -216,24 +221,20 @@ pub fn new<'a>( let cwd = cwd.as_ref().map(|dir| dir.to_str().unwrap()); // Create the client application, using startup info containing ConPTY info - let cmdline = U16CString::from_str(&cmdline.join(" ")).unwrap().into_raw(); + let cmdline = U16CString::from_str(&cmdline.join(" ")).unwrap(); let cwd = cwd.map(|s| U16CString::from_str(&s).unwrap()); - let cwd_ptr = match &cwd { - Some(b) => b.as_ptr() as LPCWSTR, - None => ptr::null(), - }; let mut proc_info: PROCESS_INFORMATION = Default::default(); unsafe { success = CreateProcessW( ptr::null(), - cmdline as LPWSTR, + cmdline.as_ptr() as LPWSTR, ptr::null_mut(), ptr::null_mut(), false as i32, EXTENDED_STARTUPINFO_PRESENT, ptr::null_mut(), - cwd_ptr, + cwd.map_or_else(ptr::null, |s| s.as_ptr()), &mut startup_info_ex.StartupInfo as *mut STARTUPINFOW, &mut proc_info as *mut PROCESS_INFORMATION, ) > 0; @@ -241,11 +242,6 @@ pub fn new<'a>( assert!(success); } - // Recover raw memory to cmdline so it can be freed - unsafe { - U16CString::from_raw(cmdline); - } - // Store handle to console unsafe { HANDLE = proc_info.hProcess; diff --git a/src/tty/windows/mod.rs b/src/tty/windows/mod.rs @@ -14,6 +14,7 @@ use std::io::{self, Read, Write}; use std::os::raw::c_void; +use std::sync::atomic::{AtomicBool, Ordering}; use mio::{self, Evented, Poll, PollOpt, Ready, Token}; use mio_anonymous_pipes::{EventedAnonRead, EventedAnonWrite}; @@ -34,6 +35,7 @@ mod winpty; /// Handle to the winpty agent or conpty process. Required so we know when it closes. static mut HANDLE: *mut c_void = 0usize as *mut c_void; +static IS_CONPTY: AtomicBool = AtomicBool::new(false); pub fn process_should_exit() -> bool { unsafe { @@ -54,6 +56,10 @@ pub fn process_should_exit() -> bool { } } +pub fn is_conpty() -> bool { + IS_CONPTY.load(Ordering::Relaxed) +} + #[derive(Clone)] pub enum PtyHandle<'a> { Winpty(winpty::WinptyHandle<'a>), @@ -86,6 +92,7 @@ pub fn new<'a>( ) -> Pty<'a> { if let Some(pty) = conpty::new(config, options, size, window_id) { info!("Using Conpty agent"); + IS_CONPTY.store(true, Ordering::Relaxed); pty } else { info!("Using Winpty agent"); diff --git a/src/window.rs b/src/window.rs @@ -224,11 +224,8 @@ impl Window { /// Set the window title #[inline] - pub fn set_title(&self, _title: &str) { - // Because winpty doesn't know anything about OSC escapes this gets set to an empty - // string on windows - #[cfg(not(windows))] - self.window.set_title(_title); + pub fn set_title(&self, title: &str) { + self.window.set_title(title); } #[inline]