Rework cursor configuration

There are a couple of cursor-related options in the Alacritty config
file now, however they aren't grouped together in any way.

To resolve this a new `cursor` field has been added where all cursor
configuration options (besides colors) have been moved.

The `custom_cursor_colors` option has also been removed, since it's not
necessary anymore. Simply making the `colors.cursor.*` fields optional,
allows overriding the cursor colors whenever one of them is present.
Like that the user doesn't have to think about a relation between two
separate configuration options.

This PR initially put the `hide_cursor_when_typing` variable under
`cursor.hide_when_typing`. However this field is completely unrelated to
the cursor, but instead relates to the mouse cursor.

Since the word `cursor` is already used for the active cell in the grid
of a terminal emulator, all occurences of the word `cursor` when talking
about the mouse have been replaced with the word `mouse`.

The configuration option has also been moved to
`mouse.hide_when_typing`, to make it clear what this option is changing.

This fixes #1080.
This commit is contained in:
Christian Duerr 2018-11-01 17:23:49 +00:00 committed by GitHub
parent f0579345ea
commit a7d9554038
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 176 additions and 203 deletions

View File

@ -14,6 +14,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- When `mouse.url.launcher` is set, clicking on URLs will now open them with the specified program
- New `mouse.url.modifiers` option to specify keyboard modifiers for opening URLs on click
### Changed
- The `colors.cursor.text` and `colors.cursor.cursor` fields are optional now
- Moved `cursor_style` to `cursor.style`
- Moved `unfocused_hollow_cursor` to `cursor.unfocused_hollow`
- Moved `hide_cursor_when_typing` to `mouse.hide_when_typing`
### Removed
- The `custom_cursor_colors` config field was deleted, remove the `colors.cursor.*` options
to achieve the same behavior as setting it to `false`
### Fixed
- Fixed erroneous results when using the `indexed_colors` config option

View File

@ -127,11 +127,6 @@ font:
# Display the time it takes to redraw each frame.
render_timer: false
# Use custom cursor colors. If `true`, the `colors.cursor.foreground` and
# `colors.cursor.background` colors will be used to display the cursor.
# Otherwise the cell colors are inverted for the cursor.
custom_cursor_colors: false
# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true
@ -152,10 +147,11 @@ colors:
# Cursor colors
#
# These will only be used when the `custom_cursor_colors` field is set to `true`.
cursor:
text: '0x000000'
cursor: '0xffffff'
# Colors which should be used to draw the terminal cursor. If these are unset,
# the cursor color will be the inverse of the cell color.
#cursor:
# text: '0x000000'
# cursor: '0xffffff'
# Normal colors
normal:
@ -258,6 +254,9 @@ mouse:
double_click: { threshold: 300 }
triple_click: { threshold: 300 }
# If this is `true`, the cursor is temporarily hidden when typing.
hide_when_typing: false
url:
# URL launcher
#
@ -281,19 +280,18 @@ selection:
dynamic_title: true
hide_cursor_when_typing: false
cursor:
# Cursor style
#
# Values for 'style':
# - ▇ Block
# - _ Underline
# - | Beam
style: Block
# Cursor style
#
# Values for 'cursor_style':
# - Block
# - Underline
# - Beam
cursor_style: Block
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow_cursor: true
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow: true
# Live config reload (changes require restart)
live_config_reload: true

View File

@ -126,11 +126,6 @@ font:
# Display the time it takes to redraw each frame.
render_timer: false
# Use custom cursor colors. If `true`, the `colors.cursor.foreground` and
# `colors.cursor.background` colors will be used to display the cursor.
# Otherwise the cell colors are inverted for the cursor.
custom_cursor_colors: false
# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true
@ -151,10 +146,11 @@ colors:
# Cursor colors
#
# These will only be used when the `custom_cursor_colors` field is set to `true`.
cursor:
text: '0x000000'
cursor: '0xffffff'
# Colors which should be used to draw the terminal cursor. If these are unset,
# the cursor color will be the inverse of the cell color.
#cursor:
# text: '0x000000'
# cursor: '0xffffff'
# Normal colors
normal:
@ -257,6 +253,9 @@ mouse:
double_click: { threshold: 300 }
triple_click: { threshold: 300 }
# If this is `true`, the cursor is temporarily hidden when typing.
hide_when_typing: false
url:
# URL launcher
#
@ -276,21 +275,18 @@ selection:
# When set to `true`, selected text will be copied to the primary clipboard.
save_to_clipboard: false
dynamic_title: true
cursor:
# Cursor style
#
# Values for 'style':
# - ▇ Block
# - _ Underline
# - | Beam
style: Block
hide_cursor_when_typing: false
# Cursor style
#
# Values for 'cursor_style':
# - Block
# - Underline
# - Beam
cursor_style: Block
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow_cursor: true
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow: true
# Live config reload (changes require restart)
live_config_reload: true

