alacritty

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

commit e9813031f6e308984cb5547aa1049839cb75745f
parent b0efa9d105b53211d8df094238c7eb8324e93566
Author: acheronfail <acheronfail@gmail.com>
Date:   Wed, 24 Apr 2019 05:05:47 +1000

Add fullscreen support

Fixes #34.
Fixes #2012.
Diffstat:
MCHANGELOG.md | 8++++++++
Malacritty.yml | 22+++++++++++++++++-----
Msrc/config/bindings.rs | 18+++++++++++++++++-
Msrc/config/mod.rs | 45++++++++++++++++++++++++++++++++++++++++-----
Msrc/display.rs | 4++--
Msrc/event.rs | 43++++++++++++++++++++++++++++++++++++-------
Msrc/input.rs | 22++++++++++++++++++++++
Msrc/window.rs | 40+++++++++++++++++++++++++++++++++++-----
8 files changed, 177 insertions(+), 25 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -6,9 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Added ToggleFullscreen action +- On macOS, there's a ToggleSimpleFullscreen action which allows switching to + fullscreen without occupying another space +- A new window option `startup_mode` which controls how the window is created + ### Changed - On Windows, Alacritty will now use the native DirectWrite font API +- The `start_maximized` window option is now `startup_mode: Maximized` ## Version 0.3.2 diff --git a/alacritty.yml b/alacritty.yml @@ -51,8 +51,16 @@ window: # - buttonless: Title bar, transparent background, but no title bar buttons decorations: full - # When true, alacritty starts maximized. - start_maximized: false + # Startup Mode (changes require restart) + # + # Values for `startup_mode`: + # - Windowed + # - Maximized + # - Fullscreen + # + # Values for `startup_mode` (macOS only): + # - SimpleFullscreen + startup_mode: Windowed scrolling: # Maximum number of lines in the scrollback buffer. @@ -184,11 +192,11 @@ colors: #cursor: # text: '0x000000' # cursor: '0xffffff' - + # Selection colors # - # Colors which should be used to draw the selection area. If selection - # background is unset, selection color will be the inverse of the cell colors. + # Colors which should be used to draw the selection area. If selection + # background is unset, selection color will be the inverse of the cell colors. # If only text is unset the cell text color will remain the same. #selection: # text: '0xeaeaea' @@ -449,8 +457,12 @@ alt_send_esc: true # - Quit # - ClearLogNotice # - SpawnNewInstance +# - ToggleFullscreen # - None # +# Values for `action` (macOS only): +# - ToggleSimpleFullscreen: Enters fullscreen without occupying another space +# # Values for `command`: # The `command` field must be a map containing a `program` string and # an `args` array of command line parameter strings. diff --git a/src/config/bindings.rs b/src/config/bindings.rs @@ -178,7 +178,7 @@ pub fn default_key_bindings() -> Vec<KeyBinding> { } #[cfg(not(any(target_os = "macos", test)))] -pub fn platform_key_bindings() -> Vec<KeyBinding> { +fn common_keybindings() -> Vec<KeyBinding> { bindings!( KeyBinding; Key::V, [ctrl: true, shift: true]; Action::Paste; @@ -192,6 +192,21 @@ pub fn platform_key_bindings() -> Vec<KeyBinding> { ) } +#[cfg(not(any(target_os = "macos", target_os = "windows", test)))] +pub fn platform_key_bindings() -> Vec<KeyBinding> { + common_keybindings() +} + +#[cfg(all(target_os = "windows", not(test)))] +pub fn platform_key_bindings() -> Vec<KeyBinding> { + let mut bindings = bindings!( + KeyBinding; + Key::Return, [alt: true]; Action::ToggleFullscreen; + ); + bindings.extend(common_keybindings()); + bindings +} + #[cfg(all(target_os = "macos", not(test)))] pub fn platform_key_bindings() -> Vec<KeyBinding> { bindings!( @@ -200,6 +215,7 @@ pub fn platform_key_bindings() -> Vec<KeyBinding> { Key::Equals, [logo: true]; Action::IncreaseFontSize; Key::Add, [logo: true]; Action::IncreaseFontSize; Key::Minus, [logo: true]; Action::DecreaseFontSize; + Key::F, [ctrl: true, logo: true]; Action::ToggleFullscreen; Key::K, [logo: true]; Action::ClearHistory; Key::K, [logo: true]; Action::Esc("\x0c".into()); Key::V, [logo: true]; Action::Paste; diff --git a/src/config/mod.rs b/src/config/mod.rs @@ -318,6 +318,21 @@ impl Default for Alpha { } } +#[derive(Debug, Deserialize, Copy, Clone, PartialEq, Eq)] +pub enum StartupMode { + Windowed, + Maximized, + Fullscreen, + #[cfg(target_os = "macos")] + SimpleFullscreen, +} + +impl Default for StartupMode { + fn default() -> StartupMode { + StartupMode::Windowed + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum Decorations { Full, @@ -438,9 +453,13 @@ pub struct WindowConfig { #[serde(deserialize_with = "failure_default")] dynamic_padding: bool, - /// Start maximized + /// Startup mode + #[serde(deserialize_with = "failure_default")] + startup_mode: StartupMode, + + /// TODO: DEPRECATED #[serde(deserialize_with = "failure_default")] - start_maximized: bool, + start_maximized: Option<bool>, } impl Default for WindowConfig { @@ -452,6 +471,7 @@ impl Default for WindowConfig { decorations: Default::default(), dynamic_padding: Default::default(), start_maximized: Default::default(), + startup_mode: Default::default(), } } } @@ -482,8 +502,8 @@ impl WindowConfig { self.dynamic_padding } - pub fn start_maximized(&self) -> bool { - self.start_maximized + pub fn startup_mode(&self) -> StartupMode { + self.startup_mode } pub fn position(&self) -> Option<Delta<i32>> { @@ -874,7 +894,7 @@ impl<'a> de::Deserialize<'a> for ActionWrapper { "Paste, Copy, PasteSelection, IncreaseFontSize, DecreaseFontSize, \ ResetFontSize, ScrollPageUp, ScrollPageDown, ScrollLineUp, ScrollLineDown, \ ScrollToTop, ScrollToBottom, ClearHistory, Hide, ClearLogNotice, \ - SpawnNewInstance, None or Quit", + SpawnNewInstance, ToggleFullscreen, ToggleSimpleFullscreen, None or Quit", ) } @@ -900,6 +920,9 @@ impl<'a> de::Deserialize<'a> for ActionWrapper { "Quit" => Action::Quit, "ClearLogNotice" => Action::ClearLogNotice, "SpawnNewInstance" => Action::SpawnNewInstance, + "ToggleFullscreen" => Action::ToggleFullscreen, + #[cfg(target_os = "macos")] + "ToggleSimpleFullscreen" => Action::ToggleSimpleFullscreen, "None" => Action::None, _ => return Err(E::invalid_value(Unexpected::Str(value), &self)), })) @@ -1992,6 +2015,18 @@ impl Config { instead" ); } + + if let Some(start_maximized) = self.window.start_maximized { + warn!( + "Config window.start_maximized is deprecated; please use window.startup_mode \ + instead" + ); + + // While `start_maximized` is deprecated its setting takes precedence. + if start_maximized { + self.window.startup_mode = StartupMode::Maximized; + } + } } } diff --git a/src/display.rs b/src/display.rs @@ -22,7 +22,7 @@ use glutin::EventsLoop; use parking_lot::MutexGuard; use crate::cli; -use crate::config::Config; +use crate::config::{Config, StartupMode}; use crate::index::Line; use crate::message_bar::Message; use crate::meter::Meter; @@ -249,7 +249,7 @@ impl Display { if dimensions.columns_u32() == 0 || dimensions.lines_u32() == 0 - || config.window().start_maximized() + || config.window().startup_mode() != StartupMode::Windowed { return None; } diff --git a/src/event.rs b/src/event.rs @@ -188,25 +188,41 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> { Err(_) => warn!("Unable to start new Alacritty process: {} {:?}", alacritty, args), } } + + fn toggle_fullscreen(&mut self) { + self.window_changes.toggle_fullscreen(); + } + + #[cfg(target_os = "macos")] + fn toggle_simple_fullscreen(&mut self) { + self.window_changes.toggle_simple_fullscreen() + } } /// The ActionContext can't really have direct access to the Window /// with the current design. Event handlers that want to change the /// window must set these flags instead. The processor will trigger /// the actual changes. +#[derive(Default)] pub struct WindowChanges { pub hide: bool, + pub toggle_fullscreen: bool, + #[cfg(target_os = "macos")] + pub toggle_simple_fullscreen: bool, } impl WindowChanges { fn clear(&mut self) { - self.hide = false; + *self = WindowChanges::default(); + } + + fn toggle_fullscreen(&mut self) { + self.toggle_fullscreen = !self.toggle_fullscreen; } -} -impl Default for WindowChanges { - fn default() -> WindowChanges { - WindowChanges { hide: false } + #[cfg(target_os = "macos")] + fn toggle_simple_fullscreen(&mut self) { + self.toggle_simple_fullscreen = !self.toggle_simple_fullscreen; } } @@ -281,6 +297,8 @@ pub struct Processor<N> { window_changes: WindowChanges, save_to_clipboard: bool, alt_send_esc: bool, + is_fullscreen: bool, + is_simple_fullscreen: bool, } /// Notify that the terminal was resized @@ -326,6 +344,8 @@ impl<N: Notify> Processor<N> { window_changes: Default::default(), save_to_clipboard: config.selection().save_to_clipboard, alt_send_esc: config.alt_send_esc(), + is_fullscreen: false, + is_simple_fullscreen: false, } } @@ -546,8 +566,17 @@ impl<N: Notify> Processor<N> { window.hide(); } - if self.window_changes.hide { - window.hide(); + #[cfg(target_os = "macos")] + { + if self.window_changes.toggle_simple_fullscreen && !self.is_fullscreen { + window.set_simple_fullscreen(!self.is_simple_fullscreen); + self.is_simple_fullscreen = !self.is_simple_fullscreen; + } + } + + if self.window_changes.toggle_fullscreen && !self.is_simple_fullscreen { + window.set_fullscreen(!self.is_fullscreen); + self.is_fullscreen = !self.is_fullscreen; } self.window_changes.clear(); diff --git a/src/input.rs b/src/input.rs @@ -81,6 +81,9 @@ pub trait ActionContext { fn terminal(&self) -> &Term; fn terminal_mut(&mut self) -> &mut Term; fn spawn_new_instance(&mut self); + fn toggle_fullscreen(&mut self); + #[cfg(target_os = "macos")] + fn toggle_simple_fullscreen(&mut self); } /// Describes a state and action to take in that state @@ -250,6 +253,13 @@ pub enum Action { /// Spawn a new instance of Alacritty. SpawnNewInstance, + /// Toggle fullscreen. + ToggleFullscreen, + + /// Toggle simple fullscreen on macos. + #[cfg(target_os = "macos")] + ToggleSimpleFullscreen, + /// No action. None, } @@ -302,6 +312,13 @@ impl Action { }, } }, + Action::ToggleFullscreen => { + ctx.toggle_fullscreen(); + }, + #[cfg(target_os = "macos")] + Action::ToggleSimpleFullscreen => { + ctx.toggle_simple_fullscreen(); + }, Action::Hide => { ctx.hide_window(); }, @@ -995,6 +1012,11 @@ mod tests { fn spawn_new_instance(&mut self) {} + fn toggle_fullscreen(&mut self) {} + + #[cfg(target_os = "macos")] + fn toggle_simple_fullscreen(&mut self) {} + fn terminal(&self) -> &Term { &self.terminal } diff --git a/src/window.rs b/src/window.rs @@ -28,7 +28,7 @@ use glutin::{ use image::ImageFormat; use crate::cli::Options; -use crate::config::{Decorations, WindowConfig}; +use crate::config::{Decorations, StartupMode, WindowConfig}; #[cfg(windows)] static WINDOW_ICON: &'static [u8] = include_bytes!("../extra/windows/alacritty.ico"); @@ -159,7 +159,7 @@ impl Window { // Maximize window after mapping in X11 #[cfg(not(any(target_os = "macos", windows)))] { - if event_loop.is_x11() && window_config.start_maximized() { + if event_loop.is_x11() && window_config.startup_mode() == StartupMode::Maximized { window.set_maximized(true); } } @@ -175,6 +175,19 @@ impl Window { window.set_position(logical); } + if let StartupMode::Fullscreen = window_config.startup_mode() { + let current_monitor = window.get_current_monitor(); + window.set_fullscreen(Some(current_monitor)); + } + + #[cfg(target_os = "macos")] + { + if let StartupMode::SimpleFullscreen = window_config.startup_mode() { + use glutin::os::macos::WindowExt; + window.set_simple_fullscreen(true); + } + } + // Text cursor window.set_cursor(MouseCursor::Text); @@ -280,7 +293,7 @@ impl Window { .with_visibility(false) .with_transparency(true) .with_decorations(decorations) - .with_maximized(window_config.start_maximized()) + .with_maximized(window_config.startup_mode() == StartupMode::Maximized) // X11 .with_class(class.into(), DEFAULT_NAME.into()) // Wayland @@ -305,7 +318,7 @@ impl Window { .with_visibility(cfg!(windows)) .with_decorations(decorations) .with_transparency(true) - .with_maximized(window_config.start_maximized()) + .with_maximized(window_config.startup_mode() == StartupMode::Maximized) .with_window_icon(Some(icon)) } @@ -321,7 +334,7 @@ impl Window { .with_title(title) .with_visibility(false) .with_transparency(true) - .with_maximized(window_config.start_maximized()); + .with_maximized(window_config.startup_mode() == StartupMode::Maximized); match window_config.decorations() { Decorations::Full => window, @@ -382,6 +395,23 @@ impl Window { self.window().hide(); } + /// Fullscreens the window on the current monitor. + pub fn set_fullscreen(&self, fullscreen: bool) { + let glutin_window = self.window(); + if fullscreen { + let current_monitor = glutin_window.get_current_monitor(); + glutin_window.set_fullscreen(Some(current_monitor)); + } else { + glutin_window.set_fullscreen(None); + } + } + + #[cfg(target_os = "macos")] + pub fn set_simple_fullscreen(&self, fullscreen: bool) { + use glutin::os::macos::WindowExt; + self.window().set_simple_fullscreen(fullscreen); + } + fn window(&self) -> &glutin::Window { self.windowed_context.window() }