1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-18 13:55:23 -05:00

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

This commit is contained in:
Christian Duerr 2018-09-23 20:55:09 +02:00
commit a4cb1167eb
No known key found for this signature in database
GPG key ID: 85CDAE3C164BA7B4
25 changed files with 1103 additions and 694 deletions

View file

@ -6,6 +6,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [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 ## Version 0.2.0
### Added ### Added

582
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -76,7 +76,7 @@ assets = [
["target/release/alacritty", "usr/local/bin/", "755"], ["target/release/alacritty", "usr/local/bin/", "755"],
["alacritty.desktop", "usr/share/applications/", "644"], ["alacritty.desktop", "usr/share/applications/", "644"],
["alacritty-completions.bash", "usr/share/bash-completion/completions/alacritty", "644"], ["alacritty-completions.bash", "usr/share/bash-completion/completions/alacritty", "644"],
["alacritty-completions.fish", "usr/share/fish/completions/alacritty", "644"], ["alacritty-completions.fish", "usr/share/fish/completions/alacritty.fish", "644"],
["alacritty-completions.zsh", "usr/share/zsh/functions/Completion/alacritty", "644"], ["alacritty-completions.zsh", "usr/share/zsh/vendor-completions/_alacritty", "644"],
["alacritty.info", "usr/share/terminfo/a/alacritty", "644"], ["alacritty.info", "usr/share/terminfo/a/alacritty", "644"],
] ]

View file

