1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2025-02-17 15:57:08 -05:00

Add fullscreen support

Fixes #34.
Fixes #2012.
This commit is contained in:
acheronfail 2019-04-24 05:05:47 +10:00 committed by Christian Duerr
parent b0efa9d105
commit e9813031f6
8 changed files with 177 additions and 25 deletions

View file

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

View file

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

View file

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

View file

@ -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")]
start_maximized: bool,
startup_mode: StartupMode,
/// TODO: DEPRECATED
#[serde(deserialize_with = "failure_default")]
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;
}
}
}
}

View file

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

View file

@ -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();
}
}
impl Default for WindowChanges {
fn default() -> WindowChanges {
WindowChanges { hide: false }
fn toggle_fullscreen(&mut self) {
self.toggle_fullscreen = !self.toggle_fullscreen;
}
#[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();

View file

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

View file

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