This changes the fill_rect function over to use the zeno crate.
zeno allows describing a path and filling or stroking.
This commit doesn't strictly need that, but it sets things
up for more interesting custom glyphs in later commits.
refs: #584
refs: #588
Since removing the regular periodic background tasks, we're now
prone to not noticing child processes exiting.
This commit explicictly schedules a thread to do that on Windows
so that we can close a tab as soon as it exits.
Removes the callbacks type and replaces event dispatch with
an async capable channel.
This makes it a bit simpler to model some of the window internals,
and to prepare for a wgpu enabled future.
This changes have been tested only on linux so far.
Adds a `ShowDebugOverlay` key assignment that will create a tab
overlay that shows a limited number of recently logged events.
refs: https://github.com/wez/wezterm/issues/641
The intent is to reveal more context on what's happening in
https://github.com/wez/wezterm/issues/671
As a nice side benefit, this avoids the potential inability
to open paths that are not utf8 or representable as c-strings
on Windows.
And on top of that: this enables memory mapped file IO as well,
which wasn't enabled previously. This should help to reduce
extraneous copies of the font in memory, have fewer open files
and minimize the chances of racing with O_CLOEXEC.
Replaces the last usage of ttf-parser with calling into freetype.
This removes a source of inconsistency, as ttf-parser doesn't support
all of the things that freetype does.
Notably, this prevents a weird error from blowing up codepoint coverage
calculations on a system where I have helvetica.bdf in my font dir for
long-forgotten reasons.
There are a few notable changes as a result:
* A number of `.ssh/config` options are now respected; host matching
and aliasing and identity file are the main things
* The authentication prompt is inline in the window, rather than
popping up a separate authentication window
Refs: https://github.com/wez/wezterm/issues/457
I can't get this to succeed though; I suspect there may be a lingering
bug from libssh2 and/or trailing support for newer openssh features.
refs: https://github.com/wez/wezterm/issues/457
The wincng based build doesn't recognize newer keys which makes it
impossible to connect to a reasonably up to date Fedora installation.
This commit points to my branch of ssh2-rs that has some changes to
build ssh2 against the vendored openssl that is already part of
the dependency graph for wezterm.
refs: https://github.com/wez/wezterm/issues/507
Rust 1.51 allows addressesing a long-standing TODO which was that we
shouldn't need to build a vendored copy of openssl on most sensible unix
systems.
We do require a vendored copy on macOS and Windows, but due to the way
that Cargo's feature resolver worked, it wasn't possible for this
requirement to be respected.
Rust 1.51 introduces `resolver="2"` which can deal with this feature
resolution!
https://doc.rust-lang.org/nightly/cargo/reference/features.html#feature-resolver-version-2
The upshot of this is that building wezterm on real unix systems that
are not macos will now link against the system libssl, resulting in both
a shorter compile time and less headaches arising from having a slightly
different openssl used by wezterm than the rest of the system.
cc: @jsgf
There's something fishy with colorspaces and blending.
This commit removes the `window::Color` type and replaces
it and the confusing array of color types exposed by the
`palette` crate with a pair of much simpler types:
`LinearRgb` - a tuple of f32 linear color components
`SrgbaPixel` - the u32 sRGBA pixel representation
This doesn't change anything about rendering, it just
makes it a bit simpler and makes the SrgbaPixel -> LinearRgb
conversion happen slightly earlier which shaves off some
ad-hoc conversions.
Refs: https://github.com/wez/wezterm/issues/544
CI got broken by the termwiz release. This commit teaches the
various `git describe --tags` calls to filter to the wezterm
tags which all start with the year. We're match `20*` which should
be good for the next 79 years.
I've removed the vergen dependency as there was no way to teach it
to do the equivalent matching, and it wasn't a terrible burden
to just inline the git describe call anyway.
Using a boxed slice means that we hold exactly the memory required
for the file data, rather than the next-power-of-two, which can
be wasteful when a large number of images are being sent to
the terminal.
This is a API breaking change for termwiz, so bump its version.
refs: #534
Queries the system battery information and returns an array of
battery information.
Each element is a lua table with the following entries:
* state_of_charge: expressed as percents
* vendor: the battery manufacturer
* model: the battery model
* serial: the battery serial number
* time_to_full: how long until the battery is full
* time_to_empty: how long until the battery is empty
* state: "Charging", "Discharging", "Empty", "Full", "Unknown"
I haven't run this on a system with a battery yet, so I'm holding
off from showing an example until I've got a work one.
refs: https://github.com/wez/wezterm/issues/500
This commit expands on the prior commits to introduce the concept
of per-window configuration overrides.
Each TermWindow maintains json compatible object value holding
a map of config key -> config value overrides.
When the window notices that the config has changed, the config
file is loaded, the CLI overrides (if any) are applied, and then
finally the per-window overrides, before attempting to coerce
the resultant lua value into a Config object.
This mechanism has some important constraints:
* Only data can be assigned to the overrides. Closures or special
lua userdata object handles are not permitted. This is because
the lifetime of those objects is tied to the lua context in which
they were parsed, which doesn't really exist in the context of
the window.
* Only simple keys are supported for the per-window overrides.
That means that trying to override a very specific field of
a deeply structured value (eg: something like `font_rules[1].italic = false`
isn't able to be expressed in this scheme. Instead, you would
need to assign the entire `font_rules` key. I don't anticipate
this being a common desire at this time; if more advance manipulations
are required, then I have some thoughts on an event where arbitrary
lua modifications can be applied.
The implementation details are fairly straight-forward, but in testing
the two examplary use cases I noticed that some hangovers from
supporting overrides for a couple of font related options meant that the
window-specific config wasn't being honored. I've removed the code that
handled those overrides in favor of the newer more general CLI option
override support, and threaded the config through to the font code.
closes: #469closes: #329
`wezterm`, `wezterm-gui` and `wezterm-mux-server` now all support
a new `--config name=value` CLI option that can be specified
multiple times to supply config overrides.
Since there isn't a simple, direct way to update arbitrary fields
of a struct in Rust (there's no runtime reflection), we do this
work in lua.
The config file returns a config table. Before that is mapped
to the Rust Config type, we have a new phase that takes each
of the `--config` values and applies it to the config table.
For example, you can think of configuration as working like this
if wezterm is started as `wezterm --config foo="bar"`:
```lua
config = load_config_file();
config.foo = "bar";
return config;
```
The `--config name=value` option is split into `name` and `value`
parts. The name part is literally concatenated with `config` in
the generated lua code, so the name MUST be valid in that context.
The `value` portion is literally inserted verbatim as the rvalue in the
assignment. Not quoting or other processing is done, which means
that you can (and must!) use the same form that you would use in
the config file for the RHS. Strings must be quoted. This allows
you to use more complicated expressions on the right hand side,
such as:
```
wezterm --config 'font=wezterm.font("Fira Code")'
```
The overrides stick for the lifetime of the process; even if
you change the config file and reload, then the value specified
by the override will take precedence.
refs: https://github.com/wez/wezterm/issues/469
refs: https://github.com/wez/wezterm/issues/499
This function is intended to deal with certain kinds of ligatures
and certain combining sequences that don't have corresponding glyphs.
It isn't hooked up to the gui yet, but does have unit tests that
are probably mostly correct.
refs: https://github.com/wez/wezterm/issues/478
In the earlier times wezterm supported different font rasterizers,
and the configuration was a bit vague and generic to accomodate
differences in how the rasterizers worked.
Since then, we've standardized on freetype.
One of the things that's been bothering me for a while is that
we have some fiddly logic to transform from the config to the freetype
flags.
This commit does away with the transformation and simply exposes
the two sets of freetype options.
The main thing that I expect people to play with is
`freetype_load_target` which can have one of the following values:
```
pub enum FreeTypeLoadTarget {
/// This corresponds to the default hinting algorithm, optimized
for standard gray-level rendering.
Normal,
/// A lighter hinting algorithm for non-monochrome modes. Many
generated glyphs are more fuzzy but better resemble its original
shape. A bit like rendering on Mac OS X. This target implies
FT_LOAD_FORCE_AUTOHINT.
Light,
/// Strong hinting algorithm that should only be used for
monochrome output. The result is probably unpleasant if the glyph
is rendered in non-monochrome modes.
Mono,
/// A variant of Normal optimized for horizontally decimated LCD displays.
HorizontalLcd,
/// A variant of Normal optimized for vertically decimated LCD displays.
VerticalLcd,
}
```
I expect most people will want to set this to one of `Normal`, `Light`
or `HorizontalLcd`. `HorizontalLcd` is what `font_antialias=Subpixel`
used to select.
refs: #491
Replaces notify-rust with directly calling into the zbus crate.
This provides a pure rust interface to DBUS and provides more
flexible control over notification handling.
closes: #485
However, I'm not able to create wayland windows any more on my nvidia
system (either with or without this change).
I don't know if this is specific to my nvidia drivers or something else
:-/
refs: https://github.com/wez/wezterm/issues/476
This commit implements the deprecated NSUserNotification bits needed
to be able to handle clicking on a notification and open our choice
of URL.
Ideally we'd use the newer UserNotifications framework, but that
requires code signing.
This persuades the CI to install both the arm and intel flavors
of the rust toolchain on macOS, and the deploy script to generate
a universal binary.
* need big sur to build for M1
* Use cross-compilation compatible mlua from my fork for now
It's been replaced with an opaque termwiz error type instead.
This is a bit of a more conservative approach than that in (refs: #407)
and has less of an impact on the surrounding code, which appeals to
me from a maintenance perspective.
refs: #406
refs: #407
wezterm sets a more restrictive umask (`0o077`) by default so that any files
that it creates (eg: unix domain socket, log files) are more secure
by default.
However, some environments rely on the more general default of (`0o022`)
without checking that it is set.
This matters because programs spawned by wezterm inherit its more
restricted umask.
I hadn't noticed this because I've had `umask 022` in my shell RC files
since sometime in the 1990's.
This commit adds some plumbing to the pty layer to specify an optional
umask for the child process, and some more to our umask saver helper
so that any thread can determine the saved umask without needing a
reference to the saver itself, which may be in a different crate.
The logic in the config crate has been adjusted to connect the saved
value to the default command builder arguments.
The net result of this is that running `wezterm -n start bash -- --norc`
and typing `umask` in the resultant window now prints `0022`.
refs: #416
This allows us to support the kitty style underline sequence,
or the : separated form of the true color escape sequences.
refs: https://github.com/wez/wezterm/issues/415
When running the GUI, we generate a unix domain socket path for
the current process and start up a mux server for that path.
This allows `wezterm cli list` and `wezterm cli split-pane` to
work implicitly inside the GUI session.
When started in this way, the mux server is not persistent;
when the GUI process is terminated, all of its windows, tabs
and panes are terminated.
refs: https://github.com/wez/wezterm/issues/230
* Allow injecting some initial output to new panes
* Have the update checker set this new-pane-banner to a short
upsell to let the user know there is an update.
* Refactor toast notifications into their own crate
* Have the update checker call a new stub function that triggers
a toast notification with an URL... but it does nothing because
the rust ecosystem doesn't support this on macos yet and I'm
writing this code there
Tidies up the plumbing around pixel dimensions so that ImageData
can be rendered via the termwiztermtab bits.
I put this together to play with sticking the wezterm logo in
the close confirmation dialogs. I didn't end up using that though,
but have preserved the commented code for use in future hacking.
80214319ae broke the use of RUST_LOG to
turn up trace logging.
This commit refactors logger initialization into the env-bootstrap crate
so that it is centralized, and adopts the use of `WEZTERM_LOG` to
override the default logging filters, rather than `RUST_LOG`.
My original goal was to update to allsorts 0.5 but the API
changes are significant and not clearly described.
To make that transition easier, the prior commit moved the shaping
logic into our allsorts shaper module, leaving the name parsing
here in parser.rs.
This commit now replaces that logic with ttf_parser, which is
potentially faster (there's more emphasis on optimal code in that
crate than in allsorts) but definitely simpler.
It's not a slam-dunk transition: ttf_parser doesn't know how to
decode MacRoman encoded text, so there's a bit of logic borrowed
from allsorts here to handle that.
I'm gradually improving snapshot testing macro devx in k9 and preparing
to ship v1. Before i do this i'm changing the inline snapshot macro to be
just `snapshot!()` that takes `Debug` trait an an arg and figures out
serialization of it.
This commit adjusts the default color palette to use the same color
cube calculation as xterm; it isn't the ideal color cube calculation
and results in slightly brighter colors.
This commit also memoizes the default palette calculation so that
it isn't recomputed each time a palette is created.
refs: https://github.com/wez/wezterm/issues/348
This commit is a bit noisy because it also meant flipping the key map
code from using the termwiz input types to the window input types, which
I thought I'd done some time ago, but clearly didn't.
This commit allows defining key assignments in terms of the underlying
operating system raw codes, if provided by the relevant layer in the
window crate (currently, only X11/Wayland).
The raw codes are inherently OS/Machine/Hardware dependent; they are the
rawest value that we have available and there is no meaningful
understanding that we can perform in code to understand what that key
is.
One useful property of the raw code is that, because it hasn't gone
through any OS level keymapping processing, its value reflects its
physical position on the keyboard, allowing you to map keys by position
rather than by value. That's useful if you use software to implement
eg: DVORAK or COLEMAK but want your muscle memory to kick in for some of
your key bindings.
New config option:
`debug_key_events = true` will cause wezterm to log an "error" to stderr
each time you press a key and show the details in the key event:
```
2020-12-06T21:23:10.313Z ERROR wezterm_gui::gui::termwindow > key_event KeyEvent { key: Char('@'), modifiers: SHIFT | CTRL, raw_key: None, raw_modifiers: SHIFT | CTRL, raw_code: Some(11), repeat_count: 1, key_is_down: true }
```
This is useful if you want to figure out the `raw_code` for a key in your
setup.
In your config, you can use this information to setup new key bindings.
The motivating example for me is that because `raw_key` (the unmodified
equivalent of `key`) is `None`, the built-in `CTRL-SHIFT-1` key
assignment doesn't function for me on Linux, but I can now "fix" this in
my local configuration, taking care to make it linux specific:
```lua
local wezterm = require 'wezterm';
local keys = {}
if wezterm.target_triple == "x86_64-unknown-linux-gnu" then
local tab_no = 0
-- raw codes 10 through 19 correspond to the number key 1-9 positions
-- on my keyboard on my linux system. They may be different on
-- your system!
for i = 10, 20 do
table.insert(keys, {
key="raw:"..tostring(i),
mods="CTRL|SHIFT",
action=wezterm.action{ActivateTab=tab_no},
})
tab_no = tab_no + 1
end
end
return {
keys = keys,
}
```
Notice that the key assignment accepts encoding a raw key code using
a value like `key="raw:11"` to indicate that you want a `raw_code` of
`11` to match your key assignment. The `raw_modifiers` portion of
the `KeyEvent` is used together with the `raw_code` when deciding
the key assignment.
cc: @bew
This tidies up the font-dir and built-in font management a little
bit and paves the way for codepoint -> font resolution for fonts
discovered in font-dirs.
This commit uses a bit of DirectWrite to discover which font(s)
can be used to render a set of codepoints.
While hooking this up, I found that the method we were using
to extract the font data didn't handle TTC data so this commit
improves some parser diagnostics and handling for that.
refs: https://github.com/wez/wezterm/issues/299
98f289f511 causes more metrics retrieval
than in earlier versions; each unchached glyph render would trigger
a metrics recompute for the relevant font.
Add a simple cache for this.
refs: #353
This is one of those massive time sinks that I almost regret...
As part of recent changes to dust-off the allsorts shaper, I noticed
that the harfbuzz shaper wasn't shaping as well as the allsorts one.
This commit:
* Adds emoji-test.txt, a text file you can `cat` to see how well
the emoji are shaped and rendered.
* Fixes (or at least, improves) the column width calculation for
combining sequences such as "deaf man" which was previously calculated
at 3 cells in width when it should have just been 2 cells wide, which
resulted in a weird "prismatic" effect during rendering where the
glyph would be rendered with an extra RHS portion of the glyph across
3 cells.
* Improved/simplified the clustering logic used to compute fallbacks.
Previously we could end up with some wonky/disjoint sequence of
undefined glyphs which wouldn't be successfully resolved from a
fallback font. We now make a better effort to consolidate runs of
undefined glyphs for fallback.
* For sequences such as "woman with veil: dark skin tone" that occupy a
single cell, the shaper may return 3 clusters with 3 glyphs in the
case that the font doesn't fully support this grapheme. At render
time we'd just take the last glyph from that sequence and render it,
resulting in eg: a female symbol in this particular case. It is
generally a bit more useful to show the first glyph in the sequence
(eg: person with veil) rather than the gender or skin tone, so the
renderer now checks for this kind of overlapping sequence and renders
only the first glyph from the sequence.
The current master of allsorts supports color fonts in both bitmap and
svg varieties. I'm interested to see if I can teach wezterm to render
the svg based variety in a subsequent diff.
First though, it's times to dust off our allsorts shaper logic.
This commit updates to point to the current master of allsorts at the
time of writing; there's a little bit of API fanout that makes it a bit
easier to manage font fallback.
The fallback logic has been improved so that we can now successfully
fall back to the emoji font.
The shaping logic has been improved so that we turn on the options that
enable ZWJ for combining sequences of emoji, such as "man health
worker".
Running with the allsorts shaper enabled produces generally superior
emoji/ligature substitution results compared to harfbuzz with Noto Color
Emoji; the "man health worker" and the flags (eg: `flag: England`) from
the subdivsion-flag section don't get substituted at all with harfbuzz,
but do produce appropriate glyphs with allsorts.
refs: https://github.com/wez/wezterm/issues/66
This causes `tmux -CC attach` to enter control mode and patch
into the terminal, printing out parsed event messages.
refs: https://github.com/wez/wezterm/issues/336
This command formats an OSC 7 escape sequence to inform the terminal
of the working directory.
It has two optional arguments:
* The hostname - if unspecified the hostname of the system will be used
* The working directory - if unspecified the working directory of the
process will be used
This command formats the hostname and working directory into a `file://`
URL and emits an OSC 7 escape sequence.
The intent of this is to make it a bit easier to produce shell
integration scripts for various shell environments without trying
to implement URL encoding in eg: bash.
Adds some supporting methods for computing the `SemanticZone`s
in the display and a key assignment that allows scrolling the
viewport to jump to the next/prev Prompt zone.
This commit introduces a small, bounded, LRU cache for recently
decoded images.
This allows the same image ID to be used in the cache that the
same image bits are repeatedly sent to the terminal.
This is advantageous because it reduces the amount of texture
space required by the gui layer.
This wasn't used by anything and the version was getting pretty stale.
Upgrading is awkward because newer versions pull in an incompatible
freetype library version.
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
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
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.
This commit adds very basic first passes at representing the Pane
and GuiWindow types in lua script.
The `open-uri` event from 9397f2a2db
has been redefined to receive `(window, pane, uri)` parameters
instead of its prior very basic `uri` parameter.
A new key assignment `wezterm.action{EmitEvent="event-name"}` is
now available that allows a key binding assignment to emit an arbitrary
event, which in turn allows for triggering an arbitrary lua callback
in response to a key or mouse click.
`EmitEvent` passes the `(window, pane)` from the triggering window and
pane as parameters.
Here's a brief example:
```lua
local wezterm = require 'wezterm';
wezterm.on("my-thingy", function(window, pane)
local dims = pane:get_dimensions();
wezterm.log_error("did my thingy with window " .. window:window_id() ..
" pane " .. pane:pane_id() .. " " .. dims.cols .. "x" .. dims.viewport_rows);
window:perform_action("IncreaseFontSize", pane);
end)
return {
keys = {
{key="E", mods="CTRL", action=wezterm.action{EmitEvent="my-thingy"}},
}
}
```
refs: #223
refs: #225
This was broken by the changes in
aad493ab2a. The issue was that the
channel send didn't wakeup the receiver. I'm not sure why, and I tried
a couple of different async channel implementation.
Doing the simplistic solution here works reliably.
This builds on the new lua event handler plumbing added
in ccea650a93 to co-opt
the default URI opening action:
```lua
wezterm.on("open-uri", function(uri)
if uri:find("jira") then
wezterm.log_error("do something with jira")
wezterm.run_child_process({
"wezterm",
"start",
"--",
"jira",
"view",
extract_task_from_uri(uri)
})
-- prevent the default action from opening in a browser
return false
else
-- log but allow the uri to be opened in the browser
wezterm.log_error("clicken " .. uri)
end
end)
```
This doesn't allow exactly the sketched out option from
issue #223 to be implemented, but may be close enough
to be useful.
refs: #223
refs: #225
* `wezterm.on("event-name", func)`
* `wezterm.emit("event-name", "arg1", "arg2")`
`on` allows registering multiple functions.
`emit` will call each of the registered functions in turn, passing
a copy of the arguments. If a handler returns false, no additional
handlers are called and `emit` will return false. Otherwise,
once all the handlers have been called, `emit` will return true.
`emit` is capable of being called by async code.
These functions are available to the config layer, but nothing in
wezterm uses them at this time.
refs: #225