Add dynamic title support for Window

This commit is contained in:
David Hewitt 2019-03-07 20:37:11 +00:00 committed by Christian Duerr
parent 9ba7c4fae4
commit ea87c1546b
5 changed files with 33 additions and 18 deletions

View File

@ -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

View File

@ -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()));
}
}
}
}

View File

@ -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;

View File

@ -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");

View File

@ -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]