diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ae5f202..6d0b0c30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - New configuration field `visual_bell.color` allows changing the visual bell color +- Crashes on Windows are now also reported with a popup in addition to stderr ### Fixed diff --git a/src/lib.rs b/src/lib.rs index d52c457b..30eb408d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -49,6 +49,7 @@ pub mod input; pub mod locale; pub mod logging; pub mod meter; +pub mod panic; pub mod renderer; pub mod selection; pub mod sync; diff --git a/src/main.rs b/src/main.rs index fea14b5f..2ce43fe1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,12 +47,15 @@ use alacritty::config::{self, Config, Error as ConfigError}; use alacritty::display::Display; use alacritty::event_loop::{self, EventLoop, Msg}; use alacritty::logging::{self, LoggerProxy}; +use alacritty::panic; use alacritty::sync::FairMutex; use alacritty::term::Term; use alacritty::tty::{self, process_should_exit}; use alacritty::util::fmt::Red; fn main() { + panic::attach_handler(); + // When linked with the windows subsystem windows won't automatically attach // to the console of the parent process, so we do it explicitly. This fails // silently if the parent has no console. diff --git a/src/panic.rs b/src/panic.rs new file mode 100644 index 00000000..4d3524ed --- /dev/null +++ b/src/panic.rs @@ -0,0 +1,53 @@ +// Copyright 2016 Joe Wilm, The Alacritty Project Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//! ANSI Terminal Stream Parsing + +// Use the default behavior of the other platforms. +#[cfg(not(windows))] +pub fn attach_handler() {} + +// Install a panic handler that renders the panic in a classical Windows error +// dialog box as well as writes the panic to STDERR. +#[cfg(windows)] +pub fn attach_handler() { + use std::{io, io::Write, panic, ptr}; + use winapi::um::winuser; + + panic::set_hook(Box::new(|panic_info| { + let _ = writeln!(io::stderr(), "{}", panic_info); + let msg = format!("{}\n\nPress Ctrl-C to Copy", panic_info); + unsafe { + winuser::MessageBoxW( + ptr::null_mut(), + win32_string(&msg).as_ptr(), + win32_string("Alacritty: Runtime Error").as_ptr(), + winuser::MB_ICONERROR + | winuser::MB_OK + | winuser::MB_SETFOREGROUND + | winuser::MB_TASKMODAL, + ); + } + })); +} + +// Converts the string slice into a Windows-standard representation for "W"- +// suffixed function variants, which accept UTF-16 encoded string values. +#[cfg(windows)] +fn win32_string(value: &str) -> Vec { + use std::ffi::OsStr; + use std::iter::once; + use std::os::windows::ffi::OsStrExt; + OsStr::new(value).encode_wide().chain(once(0)).collect() +}