View File

@ -105,11 +105,6 @@ font:
# Display the time it takes to redraw each frame.
render_timer: false
# Use custom cursor colors. If `true`, the `colors.cursor.foreground` and
# `colors.cursor.background` colors will be used to display the cursor.
# Otherwise the cell colors are inverted for the cursor.
custom_cursor_colors: false
# Colors (Tomorrow Night Bright)
colors:
# Default colors
@ -127,10 +122,11 @@ colors:
# Cursor colors
#
# These will only be used when the `custom_cursor_colors` field is set to `true`.
cursor:
text: '0x000000'
cursor: '0xffffff'
# Colors which should be used to draw the terminal cursor. If these are unset,
# the cursor color will be the inverse of the cell color.
#cursor:
# text: '0x000000'
# cursor: '0xffffff'
# Normal colors
normal:
@ -233,6 +229,9 @@ mouse:
double_click: { threshold: 300 }
triple_click: { threshold: 300 }
# If this is `true`, the cursor is temporarily hidden when typing.
hide_when_typing: false
url:
# URL launcher
#
@ -249,19 +248,18 @@ mouse:
selection:
semantic_escape_chars: ",│`|:\"' ()[]{}<>"
hide_cursor_when_typing: false
cursor:
# Cursor style
#
# Values for 'style':
# - ▇ Block
# - _ Underline
# - | Beam
style: Block
# Cursor style
#
# Values for 'cursor_style':
# - Block
# - Underline
# - Beam
cursor_style: Block
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow_cursor: true
# If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow: true
# Live config reload (changes require restart)
live_config_reload: true

View File

