As promised in the previous commit, this one implements an escape
sequence to control the unicode version.
Unknown to me in the previous commit, iTerm2 already defines such
an escape sequence, so we simply implement it here with the same
semantics.
refs: #1231
refs: #997
We rely on using freetype in order to support more fonts in more
situations, and we have a deeper existing integration with harfbuzz.
I'm unlikely to come back to allsorts to complete our integration,
and in the meantime, it just adds overhead to build/test and those
builds are taking longer and longer.
I loved the idea of using pure rust for all the font stuff, but
its time is not now.
closes: #587closes: #66
* mux: unzoom when switching panes
Add `unzoom_on_switch_pane` config option:
When switching to another pane with ActivatePaneDirection, if the
current pane is zoomed, unzoom and then switch instead of doing nothing.
* Apply suggestions from code review
Co-authored-by: Wez Furlong <wez@wezfurlong.org>
It appears as though Menlo is the only font on macos to contain the
heavy ballot cross symbol, which is commonly used on macos (eg: in
`brew` output).
Our fallback list, despite starting with Menlo, didn't include menlo
itself in the candidates.
Furthermore, `ls-fonts` wouldn never see the result of the system
fallback resolution because it didn't know to try again, and was
using the list of handles from before the fallback.
This commit resolves all of these concerns.
refs: #849
This commit introduces the `Dimension` type which allows specifying
a value in a variety of units; pixels, points, cells, percent.
`Dimension` needs contextual information to be evaluated as pixel
values, which makes resolving the value from the config slightly
more of a chore.
However, this type allows more flexible configurations that scale
with the font size and display dpi.
refs: #1124, #291, #195
More of a "fix"; we use some heuristics based on the bearing
and glyph width to figure out if a sequence looks like a funky
ligature that moves left to render the glyph.
This may be prone to false positives, but the consequences are low:
when we think a glyph is part of a ligature, then rather than using
the cursor_fg color (which is typically black, or close to invisible),
we retain the normal text fg color.
This way the portion of the glyph outside of the cursor retains its
foreground color, and just the cell containing the cursor may have
a slightly funky fg color in the case where the heuristic was bad.
closes: #478
The description of Nop was incorrect; it was describing
DisableDefaultAssignment. Just make this bit use the same
example from DisableDefaultAssignment's docs.
We now compute the cap-height from the rasterized glyph data.
Moved the scaling action of use_cap_height_to_scale_fallback_fonts from
glyphcache into the font resolver: when enabled, and we have data
about the baseline font and the font being resolved, then the resolving
font will be scaled such that the cap-height of both fonts has the same
pixel size.
The effect of this is that `I` glyphs from both fonts should appear to
have the same height.
Added a row of `I`'s in differing styles at the bottom of styles.txt
to make this easier to visualize.
refs: #1189
This is to handle situations such as some versions of the Terminus
bitmap font, where the individual bitmap strike sizes are broken
out across multiple individual files.
Font matching now passes down the nominal pixel height based on
the current DPI and font scale factor, and will use that to select
the font file that has the closest pixel size.
Previously, it would be potentially undefined which of the Terminus
font files would be selected.
refs: https://github.com/wez/wezterm/issues/1189
This font is a bit funky; the bitmap strikes are only 4px wide:
```
; ftdump gohufont.otb
There is 1 face in this file.
----- Face number: 0 -----
font name entries
family: Gohu GohuFont
style: Regular
postscript: UNAVAILABLE
created: 1904-01-01
modified: 1904-01-01
revision: 1.00
glyph count: 1694
font type entries
FreeType driver: truetype
sfnt wrapped: yes
type: fixed size
direction: horizontal
fixed width: no
glyph names: no
fixed size
0: height 11, width 3
size 11.000, x_ppem 11.000, y_ppem 11.000
1: height 14, width 4
size 14.000, x_ppem 14.000, y_ppem 14.000
charmaps (1)
0: format 4, platform 3, encoding 1 language 0 (active)
```
but using that the cell size isn't right.
We draw from the metrics we compute via cell_metrics to get more
information; we don't get a valid height from that (just 0!), but
we do get the much more plausible width of 8 pixels.
So we take the max of the two techniques for figuring the metrics.
That appears to work out, and also doesn't appear to break emoji
fonts.
refs: #1165
This commit adjusts the the window event routing/queuing so that
a queued event can capture a pane_id other than the focused pane.
Since we only allow one queued instance of a given named event in a
window, a consequence of this is that multiple bell events coming
from different panes at the same time may race and the loser's
event will be dropped. We log a warning in that case.
refs: #3
This was a bit of a PITA to run down; the essence of the problem
was that the shaper was returning an x_advance of 0 for U+3000,
which caused wezterm's shaping layer to elide that glyph.
I eventually tracked down the x_advance to be the result of
scaling by an x_scale of 0, which in turn is the result of
harfbuzz not knowing the font size.
The critical portion of this diff is the line that advises
harfbuzz that the font has changed after we've applied the
font size.
The rest is just stuff to make it easier to debug and verify.
This:
```
printf "x\u3000x."
```
Now correctly renders on screen as "x x".
fixes: #1161
This commit introduces a mechanism for specifying resize increments
for a window, and then arranges for the termwindow to set those
to match the current font cell metrics.
This should help to avoid cases where there is excess padding pixels
resulting from the window being slightly larger than computed number
of cells and the font metrics.
It appears as though kakoune hides the terminal cursor and renders
its own version of the cursor.
The hidden state was being picked up by the copymode overlay,
making it awkward to use.
This commit forces the cursor to be visible (and a block) when
copy mode is active.
closes: #1113
Not sure what happened here: presumably a borked merge or something
similar, but this commit allows `window:get_appearance` to return
the actual appearance value on X11.
Even though this plumbs the call through to Wayland, Wayland doesn't
provide an equivalent concept so still always return Light, as is
mentioned on our docs.
closes: #1098
This commit annotates fonts with a boolean that indicates whether
we think it contains glyphs with emoji presentation, and then
passes the cluster.presentation field down to the shaper.
If the presentation doesn't match the current font in the fallback,
then it will be skipped until we exhaust its options.
`wezterm ls-fonts` also shows whether we think a font has emoji
presentation.
refs: #997
* docs/term: add information to make it work with WSL
* Adapt recent changes that automatically set WSLENV, add info on how to install terminfo with nixpkgs
* Apply suggestions from code review
Co-authored-by: Wez Furlong <wez@wezfurlong.org>
Test scenario is:
* Create a split
* in each pane run: `printf "\e[?1004h" ; od -c`
* Focus the panes, focus another window, and focus the window again
* The I and O events appear in the panes when changing their focus.
* Previously, only the active pane would get focus events when the
window focus changed.
refs: https://github.com/wez/wezterm/issues/941
The man page states:
> For each parameter, the first obtained value will be used.
but then later says:
> It is possible to have multiple identity files specified in
> configuration files; all these identities will be tried in sequence.
> Multiple IdentityFile directives will add to the list of identities
> tried (this behaviour differs from that of other configuration
> directives).
So that's what this commit does
The main culprit was the calloop feature that is used by default
in the underlying SCTK crate.
This commit:
* Routes keyboard processing via the same keyboard mapping code
that we use for X11
* Implements key repeats directly, and with awareness of elapsed
time in case the repeat rate is quicker than the event dispatching
quantum
* Disables the calloop feature of SCTK and let us do our own polling
of the wayland connection.
Critically, key repeat is sticky and unpredictable while calloop is
enabled.
closes: #669
The issue is that the pane was only removed from the tab when explicitly
closed, leaving it to be later detected and flushed.
However, in the meantime, when performing eg: cursor blink maintenance,
if the set of panes in the tab is empty then the window would close.
The resolution is to ask the mux (rather than the tab) to kill the pane,
so that the cascading closure of the tab causes the window's active
tab to reference the correct remaining tab.
refs: #890
neovim doesn't like it when multiple drag events with the same
coordinates are received; it appears to treat that as though
the mouse button was double clicked.
This commit teaches the mouse report encoding to suppress multiple
drag events in succession that have the same payload.
refs: https://github.com/wez/wezterm/discussions/823
This looks like a honest typo from when panes were introduced!
We were passing the tab id rather than the pane id when specifying
the target of a split.
likely fix for this issue:
refs: https://github.com/wez/wezterm/issues/781
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.
This commit adds a slant to *scalable* (not bitmap!) fonts whose
originating font attributes requested italics but for for which
the resolved face is not italic.
refs: #815
The status information now explains the exit status and the
exit_behavior, as well as links to the docs on exit_behavior.
refs: https://github.com/wez/wezterm/issues/795
Two issues here:
* The hue angles need adjusting to work with the palette library
* The resultant RGB color had the wrong gamma level, resulting in
an overly bright image.
refs: https://github.com/wez/wezterm/issues/775
There were two bugs here:
* \u8D (the utf8 encoded representation of 0x8d, aka: RI) was not
recognized as a C1 code and was instead passed through as printable
text.
* The \u8D is a zero-width sequence which means that a subsequent
set_cell call on the new empty-by-default line wouldn't allocate
any cells in the line array, and the assigment to the line would
panic.
This commit avoids the panic for the second case, and then fixes up
the vtparser to correctly recognize the sequence as a C1 control.
refs: https://github.com/wez/wezterm/issues/768
Since the original code was written, Rust grew and stabilized
an interface for specifying argv0 for the child process, so
we can remove the fragile `-l` argument passing.
refs: https://github.com/wez/wezterm/issues/753
It's not perfect; this only handles the case where you move down
into the terminal. I couldn't easily make the same thing happen
when moving the mouse up or left outside of the window. It's
probably fixable but this is better than it was.
closes: https://github.com/wez/wezterm/issues/591
* Make alphabet and patterns configurable
* add docs
* Enhance scrollback search to support regex captures so that
searching for eg: `fo(o)` will select the last `o` in `foo`.
refs: https://github.com/wez/wezterm/issues/732
I've built this on linux, which doesn't respect the timeout.
I've made speculative changes that should build on mac and windows,
but that don't plumb the timeout functionality on those systems
as of yet.
refs: #619
We weren't fixing up the active tab position correctly after removing
a tab. I think this bug crept in around the ActivateLastTab changes.
We now try harder to set active idx back to the tab that was active
prior to the remove, and ensure that we set the active index to
something within range if it was the active tab that was removed.
Refs: https://github.com/wez/wezterm/issues/690
Now that all platforms know whether the system fallbacks
covered the requested glyph range, it is reasonable to
restore the configuration error window to advise the user
if they are missing fonts for the text they want to display.
refs: https://github.com/wez/wezterm/issues/671
Migrate information into the relevant config option pages, and
instead summarize with a demonstration of configuring the font.
For wezterm.font, there's now an expanded discussion on naming
and matching fonts.
closes: https://github.com/wez/wezterm/issues/560
The repro scenario for this case was:
* open GNU nano
* hit enter twice
* type hello
* move the text cursor to the top line
* double click on hello
* hit enter
Prior to this commit, the selection would remain on the now-blank line
that previously held `hello`.
refs: #644
This replicates `last-window` in tmux. To pull this off, I
deliberately store the last tab whenever I'm activating a new one or
spawning a new one. I had to do this explicitly rather than hooking
set_active, because we end up setting the active tab briefly for some
common operations like moving a tab.
These now operate in terms of logical lines so they deal with
lines that have wrapped outside the viewport better than in
previous releases.
closes: https://github.com/wez/wezterm/issues/408
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
Default `allow_square_glyphs_to_overflow_width="WhenFollowedBySpace"`,
and expand its meaning from mostly square glyphs to glyphs that are
also wider than they are tall.
refs: https://github.com/wez/wezterm/issues/565
I'm not sure what exactly changed (perhaps it was a Windows updated?)
but window_background_opacity was only taking effect for windows
with no title bar.
I found that explicitly configuring a region makes transparency
work again.
refs: #553
terminus-bold.otb reports 0 height!
Detect and force that case to go through the bitmap strike loading
code path.
Improve the size selection heuristic for bitmap strikes: previously,
we would just pick the largest bitmap and allow it to be scaled down,
which was OK for emoji fonts that just had 128px square glyphs, but
is not ok for pre-rendered pixel strikes like terminus.
Note that IncreaseFontSize works in terms of percentages only,
so using a font like this may have "gaps" when ctrl-+ or - to change
the font size.
refs: https://github.com/wez/wezterm/issues/560
This is first draft; the animation rate is currently tied
to the cursor_blink_rate setting, so if the gif has frames that
are intended to display more frequently than that, they will
animate more slowly.
Animation is only carried out while the window has focus.
Animation increases the load on the GPU and thus uses more power.
It's kinda fun to stick one of these animated pixel gifs in the background:
https://imgur.com/gallery/F9DAH
The previous behavior was to always treat ctrl-alt as altgr on Windows,
this has been done to better support altgr through a VNC session,
but this is very unintuitive when you don't need this behavior.
ref: #472
As explained in the docs included in this commit, ideally this
wouldn't be needed, but due to a long-standing hinting bug in
freetype <https://gitlab.freedesktop.org/freetype/freetype/-/issues/761>
it seems most expedient to just render our own block glyphs,
so that's what this does!
refs: #433
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 is defined as a trait method on Pane (default: false), and has the
obvious transitive equivalent methods in Tab and Window (eg: if all
contained items are `can_close_without_prompting`, then that container
is also `can_close_without_prompting`).
The intent is to avoid bothering the user to confirm closing a window
when the content is not stateful and doesn't warrant it.
For example: the window that is displayed in the event of a
configuration error really shouldn't prompt to the user to confirm
closing it.
All termwiztermtab panes are `can_close_without_prompting==true`
to effect this policy.
In the future, we could teach LocalPane to lookup the session leader
process against a list of "uninteresting" or "stateless" processes
and return an appropriate result (as suggested in
https://github.com/wez/wezterm/issues/280). That functionality
is NOT part of this commit.
`exit_behavior = "Hold"` will keep the pane alive until explicitly
closed. More details in the docs that are part of this commit.
refs: https://github.com/wez/wezterm/issues/499
This fixes a longstanding issue under mutter where client side
decorations are in use. The decorations were being drawn too
early in the initialization of the window which could leave them
off-screen and weird. This was masked by a couple of mutter
related bugs with client side decorations.
With these changes I now get sane decorations under mutter,
and the toggle fullscreen action is now enabled as well!
closes: #224
We weren't didn't treat the "No existing hyperlink, No new hyperlink"
case as no change in hyperlink, and were invalidating the window on
every mouse except for those over text with a hyperlink.
Pasting a lot of text could cause a deadlock between writing
to the input side of the pty and consuming the output side.
Making the writer/input side non-blocking resolves this.