aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2020-04-09 04:02:10 +0300
committerGitHub <noreply@github.com>2020-04-09 04:02:10 +0300
commit2fc5120327c6eb096154214faec5dc4e1dee2253 (patch)
treec7e6a03051949624bcb04501af2a1d7e6246288a
parent13eb50de799c4c6f7ebed1a7fa1ab25b378580bb (diff)
downloadalacritty-2fc5120327c6eb096154214faec5dc4e1dee2253.tar.gz
alacritty-2fc5120327c6eb096154214faec5dc4e1dee2253.zip
Use config colors to theme Wayland decorations
Fixes #2092.
-rw-r--r--CHANGELOG.md1
-rw-r--r--alacritty/src/event.rs70
-rw-r--r--alacritty/src/main.rs3
-rw-r--r--alacritty/src/wayland_theme.rs82
-rw-r--r--alacritty/src/window.rs12
-rw-r--r--alacritty_terminal/src/term/color.rs21
6 files changed, 155 insertions, 34 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a71e218b..19e827e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Block cursor is no longer inverted at the start/end of a selection
- Preserve selection on non-LMB or mouse mode clicks
+- Wayland client side decorations are now based on config colorscheme
### Fixed
- Tabstops not being reset with `reset`
diff --git a/alacritty/src/event.rs b/alacritty/src/event.rs
index 9757893d..89aa8be6 100644
--- a/alacritty/src/event.rs
+++ b/alacritty/src/event.rs
@@ -7,6 +7,7 @@ use std::fs;
use std::fs::File;
use std::io::Write;
use std::mem;
+use std::path::PathBuf;
use std::sync::Arc;
use std::time::Instant;
@@ -14,6 +15,8 @@ use glutin::dpi::PhysicalSize;
use glutin::event::{ElementState, Event as GlutinEvent, ModifiersState, MouseButton, WindowEvent};
use glutin::event_loop::{ControlFlow, EventLoop, EventLoopProxy, EventLoopWindowTarget};
use glutin::platform::desktop::EventLoopExtDesktop;
+#[cfg(not(any(target_os = "macos", windows)))]
+use glutin::platform::unix::EventLoopWindowTargetExtUnix;
use log::{debug, info, warn};
use serde_json as json;
@@ -522,31 +525,7 @@ impl<N: Notify + OnResize> Processor<N> {
Event::Urgent => {
processor.ctx.window.set_urgent(!processor.ctx.terminal.is_focused)
},
- Event::ConfigReload(path) => {
- processor.ctx.message_buffer.remove_target(LOG_TARGET_CONFIG);
- processor.ctx.display_update_pending.message_buffer = Some(());
-
- if let Ok(config) = config::reload_from(&path) {
- let options = Options::new();
- let config = options.into_config(config);
-
- processor.ctx.terminal.update_config(&config);
-
- if processor.ctx.config.font != config.font {
- // Do not update font size if it has been changed at runtime
- if *processor.ctx.font_size == processor.ctx.config.font.size {
- *processor.ctx.font_size = config.font.size;
- }
-
- let font = config.font.clone().with_size(*processor.ctx.font_size);
- processor.ctx.display_update_pending.font = Some(font);
- }
-
- *processor.ctx.config = config;
-
- processor.ctx.terminal.dirty = true;
- }
- },
+ Event::ConfigReload(path) => Self::reload_config(&path, processor),
Event::Message(message) => {
processor.ctx.message_buffer.push(message);
processor.ctx.display_update_pending.message_buffer = Some(());
@@ -675,6 +654,47 @@ impl<N: Notify + OnResize> Processor<N> {
}
}
+ pub fn reload_config<T>(
+ path: &PathBuf,
+ processor: &mut input::Processor<T, ActionContext<N, T>>,
+ ) where
+ T: EventListener,
+ {
+ processor.ctx.message_buffer.remove_target(LOG_TARGET_CONFIG);
+ processor.ctx.display_update_pending.message_buffer = Some(());
+
+ let config = match config::reload_from(&path) {
+ Ok(config) => config,
+ Err(_) => return,
+ };
+
+ let options = Options::new();
+ let config = options.into_config(config);
+
+ processor.ctx.terminal.update_config(&config);
+
+ if processor.ctx.config.font != config.font {
+ // Do not update font size if it has been changed at runtime
+ if *processor.ctx.font_size == processor.ctx.config.font.size {
+ *processor.ctx.font_size = config.font.size;
+ }
+
+ let font = config.font.clone().with_size(*processor.ctx.font_size);
+ processor.ctx.display_update_pending.font = Some(font);
+ }
+
+ #[cfg(not(any(target_os = "macos", windows)))]
+ {
+ if processor.ctx.event_loop.is_wayland() {
+ processor.ctx.window.set_wayland_theme(&config.colors);
+ }
+ }
+
+ *processor.ctx.config = config;
+
+ processor.ctx.terminal.dirty = true;
+ }
+
// Write the ref test results to the disk
pub fn write_ref_test_results<T>(&self, terminal: &Term<T>) {
if !self.config.debug.ref_test {
diff --git a/alacritty/src/main.rs b/alacritty/src/main.rs
index db08245a..ca912943 100644
--- a/alacritty/src/main.rs
+++ b/alacritty/src/main.rs
@@ -58,6 +58,9 @@ mod renderer;
mod url;
mod window;
+#[cfg(not(any(target_os = "macos", windows)))]
+mod wayland_theme;
+
mod gl {
#![allow(clippy::all)]
include!(concat!(env!("OUT_DIR"), "/gl_bindings.rs"));
diff --git a/alacritty/src/wayland_theme.rs b/alacritty/src/wayland_theme.rs
new file mode 100644
index 00000000..b1d4b44c
--- /dev/null
+++ b/alacritty/src/wayland_theme.rs
@@ -0,0 +1,82 @@
+use glutin::platform::unix::{ButtonState, Theme as WaylandTheme};
+
+use alacritty_terminal::config::Colors;
+use alacritty_terminal::term::color::{Rgb, DIM_FACTOR};
+
+#[derive(Debug, Clone)]
+pub struct AlacrittyWaylandTheme {
+ pub background: Rgb,
+ pub foreground: Rgb,
+ pub dim_foreground: Rgb,
+ pub hovered_close_icon: Rgb,
+ pub hovered_maximize_icon: Rgb,
+ pub hovered_minimize_icon: Rgb,
+}
+
+impl AlacrittyWaylandTheme {
+ pub fn new(colors: &Colors) -> Self {
+ let hovered_close_icon = colors.normal().red;
+ let hovered_maximize_icon = colors.normal().green;
+ let hovered_minimize_icon = colors.normal().yellow;
+ let foreground = colors.primary.foreground;
+ let background = colors.primary.background;
+ let dim_foreground = colors.primary.dim_foreground.unwrap_or(foreground * DIM_FACTOR);
+
+ Self {
+ foreground,
+ background,
+ dim_foreground,
+ hovered_close_icon,
+ hovered_minimize_icon,
+ hovered_maximize_icon,
+ }
+ }
+
+ fn color_icon_color(&self, color: Rgb, status: ButtonState) -> [u8; 4] {
+ match status {
+ ButtonState::Hovered => [0xff, color.r, color.g, color.b],
+ ButtonState::Idle => [0xff, self.foreground.r, self.foreground.g, self.foreground.b],
+ ButtonState::Disabled => {
+ [0xff, self.dim_foreground.r, self.dim_foreground.g, self.dim_foreground.b]
+ },
+ }
+ }
+}
+
+impl WaylandTheme for AlacrittyWaylandTheme {
+ fn primary_color(&self, _window_active: bool) -> [u8; 4] {
+ [0xff, self.background.r, self.background.g, self.background.b]
+ }
+
+ fn secondary_color(&self, window_active: bool) -> [u8; 4] {
+ if window_active {
+ [0xff, self.foreground.r, self.foreground.g, self.foreground.b]
+ } else {
+ [0xff, self.dim_foreground.r, self.dim_foreground.g, self.dim_foreground.b]
+ }
+ }
+
+ fn close_button_color(&self, _status: ButtonState) -> [u8; 4] {
+ [0x00, self.background.r, self.background.g, self.background.b]
+ }
+
+ fn close_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
+ self.color_icon_color(self.hovered_close_icon, status)
+ }
+
+ fn maximize_button_color(&self, _status: ButtonState) -> [u8; 4] {
+ [0x00, self.background.r, self.background.g, self.background.b]
+ }
+
+ fn maximize_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
+ self.color_icon_color(self.hovered_maximize_icon, status)
+ }
+
+ fn minimize_button_color(&self, _status: ButtonState) -> [u8; 4] {
+ [0x00, self.background.r, self.background.g, self.background.b]
+ }
+
+ fn minimize_button_icon_color(&self, status: ButtonState) -> [u8; 4] {
+ self.color_icon_color(self.hovered_minimize_icon, status)
+ }
+}
diff --git a/alacritty/src/window.rs b/alacritty/src/window.rs
index 71327bac..feb09c61 100644
--- a/alacritty/src/window.rs
+++ b/alacritty/src/window.rs
@@ -33,6 +33,8 @@ use image::ImageFormat;
#[cfg(not(any(target_os = "macos", windows)))]
use x11_dl::xlib::{Display as XDisplay, PropModeReplace, XErrorEvent, Xlib};
+#[cfg(not(any(target_os = "macos", windows)))]
+use alacritty_terminal::config::Colors;
use alacritty_terminal::config::{Decorations, StartupMode, WindowConfig};
use alacritty_terminal::event::Event;
#[cfg(not(windows))]
@@ -40,6 +42,8 @@ use alacritty_terminal::term::{SizeInfo, Term};
use crate::config::Config;
use crate::gl;
+#[cfg(not(any(target_os = "macos", windows)))]
+use crate::wayland_theme::AlacrittyWaylandTheme;
// It's required to be in this directory due to the `windows.rc` file
#[cfg(not(target_os = "macos"))]
@@ -158,6 +162,9 @@ impl Window {
if let Some(parent_window_id) = config.window.embed {
x_embed_window(windowed_context.window(), parent_window_id);
}
+ } else {
+ let theme = AlacrittyWaylandTheme::new(&config.colors);
+ windowed_context.window().set_wayland_theme(theme);
}
}
@@ -361,6 +368,11 @@ impl Window {
self.window().wayland_display()
}
+ #[cfg(not(any(target_os = "macos", target_os = "windows")))]
+ pub fn set_wayland_theme(&mut self, colors: &Colors) {
+ self.window().set_wayland_theme(AlacrittyWaylandTheme::new(colors));
+ }
+
/// Adjust the IME editor position according to the new location of the cursor
#[cfg(not(windows))]
pub fn update_ime_position<T>(&mut self, terminal: &Term<T>, size_info: &SizeInfo) {
diff --git a/alacritty_terminal/src/term/color.rs b/alacritty_terminal/src/term/color.rs
index b452245e..f9d7cf3a 100644
--- a/alacritty_terminal/src/term/color.rs
+++ b/alacritty_terminal/src/term/color.rs
@@ -11,6 +11,9 @@ use crate::config::{Colors, LOG_TARGET_CONFIG};
pub const COUNT: usize = 269;
+/// Factor for automatic computation of dim colors used by terminal.
+pub const DIM_FACTOR: f32 = 0.66;
+
pub const RED: Rgb = Rgb { r: 0xff, g: 0x0, b: 0x0 };
pub const YELLOW: Rgb = Rgb { r: 0xff, g: 0xff, b: 0x0 };
@@ -181,7 +184,7 @@ impl List {
// Dims
self[ansi::NamedColor::DimForeground] =
- colors.primary.dim_foreground.unwrap_or(colors.primary.foreground * 0.66);
+ colors.primary.dim_foreground.unwrap_or(colors.primary.foreground * DIM_FACTOR);
match colors.dim {
Some(ref dim) => {
trace!("Using config-provided dim colors");
@@ -196,14 +199,14 @@ impl List {
},
None => {
trace!("Deriving dim colors from normal colors");
- self[ansi::NamedColor::DimBlack] = colors.normal().black * 0.66;
- self[ansi::NamedColor::DimRed] = colors.normal().red * 0.66;
- self[ansi::NamedColor::DimGreen] = colors.normal().green * 0.66;
- self[ansi::NamedColor::DimYellow] = colors.normal().yellow * 0.66;
- self[ansi::NamedColor::DimBlue] = colors.normal().blue * 0.66;
- self[ansi::NamedColor::DimMagenta] = colors.normal().magenta * 0.66;
- self[ansi::NamedColor::DimCyan] = colors.normal().cyan * 0.66;
- self[ansi::NamedColor::DimWhite] = colors.normal().white * 0.66;
+ self[ansi::NamedColor::DimBlack] = colors.normal().black * DIM_FACTOR;
+ self[ansi::NamedColor::DimRed] = colors.normal().red * DIM_FACTOR;
+ self[ansi::NamedColor::DimGreen] = colors.normal().green * DIM_FACTOR;
+ self[ansi::NamedColor::DimYellow] = colors.normal().yellow * DIM_FACTOR;
+ self[ansi::NamedColor::DimBlue] = colors.normal().blue * DIM_FACTOR;
+ self[ansi::NamedColor::DimMagenta] = colors.normal().magenta * DIM_FACTOR;
+ self[ansi::NamedColor::DimCyan] = colors.normal().cyan * DIM_FACTOR;
+ self[ansi::NamedColor::DimWhite] = colors.normal().white * DIM_FACTOR;
},
}
}