Avoid a "flash" of a single black but likely overly stretched and
awkwardly interpolated frame while we wait for big/animated/complex
images to load and decode.
For corrupt images, or images with an incorrect or typo'd filename in
the config, this prevents us from punting and just showing a transparent
background instead of something reasonable.
There were a couple of layers of issue here:
* In the ImageDataType::decode method, we didn't detect and do something
reasonable when the decoded image had 0 frames, later leading to
a panic in glyphcache when trying to index frame 0 of an empty vec.
* We shouldn't have been using ImageDataType::decode for window
background images
* Make the fallback/placeholder black rather than fully transparent
in the more modern decoder thread routine that we use for image
decoding at the gui layer.
refs: #3614
Further constrain the hiding logic for key-down events, so that
we are less likely to hide for things ctrl-shift-c when the user
is mousing around and copy/pasting.
Also, consider CapsLock to be a modifier for this and other
similar purposes.
refs: #3570
refs: #3306
For eg: RU layout, CTRL-S shouldn't result in ы in the context
of a terminal.
The approach taken here is similar to kitty; when the key combination
doesn't produce a definitive composed output, and when any of
ctrl/alt/super are present, we treat the keypress as though it were
the same as the one from the system default keymap.
The result is that ctrl-c now works like ctrl-c and alt-b and alt-f work
like their latin counterparts.
Hopefully there are no downsides to this!
refs: https://github.com/wez/wezterm/issues/2845
refs: https://github.com/kovidgoyal/kitty/issues/606
The main part of the problem is that NSWindow::isZoomed lies to us
sometimes.
This is a relatively gross workaround.
Add missing invalidation after setting the content size; that prevents
janky when dragging the window between monitors.
Removed some redundant Dimensions computation from that method; nothing
ever read it.
refs: https://github.com/wez/wezterm/issues/3503
It's a little limited in the scope of its detection: we have a built-in
list of tiling WM environments and if the current one is on the list
then we set an appropriate value for this option.
The list currently has just a single entry.
This pulls in almost all of the original PR in #2235.
I skipped a dead key case that I recall being tricky:
I didn't want to break the non win32-input mode version
of that.
I'd be happy to have that case re-evaluated in a smaller
PR where we can focus on its details.
Co-authored-by: Dominik Kreutzer <kreudom@gmail.com>
For whatever reason, it appears as though the wayland
frame event stuff is unreliable when used with webgpu,
so we simply avoid using it.
refs: https://github.com/wez/wezterm/issues/3126
These conditions were from the earliest days of panes and aren't
needed any more, especially because they make it hard to have
consistent behavior!
refs: https://github.com/wez/wezterm/issues/3450
I think the future for this is to extend the Pattern type to accept
a list of regexes and use a RegexSet to unambiguously handle multiple
patterns with captures.
That might help a little with https://github.com/wez/wezterm/issues/3247
but the stated use in that issue may not even work with the rust
regex crate.
For now we do the simple thing and match the user's patterns
first.
refs: https://github.com/wez/wezterm/issues/3456
Allows prompting the user to select from a list and then
triggering some action on the selected item.
This is the guts of the launcher menu hooked up to user-supplied
arbitrary entries.
Previously, we'd record the focused pane only in the per-client
view.
That status didn't propagate through the model fully, leading to
inconsistencies when using activate-pane-direction.
This commit does the full model update to force that through.
I may regret this later: the focus state was intended to be
a per-client attribute and this effectively prevents that
from ever being useful.
Maybe the per-client state should just be removed?
Will ponder that later.
refs: https://github.com/wez/wezterm/issues/3448
refs: https://github.com/wez/wezterm/issues/3387
Also sneaking in here is not updating the last input time
for a client unless the input was taken by a user.
This had a referencing issue, similar to the more recent GLOBALS
issue.
The resolution in this case is a lot simpler: we can just return
a regular lua table and use all the same underlying semantics,
but stick a metatable over the top to handle assignment and
provide the strict mode method.
If the target domain_id doesn't match the source pane.domain_id(),
then we consider the filesystem namespace to be incompatible and
won't try to use it.
refs: https://github.com/wez/wezterm/issues/3442
The server-side ownership of the palette is a stumbling block for
many users, so let's fix it.
This commit allows the client to pass its configured palette to
the server when it connects, and when the config is changed.
That palette takes precedence over the palette from the server config.
However, if the remote application uses any escape sequences that
redefine the color palette, the color palette that was active at
that point in time is forked and use as the basis, and will remain
the active palette until the palette is reset via escape sequences.
refs: https://github.com/wez/wezterm/issues/2686
refs: https://github.com/wez/wezterm/issues/3397
This commit teaches the config about SerialDomains, and the mux
layer about constructing a SerialDomain, then changes the GUI
layer to use those pieces to set up `wezterm serial`.
A new `serial_ports` config is added, and the GUI layer knows how
to apply it to the set of domains in the mux.
The result of this is that you can now define a domain for each
serial port and spawn a serial connection into a new tab or window
in your running wezterm gui instance.
This got broken around the time we started to re-exec the mux
server. Since the fd was CLOEXEC we'd essentially unlock and
ignore the lock at the point we'd re-exec.
This commit allows the fd to remain open and locked across
the exec, and causes the exec'd process to set CLOEXEC by
explicitly telling it about the log fd, so that shells and
things spawned by the mux don't hold the lock.
Work harder to notice and handle the PaneRemoved notification
more centrally, which allows removing some earlier workarounds.
Now when we receive PaneRemoved, we take the opportunity to handle
missing mapping or stale mapping between local and remote ids and
perform a resync before continuing to handle the PaneRemoved message.
Doing it this way means that we don't need to second guess the timing
of notification or the resync, so we end up with the correct sequence
of notifications, and the result is the correct size of the splits
because the local and remote aren't independently managing the
the pane removal with conflicting ideas of the new size.
refs: https://github.com/wez/wezterm/issues/3386
It's a tremendous PITA for the user to do this at the system level on a
mac, where it is sorely needed. This commit allows raising to a desired
minimum level, but won't decrease from an already larger soft limit.
refs: https://github.com/wez/wezterm/discussions/3353
Add a link to regex syntax supported in wezterm, so eg. we have a way to know that perl character class '\c' is not supported and instead we can use the ascii equivalent [:cntrl:]
Three issues:
* The initial connect would leave the dpi assigned to 0, resulting
in incorrect scaling when using imgcat until the window was resized
and the correct dpi was passed up.
* On resize, we'd only compare the row/col count and not notice changes
in pixel dimensions/dpi
* On the server side, when processing a resize and recomputing
the tab size, we would omit the pixel dimensions and leave
the resulting tabs and panes with 0 dimensions, breaking imgcat
because it thought the window was 0x0.
refs: https://github.com/wez/wezterm/issues/3366
This fixes a surprising interaction between copy mode and the
command palette, but is also the root cause of another issue
with CharSelect mode.
refs: https://github.com/wez/wezterm/issues/2947
Given an assignment like this:
```
{
key = "b",
mods = "ALT",
action = wezterm.action.SplitPane {
direction = 'Right',
command = {
label = 'Bash Right',
args = {'/usr/bin/bash' }
}
}
}
```
we should show the label from the command in the palette.
That's what this commit enables.
If there is no label, but the arguments are set, then the
arguments will be shown instead.
refs: #3252
This commit causes the mux to generate a PaneFocused notification
when the active pane is changed.
The mux server will forward that as a unilateral PDU to connected
clients.
The clientpane implementation will handle that by applying the
same state to the local mux.
refs: #2863
* Translate from File to EncodedFile as needed
* Adopt blob leases in the mux server
* Fix an issue where the first image sent by the mux server would
be replaced on the client by its background image, if configured.
Removed the ImageData::id field to resolve this: you should use
the hash field instead to identify and disambiguate images.
Bumped the termwiz API version because this is conceptually
a breaking change to the API
refs: https://github.com/wez/wezterm/issues/3343
Weird behavior from macos; the command line:
`wezterm start vim hello`
would result in macos requesting `vim` and `hello` be opened
as "documents" which would route each of those to the .command
script handling flow and spawn a window for each; running:
`vim ; exit` in one
`hello ; exit` in another
in addition to the normal handling of that command line.
This commit resolves this by igoring document opening
requests until after the application is fully launched.
I tested this by trying to open a .command script with
this new build and verified that that continued to work.
refs: #3340
This one was a bit weird because something appeared to be a bit
non-deterministic. With this config:
```lua
local wezterm = require 'wezterm'
return {
window_frame = {
border_left_width = '1cell',
border_right_width = '1cell',
border_bottom_height = '0.5cell',
border_top_height = '0.5cell',
border_left_color = '#444',
border_right_color = '#444',
border_bottom_color = '#444',
border_top_color = '#444',
},
window_padding = {
left = '1.5cell',
right = '1.5cell',
top = '0.5cell',
bottom = '0.5cell',
},
}
```
starting wezterm could result in a terminal that reported either 23 or
24 lines. I got 24 when running the build from da7e29df but usually
23 when running a build out of my repo.
Looking closely, the issue is that the initial window size didn't
account for the configured border size, and that we'd subsequently
fix that up when we later do a resize fixup after creating the window.
This commit refactors the window border logic so that it can be
used prior to having fully constructed the terminal window and then
uses that to fixup the initial computed dimensions.
I also noticed with this config that increasing the font size
with CTRL-+ could also result in an inconsistency between the displayed
terminal size and the pty size we set in the kernel: it was missing
the border adjustment as well, so I added it in there.
refs: #3333
Really, this is adjusting the logical line breaking behavior, or the
lack thereof.
The situation is this: conpty can decided to reinterpret and flush
large sections of its buffer as a continuous stream of unbroken
characters with no breaks when it repaints the full screen.
When we receive such an update, we see it as one long logical line,
and when we subsequently select multiple lines we can run into the
maximum logical line length and insert invalid synthetic line breaks
into the data that we send to the clipboard.
This commit adjusts the wrapping logic at the time that we receive
the text so that we don't tag the line as a logical line continuation
if:
* The alt screen is active. Full screen apps will re-render on resize
anyway, and we don't reflow long lines on resize either for the same
reasons
* If we are talking to ConPTY:
* If the last character in the line is not alphanumeric or
punctuation (in other words: it doesn't look plausibly like
text that should be a line continuation).
refs: #3278
refs: #3177
* Update ssh_backend.md
* Update normalize_output_to_unicode_nfc.md
* Update strikethrough_position.md
* Update underline_position.md
* Update underline_thickness.md
* Fix lua config docs titles to be formatted as inline code
* Mention how suggested alphabet for quick select is choosen
* Mention update-status and update-right-status for status_update_interval
* Fix docs for all keyassignments to be formatted as inline code
* Fix Lua object index titles
* Fix titles of `wezterm.*` module index pages
* Fix title of `Color` object & `wezterm.color` functions
We reduce titles from h2 to h1 because mkdocs defaults the page title to
the page file name if no h1 header is found.
* Unify title of all object methods
* Add index page for Gui events
Fixes this:
```
> wezterm.GLOBAL.foo = {"bar", "baz"}
> wezterm.GLOBAL.foo
[
"bar",
"baz",
]
> #wezterm.GLOBAL.foo
runtime error: [string "repl"]:1: attempt to get length of a userdata value (field 'foo')
stack traceback:
[string "repl"]:1: in main chunk
>
```
and allows this:
```
> for k, v in pairs(wezterm.GLOBAL.foo) do print(k, v) ; end
```
Pull in the enhanced scheme that includes wezterm metadata and colors.
Co-authored-by: Thomas Croft <103956335+thomascft@users.noreply.github.com>
closes: https://github.com/wez/wezterm/pull/3208
GH actions has been awful slow and bogged down recently,
getting in the way of work that is more important.
This commit removes a variety of alpine builds (which are
not widely used by wezterm users), and the eldest fedora
version to free up some resources.
Nudge new users towards using this style:
```lua
local config = {}
config.color_scheme = 'Batman'
return config
```
and surface how to write lua modules closer to the main section
on config files. In that lua modules section, nudge towards using
a convention similar to that of the plugin spec described in
this commit: e4ae8a844d
Input data:
\e_Ga=T,f=32,s=10,v=22,c=1,r=1,m=1\e\\e_Gm=1;/xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T//P=\e\\e_Gm=1;/xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T////E////xP///8T//P=\e\\e_Gm=0\e\
There were two issues in handling this:
* We expected there to be `;payload` in the first transmission packet,
but there wasn't one, so we ignored it as ill-formed.
* The standard base64 decoder in the rust ecosystem is super strict
and rejects the "sloppy" python base64 encoder output that isn't
strictly conformant with the RFC. We need to jump through some
hoops to get it to relax and accept the input.
refs: https://github.com/wez/wezterm/issues/2716
Continuing from the previous commit, this shifts:
* In-memory data -> temporary file
* Image decoding -> background thread
The background thread asynchronously decodes frames and
sends them to the render thread via a bounded channel.
While decoding frames, it writes them, uncompressed, to
a scratch file so that when the animation loops, it is
a very cheap operation to rewind and pull that data
from the file, without having to burn CPU to re-decode
the data from the start.
Memory usage is bounded to 4 uncompressed frames while
decoding, then 3 uncompressed frames (triple buffered)
while looping over the rest.
However, disk usage is N uncompressed frames.
refs: https://github.com/wez/wezterm/issues/3263
Need to use a newer version of libssh-rs that can report this state,
as the underlying libssh doesn't fold it into the process exit
status.
refs: https://github.com/wez/wezterm/issues/3095