@ -26,9 +26,7 @@ use glutin::ModifiersState;
use cli::Options;
use input::{Action, Binding, MouseBinding, KeyBinding};
use index::{Line, Column};
use ansi::CursorStyle;
use util::fmt::Yellow;
use ansi::{CursorStyle, NamedColor, Color};
const MAX_SCROLLBACK_LINES: u32 = 100_000;
@ -88,6 +86,8 @@ pub struct Mouse {
#[serde(default, deserialize_with = "failure_default")]
pub triple_click: ClickHandler,
#[serde(default, deserialize_with = "failure_default")]
pub hide_when_typing: bool,
#[serde(default, deserialize_with = "failure_default")]
pub url: Url,
// TODO: DEPRECATED
@ -132,6 +132,7 @@ impl Default for Mouse {
triple_click: ClickHandler {
threshold: Duration::from_millis(300),
},
hide_when_typing: false,
url: Url::default(),
faux_scrollback_lines: None,
}
@ -443,10 +444,6 @@ pub struct Config {
#[serde(default, deserialize_with = "failure_default")]
render_timer: bool,
/// Should use custom cursor colors
#[serde(default, deserialize_with = "failure_default")]
custom_cursor_colors: bool,
/// Should draw bold text with brighter colors instead of bold font
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
draw_bold_text_with_bright_colors: bool,
@ -492,18 +489,6 @@ pub struct Config {
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
dynamic_title: bool,
/// Hide cursor when typing
#[serde(default, deserialize_with = "failure_default")]
hide_cursor_when_typing: bool,
/// Style of the cursor
#[serde(default, deserialize_with = "failure_default")]
cursor_style: CursorStyle,
/// Use hollow block cursor when unfocused
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
unfocused_hollow_cursor: bool,
/// Live config reload
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
live_config_reload: bool,
@ -515,6 +500,26 @@ pub struct Config {
/// How much scrolling history to keep
#[serde(default, deserialize_with="failure_default")]
scrolling: Scrolling,
/// Cursor configuration
#[serde(default, deserialize_with="failure_default")]
cursor: Cursor,
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
custom_cursor_colors: Option<bool>,
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
hide_cursor_when_typing: Option<bool>,
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
cursor_style: Option<CursorStyle>,
// TODO: DEPRECATED
#[serde(default, deserialize_with = "failure_default")]
unfocused_hollow_cursor: Option<bool>,
}
fn failure_default_vec<'a, D, T>(deserializer: D) -> ::std::result::Result<Vec<T>, D::Error>
@ -1166,7 +1171,7 @@ pub enum Error {
pub struct Colors {
#[serde(default, deserialize_with = "failure_default")]
pub primary: PrimaryColors,
#[serde(default, deserialize_with = "deserialize_cursor_colors")]
#[serde(default, deserialize_with = "failure_default")]
pub cursor: CursorColors,
pub normal: AnsiColors,
pub bright: AnsiColors,
@ -1212,71 +1217,20 @@ fn deserialize_color_index<'a, D>(deserializer: D) -> ::std::result::Result<u8,
}
}
#[derive(Deserialize)]
#[serde(untagged)]
pub enum CursorOrPrimaryColors {
Cursor {
#[serde(deserialize_with = "rgb_from_hex")]
text: Rgb,
#[serde(deserialize_with = "rgb_from_hex")]
cursor: Rgb,
},
Primary {
#[serde(deserialize_with = "rgb_from_hex")]
foreground: Rgb,
#[serde(deserialize_with = "rgb_from_hex")]
background: Rgb,
}
#[derive(Copy, Clone, Debug, Default, Deserialize)]
pub struct Cursor {
#[serde(default, deserialize_with = "failure_default")]
pub style: CursorStyle,
#[serde(default="true_bool", deserialize_with = "default_true_bool")]
pub unfocused_hollow: bool,
}
impl CursorOrPrimaryColors {
fn into_cursor_colors(self) -> CursorColors {
match self {
CursorOrPrimaryColors::Cursor { text, cursor } => CursorColors {
text,
cursor,
},
CursorOrPrimaryColors::Primary { foreground, background } => {
// Must print in config since logger isn't setup yet.
eprintln!("{}",
Yellow("Config `colors.cursor.foreground` and `colors.cursor.background` \
are deprecated. Please use `colors.cursor.text` and \
`colors.cursor.cursor` instead.")
);
CursorColors {
text: foreground,
cursor: background
}
}
}
}
}
#[derive(Debug)]
#[derive(Debug, Copy, Clone, Default, Deserialize)]
pub struct CursorColors {
pub text: Rgb,
pub cursor: Rgb,
}
impl Default for CursorColors {
fn default() -> Self {
CursorColors {
text: Rgb { r: 0, g: 0, b: 0 },
cursor: Rgb { r: 0xff, g: 0xff, b: 0xff },
}
}
}
fn deserialize_cursor_colors<'a, D>(deserializer: D) -> ::std::result::Result<CursorColors, D::Error>
where D: de::Deserializer<'a>
{
match CursorOrPrimaryColors::deserialize(deserializer) {
Ok(either) => Ok(either.into_cursor_colors()),
Err(err) => {
eprintln!("problem with config: {}; Using default value", err);
Ok(CursorColors::default())
},
}
#[serde(default, deserialize_with = "deserialize_optional_color")]
pub text: Option<Rgb>,
#[serde(default, deserialize_with = "deserialize_optional_color")]
pub cursor: Option<Rgb>,
}
#[derive(Debug, Deserialize)]
@ -1644,12 +1598,6 @@ impl Config {
self.font.use_thin_strokes
}
/// show cursor as inverted
#[inline]
pub fn custom_cursor_colors(&self) -> bool {
self.custom_cursor_colors
}
pub fn path(&self) -> Option<&Path> {
self.config_path
.as_ref()
@ -1664,22 +1612,22 @@ impl Config {
&self.env
}
/// Should hide cursor when typing
/// Should hide mouse cursor when typing
#[inline]
pub fn hide_cursor_when_typing(&self) -> bool {
self.hide_cursor_when_typing
pub fn hide_mouse_when_typing(&self) -> bool {
self.hide_cursor_when_typing.unwrap_or(self.mouse.hide_when_typing)
}
/// Style of the cursor
#[inline]
pub fn cursor_style(&self) -> CursorStyle {
self.cursor_style
self.cursor_style.unwrap_or(self.cursor.style)
}
/// Use hollow block cursor when unfocused
#[inline]
pub fn unfocused_hollow_cursor(&self) -> bool {
self.unfocused_hollow_cursor
self.unfocused_hollow_cursor.unwrap_or(self.cursor.unfocused_hollow)
}
/// Live config reload
@ -1699,6 +1647,18 @@ impl Config {
self.scrolling
}
/// Cursor foreground color
#[inline]
pub fn cursor_text_color(&self) -> Option<Color> {
self.colors.cursor.text.map(|_| Color::Named(NamedColor::CursorText))
}
/// Cursor background color
#[inline]
pub fn cursor_cursor_color(&self) -> Option<Color> {
self.colors.cursor.cursor.map(|_| Color::Named(NamedColor::Cursor))
}
// Update the history size, used in ref tests
pub fn set_history(&mut self, history: u32) {
self.scrolling.history = history;
@ -1733,7 +1693,7 @@ impl Config {
Ok(contents)
}
fn print_deprecation_warnings(&self) {
fn print_deprecation_warnings(&mut self) {
use ::util::fmt;
if self.dimensions.is_some() {
eprintln!("{}", fmt::Yellow("Config `dimensions` is deprecated. \
@ -1749,6 +1709,30 @@ impl Config {
println!("{}", fmt::Yellow("Config `mouse.faux_scrollback_lines` is deprecated. \
Please use `mouse.faux_scrolling_lines` instead."));
}
if let Some(custom_cursor_colors) = self.custom_cursor_colors {
eprintln!("{}", fmt::Yellow("Config `custom_cursor_colors` is deprecated."));
if !custom_cursor_colors {
self.colors.cursor.cursor = None;
self.colors.cursor.text = None;
}
}
if self.cursor_style.is_some() {
eprintln!("{}", fmt::Yellow("Config `cursor_style` is deprecated. \
Please use `cursor.style` instead."));
}
if self.hide_cursor_when_typing.is_some() {
eprintln!("{}", fmt::Yellow("Config `hide_cursor_when_typing` is deprecated. \
Please use `mouse.hide_when_typing` instead."));
}
if self.unfocused_hollow_cursor.is_some() {
eprintln!("{}", fmt::Yellow("Config `unfocused_hollow_cursor` is deprecated. \
Please use `cursor.unfocused_hollow` instead."));
}
}
}

View File

@ -243,8 +243,8 @@ pub struct Processor<N> {
resize_tx: mpsc::Sender<(u32, u32)>,
ref_test: bool,
size_info: SizeInfo,
hide_cursor_when_typing: bool,
hide_cursor: bool,
hide_mouse_when_typing: bool,
hide_mouse: bool,
received_count: usize,
suppress_chars: bool,
last_modifiers: ModifiersState,
@ -287,8 +287,8 @@ impl<N: Notify> Processor<N> {
ref_test,
mouse: Default::default(),
size_info,
hide_cursor_when_typing: config.hide_cursor_when_typing(),
hide_cursor: false,
hide_mouse_when_typing: config.hide_mouse_when_typing(),
hide_mouse: false,
received_count: 0,
suppress_chars: false,
last_modifiers: Default::default(),
@ -306,7 +306,7 @@ impl<N: Notify> Processor<N> {
event: Event,
ref_test: bool,
resize_tx: &mpsc::Sender<(u32, u32)>,
hide_cursor: &mut bool,
hide_mouse: &mut bool,
window_is_focused: &mut bool,
) {
match event {
@ -347,7 +347,7 @@ impl<N: Notify> Processor<N> {
processor.process_key(input);
if input.state == ElementState::Pressed {
// Hide cursor while typing
*hide_cursor = true;
*hide_mouse = true;
}
},
ReceivedCharacter(c) => {
@ -355,7 +355,7 @@ impl<N: Notify> Processor<N> {
},
MouseInput { state, button, modifiers, .. } => {
if !cfg!(target_os = "macos") || *window_is_focused {
*hide_cursor = false;
*hide_mouse = false;
processor.mouse_input(state, button, modifiers);
processor.ctx.terminal.dirty = true;
}
@ -364,11 +364,11 @@ impl<N: Notify> Processor<N> {
let x = limit(x as i32, 0, processor.ctx.size_info.width as i32);
let y = limit(y as i32, 0, processor.ctx.size_info.height as i32);
*hide_cursor = false;
*hide_mouse = false;
processor.mouse_moved(x as usize, y as usize, modifiers);
},
MouseWheel { delta, phase, modifiers, .. } => {
*hide_cursor = false;
*hide_mouse = false;
processor.on_mouse_wheel(delta, phase, modifiers);
},
Refresh => {
@ -382,7 +382,7 @@ impl<N: Notify> Processor<N> {
processor.ctx.terminal.next_is_urgent = Some(false);
} else {
processor.ctx.terminal.dirty = true;
*hide_cursor = false;
*hide_mouse = false;
}
processor.on_focus_change(is_focused);
@ -460,10 +460,10 @@ impl<N: Notify> Processor<N> {
let mut window_is_focused = window.is_focused;
// Scope needed to that hide_cursor isn't borrowed after the scope
// Scope needed to that hide_mouse isn't borrowed after the scope
// ends.
{
let hide_cursor = &mut self.hide_cursor;
let hide_mouse = &mut self.hide_mouse;
let mut process = |event| {
if print_events {
println!("glutin event: {:?}", event);
@ -473,7 +473,7 @@ impl<N: Notify> Processor<N> {
event,
ref_test,
resize_tx,
hide_cursor,
hide_mouse,
&mut window_is_focused,
);
};
@ -485,8 +485,8 @@ impl<N: Notify> Processor<N> {
window.poll_events(process);
}
if self.hide_cursor_when_typing {
window.set_cursor_visible(!self.hide_cursor);
if self.hide_mouse_when_typing {
window.set_mouse_visible(!self.hide_mouse);
}
window.is_focused = window_is_focused;

View File

@ -911,6 +911,7 @@ mod tests {
triple_click: ClickHandler {
threshold: Duration::from_millis(1000),
},
hide_when_typing: false,
faux_scrollback_lines: None,
url: Default::default(),
},

View File

@ -61,8 +61,8 @@ impl List {
self[ansi::NamedColor::Background] = colors.primary.background;
// Foreground and background for custom cursor colors
self[ansi::NamedColor::CursorText] = colors.cursor.text;
self[ansi::NamedColor::Cursor] = colors.cursor.cursor;
self[ansi::NamedColor::CursorText] = colors.cursor.text.unwrap_or_else(Rgb::default);
self[ansi::NamedColor::Cursor] = colors.cursor.cursor.unwrap_or_else(Rgb::default);
// Dims
self[ansi::NamedColor::DimForeground] = colors

View File

@ -278,16 +278,9 @@ impl<'a> RenderableCellsIter<'a> {
}
fn populate_block_cursor(&mut self) {
let (text_color, cursor_color) = if self.config.custom_cursor_colors() {
(
Color::Named(NamedColor::CursorText),
Color::Named(NamedColor::Cursor)
)
} else {
// Swap fg, bg
let cell = &self.grid[self.cursor];
(cell.bg, cell.fg)
};
let cell = &self.grid[self.cursor];
let text_color = self.config.cursor_text_color().unwrap_or(cell.bg);
let cursor_color = self.config.cursor_cursor_color().unwrap_or(cell.fg);
let original_cell = self.grid[self.cursor];
@ -305,7 +298,7 @@ impl<'a> RenderableCellsIter<'a> {
let original_cell = self.grid[self.cursor];
let mut cursor_cell = self.grid[self.cursor];
let cursor_color = self.text_cursor_color(&cursor_cell);
let cursor_color = self.config.cursor_cursor_color().unwrap_or(cursor_cell.fg);
cursor_cell.c = cursor_cell_char;
cursor_cell.fg = cursor_color;
@ -332,15 +325,6 @@ impl<'a> RenderableCellsIter<'a> {
cell.flags.contains(cell::Flags::WIDE_CHAR) && (self.cursor.col + 1) < self.grid.num_cols()
}
fn text_cursor_color(&self, cell: &Cell) -> Color {
if self.config.custom_cursor_colors() {
Color::Named(NamedColor::Cursor)
} else {
// Cursor is same color as text
cell.fg
}
}
/// Populates list of cursor cells with the original cell
fn populate_no_cursor(&mut self) {
self.cursor_cells.push_back(Indexed {

View File

@ -70,7 +70,7 @@ type Result<T> = ::std::result::Result<T, Error>;
pub struct Window {
event_loop: EventsLoop,
window: glutin::GlWindow,
cursor_visible: bool,
mouse_visible: bool,
/// Whether or not the window is the focused window.
pub is_focused: bool,
@ -243,7 +243,7 @@ impl Window {
let window = Window {
event_loop,
window,
cursor_visible: true,
mouse_visible: true,
is_focused: false,
};
@ -326,16 +326,16 @@ impl Window {
});
}
/// Set cursor visible
pub fn set_cursor_visible(&mut self, visible: bool) {
if visible != self.cursor_visible {
self.cursor_visible = visible;
/// Set mouse cursor visible
pub fn set_mouse_visible(&mut self, visible: bool) {
if visible != self.mouse_visible {
self.mouse_visible = visible;
if let Err(err) = self.window.set_cursor_state(if visible {
CursorState::Normal
} else {
CursorState::Hide
}) {
warn!("Failed to set cursor visibility: {}", err);
warn!("Failed to set mouse cursor visibility: {}", err);
}
}
}