There's a few different knobs to turn, but this
commit turns them and we're now able to respect
opacity settings for both OpenGL/CGL and Metal
renderers.
closes: #141
9d33073d70 improved how we handle
the case where we run out of fallbacks, but with the unintended
consequence that we'd just give up on rendering the current frame,
which isn't super useful.
Since that commit landed we now bundle JetBrains Mono so that
means that we can guarantee to find our fallback glyph in case
we can't locate the font holding the requested glyph.
This commit causes us to unconditionally recurse and shape
the replacement character to use in this situation.
refs: #299
This is the same class of problem as c32de40978
but on X11/Wayland systems.
In this case, the 100 or so "random" fontconfig fallbacks were
taking precedence over our locally configured emoji fallback.
This commit filters the fontconfig results to more exact matches,
with less surprising results.
This may come at the cost of magically resolving fallback fonts
for unusual scripts, however.
I thought it would be cute to add an option to add a background image to
the window.
While playing around with the parameters, I accidentally implemented
window transparency on X11/Wayland, provided that you have a compositing
window manager. I don't know of the transparency also works on macOS or
Windows as of yet; will try that out once I push this commit.
This commit introduces three new configuration options explained below.
In the future I'd like to allow specifying equivalent settings in a
color scheme, and then that would allow setting per-pane background
images.
```lua
return {
--[[
Specifies the path to a background image attachment file.
The file can be any image format that the rust `image`
crate is able to identify and load.
A window background image is rendered into the background
of the window before any other content.
The image will be scaled to fit the window.
If the path is not absolute, then it will taken as being
relative to the directory containing wezterm.lua.
]]
window_background_image = "/some/file",
--[[ Specifies the alpha value to use when rendering the background
of the window. The background is taken either from the
window_background_image, or if there is none, the background
color of the cell in the current position.
The default is 1.0 which is 100% opaque. Setting it to a number
between 0.0 and 1.0 will allow for the screen behind the window
to "shine through" to varying degrees.
This only works on systems with a compositing window manager.
Setting opacity to a value other than 1.0 can impact render
performance.
]]
window_background_opacity = 1.0,
--[[
Specifies the alpha value to use when applying the default
background color in a cell. This is useful to apply a kind
of "tint" to the background image if either window_background_image
or window_background_opacity are in used.
It can be a number between 0.0 and 1.0.
The default is 0.0
Larger numbers increase the amount of the color scheme's
background color that is applied over the background image.
This can be useful to increase effective contrast for text
that is rendered over the top.
]]
window_background_tint = 0.0,
}
```
refs: https://github.com/wez/wezterm/issues/141
This is similar in spirit to the work in 4d71a7913a
but for Windows.
This commit adds ANGLE binaries built from
07ea804e62
to the repo. The build and packaging will copy those into the same
directory as wezterm.exe so that they can be resolved at runtime.
By default, `prefer_egl = true`, which will cause the window
crate to first try to load an EGL implementation. If that fails,
or if `prefer_egl = false`, then the window crate will perform
the usual WGL initialization.
The practical effect of this change is that Direct3D11 is used for the
underlying render, which avoids problematic OpenGL drivers and means
that the process can survive graphics drivers being updated.
It may also increase the chances that the GPU will really be used
in an RDP session rather than the pessimised use of the software
renderer.
The one downside that I've noticed is that the resize behavior feels a
little janky in comparison to WGL (frames can render with mismatched
surface/window sizes which makes the window contents feel like they're
zooming/rippling slightly as the window is live resized). I think this
is specific to the ANGLE D3D implementation as EGL on other platforms
feels more solid.
I'm a little on the fence about making this the default; I think
it makes sense to prefer something that won't quit unexpectedly
while a software update is in progress, so that's a strong plus
in favor of EGL as the default, but I'm not sure how much the
resize wobble is going to set people off.
If you prefer WGL and are fine with the risk of a drive update
killing wezterm, then you can set this in your config:
```lua
return {
prefer_egl = false,
}
```
refs: https://github.com/wez/wezterm/issues/265
closes: https://github.com/wez/wezterm/issues/156
6c5a996423 was almost great...
the problem is that CTRL-W for example was generating a raw
uppercase W instead of a lowercase W which meant that CTRL-W
for split navigation in vim would trigger the close pane
key assignment.
The default font locator on Windows is font-loader. That will always
return *something* that matched, even if it didn't match what we asked
for very well. This is problematic if for example we asked for
"JetBrains Mono" and that isn't installed. font-loader will return
the data for "Consolas". That's great if there is no other fallback
mechanism, but it prevented us from searching our built-in fonts.
This commit parsed the returned font and uses the same font
family matching that we use for our own font directory searching
to see if it matched well enough.
This commit also tidies up that matching routine so that it more
carefully matches sub-family characteristics such as bold, italic
and bold-italic.
I noticed that the built-in CTRL-SHIFT-1 assignment had
stopped working because that key press was being recognized
as CTRL-SHIFT-! with the recent changes in handling keyboard
input.
This commit sets the raw key to the position-based fallback
that we'd use if ToUnicode didn't return the correct mapping.
This is sufficient for this sort of un-modified key assignment
because the key is based on the virtual key code and is ignorant
of how the keyboard layout might compose those keys with SHIFT;
that is exactly what we want in this situation.
This commit adjusts the window layer to have it try to load EGL
implementations on macOS. This is important as the system
provided OpenGL implementation is deprecated and I wanted to
have a path forward for when it is finally removed.
If EGL fails to initialize, we fall back to the CGL/OpenGL
implementation that we used previously.
I've included binaries built for 64-bit intel from the MetalANGLE
project; here's how I built them:
```
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git --depth 1
git clone https://github.com/kakashidinho/metalangle --depth 1
cd metalangle
PATH=$PWD/../depot_tools:$PATH python scripts/bootstrap.py
PATH=$PWD/../depot_tools:$PATH gclient sync
PATH=$PWD/../depot_tools:$PATH gn --args="is_debug=false angle_enable_metal=true angle_enable_vulkan=false angle_enable_gl=false angle_build_all=false" gen out/Release
PATH=$PWD/../depot_tools:$PATH autoninja -C out/Release
```
Those steps are a little too long to want to put them directly
into the wezterm CI.
It is important for metalangle to be >= 8230df39a5
in order for scaling to be handled correctly when dragging windows
between monitors.
refs: https://github.com/kakashidinho/metalangle/issues/34
This changes the ALT/dead key behavior a little bit more,
and in a way that is likely more useful to terminal users.
The default behavior is that system dead key processing is enabled.
For example, with DEU keyboard layout activated:
* `^` `<SPACE>` results in a single `^`
* `^` `e` result in those two characters combining into an e with a
diacritic.
If the config sets `use_dead_keys = false` then the behavior changes;
wezterm probes the active keymap to determine which keys are marked
as dead keys and computes their single character expansion. When
the dead key is pressed then that expansion is substituted instead.
So `^` is simply `^`.
In order to pull this off, the window layer needs to selectively
call `TranslateMessage` for the system dead key expansion case
instead of unconditionally in the global message loop.
As a result of *that*, it means that we don't perform the default ALT
key translation for every key press any more. I looked to see how old
friend putty handles this and found that it only allows default system
processing for ALT-space and ALT-F4. I was resistent to selectively
processing system shortcuts because the full set are effectively
unknowable to an application and I didn't want to try to replicate
a wide selection of varying keypresses. I'm fine to only allow
these two, so this commit does that, and reverts the portion of
the prior commit that prevented passing general ALT key combinations
through.
refs: #275
refs: #296
For some definition of improve, at least.
On Windows, ALT is basically reserved by the Window management
layer for functions such as ALT-space, ALT-F4 and so on.
Windows doesn't provide a method by which an application can
test whether a given key would be processed by the default
window procedure so we're in a bit of a bind in terms of
allowing ALT+a keypress to do something meaningful in the
terminal.
What I've settled on for now is:
On Windows only, if ALT is pressed, allow matching key assignments that
include ALT to be matched. If there are no key assignments, then DON'T
pass the key press to the active pane, and instead allow it to be passed
to DefWindowProc. This allows ALT-space to be handled correctly,
provided the user hasn't defined an ALT-space key assignment of their
own.
This may have some unforeseen consequences. For example, ALT-<number>
is a readline binding that repeats an argument a number of times.
This change "breaks" that, but the user can provide a key assignment
to `SendString` the equivalent sequence to restore that behavior.
I'm kindof hoping that no one notices, but I'm prepared to explicitly
add default key assignments for that.
The other aspect of this commit is that I now understand a bit better
what a dead key is and how they should be handled. I've tested the
behavior of wezterm with these changes and the behavior is consistent
with a regular CMD window when I have the DEU keymap active.
Specifically, using the on-screen keyboard, if I click `^` then click
`e` wezterm will emit `ê`. If I click `^` then `^` then wezterm emits
`^^`.
refs: #275
refs: #296
This appears to be an unexpected consequence of 6708ea4b36
but thankfully that change allows de-coupling shift processing
from the ctrl processing in this block of code.
refs: #275
It's not clear why the first choice isn't always the right choice
for some users.
This commit changes the logic to try all potential configs,
one after the other, until we find one that sticks.
I don't know if this will work in practice: I suspect that
trying to configure one of them may prevent later configs from
being used.
But maybe it will, and it may reveal more information about
what the real cause of the problem is.
refs: #272
This is imperfect in that it may feel slightly off for very large
or very small font sizes, but it feels more similar to the scroll
speed in eg: iTerm2 with these changes.
refs: #206
To reproduce the problem, maximize wezterm, then press CMD-N.
This commit tells the window not to use cocoa native tabs and
instead really create a new window when we ask it to create
a new window.
closes: #254
Split the font loading into two phases; first phase for non-fallback
fonts, second phase for fallback fonts.
This allows all potential sources to be searched for the preferred
fonts before populating the handles list with fallback fonts.
Previously we'd silently (well, we'd log to stderr) fall
back to the CPU renderer.
Let's instead pop up a config error window to make this
class of error more visible.
refs: #272
This commit teaches the config layer to distinguish between
explicitly configured fonts and automatic fallback fonts.
Font loading now maintains the set of loaded fonts. If after
loading from all configured sources a non-fallback font is
not present in the loaded set, wezterm will now pop up the
configuration error window to explain what is happening.
closes: #263
In this scenario:
```lua
local wezterm = require "wezterm"
return {
font_size = 12.0,
font_dirs = {"/home/wez/.fonts"},
font_locator = "ConfigDirsOnly",
font = wezterm.font_with_fallback({
-- this is an invalid font
"does not exist",
"Noto Color Emoji",
}),
}
```
we'd take the metrics from the emoji font and the cell size would
be crazy huge.
With this change we filter out "outliers" based on the approximate
pixel size for a font given its size and dpi. If a fallback position
is significantly larger or smaller than the theoretical size then
we skip it when considering the metrics.
The result of this is that with the above configuration we end up
with `{"Noto Color Emoji", "JetBrains Mono"}` as the font order;
most of the textual glyphs will render from `JetBrains Mono` but
the number glyphs prefer the `Noto Color Emoji` renditions which
are typically double width. While the terminal looks a bit
cartoonish as a result of that selection, the sizes are much more
reasonable compared to the screenshot in #263.
refs: #263
Moved the image and hyperlink portion of CellAttributes out
to a separate heap structure, saving 8 bytes per Cell
for the common case of no hyperlink and no image.
Replaces SmallVec with an internal TeenyString that only
occupies a single machine word and avoids heap allocation
in the common case on most architectures. This takes the
textual portion of Cell from 32 bytes to 8 bytes.