Use config colors to theme Wayland decorations

Fixes #2092.
This commit is contained in:
Kirill Chibisov 2020-04-09 04:02:10 +03:00 committed by GitHub
parent 13eb50de79
commit 2fc5120327
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 155 additions and 34 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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