This commit moves a bunch of stuff around such that `wezterm` is now a
lighter-weight executable that knows how to spawn the gui, talk to
the mux or emit some escape sequences for imgcat.
The gui portion has been moved into `wezterm-gui`, a separate executable
that doesn't know about the CLI or imgcat functionality.
Importantly, `wezterm.exe` is no longer a window subsystem executable
on windows, which makes interactions such as `wezterm -h` feel more
natural when spawned from `cmd`, and should allow
`type foo.png | wezterm imgcat` to work as expected.
That said, I've only tested this on linux so far, and there's a good
chance that something mac or windows specific is broken by this
change and will need fixing up.
refs: #301
When allocating space in the texture atlas, we typically use
a small padding to avoid accidentally interpolating textures
into glyphs.
When it comes to rendering images via iterm2 or sixel image
protocols, the image emitted by the user may not exactly fill
the cell dimensions, and due to the how the shader works to
apply those textures we could end up revealing nearby images
in the texture when displaying an unrelated image.
This commit adjusts the texture atlas allocation when making
space for image protocol textures; excess padding based on
an overestimate of the cell dimensions is added to the right
and bottom of the image, guaranteeing that that border will
be filled with transparent pixels.
This is a bit wasteful of texture space, but isn't egregiously
bad and is easy to reason about and makes things look less
janky.
refs: #292
There was an integer conversion happening when taking the
per-cell image texture coordinates and applying them to the
texture atlas image coordinates.
This commit replaces that math with floating point and corrects
the visual artifacts within squirrel.png.
refs: #292
The fragment shader was set to use nearest texel sampling
because that made for sharper lines when rendering the
cursor bar or outlines.
This commit adds a supplemental sampler over the same
texture that is set to merge nearby texels. We now
use this sampler for the background image and cells
marked as having full color textures (eg: emoji,
image protocol).
This makes the window background image look better
when it is scaled. I'm not 100% sure about image
protocol cells, but I'm looking into that in general
at the moment.
This commit revises the opacity configuration to make it more
consistently applied.
* `window_background_opacity` controls the overall window capacity,
whether a background image is present or not.
* When a background image is present, or if the window is transparent,
then text whose background color is the default background is
changed to have a fully transparent background.
* `text_background_opacity` controls the alpha channel value for
text whose background color is NOT the default background.
It defaults to 1.0 (fully opaque), but can be set to be
transparent by setting it to a number between 0.0 and 1.0.
* The inactive pane hue, saturation, brightness multipliers
have been factored out into their own struct which changes
that set of options to:
```lua
return {
inactive_pane_hsb = {
hue = 1.0,
saturation = 1.0,
brightness = 1.0,
},
}
```
* `window_background_image_hsb` is a new option that can apply
a hue, saturation, brightness transformation to a background
image. This is primarily useful to make a background image
darker:
```lua
return {
window_background_image = "/some/pic.png",
window_background_image_hsb = {
brightness = 0.3,
},
}
```
refs: #302
refs: #297
This commit uses the guillotine algorithm to assign rectangles,
which is superior to the dumb algorithm previously in use.
In addition, in the first pass of painting, if we get a texture
space error, we clear the atlas and try again without increasing
it size, which should serve as the ultimate defrag.
Subsequent passes will cause the texture to grow if needed.
refs: #306
Reduce the initial atlas size from 4096*4096*4 to
128*128*4.
Fixup an issue with rendering image cells that would
prevent the render from propagating a texture space
error and keep wezterm busy.
refs: #306
refs: #292
This is a bit more involved than I'd like, but it seems more
deterministic than using `TranslateMessage` or `ToUnicode` in all cases.
This commit expands the depth of the keyboard layout probing that
is performed when we detect a changed keyboard layout.
We know detect starting `(Modifier, VK) -> char` for a dead key press,
as well as the map of terminating `(Modifier, VK) -> char` for valid
dead key presses.
This information allows us to simply lookup the mapping without
calling `ToUnicode`. Avoiding `ToUnicode` is desirable because it
maintains a global state and it is unpredictable what else is
manipulating that same state. In particular, for the ESP keyboard
layout where `~` is a dead key that is reached via `AltGr 4`, there
doesn't appear to be a reliable way to extract the correct mapping
from it when calling `ToUnicode` in response to the various KEYUP,
KEYDOWN messages. We could get it if we always called
`TranslateMessage` and only looked at `WM_CHAR`, but that means that
we cannot decompose `WM_CHAR` back to the raw key events when we
need to. Bleh!
Test Plan for this commit:
* With ENG layout active, check that CTRL, ALT and so on have the
intended effect in the terminal; eg: CTRL-C, CTRL-W (in vim).
* Switch to pinyin layout, check that typing still invokes the
IME and that it can insert text
* Switch to DEU. Check that `AltGr m` produces a `mu` symbol.
Check that grave (`\``) (a dead key) doesn't immediately output
anything, then press `e`; that produces an `e` with a grave
diacritic. Grave followed by space emits grave. Grave
followed by grave emits a grave and holds the second grave; pressing
`e` at this point now emits `e` with a grave diacritic.
(This is a difference from the "normal" system behavior, which
would just emit two graves in a row, then a regular `e`).
* Switch to ESP. Check that `AltGr 4` (tilde) doesn't immediately
output anything, then press `n`; that produces an `n` with the
tilde diacritic.
* Change `use_dead_keys = false`. Now verify in DEU that `grave`
just emits grave. In ESP, verify that `AltGr 4` just emits
a tilde.
* Switch back to ENG. Verify that `ALT-space` pops up the system
menu.
refs: #275
refs: #305
Change the cursor to an appropriate one of these when hoving
over and dragging a split.
Fix an issue where we wouldn't always change the cursor when
hovering over a split when multiple splits are present.
If you split and run top in one pane, then switch to another pane, the
inactive `top` pane display would only repaint when moving the mouse or
typing.
This commit fixed the periodic task to consider all renderable panes
rather than just the active pane.
This includes a script to generate a screenshot from a wezterm
running the default config under X11.
It expects the iTerm2-Color-Schemes to be checked out alongside
the wezterm repo as it uses the dynamic color schemes scripts
to activate the schemes one by one and capture the display.
Upcoming changes to the GUI mean that it will be double
the work to keep maintaining this, and it is already lagging
behind on pane support.
With the Mesa llvmpipe fallback we should be in a pretty
good state to not need another non-GL implementation.
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