Commit a4cb1167 authored by Christian Duerr's avatar Christian Duerr

Merge remote-tracking branch 'upstream/master' into glutin-0.17-upgrade

parents 6d0a820c 9b694fcc
......@@ -6,6 +6,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Implement the `hidden` escape sequence (`echo -e "\e[8mTEST"`)
- Add support for macOS systemwide dark mode
- Set the environment variable `COLORTERM="truecolor"` to advertise 24-bit color support
- On macOS, there are two new values for the config option `window.decorations`:
- `transparent` - This makes the title bar transparent and allows the
viewport to extend to the top of the window.
- `buttonless` - Similar to transparent but also removed the buttons.
### Changed
- Inverse/Selection color is now modelled after XTerm/VTE instead of URxvt to improve consistency
- First click on unfocused Alacritty windows is no longer ignored on platforms other than macOS
### Fixed
- Clear screen properly before rendering of content to prevent various graphical glitches
- Fix build failure on 32-bit systems
- Windows started as unfocused now show the hollow cursor if the setting is enabled
### Deprecated
- The config option `window.decorations` should now use `full` or `none` instead
of `true` or `false`, respectively.
### Security
- Bracketed paste mode now filters escape sequences beginning with \x1b
## Version 0.2.0
### Added
......
This diff is collapsed.
......@@ -76,7 +76,7 @@ assets = [
["target/release/alacritty", "usr/local/bin/", "755"],
["alacritty.desktop", "usr/share/applications/", "644"],
["alacritty-completions.bash", "usr/share/bash-completion/completions/alacritty", "644"],
["alacritty-completions.fish", "usr/share/fish/completions/alacritty", "644"],
["alacritty-completions.zsh", "usr/share/zsh/functions/Completion/alacritty", "644"],
["alacritty-completions.fish", "usr/share/fish/completions/alacritty.fish", "644"],
["alacritty-completions.zsh", "usr/share/zsh/vendor-completions/_alacritty", "644"],
["alacritty.info", "usr/share/terminfo/a/alacritty", "644"],
]
......@@ -36,18 +36,17 @@ built from source.
## Installation
Instructions are provided for macOS and many Linux variants to compile Alacritty
from source. With the exception of Arch (which has a package in the AUR), Void Linux (in main repository) and
[NixOS](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/misc/alacritty/default.nix), please first read the
[prerequisites](#prerequisites) section, then find the section for your OS, and
finally go to [building](#building) and [configuration](#configuration).
Some operating systems already provide binaries for Alacritty, for everyone else there are
instructions to compile Alacritty from source.
For the manual installation, please first read the [prerequisites](#prerequisites) section,
then find the instructions for your OS, and finally go through the [building](#building)
and [configuration](#configuration) steps.
### Arch Linux
```sh
git clone https://aur.archlinux.org/alacritty-git.git
cd alacritty-git
makepkg -isr
pacman -S alacritty
```
### Debian/Ubuntu
......@@ -165,7 +164,7 @@ On [Void Linux](https://voidlinux.eu), install following packages before
compiling Alacritty:
```sh
xbps-install cmake freetype-devel freetype expat-devel fontconfig xclip
xbps-install cmake freetype-devel freetype expat-devel fontconfig-devel fontconfig xclip
```
#### FreeBSD
......@@ -296,10 +295,19 @@ To get automatic completions for alacritty's flags and arguments you can install
### Zsh
To install the completions for zsh, run
To install the completions for zsh, you can place the `alacritty-completions.zsh` as `_alacritty` in any directory referenced by `$fpath`.
If you do not already have such a directory registered through your `~/.zshrc`, you can add one like this:
```sh
mkdir -p ${ZDOTDIR:-~}/.zsh_functions
echo 'fpath+=${ZDOTDIR:-~}/.zsh_functions' >> ${ZDOTDIR:-~}/.zshrc
```
sudo cp alacritty-completions.zsh /usr/share/zsh/functions/Completion/X/_alacritty
Then copy the completion file to this directory:
```sh
cp alacritty-completions.zsh ${ZDOTDIR:-~}/.zsh_functions/_alacritty
```
### Bash
......
This diff is collapsed.
This diff is collapsed.
......@@ -32,5 +32,7 @@
<true/>
<key>CFBundleDisplayName</key>
<string>Alacritty</string>
<key>NSRequiresAquaSystemAppearance</key>
<string>NO</string>
</dict>
</plist>
......@@ -16,7 +16,7 @@ servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig", branch =
freetype-rs = "0.13"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.5"
core-text = "9.1"
core-graphics = "0.13"
core-foundation-sys = "0.5"
core-foundation = "0.6"
core-text = "13"
core-graphics = "0.17"
core-foundation-sys = "0.6"
......@@ -18,6 +18,7 @@
#![allow(improper_ctypes)]
use std::collections::HashMap;
use std::ptr;
use std::path::PathBuf;
use ::{Slant, Weight, Style};
......@@ -56,7 +57,7 @@ pub struct Descriptor {
font_name: String,
style_name: String,
display_name: String,
font_path: String,
font_path: PathBuf,
ct_descriptor: CTFontDescriptor
}
......@@ -68,7 +69,7 @@ impl Descriptor {
font_name: desc.font_name(),
style_name: desc.style_name(),
display_name: desc.display_name(),
font_path: desc.font_path().unwrap_or_else(||{"".to_owned()}),
font_path: desc.font_path().unwrap_or_else(PathBuf::new),
ct_descriptor: desc,
}
}
......@@ -339,8 +340,10 @@ pub fn descriptors_for_family(family: &str) -> Vec<Descriptor> {
// CFArray of CTFontDescriptorRef (i think)
let descriptors = ct_collection.get_descriptors();
for descriptor in descriptors.iter() {
out.push(Descriptor::new(descriptor.clone()));
if let Some(descriptors) = descriptors {
for descriptor in descriptors.iter() {
out.push(Descriptor::new(descriptor.clone()));
}
}
out
......@@ -363,7 +366,7 @@ impl Descriptor {
// TODO fixme, hardcoded en for english
let mut fallbacks = cascade_list_for_languages(&menlo, &["en".to_owned()])
.into_iter()
.filter(|desc| desc.font_path != "")
.filter(|desc| !desc.font_path.as_os_str().is_empty())
.map(|desc| desc.to_font(size, false))
.collect::<Vec<_>>();
......@@ -447,12 +450,14 @@ impl Font {
let indices = [index as CGGlyph];
self.ct_font.get_advances_for_glyphs(
FontOrientation::Default as _,
&indices[0],
ptr::null_mut(),
1
)
unsafe {
self.ct_font.get_advances_for_glyphs(
FontOrientation::Default as _,
&indices[0],
ptr::null_mut(),
1
)
}
}
pub fn get_glyph(&self, character: char, _size: f64, use_thin_strokes: bool) -> Result<RasterizedGlyph, Error> {
......@@ -582,11 +587,13 @@ impl Font {
// always being a 0.
let mut glyphs:[CGGlyph; 2] = [0; 2];
let res = self.ct_font.get_glyphs_for_characters(
encoded.as_ptr(),
glyphs.as_mut_ptr(),
encoded.len() as CFIndex
);
let res = unsafe {
self.ct_font.get_glyphs_for_characters(
encoded.as_ptr(),
glyphs.as_mut_ptr(),
encoded.len() as CFIndex
)
};
if res {
Some(u32::from(glyphs[0]))
......
......@@ -99,7 +99,7 @@ impl<'a> Iterator for Iter<'a> {
None
} else {
let pattern = unsafe {
let ptr = *(*self.font_set.as_ptr()).fonts.offset(self.current as isize);
let ptr = *(*self.font_set.as_ptr()).fonts.add(self.current);
PatternRef::from_ptr(ptr)
};
......
#!/bin/bash
printf "Fg=Black, Bg=Background \e[30;49mTEST\e[m\n"
printf "Fg=Black, Bg=Black \e[30;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=Background \e[39;49mTEST\e[m\n"
printf "Fg=Foreground,Bg=Black \e[39;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=White \e[39;47mTEST\e[m\n"
printf "Fg=White, Bg=Foreground \e[37;39mTEST\e[m\n"
printf "Fg=Black, Bg=Background, Inverse \e[7;30;49mTEST\e[m\n"
printf "Fg=Black, Bg=Black, Inverse \e[7;30;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=Background, Inverse \e[7;39;49mTEST\e[m\n"
printf "Fg=Foreground,Bg=Black, Inverse \e[7;39;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=White, Inverse \e[7;39;47mTEST\e[m\n"
printf "Fg=White, Bg=Foreground, Inverse \e[7;37;39mTEST\e[m\n"
printf "Fg=Black Bg=Black \e[30;40mTEST\e[m\n"
printf "Fg=Black Bg=White \e[30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red \e[30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG \e[30;49mTEST\e[m\n"
printf "Fg=White Bg=Black \e[97;40mTEST\e[m\n"
printf "Fg=White Bg=White \e[97;107mTEST\e[m\n"
printf "Fg=White Bg=Red \e[97;41mTEST\e[m\n"
printf "Fg=White Bg=BG \e[97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black \e[31;40mTEST\e[m\n"
printf "Fg=Red Bg=White \e[31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red \e[31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG \e[31;49mTEST\e[m\n"
printf "\n"
printf "Fg=Black Bg=Black Inverse \e[7;30;40mTEST\e[m\n"
printf "Fg=Black Bg=White Inverse \e[7;30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red Inverse \e[7;30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG Inverse \e[7;30;49mTEST\e[m\n"
printf "Fg=White Bg=Black Inverse \e[7;97;40mTEST\e[m\n"
printf "Fg=White Bg=White Inverse \e[7;97;107mTEST\e[m\n"
printf "Fg=White Bg=Red Inverse \e[7;97;41mTEST\e[m\n"
printf "Fg=White Bg=BG Inverse \e[7;97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black Inverse \e[7;31;40mTEST\e[m\n"
printf "Fg=Red Bg=White Inverse \e[7;31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red Inverse \e[7;31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG Inverse \e[7;31;49mTEST\e[m\n"
printf "\n"
printf "Fg=Black Bg=Black Hidden \e[8;30;40mTEST\e[m\n"
printf "Fg=Black Bg=White Hidden \e[8;30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red Hidden \e[8;30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG Hidden \e[8;30;49mTEST\e[m\n"
printf "Fg=White Bg=Black Hidden \e[8;97;40mTEST\e[m\n"
printf "Fg=White Bg=White Hidden \e[8;97;107mTEST\e[m\n"
printf "Fg=White Bg=Red Hidden \e[8;97;41mTEST\e[m\n"
printf "Fg=White Bg=BG Hidden \e[8;97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black Hidden \e[8;31;40mTEST\e[m\n"
printf "Fg=Red Bg=White Hidden \e[8;31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red Hidden \e[8;31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG Hidden \e[8;31;49mTEST\e[m\n"
printf "\n"
printf "Fg=Black Bg=Black Hid+Inv \e[7;8;30;40mTEST\e[m\n"
printf "Fg=Black Bg=White Hid+Inv \e[7;8;30;107mTEST\e[m\n"
printf "Fg=Black Bg=Red Hid+Inv \e[7;8;30;41mTEST\e[m\n"
printf "Fg=Black Bg=BG Hid+Inv \e[7;8;30;49mTEST\e[m\n"
printf "Fg=White Bg=Black Hid+Inv \e[7;8;97;40mTEST\e[m\n"
printf "Fg=White Bg=White Hid+Inv \e[7;8;97;107mTEST\e[m\n"
printf "Fg=White Bg=Red Hid+Inv \e[7;8;97;41mTEST\e[m\n"
printf "Fg=White Bg=BG Hid+Inv \e[7;8;97;49mTEST\e[m\n"
printf "Fg=Red Bg=Black Hid+Inv \e[7;8;31;40mTEST\e[m\n"
printf "Fg=Red Bg=White Hid+Inv \e[7;8;31;107mTEST\e[m\n"
printf "Fg=Red Bg=Red Hid+Inv \e[7;8;31;41mTEST\e[m\n"
printf "Fg=Red Bg=BG Hid+Inv \e[7;8;31;49mTEST\e[m\n"
......@@ -15,8 +15,8 @@ parts:
plugin: dump
source: .
stage:
- Alacritty.desktop
- alacritty.desktop
apps:
alacritty:
command: env XDG_RUNTIME_DIR= XDG_CONFIG_HOME=$SNAP_USER_DATA XDG_DATA_DIRS=$SNAP_DATA PATH=$SNAP/bin:$PATH SNAP= alacritty
desktop: Alacritty.desktop
desktop: alacritty.desktop
......@@ -30,6 +30,8 @@ use ansi::CursorStyle;
use util::fmt::Yellow;
const MAX_SCROLLBACK_LINES: u32 = 100_000;
/// Function that returns true for serde default
fn true_bool() -> bool {
true
......@@ -246,6 +248,91 @@ impl Default for Alpha {
}
}
#[derive(Debug, Copy, Clone)]
pub enum Decorations {
Full,
Transparent,
Buttonless,
None,
}
impl Default for Decorations {
fn default() -> Decorations {
Decorations::Full
}
}
impl<'de> Deserialize<'de> for Decorations {
fn deserialize<D>(deserializer: D) -> ::std::result::Result<Decorations, D::Error>
where D: de::Deserializer<'de>
{
struct DecorationsVisitor;
impl<'de> Visitor<'de> for DecorationsVisitor {
type Value = Decorations;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("Some subset of full|transparent|buttonless|none")
}
fn visit_bool<E>(self, value: bool) -> ::std::result::Result<Decorations, E>
where E: de::Error
{
if value {
eprintln!("deprecated decorations boolean value, use one of \
default|transparent|buttonless|none instead; Falling back to \"full\"");
Ok(Decorations::Full)
} else {
eprintln!("deprecated decorations boolean value, use one of \
default|transparent|buttonless|none instead; Falling back to \"none\"");
Ok(Decorations::None)
}
}
#[cfg(target_os = "macos")]
fn visit_str<E>(self, value: &str) -> ::std::result::Result<Decorations, E>
where E: de::Error
{
match value {
"transparent" => Ok(Decorations::Transparent),
"buttonless" => Ok(Decorations::Buttonless),
"none" => Ok(Decorations::None),
"full" => Ok(Decorations::Full),
_ => {
eprintln!("invalid decorations value: {}; Using default value", value);
Ok(Decorations::Full)
}
}
}
#[cfg(not(target_os = "macos"))]
fn visit_str<E>(self, value: &str) -> ::std::result::Result<Decorations, E>
where E: de::Error
{
match value.to_lowercase().as_str() {
"none" => Ok(Decorations::None),
"full" => Ok(Decorations::Full),
"transparent" => {
eprintln!("macos-only decorations value: {}; Using default value", value);
Ok(Decorations::Full)
},
"buttonless" => {
eprintln!("macos-only decorations value: {}; Using default value", value);
Ok(Decorations::Full)
}
_ => {
eprintln!("invalid decorations value: {}; Using default value", value);
Ok(Decorations::Full)
}
}
}
}
deserializer.deserialize_str(DecorationsVisitor)
}
}
#[derive(Debug, Copy, Clone, Deserialize)]
pub struct WindowConfig {
/// Initial dimensions
......@@ -257,8 +344,8 @@ pub struct WindowConfig {
padding: Delta<u8>,
/// Draw the window with title bar / borders
#[serde(default, deserialize_with = "failure_default")]
decorations: bool,
#[serde(default)]
decorations: Decorations,
}
fn default_padding() -> Delta<u8> {
......@@ -278,7 +365,7 @@ fn deserialize_padding<'a, D>(deserializer: D) -> ::std::result::Result<Delta<u8
}
impl WindowConfig {
pub fn decorations(&self) -> bool {
pub fn decorations(&self) -> Decorations {
self.decorations
}
}
......@@ -288,7 +375,7 @@ impl Default for WindowConfig {
WindowConfig{
dimensions: Default::default(),
padding: default_padding(),
decorations: true,
decorations: Default::default(),
}
}
}
......@@ -511,7 +598,18 @@ fn deserialize_scrolling_history<'a, D>(deserializer: D) -> ::std::result::Resul
where D: de::Deserializer<'a>
{
match u32::deserialize(deserializer) {
Ok(lines) => Ok(lines),
Ok(lines) => {
if lines > MAX_SCROLLBACK_LINES {
eprintln!(
"problem with config: scrollback size is {}, but expected a maximum of {}; \
Using {1} instead",
lines, MAX_SCROLLBACK_LINES,
);
Ok(MAX_SCROLLBACK_LINES)
} else {
Ok(lines)
}
},
Err(err) => {
eprintln!("problem with config: {}; Using default value", err);
Ok(default_scrolling_history())
......
......@@ -26,6 +26,7 @@ use font::{self, Rasterize};
use meter::Meter;
use renderer::{self, GlyphCache, QuadRenderer};
use term::{Term, SizeInfo};
use sync::FairMutex;
use window::{self, Window};
......@@ -99,7 +100,6 @@ pub struct Display {
meter: Meter,
font_size: font::Size,
size_info: SizeInfo,
last_background_color: Rgb,
}
/// Can wakeup the render loop from other threads
......@@ -208,7 +208,6 @@ impl Display {
meter: Meter::new(),
font_size: font::Size::new(0.),
size_info,
last_background_color: background_color,
})
}
......@@ -333,7 +332,29 @@ impl Display {
/// A reference to Term whose state is being drawn must be provided.
///
/// This call may block if vsync is enabled
pub fn draw(&mut self, mut terminal: MutexGuard<Term>, config: &Config) {
pub fn draw(&mut self, terminal: &FairMutex<Term>, config: &Config) {
let terminal_locked = terminal.lock();
let size_info = *terminal_locked.size_info();
let visual_bell_intensity = terminal_locked.visual_bell.intensity();
let background_color = terminal_locked.background_color();
// Clear when terminal mutex isn't held. Mesa for
// some reason takes a long time to call glClear(). The driver descends
// into xcb_connect_to_fd() which ends up calling __poll_nocancel()
// which blocks for a while.
//
// By keeping this outside of the critical region, the Mesa bug is
// worked around to some extent. Since this doesn't actually address the
// issue of glClear being slow, less time is available for input
// handling and rendering.
drop(terminal_locked);
self.renderer.with_api(config, &size_info, visual_bell_intensity, |api| {
api.clear(background_color);
});
let mut terminal = terminal.lock();
// Clear dirty flag
terminal.dirty = !terminal.visual_bell.completed();
......@@ -353,13 +374,6 @@ impl Display {
}
}
let size_info = *terminal.size_info();
let visual_bell_intensity = terminal.visual_bell.intensity();
let background_color = terminal.background_color();
let background_color_changed = background_color != self.last_background_color;
self.last_background_color = background_color;
{
let glyph_cache = &mut self.glyph_cache;
......@@ -374,11 +388,6 @@ impl Display {
// mutable borrow
let window_focused = self.window.is_focused;
self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| {
// Clear screen to update whole background with new color
if background_color_changed {
api.clear(background_color);
}
// Draw the grid
api.render_cells(
terminal.renderable_cells(config, window_focused),
......@@ -402,19 +411,6 @@ impl Display {
self.window
.swap_buffers()
.expect("swap buffers");
// Clear after swap_buffers when terminal mutex isn't held. Mesa for
// some reason takes a long time to call glClear(). The driver descends
// into xcb_connect_to_fd() which ends up calling __poll_nocancel()
// which blocks for a while.
//
// By keeping this outside of the critical region, the Mesa bug is
// worked around to some extent. Since this doesn't actually address the
// issue of glClear being slow, less time is available for input
// handling and rendering.
self.renderer.with_api(config, &size_info, visual_bell_intensity, |api| {
api.clear(background_color);
});
}
pub fn get_window_id(&self) -> Option<usize> {
......
......@@ -347,7 +347,7 @@ impl<N: Notify> Processor<N> {
processor.received_char(c);
},
MouseInput { state, button, modifiers, .. } => {
if *window_is_focused {
if !cfg!(target_os = "macos") || *window_is_focused {
*hide_cursor = false;
processor.mouse_input(state, button, modifiers);
processor.ctx.terminal.dirty = true;
......
......@@ -15,7 +15,7 @@
//! Defines the Row type which makes up lines in the grid
use std::ops::{Index, IndexMut};
use std::ops::{Range, RangeTo, RangeFrom, RangeFull};
use std::ops::{Range, RangeTo, RangeFrom, RangeFull, RangeToInclusive};
use std::cmp::{max, min};
use std::slice;
......@@ -200,3 +200,20 @@ impl<T> IndexMut<RangeFull> for Row<T> {
&mut self.inner[..]
}
}
impl<T> Index<RangeToInclusive<Column>> for Row<T> {
type Output = [T];
#[inline]
fn index(&self, index: RangeToInclusive<Column>) -> &[T] {
&self.inner[..=(index.end.0)]
}
}
impl<T> IndexMut<RangeToInclusive<Column>> for Row<T> {
#[inline]
fn index_mut(&mut self, index: RangeToInclusive<Column>) -> &mut [T] {
self.occ = max(self.occ, *index.end);
&mut self.inner[..=(index.end.0)]
}
}
......@@ -223,7 +223,7 @@ impl<T> Storage<T> {
/// instructions. This implementation achieves the swap in only 8 movups
/// instructions.
pub fn swap(&mut self, a: usize, b: usize) {
assert_eq_size!(Row<T>, [u32; 8]);
assert_eq_size!(Row<T>, [usize; 4]);
let a = self.compute_index(a);
let b = self.compute_index(b);
......@@ -232,13 +232,13 @@ impl<T> Storage<T> {
// Cast to a qword array to opt out of copy restrictions and avoid
// drop hazards. Byte array is no good here since for whatever
// reason LLVM won't optimized it.
let a_ptr = self.inner.as_mut_ptr().offset(a as isize) as *mut u64;
let b_ptr = self.inner.as_mut_ptr().offset(b as isize) as *mut u64;
let a_ptr = self.inner.as_mut_ptr().add(a) as *mut usize;
let b_ptr = self.inner.as_mut_ptr().add(b) as *mut usize;
// Copy 1 qword at a time
//
// The optimizer unrolls this loop and vectorizes it.
let mut tmp: u64;
let mut tmp: usize;
for i in 0..4 {
tmp = *a_ptr.offset(i);
*a_ptr.offset(i) = *b_ptr.offset(i);
......
......@@ -211,7 +211,7 @@ impl Action {
Action::Paste => {
Clipboard::new()
.and_then(|clipboard| clipboard.load_primary() )
.map(|contents| { self.paste(ctx, contents) })
.map(|contents| { self.paste(ctx, &contents) })
.unwrap_or_else(|err| {
eprintln!("Error loading data from clipboard. {}", Red(err));
});
......@@ -222,7 +222,7 @@ impl Action {
if !ctx.terminal_mode().intersects(mouse_modes) {
Clipboard::new()
.and_then(|clipboard| clipboard.load_selection() )
.map(|contents| { self.paste(ctx, contents) })
.map(|contents| { self.paste(ctx, &contents) })
.unwrap_or_else(|err| {
warn!("Error loading data from clipboard. {}", Red(err));
});
......@@ -282,10 +282,10 @@ impl Action {
}
}
fn paste<A: ActionContext>(&self, ctx: &mut A, contents: String) {
fn paste<A: ActionContext>(&self, ctx: &mut A, contents: &str) {
if ctx.terminal_mode().contains(TermMode::BRACKETED_PASTE) {
ctx.write_to_pty(&b"\x1b[200~"[..]);
ctx.write_to_pty(contents.into_bytes());
ctx.write_to_pty(contents.replace("\x1b","").into_bytes());
ctx.write_to_pty(&b"\x1b[201~"[..]);
} else {
// In non-bracketed (ie: normal) mode, terminal applications cannot distinguish
......
......@@ -67,7 +67,7 @@ pub fn set_locale_environment() {
// try setting `locale_id`
let modified = setlocale(LC_CTYPE, locale_ptr);
let result = if modified.is_null() {
String::from("")
String::new()
} else {
locale_id
};
......
......@@ -173,7 +173,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
// Main display loop
loop {
// Process input and window events
let mut terminal = processor.process_events(&terminal, display.window());
let mut terminal_lock = processor.process_events(&terminal, display.window());
// Handle config reloads
if let Some(new_config) = config_monitor
......@@ -183,22 +183,23 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
config = new_config.update_dynamic_title(options);
display.update_config(&config);
processor.update_config(&config);
terminal.update_config(&config);
terminal.dirty = true;
terminal_lock.update_config(&config);
terminal_lock.dirty = true;
}
// Maybe draw the terminal
if terminal.needs_draw() {
if terminal_lock.needs_draw() {
// Try to update the position of the input method editor
display.update_ime_position(&terminal);
display.update_ime_position(&terminal_lock);
// Handle pending resize events
//
// The second argument is a list of types that want to be notified
// of display size changes.
display.handle_resize(&mut terminal, &config, &mut [&mut pty, &mut processor]);
display.handle_resize(&mut terminal_lock, &config, &mut [&mut pty, &mut processor]);
drop(terminal_lock);
// Draw the current state of the terminal
display.draw(terminal, &config);
display.draw(&terminal, &config);
}
// Begin shutdown if the flag was raised.
......
......@@ -837,12 +837,17 @@ impl<'a> RenderApi<'a> {
glyph_cache.font_key
};
let glyph_key = GlyphKey {
let mut glyph_key = GlyphKey {
font_key,
size: glyph_cache.font_size,
c: cell.c
};
// Don't render text of HIDDEN cells
if cell.flags.contains(cell::Flags::HIDDEN) {
glyph_key.c = ' ';
}
// Add cell to batch
{
let glyph = glyph_cache.get(glyph_key, self);
......
......@@ -18,15 +18,16 @@ use index::Column;
bitflags! {
#[derive(Serialize, Deserialize)]
pub struct Flags: u32 {
const INVERSE = 0b0000_0001;
const BOLD = 0b0000_0010;
const ITALIC = 0b0000_0100;
const UNDERLINE = 0b0000_1000;
const WRAPLINE = 0b0001_0000;
const WIDE_CHAR = 0b0010_0000;
const WIDE_CHAR_SPACER = 0b0100_0000;
const DIM = 0b1000_0000;
const DIM_BOLD = 0b1000_0010;
const INVERSE = 0b0_0000_0001;
const BOLD = 0b0_0000_0010;
const ITALIC = 0b0_0000_0100;
const UNDERLINE = 0b0_0000_1000;