@ -36,18 +36,17 @@ built from source.
## Installation ## Installation
Instructions are provided for macOS and many Linux variants to compile Alacritty Some operating systems already provide binaries for Alacritty, for everyone else there are
from source. With the exception of Arch (which has a package in the AUR), Void Linux (in main repository) and instructions to compile Alacritty from source.
[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 For the manual installation, please first read the [prerequisites](#prerequisites) section,
finally go to [building](#building) and [configuration](#configuration). then find the instructions for your OS, and finally go through the [building](#building)
and [configuration](#configuration) steps.
### Arch Linux ### Arch Linux
```sh ```sh
git clone https://aur.archlinux.org/alacritty-git.git pacman -S alacritty
cd alacritty-git
makepkg -isr
``` ```
### Debian/Ubuntu ### Debian/Ubuntu
@ -165,7 +164,7 @@ On [Void Linux](https://voidlinux.eu), install following packages before
compiling Alacritty: compiling Alacritty:
```sh ```sh
xbps-install cmake freetype-devel freetype expat-devel fontconfig xclip xbps-install cmake freetype-devel freetype expat-devel fontconfig-devel fontconfig xclip
``` ```
#### FreeBSD #### FreeBSD
@ -296,10 +295,19 @@ To get automatic completions for alacritty's flags and arguments you can install
### Zsh ### 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 ### Bash

View file

@ -1,13 +1,13 @@
# Configuration for Alacritty, the GPU enhanced terminal emulator # Configuration for Alacritty, the GPU enhanced terminal emulator.
# Any items in the `env` entry below will be added as # Any items in the `env` entry below will be added as
# environment variables. Some entries may override variables # environment variables. Some entries may override variables
# set by alacritty it self. # set by alacritty itself.
env: env:
# TERM env customization. # TERM env customization
# #
# If this property is not set, alacritty will set it to xterm-256color. # If this property is not set, alacritty will set it to `xterm-256color`.
# #
# Note that some xterm terminfo databases don't declare support for italics. # Note that some xterm terminfo databases don't declare support for italics.
# You can verify this by checking for the presence of `smso` and `sitm` in # You can verify this by checking for the presence of `smso` and `sitm` in
@ -15,119 +15,128 @@ env:
TERM: xterm-256color TERM: xterm-256color
window: window:
# Window dimensions in character columns and lines # Window dimensions (changes require restart)
# Falls back to size specified by window manager if set to 0x0. #
# (changes require restart) # Specified in number of columns/lines, not pixels.
# If both are `0`, this setting is ignored.
dimensions: dimensions:
columns: 80 columns: 80
lines: 24 lines: 24
# Adds this many blank pixels of padding around the window # Window padding (changes require restart)
# Units are physical pixels; this is not DPI aware. #
# (change requires restart) # Blank space added around the window in pixels. This padding is not scaled
# by DPI and the specified value is always added at both opposing sides.
padding: padding:
x: 2 x: 2
y: 2 y: 2
# Window decorations # Window decorations
# Setting this to false will result in window without borders and title bar. #
decorations: true # Values for `decorations`:
# - full: Borders and title bar
# - none: Neither borders nor title bar
decorations: full
scrolling: scrolling:
# How many lines of scrollback to keep, # Maximum number of lines in the scrollback buffer.
# '0' will disable scrolling. # Specifying '0' will disable scrolling.
history: 10000 history: 10000
# Number of lines the viewport will move for every line # Number of lines the viewport will move for every line scrolled when
# scrolled when scrollback is enabled (history > 0). # scrollback is enabled (history > 0).
multiplier: 3 multiplier: 3
# Faux Scrolling # Faux Scrolling
# #
# The `faux_multiplier` setting controls the number # The `faux_multiplier` setting controls the number of lines the terminal
# of lines the terminal should scroll when the alternate # should scroll when the alternate screen buffer is active. This is used
# screen buffer is active. This is used to allow mouse # to allow mouse scrolling for applications like `man`.
# scrolling for applications like `man`.
# #
# To disable this completely, set `faux_multiplier` to 0. # Specifying `0` will disable faux scrolling.
faux_multiplier: 3 faux_multiplier: 3
# Automatically scroll to the bottom when new text is written # Scroll to the bottom when new text is written to the terminal.
# to the terminal.
auto_scroll: false auto_scroll: false
# Display tabs using this many cells (changes require restart) # Spaces per Tab (changes require restart)
#
# This setting defines the width of a tab in cells.
#
# Some applications, like Emacs, rely on knowing about the width of a tab.
# To prevent unexpected behavior in these applications, it's also required to
# change the `it` value in terminfo when altering this setting.
tabspaces: 8 tabspaces: 8
# When true, bold text is drawn using the bright variant of colors.
draw_bold_text_with_bright_colors: true
# Font configuration (changes require restart) # Font configuration (changes require restart)
# #
# Important font attributes like antialiasing, subpixel aa, and hinting can be # Important font attributes like antialiasing, subpixel aa, and hinting can be
# controlled through fontconfig. Specifically, the following attributes should # controlled through fontconfig. Specifically, the following attributes should
# have an effect: # have an effect:
# # - hintstyle
# * hintstyle # - antialias
# * antialias # - lcdfilter
# * lcdfilter # - rgba
# * rgba
# #
# For instance, if you wish to disable subpixel antialiasing, you might set the # For instance, if you wish to disable subpixel antialiasing, you might set the
# rgba property to "none". If you wish to completely disable antialiasing, you # rgba property to `none`. If you wish to completely disable antialiasing, you
# can set antialias to false. # can set antialias to `false`.
# #
# Please see these resources for more information on how to use fontconfig # Please see these resources for more information on how to use fontconfig:
# # - https://wiki.archlinux.org/index.php/font_configuration#Fontconfig_configuration
# * https://wiki.archlinux.org/index.php/font_configuration#Fontconfig_configuration # - file:///usr/share/doc/fontconfig/fontconfig-user.html
# * file:///usr/share/doc/fontconfig/fontconfig-user.html
font: font:
# The normal (roman) font face to use. # Normal (roman) font face
normal: normal:
family: monospace # should be "Menlo" or something on macOS. family: monospace
# Style can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
# style: Regular # style: Regular
# The bold font face # Bold font face
bold: bold:
family: monospace # should be "Menlo" or something on macOS. family: monospace
# Style can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
# style: Bold # style: Bold
# The italic font face # Italic font face
italic: italic:
family: monospace # should be "Menlo" or something on macOS. family: monospace
# Style can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
# style: Italic # style: Italic
# Point size of the font # Point size
size: 11.0 size: 11.0
# Offset is the extra space around each character. offset.y can be thought of # Offset is the extra space around each character. `offset.y` can be thought of
# as modifying the linespacing, and offset.x as modifying the letter spacing. # as modifying the line spacing, and `offset.x` as modifying the letter spacing.
offset: offset:
x: 0 x: 0
y: 0 y: 0
# Glyph offset determines the locations of the glyphs within their cells with # Glyph offset determines the locations of the glyphs within their cells with
# the default being at the bottom. Increase the x offset to move the glyph to # the default being at the bottom. Increasing `x` moves the glyph to the right,
# the right, increase the y offset to move the glyph upward. # increasing `y` moves the glyph upwards.
glyph_offset: glyph_offset:
x: 0 x: 0
y: 0 y: 0
# OS X only: use thin stroke font rendering. Thin strokes are suitable # Scale the font size based on the monitor's DPI. This will lead to bigger text on HiDPI
# for retina displays, but for non-retina you probably want this set to # screens and make reading text a little easier.
# false. # On X11 it is possible to change the DPI for each instance of alacritty by using
use_thin_strokes: true # `WINIT_HIDPI_FACTOR=1.0 alacritty` to scale the font.
scale_with_dpi: true
# Should display the render timer # Display the time it takes to redraw each frame.
render_timer: false render_timer: false
# Use custom cursor colors. If true, display the cursor in the cursor.foreground # Use custom cursor colors. If `true`, the `colors.cursor.foreground` and
# and cursor.background colors, otherwise invert the colors of the cursor. # `colors.cursor.background` colors will be used to display the cursor.
# Otherwise the cell colors are inverted for the cursor.
custom_cursor_colors: false custom_cursor_colors: false
# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true
# Colors (Tomorrow Night Bright) # Colors (Tomorrow Night Bright)
colors: colors:
# Default colors # Default colors
@ -135,16 +144,18 @@ colors:
background: '0x000000' background: '0x000000'
foreground: '0xeaeaea' foreground: '0xeaeaea'
# (Optional) Bright and Dim foreground colors # Bright and dim foreground colors
# #
# The dimmed foreground color is calculated automatically if it is not present. # The dimmed foreground color is calculated automatically if it is not present.
# If the bright foreground color is not set, or `draw_bold_text_with_bright_colors` # If the bright foreground color is not set, or `draw_bold_text_with_bright_colors`
# is `false`, the normal foreground color will be used. # is `false`, the normal foreground color will be used.
# #
# dim_foreground: '0x9a9a9a' #dim_foreground: '0x9a9a9a'
# bright_foreground: '0xffffff' #bright_foreground: '0xffffff'
# Colors the cursor will use if `custom_cursor_colors` is true # Cursor colors
#
# These will only be used when the `custom_cursor_colors` field is set to `true`.
cursor: cursor:
text: '0x000000' text: '0x000000'
cursor: '0xffffff' cursor: '0xffffff'
@ -171,7 +182,10 @@ colors:
cyan: '0x54ced6' cyan: '0x54ced6'
white: '0xffffff' white: '0xffffff'
# Dim colors (Optional) # Dim colors
#
# If the dim colors are not set, they will be calculated automatically based
# on the `normal` colors.
dim: dim:
black: '0x333333' black: '0x333333'
red: '0xf2777a' red: '0xf2777a'
@ -190,20 +204,19 @@ colors:
# setting the `duration` property (represented in milliseconds). You can also # setting the `duration` property (represented in milliseconds). You can also
# configure the transition function by setting the `animation` property. # configure the transition function by setting the `animation` property.
# #
# Possible values for `animation` # Values for `animation`:
# `Ease` # - Ease
# `EaseOut` # - EaseOut
# `EaseOutSine` # - EaseOutSine
# `EaseOutQuad` # - EaseOutQuad
# `EaseOutCubic` # - EaseOutCubic
# `EaseOutQuart` # - EaseOutQuart
# `EaseOutQuint` # - EaseOutQuint
# `EaseOutExpo` # - EaseOutExpo
# `EaseOutCirc` # - EaseOutCirc
# `Linear` # - Linear
#
# To completely disable the visual bell, set its duration to 0.
# #
# Specifying a `duration` of `0` will disable the visual bell.
visual_bell: visual_bell:
animation: EaseOutExpo animation: EaseOutExpo
duration: 0 duration: 0
@ -213,19 +226,19 @@ background_opacity: 1.0
# Mouse bindings # Mouse bindings
# #
# Currently doesn't support modifiers. Both the `mouse` and `action` fields must # Available fields:
# be specified. # - mouse
# - action
# - mods (optional)
# #
# Values for `mouse`: # Values for `mouse`:
# - Middle # - Middle
# - Left # - Left
# - Right # - Right
# - Numeric identifier such as `5` # - Numeric identifier such as `5`
# #
# Values for `action`: # All available `mods` and `action` values are documented in the key binding
# - Paste # section.
# - PasteSelection
# - Copy (TODO)
mouse_bindings: mouse_bindings:
- { mouse: Middle, action: PasteSelection } - { mouse: Middle, action: PasteSelection }
@ -245,15 +258,16 @@ dynamic_title: true
hide_cursor_when_typing: false hide_cursor_when_typing: false
# Style of the cursor # Cursor style
# #
# Values for 'cursor_style': # Values for 'cursor_style':
# - Block # - Block
# - Underline # - Underline
# - Beam # - Beam
cursor_style: Block cursor_style: Block
# Whether the cursor should be a hollow block on window focus loss # If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow_cursor: true unfocused_hollow_cursor: true
# Live config reload (changes require restart) # Live config reload (changes require restart)
@ -261,64 +275,82 @@ live_config_reload: true
# Shell # Shell
# #
# You can set shell.program to the path of your favorite shell, e.g. /bin/fish. # You can set `shell.program` to the path of your favorite shell, e.g. `/bin/fish`.
# Entries in shell.args are passed unmodified as arguments to the shell. # Entries in `shell.args` are passed unmodified as arguments to the shell.
# #
# shell: #shell:
# program: /bin/bash # program: /bin/bash
# args: # args:
# - --login # - --login
# Key bindings # Key bindings
# #
# Each binding is defined as an object with some properties. Most of the # Key bindings are specified as a list of objects. Each binding will specify
# properties are optional. All of the alphabetical keys should have a letter for # a key and modifiers required to trigger it, terminal modes where the binding
# the `key` value such as `V`. Function keys are probably what you would expect # is applicable, and what should be done when the key binding fires. It can
# as well (F1, F2, ..). The number keys above the main keyboard are encoded as # either send a byte sequnce to the running application (`chars`), execute
# `Key1`, `Key2`, etc. Keys on the number pad are encoded `Number1`, `Number2`, # a predefined action (`action`) or fork and execute a specified command plus
# etc. These all match the glutin::VirtualKeyCode variants. # arguments (`command`).
# #
# A list with all available `key` names can be found here: # Example:
# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants # `- { key: V, mods: Command, action: Paste }`
# #
# Possible values for `mods` # Available fields:
# `Command`, `Super` refer to the super/command/windows key # - key
# `Control` for the control key # - mods (optional)
# `Shift` for the Shift key # - chars | action | command (exactly one required)
# `Alt` and `Option` refer to alt/option # - mode (optional)
# #
# mods may be combined with a `|`. For example, requiring control and shift # Values for `key`:
# looks like: # - `A` -> `Z`
# - `F1` -> `F12`
# - `Key1` -> `Key0`
# #
# mods: Control|Shift # A full list with available key codes can be found here:
# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants
# #
# The parser is currently quite sensitive to whitespace and capitalization - # Values for `mods`:
# capitalization must match exactly, and piped items must not have whitespace # - Command
# around them. # - Control
# - Shift
# - Alt
# #
# Either an `action`, `chars`, or `command` field must be present. # Multiple `mods` can be combined using `|` like this: `mods: Control|Shift`.
# `action` must be one of the following: # Whitespace and capitalization is relevant and must match the example.
# - `Paste`
# - `PasteSelection`
# - `Copy`
# - `IncreaseFontSize`
# - `DecreaseFontSize`
# - `ResetFontSize`
# - `ScrollPageUp`
# - `ScrollPageDown`
# - `ScrollToTop`
# - `ScrollToBottom`
# - `Quit`
# `chars` writes the specified string every time that binding is activated.
# These should generally be escape sequences, but they can be configured to
# send arbitrary strings of bytes.
# `command` must be a map containing a `program` string, and `args` array of
# strings. For example:
# - { ... , command: { program: "alacritty", args: ["-e", "vttest"] } }
# #
# Want to add a binding (e.g. "PageUp") but are unsure what the X sequence # Values for `chars`:
# (e.g. "\x1b[5~") is? Open another terminal (like xterm) without tmux, # The `chars` field writes the specified string to the terminal. This makes
# then run `showkey -a` to get the sequence associated to a key combination. # it possible to pass escape sequences.
# To find escape codes for bindings like `PageUp` ("\x1b[5~"), you can run
# the command `showkey -a` outside of tmux.
#
# Values for `action`:
# - Paste
# - PasteSelection
# - Copy
# - IncreaseFontSize
# - DecreaseFontSize
# - ResetFontSize
# - ScrollPageUp
# - ScrollPageDown
# - ScrollToTop
# - ScrollToBottom
# - ClearHistory
# - Hide
# - Quit
#
# Values for `command`:
# The `command` field must be a map containing a `program` string and
# an `args` array of command line parameter strings.
#
# Example:
# `command: { program: "alacritty", args: ["-e", "vttest"] }`
#
# Values for `mode`:
# - ~AppCursor
# - AppCursor
# - ~AppKeypad
# - AppKeypad
key_bindings: key_bindings:
- { key: V, mods: Control|Shift, action: Paste } - { key: V, mods: Control|Shift, action: Paste }
- { key: C, mods: Control|Shift, action: Copy } - { key: C, mods: Control|Shift, action: Copy }

View file

@ -1,12 +1,12 @@
# Configuration for Alacritty, the GPU enhanced terminal emulator # Configuration for Alacritty, the GPU enhanced terminal emulator.
# Any items in the `env` entry below will be added as # Any items in the `env` entry below will be added as
# environment variables. Some entries may override variables # environment variables. Some entries may override variables
# set by alacritty it self. # set by alacritty itself.
env: env:
# TERM env customization. # TERM env customization
# #
# If this property is not set, alacritty will set it to xterm-256color. # If this property is not set, alacritty will set it to `xterm-256color`.
# #
# Note that some xterm terminfo databases don't declare support for italics. # Note that some xterm terminfo databases don't declare support for italics.
# You can verify this by checking for the presence of `smso` and `sitm` in # You can verify this by checking for the presence of `smso` and `sitm` in
@ -14,100 +14,123 @@ env:
TERM: xterm-256color TERM: xterm-256color
window: window:
# Window dimensions in character columns and lines # Window dimensions (changes require restart)
# (changes require restart) #
# Specified in number of columns/lines, not pixels.
# If both are `0`, this setting is ignored.
dimensions: dimensions:
columns: 80 columns: 80
lines: 24 lines: 24
# Adds this many blank pixels of padding around the window # Window padding (changes require restart)
# Units are physical pixels; this is not DPI aware. #
# (change requires restart) # Blank space added around the window in pixels. This padding is not scaled
# by DPI and the specified value is always added at both opposing sides.
padding: padding:
x: 2 x: 2
y: 2 y: 2
# Window decorations # Window decorations
# Setting this to false will result in window without borders and title bar. #
decorations: true # Available values:
# - `full`: Window with title bar and title bar buttons
# - `none`: Window without title bar, rounded corners, or drop shadow
# - `transparent`: Window with title bar with transparent background and title
# bar buttons
# - `buttonless`: Window with title bar with transparent background and no
# title bar buttons
# Window decorations
#
# Values for `decorations`:
# - full: Borders and title bar
# - none: Neither borders nor title bar
# - buttonless: Title bar, transparent background and title bar buttons
# - transparent: Title bar, transparent background, but no title bar buttons
decorations: full
scrolling: scrolling:
# How many lines of scrollback to keep, # Maximum number of lines in the scrollback buffer.
# '0' will disable scrolling. # Specifying '0' will disable scrolling.
history: 10000 history: 10000
# Number of lines the viewport will move for every line # Number of lines the viewport will move for every line scrolled when
# scrolled when scrollback is enabled (history > 0). # scrollback is enabled (history > 0).
multiplier: 3 multiplier: 3
# Faux Scrolling # Faux Scrolling
# #
# The `faux_multiplier` setting controls the number # The `faux_multiplier` setting controls the number of lines the terminal
# of lines the terminal should scroll when the alternate # should scroll when the alternate screen buffer is active. This is used
# screen buffer is active. This is used to allow mouse # to allow mouse scrolling for applications like `man`.
# scrolling for applications like `man`.
# #
# To disable this completely, set `faux_multiplier` to 0. # Specifying `0` will disable faux scrolling.
faux_multiplier: 3 faux_multiplier: 3
# Automatically scroll to the bottom when new text is written # Scroll to the bottom when new text is written to the terminal.
# to the terminal.
auto_scroll: false auto_scroll: false
# Display tabs using this many cells (changes require restart) # Spaces per Tab (changes require restart)
#
# This setting defines the width of a tab in cells.
#
# Some applications, like Emacs, rely on knowing about the width of a tab.
# To prevent unexpected behavior in these applications, it's also required to
# change the `it` value in terminfo when altering this setting.
tabspaces: 8 tabspaces: 8
# When true, bold text is drawn using the bright variant of colors.
draw_bold_text_with_bright_colors: true
# Font configuration (changes require restart) # Font configuration (changes require restart)
font: font:
# The normal (roman) font face to use. # Normal (roman) font face
normal: normal:
family: Menlo family: Menlo
# Style can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
# style: Regular # style: Regular
# The bold font face # Italic font face
bold: bold:
family: Menlo family: Menlo
# Style can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
# style: Bold # style: Bold
# The italic font face # Italic font face
italic: italic:
family: Menlo family: Menlo
# Style can be specified to pick a specific face. # The `style` can be specified to pick a specific face.
# style: Italic # style: Italic
# Point size of the font # Point size
size: 12.0 size: 12.0
# Offset is the extra space around each character. offset.y can be thought of # Offset is the extra space around each character. `offset.y` can be thought of
# as modifying the linespacing, and offset.x as modifying the letter spacing. # as modifying the line spacing, and `offset.x` as modifying the letter spacing.
offset: offset:
x: 0 x: 0
y: 0 y: 0
# Glyph offset determines the locations of the glyphs within their cells with # Glyph offset determines the locations of the glyphs within their cells with
# the default being at the bottom. Increase the x offset to move the glyph to # the default being at the bottom. Increasing `x` moves the glyph to the right,
# the right, increase the y offset to move the glyph upward. # increasing `y` moves the glyph upwards.
glyph_offset: glyph_offset:
x: 0 x: 0
y: 0 y: 0
# OS X only: use thin stroke font rendering. Thin strokes are suitable # Thin stroke font rendering (OS X only)
# for retina displays, but for non-retina you probably want this set to #
# false. # Thin strokes are suitable for retina displays, but for non-retina screens
# it is recommended to set `use_thin_strokes` to `false`
use_thin_strokes: true use_thin_strokes: true
# Should display the render timer # Display the time it takes to redraw each frame.
render_timer: false render_timer: false
# Use custom cursor colors. If true, display the cursor in the cursor.foreground # Use custom cursor colors. If `true`, the `colors.cursor.foreground` and
# and cursor.background colors, otherwise invert the colors of the cursor. # `colors.cursor.background` colors will be used to display the cursor.
# Otherwise the cell colors are inverted for the cursor.
custom_cursor_colors: false custom_cursor_colors: false
# If `true`, bold text is drawn using the bright color variants.
draw_bold_text_with_bright_colors: true
# Colors (Tomorrow Night Bright) # Colors (Tomorrow Night Bright)
colors: colors:
# Default colors # Default colors
@ -115,16 +138,18 @@ colors:
background: '0x000000' background: '0x000000'
foreground: '0xeaeaea' foreground: '0xeaeaea'
# (Optional) Bright and Dim foreground colors # Bright and dim foreground colors
# #
# The dimmed foreground color is calculated automatically if it is not present. # The dimmed foreground color is calculated automatically if it is not present.
# If the bright foreground color is not set, or `draw_bold_text_with_bright_colors` # If the bright foreground color is not set, or `draw_bold_text_with_bright_colors`
# is `false`, the normal foreground color will be used. # is `false`, the normal foreground color will be used.
# #
# dim_foreground: '0x9a9a9a' #dim_foreground: '0x9a9a9a'
# bright_foreground: '0xffffff' #bright_foreground: '0xffffff'
# Colors the cursor will use if `custom_cursor_colors` is true # Cursor colors
#
# These will only be used when the `custom_cursor_colors` field is set to `true`.
cursor: cursor:
text: '0x000000' text: '0x000000'
cursor: '0xffffff' cursor: '0xffffff'
@ -151,7 +176,10 @@ colors:
cyan: '0x54ced6' cyan: '0x54ced6'
white: '0xffffff' white: '0xffffff'
# Dim colors (Optional) # Dim colors
#
# If the dim colors are not set, they will be calculated automatically based
# on the `normal` colors.
dim: dim:
black: '0x333333' black: '0x333333'
red: '0xf2777a' red: '0xf2777a'
@ -162,7 +190,6 @@ colors:
cyan: '0x66cccc' cyan: '0x66cccc'
white: '0xdddddd' white: '0xdddddd'
# Visual Bell # Visual Bell
# #
# Any time the BEL code is received, Alacritty "rings" the visual bell. Once # Any time the BEL code is received, Alacritty "rings" the visual bell. Once
@ -171,20 +198,19 @@ colors:
# setting the `duration` property (represented in milliseconds). You can also # setting the `duration` property (represented in milliseconds). You can also
# configure the transition function by setting the `animation` property. # configure the transition function by setting the `animation` property.
# #
# Possible values for `animation` # Values for `animation`:
# `Ease` # - Ease
# `EaseOut` # - EaseOut
# `EaseOutSine` # - EaseOutSine
# `EaseOutQuad` # - EaseOutQuad
# `EaseOutCubic` # - EaseOutCubic
# `EaseOutQuart` # - EaseOutQuart
# `EaseOutQuint` # - EaseOutQuint
# `EaseOutExpo` # - EaseOutExpo
# `EaseOutCirc` # - EaseOutCirc
# `Linear` # - Linear
#
# To completely disable the visual bell, set its duration to 0.
# #
# Specifying a `duration` of `0` will disable the visual bell.
visual_bell: visual_bell:
animation: EaseOutExpo animation: EaseOutExpo
duration: 0 duration: 0
@ -194,8 +220,10 @@ background_opacity: 1.0
# Mouse bindings # Mouse bindings
# #
# Currently doesn't support modifiers. Both the `mouse` and `action` fields must # Available fields:
# be specified. # - mouse
# - action
# - mods (optional)
# #
# Values for `mouse`: # Values for `mouse`:
# - Middle # - Middle
@ -203,10 +231,8 @@ background_opacity: 1.0
# - Right # - Right
# - Numeric identifier such as `5` # - Numeric identifier such as `5`
# #
# Values for `action`: # All available `mods` and `action` values are documented in the key binding
# - Paste # section.
# - PasteSelection
# - Copy (TODO)
mouse_bindings: mouse_bindings:
- { mouse: Middle, action: PasteSelection } - { mouse: Middle, action: PasteSelection }
@ -226,15 +252,16 @@ dynamic_title: true
hide_cursor_when_typing: false hide_cursor_when_typing: false
# Style of the cursor # Cursor style
# #
# Values for 'cursor_style': # Values for 'cursor_style':
# - Block # - Block
# - Underline # - Underline
# - Beam # - Beam
cursor_style: Block cursor_style: Block
# Whether the cursor should be a hollow block on window focus loss # If this is `true`, the cursor will be rendered as a hollow box when the
# window is not focused.
unfocused_hollow_cursor: true unfocused_hollow_cursor: true
# Live config reload (changes require restart) # Live config reload (changes require restart)
@ -242,60 +269,82 @@ live_config_reload: true
# Shell # Shell
# #
# You can set shell.program to the path of your favorite shell, e.g. /bin/fish. # You can set `shell.program` to the path of your favorite shell, e.g. `/bin/fish`.
# Entries in shell.args are passed unmodified as arguments to the shell. # Entries in `shell.args` are passed unmodified as arguments to the shell.
# #
# shell: #shell:
# program: /bin/bash # program: /bin/bash
# args: # args:
# - --login # - --login
# Key bindings # Key bindings
# #
# Each binding is defined as an object with some properties. Most of the # Key bindings are specified as a list of objects. Each binding will specify
# properties are optional. All of the alphabetical keys should have a letter for # a key and modifiers required to trigger it, terminal modes where the binding
# the `key` value such as `V`. Function keys are probably what you would expect # is applicable, and what should be done when the key binding fires. It can
# as well (F1, F2, ..). The number keys above the main keyboard are encoded as # either send a byte sequnce to the running application (`chars`), execute
# `Key1`, `Key2`, etc. Keys on the number pad are encoded `Number1`, `Number2`, # a predefined action (`action`) or fork and execute a specified command plus
# etc. These all match the glutin::VirtualKeyCode variants. # arguments (`command`).
# #
# A list with all available `key` names can be found here: # Example:
# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants # `- { key: V, mods: Command, action: Paste }`
# #
# Possible values for `mods` # Available fields:
# `Command`, `Super` refer to the super/command/windows key # - key
# `Control` for the control key # - mods (optional)
# `Shift` for the Shift key # - chars | action | command (exactly one required)
# `Alt` and `Option` refer to alt/option # - mode (optional)
# #
# mods may be combined with a `|`. For example, requiring control and shift # Values for `key`:
# looks like: # - `A` -> `Z`
# - `F1` -> `F12`
# - `Key1` -> `Key0`
# #
# mods: Control|Shift # A full list with available key codes can be found here:
# https://docs.rs/glutin/*/glutin/enum.VirtualKeyCode.html#variants
# #
# The parser is currently quite sensitive to whitespace and capitalization - # Values for `mods`:
# capitalization must match exactly, and piped items must not have whitespace # - Command
# around them. # - Control
# - Shift
# - Alt
# #
# Either an `action`, `chars`, or `command` field must be present. # Multiple `mods` can be combined using `|` like this: `mods: Control|Shift`.
# `action` must be one of the following: # Whitespace and capitalization is relevant and must match the example.
# - `Paste` #
# - `PasteSelection` # Values for `chars`:
# - `Copy` # The `chars` field writes the specified string to the terminal. This makes
# - `IncreaseFontSize` # it possible to pass escape sequences.
# - `DecreaseFontSize` # To find escape codes for bindings like `PageUp` ("\x1b[5~"), you can run
# - `ResetFontSize` # the command `showkey -a` outside of tmux.
# - `ScrollPageUp` #
# - `ScrollPageDown` # Values for `action`:
# - `ScrollToTop` # - Paste
# - `ScrollToBottom` # - PasteSelection
# - `Quit` # - Copy
# `chars` writes the specified string every time that binding is activated. # - IncreaseFontSize
# These should generally be escape sequences, but they can be configured to # - DecreaseFontSize
# send arbitrary strings of bytes. # - ResetFontSize
# `command` must be a map containing a `program` string, and `args` array of # - ScrollPageUp
# strings. For example: # - ScrollPageDown
# - { ... , command: { program: "alacritty", args: ["-e", "vttest"] } } # - ScrollToTop
# - ScrollToBottom
# - ClearHistory
# - Hide
# - Quit
#
# Values for `command`:
# The `command` field must be a map containing a `program` string and
# an `args` array of command line parameter strings.
#
# Example:
# `command: { program: "alacritty", args: ["-e", "vttest"] }`
#
# Values for `mode`:
# - ~AppCursor
# - AppCursor
# - ~AppKeypad
# - AppKeypad
key_bindings: key_bindings:
- { key: V, mods: Command, action: Paste } - { key: V, mods: Command, action: Paste }
- { key: C, mods: Command, action: Copy } - { key: C, mods: Command, action: Copy }

View file

@ -32,5 +32,7 @@
<true/> <true/>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Alacritty</string> <string>Alacritty</string>
<key>NSRequiresAquaSystemAppearance</key>
<string>NO</string>
</dict> </dict>
</plist> </plist>

View file

@ -16,7 +16,7 @@ servo-fontconfig = { git = "https://github.com/jwilm/rust-fontconfig", branch =
freetype-rs = "0.13" freetype-rs = "0.13"
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.5" core-foundation = "0.6"
core-text = "9.1" core-text = "13"
core-graphics = "0.13" core-graphics = "0.17"
core-foundation-sys = "0.5" core-foundation-sys = "0.6"

View file

@ -18,6 +18,7 @@
#![allow(improper_ctypes)] #![allow(improper_ctypes)]
use std::collections::HashMap; use std::collections::HashMap;
use std::ptr; use std::ptr;
use std::path::PathBuf;
use ::{Slant, Weight, Style}; use ::{Slant, Weight, Style};
@ -56,7 +57,7 @@ pub struct Descriptor {
font_name: String, font_name: String,
style_name: String, style_name: String,
display_name: String, display_name: String,
font_path: String, font_path: PathBuf,
ct_descriptor: CTFontDescriptor ct_descriptor: CTFontDescriptor
} }
@ -68,7 +69,7 @@ impl Descriptor {
font_name: desc.font_name(), font_name: desc.font_name(),
style_name: desc.style_name(), style_name: desc.style_name(),
display_name: desc.display_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, ct_descriptor: desc,
} }
} }
@ -339,8 +340,10 @@ pub fn descriptors_for_family(family: &str) -> Vec<Descriptor> {
// CFArray of CTFontDescriptorRef (i think) // CFArray of CTFontDescriptorRef (i think)
let descriptors = ct_collection.get_descriptors(); let descriptors = ct_collection.get_descriptors();
for descriptor in descriptors.iter() { if let Some(descriptors) = descriptors {
out.push(Descriptor::new(descriptor.clone())); for descriptor in descriptors.iter() {
out.push(Descriptor::new(descriptor.clone()));
}
} }
out out
@ -363,7 +366,7 @@ impl Descriptor {
// TODO fixme, hardcoded en for english // TODO fixme, hardcoded en for english
let mut fallbacks = cascade_list_for_languages(&menlo, &["en".to_owned()]) let mut fallbacks = cascade_list_for_languages(&menlo, &["en".to_owned()])
.into_iter() .into_iter()
.filter(|desc| desc.font_path != "") .filter(|desc| !desc.font_path.as_os_str().is_empty())
.map(|desc| desc.to_font(size, false)) .map(|desc| desc.to_font(size, false))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -447,12 +450,14 @@ impl Font {
let indices = [index as CGGlyph]; let indices = [index as CGGlyph];
self.ct_font.get_advances_for_glyphs( unsafe {
FontOrientation::Default as _, self.ct_font.get_advances_for_glyphs(
&indices[0], FontOrientation::Default as _,
ptr::null_mut(), &indices[0],
1 ptr::null_mut(),
) 1
)
}
} }
pub fn get_glyph(&self, character: char, _size: f64, use_thin_strokes: bool) -> Result<RasterizedGlyph, Error> { 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. // always being a 0.
let mut glyphs:[CGGlyph; 2] = [0; 2]; let mut glyphs:[CGGlyph; 2] = [0; 2];
let res = self.ct_font.get_glyphs_for_characters( let res = unsafe {
encoded.as_ptr(), self.ct_font.get_glyphs_for_characters(
glyphs.as_mut_ptr(), encoded.as_ptr(),
encoded.len() as CFIndex glyphs.as_mut_ptr(),
); encoded.len() as CFIndex
)
};
if res { if res {
Some(u32::from(glyphs[0])) Some(u32::from(glyphs[0]))

View file

@ -99,7 +99,7 @@ impl<'a> Iterator for Iter<'a> {
None None
} else { } else {
let pattern = unsafe { 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) PatternRef::from_ptr(ptr)
}; };

View file

@ -1,14 +1,53 @@
#!/bin/bash #!/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=Black, Bg=Black \e[30;40mTEST\e[m\n" printf "Fg=Black Bg=White \e[30;107mTEST\e[m\n"
printf "Fg=Foreground,Bg=Background \e[39;49mTEST\e[m\n" printf "Fg=Black Bg=Red \e[30;41mTEST\e[m\n"
printf "Fg=Foreground,Bg=Black \e[39;40mTEST\e[m\n" printf "Fg=Black Bg=BG \e[30;49mTEST\e[m\n"
printf "Fg=Foreground,Bg=White \e[39;47mTEST\e[m\n" printf "Fg=White Bg=Black \e[97;40mTEST\e[m\n"
printf "Fg=White, Bg=Foreground \e[37;39mTEST\e[m\n" printf "Fg=White Bg=White \e[97;107mTEST\e[m\n"
printf "Fg=Black, Bg=Background, Inverse \e[7;30;49mTEST\e[m\n" printf "Fg=White Bg=Red \e[97;41mTEST\e[m\n"
printf "Fg=Black, Bg=Black, Inverse \e[7;30;40mTEST\e[m\n" printf "Fg=White Bg=BG \e[97;49mTEST\e[m\n"
printf "Fg=Foreground,Bg=Background, Inverse \e[7;39;49mTEST\e[m\n" printf "Fg=Red Bg=Black \e[31;40mTEST\e[m\n"
printf "Fg=Foreground,Bg=Black, Inverse \e[7;39;40mTEST\e[m\n" printf "Fg=Red Bg=White \e[31;107mTEST\e[m\n"
printf "Fg=Foreground,Bg=White, Inverse \e[7;39;47mTEST\e[m\n" printf "Fg=Red Bg=Red \e[31;41mTEST\e[m\n"
printf "Fg=White, Bg=Foreground, Inverse \e[7;37;39mTEST\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"

View file

@ -15,8 +15,8 @@ parts:
plugin: dump plugin: dump
source: . source: .
stage: stage:
- Alacritty.desktop - alacritty.desktop
apps: apps:
alacritty: alacritty:
command: env XDG_RUNTIME_DIR= XDG_CONFIG_HOME=$SNAP_USER_DATA XDG_DATA_DIRS=$SNAP_DATA PATH=$SNAP/bin:$PATH SNAP= 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

View file

@ -30,6 +30,8 @@ use ansi::CursorStyle;
use util::fmt::Yellow; use util::fmt::Yellow;
const MAX_SCROLLBACK_LINES: u32 = 100_000;
/// Function that returns true for serde default /// Function that returns true for serde default
fn true_bool() -> bool { fn true_bool() -> bool {
true 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)] #[derive(Debug, Copy, Clone, Deserialize)]
pub struct WindowConfig { pub struct WindowConfig {
/// Initial dimensions /// Initial dimensions
@ -257,8 +344,8 @@ pub struct WindowConfig {
padding: Delta<u8>, padding: Delta<u8>,
/// Draw the window with title bar / borders /// Draw the window with title bar / borders
#[serde(default, deserialize_with = "failure_default")] #[serde(default)]
decorations: bool, decorations: Decorations,
} }
fn default_padding() -> Delta<u8> { fn default_padding() -> Delta<u8> {
@ -278,7 +365,7 @@ fn deserialize_padding<'a, D>(deserializer: D) -> ::std::result::Result<Delta<u8
} }
impl WindowConfig { impl WindowConfig {
pub fn decorations(&self) -> bool { pub fn decorations(&self) -> Decorations {
self.decorations self.decorations
} }
} }
@ -288,7 +375,7 @@ impl Default for WindowConfig {
WindowConfig{ WindowConfig{
dimensions: Default::default(), dimensions: Default::default(),
padding: default_padding(), 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> where D: de::Deserializer<'a>
{ {
match u32::deserialize(deserializer) { 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) => { Err(err) => {
eprintln!("problem with config: {}; Using default value", err); eprintln!("problem with config: {}; Using default value", err);
Ok(default_scrolling_history()) Ok(default_scrolling_history())

View file

@ -26,6 +26,7 @@ use font::{self, Rasterize};
use meter::Meter; use meter::Meter;
use renderer::{self, GlyphCache, QuadRenderer}; use renderer::{self, GlyphCache, QuadRenderer};
use term::{Term, SizeInfo}; use term::{Term, SizeInfo};
use sync::FairMutex;
use window::{self, Window}; use window::{self, Window};
@ -99,7 +100,6 @@ pub struct Display {
meter: Meter, meter: Meter,
font_size: font::Size, font_size: font::Size,
size_info: SizeInfo, size_info: SizeInfo,
last_background_color: Rgb,
} }
/// Can wakeup the render loop from other threads /// Can wakeup the render loop from other threads
@ -208,7 +208,6 @@ impl Display {
meter: Meter::new(), meter: Meter::new(),
font_size: font::Size::new(0.), font_size: font::Size::new(0.),
size_info, 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. /// A reference to Term whose state is being drawn must be provided.
/// ///
/// This call may block if vsync is enabled /// 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 // Clear dirty flag
terminal.dirty = !terminal.visual_bell.completed(); 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; let glyph_cache = &mut self.glyph_cache;
@ -374,11 +388,6 @@ impl Display {
// mutable borrow // mutable borrow
let window_focused = self.window.is_focused; let window_focused = self.window.is_focused;
self.renderer.with_api(config, &size_info, visual_bell_intensity, |mut api| { 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 // Draw the grid
api.render_cells( api.render_cells(
terminal.renderable_cells(config, window_focused), terminal.renderable_cells(config, window_focused),
@ -402,19 +411,6 @@ impl Display {
self.window self.window
.swap_buffers() .swap_buffers()
.expect("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> { pub fn get_window_id(&self) -> Option<usize> {

View file

@ -347,7 +347,7 @@ impl<N: Notify> Processor<N> {
processor.received_char(c); processor.received_char(c);
}, },
MouseInput { state, button, modifiers, .. } => { MouseInput { state, button, modifiers, .. } => {
if *window_is_focused { if !cfg!(target_os = "macos") || *window_is_focused {
*hide_cursor = false; *hide_cursor = false;
processor.mouse_input(state, button, modifiers); processor.mouse_input(state, button, modifiers);
processor.ctx.terminal.dirty = true; processor.ctx.terminal.dirty = true;

View file

@ -15,7 +15,7 @@
//! Defines the Row type which makes up lines in the grid //! Defines the Row type which makes up lines in the grid
use std::ops::{Index, IndexMut}; 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::cmp::{max, min};
use std::slice; use std::slice;
@ -200,3 +200,20 @@ impl<T> IndexMut<RangeFull> for Row<T> {
&mut self.inner[..] &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)]
}
}

View file

@ -223,7 +223,7 @@ impl<T> Storage<T> {
/// instructions. This implementation achieves the swap in only 8 movups /// instructions. This implementation achieves the swap in only 8 movups
/// instructions. /// instructions.
pub fn swap(&mut self, a: usize, b: usize) { 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 a = self.compute_index(a);
let b = self.compute_index(b); 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 // Cast to a qword array to opt out of copy restrictions and avoid
// drop hazards. Byte array is no good here since for whatever // drop hazards. Byte array is no good here since for whatever
// reason LLVM won't optimized it. // reason LLVM won't optimized it.
let a_ptr = self.inner.as_mut_ptr().offset(a 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().offset(b as isize) as *mut u64; let b_ptr = self.inner.as_mut_ptr().add(b) as *mut usize;
// Copy 1 qword at a time // Copy 1 qword at a time
// //
// The optimizer unrolls this loop and vectorizes it. // The optimizer unrolls this loop and vectorizes it.
let mut tmp: u64; let mut tmp: usize;
for i in 0..4 { for i in 0..4 {
tmp = *a_ptr.offset(i); tmp = *a_ptr.offset(i);
*a_ptr.offset(i) = *b_ptr.offset(i); *a_ptr.offset(i) = *b_ptr.offset(i);

View file

@ -211,7 +211,7 @@ impl Action {
Action::Paste => { Action::Paste => {
Clipboard::new() Clipboard::new()
.and_then(|clipboard| clipboard.load_primary() ) .and_then(|clipboard| clipboard.load_primary() )
.map(|contents| { self.paste(ctx, contents) }) .map(|contents| { self.paste(ctx, &contents) })
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
eprintln!("Error loading data from clipboard. {}", Red(err)); eprintln!("Error loading data from clipboard. {}", Red(err));
}); });
@ -222,7 +222,7 @@ impl Action {
if !ctx.terminal_mode().intersects(mouse_modes) { if !ctx.terminal_mode().intersects(mouse_modes) {
Clipboard::new() Clipboard::new()
.and_then(|clipboard| clipboard.load_selection() ) .and_then(|clipboard| clipboard.load_selection() )
.map(|contents| { self.paste(ctx, contents) }) .map(|contents| { self.paste(ctx, &contents) })
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
warn!("Error loading data from clipboard. {}", Red(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) { if ctx.terminal_mode().contains(TermMode::BRACKETED_PASTE) {
ctx.write_to_pty(&b"\x1b[200~"[..]); 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~"[..]); ctx.write_to_pty(&b"\x1b[201~"[..]);
} else { } else {
// In non-bracketed (ie: normal) mode, terminal applications cannot distinguish // In non-bracketed (ie: normal) mode, terminal applications cannot distinguish

View file

@ -67,7 +67,7 @@ pub fn set_locale_environment() {
// try setting `locale_id` // try setting `locale_id`
let modified = setlocale(LC_CTYPE, locale_ptr); let modified = setlocale(LC_CTYPE, locale_ptr);
let result = if modified.is_null() { let result = if modified.is_null() {
String::from("") String::new()
} else { } else {
locale_id locale_id
}; };

View file

@ -173,7 +173,7 @@ fn run(mut config: Config, options: &cli::Options) -> Result<(), Box<Error>> {
// Main display loop // Main display loop
loop { loop {
// Process input and window events // 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 // Handle config reloads
if let Some(new_config) = config_monitor 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); config = new_config.update_dynamic_title(options);
display.update_config(&config); display.update_config(&config);
processor.update_config(&config); processor.update_config(&config);
terminal.update_config(&config); terminal_lock.update_config(&config);
terminal.dirty = true; terminal_lock.dirty = true;
} }
// Maybe draw the terminal // Maybe draw the terminal
if terminal.needs_draw() { if terminal_lock.needs_draw() {
// Try to update the position of the input method editor // 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 // Handle pending resize events
// //
// The second argument is a list of types that want to be notified // The second argument is a list of types that want to be notified
// of display size changes. // 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 // Draw the current state of the terminal
display.draw(terminal, &config); display.draw(&terminal, &config);
} }
// Begin shutdown if the flag was raised. // Begin shutdown if the flag was raised.

View file

@ -837,12 +837,17 @@ impl<'a> RenderApi<'a> {
glyph_cache.font_key glyph_cache.font_key
}; };
let glyph_key = GlyphKey { let mut glyph_key = GlyphKey {
font_key, font_key,
size: glyph_cache.font_size, size: glyph_cache.font_size,
c: cell.c c: cell.c
}; };
// Don't render text of HIDDEN cells
if cell.flags.contains(cell::Flags::HIDDEN) {
glyph_key.c = ' ';
}
// Add cell to batch // Add cell to batch
{ {
let glyph = glyph_cache.get(glyph_key, self); let glyph = glyph_cache.get(glyph_key, self);

View file

@ -18,15 +18,16 @@ use index::Column;
bitflags! { bitflags! {
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct Flags: u32 { pub struct Flags: u32 {
const INVERSE = 0b0000_0001; const INVERSE = 0b0_0000_0001;
const BOLD = 0b0000_0010; const BOLD = 0b0_0000_0010;
const ITALIC = 0b0000_0100; const ITALIC = 0b0_0000_0100;
const UNDERLINE = 0b0000_1000; const UNDERLINE = 0b0_0000_1000;
const WRAPLINE = 0b0001_0000; const WRAPLINE = 0b0_0001_0000;
const WIDE_CHAR = 0b0010_0000; const WIDE_CHAR = 0b0_0010_0000;
const WIDE_CHAR_SPACER = 0b0100_0000; const WIDE_CHAR_SPACER = 0b0_0100_0000;
const DIM = 0b1000_0000; const DIM = 0b0_1000_0000;
const DIM_BOLD = 0b1000_0010; const DIM_BOLD = 0b0_1000_0010;
const HIDDEN = 0b1_0000_0000;
} }
} }

View file

@ -14,9 +14,8 @@
// //
//! Exports the `Term` type which is a high-level API for the Grid //! Exports the `Term` type which is a high-level API for the Grid
use std::ops::{Range, Index, IndexMut}; use std::ops::{Range, Index, IndexMut};
use std::ptr; use std::{ptr, io, mem};
use std::cmp::{min, max}; use std::cmp::{min, max};
use std::io;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use arraydeque::ArrayDeque; use arraydeque::ArrayDeque;
@ -424,26 +423,15 @@ impl<'a> Iterator for RenderableCellsIter<'a> {
}; };
// Apply inversion and lookup RGB values // Apply inversion and lookup RGB values
let mut bg_alpha = 1.0; let mut fg_rgb = self.compute_fg_rgb(cell.fg, &cell);
let fg_rgb; let mut bg_rgb = self.compute_bg_rgb(cell.bg);
let bg_rgb;
let invert = selected ^ cell.inverse(); let bg_alpha = if selected ^ cell.inverse() {
mem::swap(&mut fg_rgb, &mut bg_rgb);
if invert { self.compute_bg_alpha(cell.fg)
if cell.fg == cell.bg {
bg_rgb = self.colors[NamedColor::Foreground];
fg_rgb = self.colors[NamedColor::Background];
bg_alpha = 1.0
} else {
bg_rgb = self.compute_fg_rgb(cell.fg, &cell);
fg_rgb = self.compute_bg_rgb(cell.bg);
}
} else { } else {
fg_rgb = self.compute_fg_rgb(cell.fg, &cell); self.compute_bg_alpha(cell.bg)
bg_rgb = self.compute_bg_rgb(cell.bg); };
bg_alpha = self.compute_bg_alpha(cell.bg);
}
return Some(RenderableCell { return Some(RenderableCell {
line: cell.line, line: cell.line,
@ -1729,7 +1717,7 @@ impl ansi::Handler for Term {
}, },
ansi::LineClearMode::Left => { ansi::LineClearMode::Left => {
let row = &mut self.grid[self.cursor.point.line]; let row = &mut self.grid[self.cursor.point.line];
for cell in &mut row[..(col + 1)] { for cell in &mut row[..=col] {
cell.reset(&template); cell.reset(&template);
} }
}, },
@ -1881,6 +1869,8 @@ impl ansi::Handler for Term {
Attr::CancelItalic => self.cursor.template.flags.remove(cell::Flags::ITALIC), Attr::CancelItalic => self.cursor.template.flags.remove(cell::Flags::ITALIC),
Attr::Underscore => self.cursor.template.flags.insert(cell::Flags::UNDERLINE), Attr::Underscore => self.cursor.template.flags.insert(cell::Flags::UNDERLINE),
Attr::CancelUnderline => self.cursor.template.flags.remove(cell::Flags::UNDERLINE), Attr::CancelUnderline => self.cursor.template.flags.remove(cell::Flags::UNDERLINE),
Attr::Hidden => self.cursor.template.flags.insert(cell::Flags::HIDDEN),
Attr::CancelHidden => self.cursor.template.flags.remove(cell::Flags::HIDDEN),
_ => { _ => {
debug!("Term got unhandled attr: {:?}", attr); debug!("Term got unhandled attr: {:?}", attr);
} }

View file

@ -211,6 +211,7 @@ pub fn new<T: ToWinsize>(config: &Config, options: &Options, size: &T, window_id
builder.env("SHELL", shell.program()); builder.env("SHELL", shell.program());
builder.env("HOME", pw.dir); builder.env("HOME", pw.dir);
builder.env("TERM", "xterm-256color"); // default term until we can supply our own builder.env("TERM", "xterm-256color"); // default term until we can supply our own
builder.env("COLORTERM", "truecolor"); // advertise 24-bit support
if let Some(window_id) = window_id { if let Some(window_id) = window_id {
builder.env("WINDOWID", format!("{}", window_id)); builder.env("WINDOWID", format!("{}", window_id));
} }

View file

@ -19,12 +19,11 @@ use glutin::{self, ContextBuilder, ControlFlow, Event, EventsLoop,
MouseCursor as GlutinMouseCursor, WindowBuilder}; MouseCursor as GlutinMouseCursor, WindowBuilder};
use glutin::GlContext; use glutin::GlContext;
use {LogicalPosition, LogicalSize, MouseCursor, PhysicalSize}; use {LogicalPosition, LogicalSize, MouseCursor, PhysicalSize};
use cli::Options; use cli::Options;
use config::WindowConfig; use config::{Decorations, WindowConfig};
/// Default text for the window's title bar, if not overriden. /// Default text for the window's title bar, if not overriden.
/// ///
@ -104,12 +103,8 @@ impl ::std::error::Error for Error {
impl Display for Error { impl Display for Error {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self { match *self {
Error::ContextCreation(ref err) => { Error::ContextCreation(ref err) => write!(f, "Error creating GL context; {}", err),
write!(f, "Error creating GL context; {}", err) Error::Context(ref err) => write!(f, "Error operating on render context; {}", err),
},
Error::Context(ref err) => {
write!(f, "Error operating on render context; {}", err)
},
} }
} }
} }
@ -142,19 +137,12 @@ impl Window {
/// Create a new window /// Create a new window
/// ///
/// This creates a window and fully initializes a window. /// This creates a window and fully initializes a window.
pub fn new( pub fn new(options: &Options, window_config: &WindowConfig) -> Result<Window> {
options: &Options,
window_config: &WindowConfig,
) -> Result<Window> {
let event_loop = EventsLoop::new(); let event_loop = EventsLoop::new();
let title = options.title.as_ref().map_or(DEFAULT_TITLE, |t| t); let title = options.title.as_ref().map_or(DEFAULT_TITLE, |t| t);
let class = options.class.as_ref().map_or(DEFAULT_CLASS, |c| c); let class = options.class.as_ref().map_or(DEFAULT_CLASS, |c| c);
let window_builder = WindowBuilder::new() let window_builder = Window::get_platform_window(title, window_config);
.with_title(title)
.with_visibility(false)
.with_transparency(true)
.with_decorations(window_config.decorations());
let window_builder = Window::platform_builder_ext(window_builder, &class); let window_builder = Window::platform_builder_ext(window_builder, &class);
let window = create_gl_window(window_builder.clone(), &event_loop, false) let window = create_gl_window(window_builder.clone(), &event_loop, false)
.or_else(|_| create_gl_window(window_builder, &event_loop, true))?; .or_else(|_| create_gl_window(window_builder, &event_loop, true))?;
@ -175,7 +163,7 @@ impl Window {
event_loop, event_loop,
window, window,
cursor_visible: true, cursor_visible: true,
is_focused: true, is_focused: false,
}; };
window.run_os_extensions(); window.run_os_extensions();
@ -196,7 +184,7 @@ impl Window {
pub fn inner_size_pixels(&self) -> Option<LogicalSize> { pub fn inner_size_pixels(&self) -> Option<LogicalSize> {
self.window.get_inner_size() self.window.get_inner_size()
} }
pub fn set_inner_size(&mut self, size: LogicalSize) { pub fn set_inner_size(&mut self, size: LogicalSize) {
self.window.set_inner_size(size); self.window.set_inner_size(size);
} }
@ -215,15 +203,14 @@ impl Window {
#[inline] #[inline]
pub fn swap_buffers(&self) -> Result<()> { pub fn swap_buffers(&self) -> Result<()> {
self.window self.window.swap_buffers().map_err(From::from)
.swap_buffers()
.map_err(From::from)
} }
/// Poll for any available events /// Poll for any available events
#[inline] #[inline]
pub fn poll_events<F>(&mut self, func: F) pub fn poll_events<F>(&mut self, func: F)
where F: FnMut(Event) where
F: FnMut(Event),
{ {
self.event_loop.poll_events(func); self.event_loop.poll_events(func);
} }
@ -236,7 +223,8 @@ impl Window {
/// Block waiting for events /// Block waiting for events
#[inline] #[inline]
pub fn wait_events<F>(&mut self, func: F) pub fn wait_events<F>(&mut self, func: F)
where F: FnMut(Event) -> ControlFlow where
F: FnMut(Event) -> ControlFlow,
{ {
self.event_loop.run_forever(func); self.event_loop.run_forever(func);
} }
@ -263,24 +251,95 @@ impl Window {
} }
} }
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))] #[cfg(
any(
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd"
)
)]
fn platform_builder_ext(window_builder: WindowBuilder, wm_class: &str) -> WindowBuilder { fn platform_builder_ext(window_builder: WindowBuilder, wm_class: &str) -> WindowBuilder {
use glutin::os::unix::WindowBuilderExt; use glutin::os::unix::WindowBuilderExt;
window_builder.with_class(wm_class.to_owned(), "Alacritty".to_owned()) window_builder.with_class(wm_class.to_owned(), "Alacritty".to_owned())
} }
#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))] #[cfg(
not(
any(
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd"
)
)
)]
fn platform_builder_ext(window_builder: WindowBuilder, _: &str) -> WindowBuilder { fn platform_builder_ext(window_builder: WindowBuilder, _: &str) -> WindowBuilder {
window_builder window_builder
} }
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd"))] #[cfg(not(target_os = "macos"))]
pub fn get_platform_window(title: &str, window_config: &WindowConfig) -> WindowBuilder {
let decorations = match window_config.decorations() {
Decorations::None => false,
_ => true,
};
WindowBuilder::new()
.with_title(title)
.with_visibility(false)
.with_transparency(true)
.with_decorations(decorations)
}
#[cfg(target_os = "macos")]
pub fn get_platform_window(title: &str, window_config: &WindowConfig) -> WindowBuilder {
use glutin::os::macos::WindowBuilderExt;
let window = WindowBuilder::new()
.with_title(title)
.with_visibility(false)
.with_transparency(true);
match window_config.decorations() {
Decorations::Full => window,
Decorations::Transparent => window
.with_title_hidden(true)
.with_titlebar_transparent(true)
.with_fullsize_content_view(true),
Decorations::Buttonless => window
.with_title_hidden(true)
.with_titlebar_buttons_hidden(true)
.with_titlebar_transparent(true)
.with_fullsize_content_view(true),
Decorations::None => window
.with_titlebar_hidden(true),
}
}
#[cfg(
any(
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd"
)
)]
pub fn set_urgent(&self, is_urgent: bool) { pub fn set_urgent(&self, is_urgent: bool) {
use glutin::os::unix::WindowExt; use glutin::os::unix::WindowExt;
self.window.set_urgent(is_urgent); self.window.set_urgent(is_urgent);
} }
#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")))] #[cfg(
not(
any(
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd"
)
)
)]
pub fn set_urgent(&self, _is_urgent: bool) {} pub fn set_urgent(&self, _is_urgent: bool) {}
pub fn set_ime_spot(&self, pos: LogicalPosition) { pub fn set_ime_spot(&self, pos: LogicalPosition) {
@ -293,7 +352,7 @@ impl Window {
match self.window.get_xlib_window() { match self.window.get_xlib_window() {
Some(xlib_window) => Some(xlib_window as usize), Some(xlib_window) => Some(xlib_window as usize),
None => None None => None,
} }
} }
@ -312,17 +371,28 @@ pub trait OsExtensions {
fn run_os_extensions(&self) {} fn run_os_extensions(&self) {}
} }
#[cfg(not(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd")))] #[cfg(
impl OsExtensions for Window { } not(
any(
target_os = "linux",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "openbsd"
)
)
)]
impl OsExtensions for Window {}
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os="dragonfly", target_os="openbsd"))] #[cfg(
any(target_os = "linux", target_os = "freebsd", target_os = "dragonfly", target_os = "openbsd")
)]
impl OsExtensions for Window { impl OsExtensions for Window {
fn run_os_extensions(&self) { fn run_os_extensions(&self) {
use glutin::os::unix::WindowExt; use glutin::os::unix::WindowExt;
use x11_dl::xlib::{self, XA_CARDINAL, PropModeReplace};
use std::ffi::{CStr};
use std::ptr;
use libc::getpid; use libc::getpid;
use std::ffi::CStr;
use std::ptr;
use x11_dl::xlib::{self, PropModeReplace, XA_CARDINAL};
let xlib_display = self.window.get_xlib_display(); let xlib_display = self.window.get_xlib_display();
let xlib_window = self.window.get_xlib_window(); let xlib_window = self.window.get_xlib_window();
@ -336,17 +406,32 @@ impl OsExtensions for Window {
let atom = (xlib.XInternAtom)(xlib_display as *mut _, _net_wm_pid.as_ptr(), 0); let atom = (xlib.XInternAtom)(xlib_display as *mut _, _net_wm_pid.as_ptr(), 0);
let pid = getpid(); let pid = getpid();
(xlib.XChangeProperty)(xlib_display as _, xlib_window as _, atom, (xlib.XChangeProperty)(
XA_CARDINAL, 32, PropModeReplace, &pid as *const i32 as *const u8, 1); xlib_display as _,
xlib_window as _,
atom,
XA_CARDINAL,
32,
PropModeReplace,
&pid as *const i32 as *const u8,
1,
);
} }
// Although this call doesn't actually pass any data, it does cause // Although this call doesn't actually pass any data, it does cause
// WM_CLIENT_MACHINE to be set. WM_CLIENT_MACHINE MUST be set if _NET_WM_PID is set // WM_CLIENT_MACHINE to be set. WM_CLIENT_MACHINE MUST be set if _NET_WM_PID is set
// (which we do above). // (which we do above).
unsafe { unsafe {
(xlib.XSetWMProperties)(xlib_display as _, xlib_window as _, ptr::null_mut(), (xlib.XSetWMProperties)(
ptr::null_mut(), ptr::null_mut(), 0, ptr::null_mut(), ptr::null_mut(), xlib_display as _,
ptr::null_mut()); xlib_window as _,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
0,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
);
} }
} }
} }