We budget size based on the x_advance, which can be 1 pixel less
than the width of the glyph texture, so we could often end up
omitting the last character in "Launcher" or "default" in the
tab title or right status area.
This commit uses x_advance in both places.
Make the scrolling mostly independent of the active row; adjust
the top row when hitting the top/bottom edges of the display.
Mouse movement no longer changes the scroll position. Instead,
the wheel is used to scroll the list.
refs: https://github.com/wez/wezterm/issues/1485
This isn't ideal, but it is better than previously: we would
close the window and before the Drop impl had updated the
list of known windows, we'd try to re-assign that window
to another mux window in a different workspace, but it would
never appear because the window was closed.
refs: https://github.com/wez/wezterm/issues/1531
Originally I had this the other way around but it was problematic
when considering things like maximized, font scaling and full screen
states.
refs: https://github.com/wez/wezterm/issues/1531
Rather than just quitting the app and potentially silently killing off
a number of panes that might be running in other workspaces, we now
will pick one of those workspaces and activate it.
refs: #1531
This action causes the active workspace for the gui to change.
If the name is omitted a random name will be generated.
If the workspace doesn't exist, it will be be created.
The optional spawn parameter can be used to launch a specific
program into the new workspace; if omitted, the default prog
will be used.
The gui only supports a single active workspace. Switching workspaces
will repurpose existing gui windows and re-assign them to windows
in the new workspace, adjusting their size to fit those windows,
spawning new windows or closing unused windows as required.
The gui now exits when there are no panes in the active workspace,
rather than no panes at all.
refs: #1531
The mux now has a notion of which client is actively doing things.
This allows, for example, newly spawned windows to take on the
active workspace for a given client.
The gui now assigns a client id on startup, and sets the active
workspace to `default`.
The mux server temporarily overrides the active id to that of
the currently dispatching client when processing PDUs.
refs: https://github.com/wez/wezterm/issues/1531
Tidies up some code duplication within the mux protocol handler.
Move some of the logic into Mux, remove legacy Spawn Pdu to reduce
more duplication.
I want to dedup some of the similar logic that exists in the gui
spawn implementation as well in a follow up.
`ScrollByPage` can accept non-integer values in the configuration.
This allows fractional page scrolling, such as by half a page.
The default remains the same, at 1 page.
This is not exposed through any UX; the mux api allows setting
the workspace and propagating information about windows whose
workspace has changed.
Windows start with a blank workspace name.
This is just plumbing; nothing uses it yet.
refs: #1531
This is a similar race condition to one we had before with the
multiplexer, where the connection UI made us think that we didn't
need to start a new process.
Additionally, the attach method would unconditionally create a
new client without checking whether we already had one.
In the case that the published symlink is stale, our default
client connection logic was to retry connecting with backoff
to give a newly spawned server a chance to startup.
In the context of a newly launched gui process checking to see
if an existing gui process can serve the same request, we don't
need to give it any grace: it will either answer immediately
or be deemed not useful.
This commit limits us to a single connection attempt in the case
where we're not automatically starting the server, which in turn
constrains the overhead to something in the order of microseconds
rather than nearly 0.5 seconds.
While we're in here, I noticed that if we thought we had a socket
to try and that failed, we'd always try to publish a new symlink.
However, if we failed due to mismatched version info, we shouldn't
publish over the top of the already running instance.
refs: #1529
user vars were stubbed out. This commit adds storage for them
in the mux client and adds a new notification that publishes each
var as it is changed. That differential stream is applied to the
storage in the mux client when it is received.
```lua
local wezterm = require 'wezterm'
wezterm.on("update-right-status", function(window, pane)
local woot = pane:get_user_vars().woot
window:set_right_status(tostring(woot))
end);
return {
unix_domains = {
{name="unix"},
},
}
```
then running:
* `wezterm connect unix`
* in that session: `printf "\033]1337;SetUserVar=%s=%s\007" woot `echo -n nice | base64``
causes `nice` to show in the status area.
refs: #1528
This puts us in a better position for the future to be able
to configure whether we use wezterm, tmux or no multiplexing.
Today we allow wezterm or no multiplexing.
Add docs on this new setting.
refs: https://github.com/wez/wezterm/issues/1456
If an ssh domain is set to use_multiplexer=false, it is now
possible to `wezterm connect` to it.
Previously, it was only possible to connect to domains that
used the mux client.
refs: https://github.com/wez/wezterm/issues/1456
If we decide we want re-use and existing gui due to config differences
we shouldn't then publish the new, differently configured, gui as
the canonical path for that display/class.
Clarify the message that we print when re-using an existing gui
in case someone doesn't want that behavior.
When set, changes the default domain to the domain with the specified
name, which potentially affects the default program.
eg: default_domain = "WSL:Ubuntu-18.04" will cause the initial tab
to be spawned via WSL.
The idea is that we want to be able to spawn into wsl with the
convenience of a local domain, but without the awkwardness of
it having a different filesystem namespace.
It would also be great to be able to spawn a new tab or pane
in the same domain and pick up the cwd of the existing one.
The WslDomain allows the user to explicitly list WslDomains
and control eg: default shell, username and so on, but wezterm
will pre-fill a default list of domains based on the `wsl -l`
output that we were already using in the launcher menu.
The existing LocalDomain has been augmented to understand that
it may need to fixup a command invocation and that gives it
the opportunity to rewrite the command so that we can launch
it via `wsl.exe` and pass down the cwd and so on.
This same technique might be extensible to eg: docker instances
in the future.
This commit:
* Introduces `wsl_domains` config and its default list of wsl
distributions
* Creates LocalDomain instances from that list
* The launcher menu allows spawning a new tab via one of those domains
The client machinery would try to spawn an async attempt at
detaching the unixdomain from the mux on shutdown, but since
we're in the middle of tearing down the scoped executor,
we could sometimes panic.
The client we have in this situation isn't actually associated
with a domain, so we don't need to detach in that situation.
Formalize that by making it an Option, and address the
fanout.
Using the new publish/discovery stuff from the past couple of commits,
if we can find a matching socket path for a running gui, and the
configuration is likely a match, then use the mux protocol to talk
to the already running gui and ask it to spawn the equivalent program
into the same process.
refs: https://github.com/wez/wezterm/discussions/1486
We need 100% of the info for it to work correctly, so this commit:
* Exposes the keyboard encoding mode via the Pane trait
* Adds the scan code to the RawKeyEvent
* Has the GUI perform the encoding if the keyboard is set that way
* Removes the basic encoder from termwiz in favor of the gui level one
The net result is that we bypass the Pane::key_up/Pane::key_down methods
in almost all cases when the encoding mode is set to win32-input-mode.
There is now a config option: allow_win32_input_mode that can be
used to prevent using this mode.
refs: #1509
When spawned with no WEZTERM_UNIX_SOCKET environment set,
we now prefer to resolve the gui instance, falling back to
the mux if it doesn't look like the gui is running.
`wezterm cli --prefer-mux` will use the original behavior of
trying to resolve the path from the unix domain in the config.
Nothing generates them right now, and the mux client has no
way to represent them on the wire.
I'm considering constraining them to just win32 for now.
refs: https://github.com/wez/wezterm/issues/1509
It was showing the whole text for the cluster for each shaped
glyph.
Fix it up to map back to the corresponding cell range and
extract the text from the line.
Include the x_advance metric in the output while we're in
there.
refs: https://github.com/wez/wezterm/issues/1333
When rendering the IME composing text, I noticed that for the Korean
input sequence: shift+'ㅅ' followed by 'ㅏ' we'd render the 'ㅆ' (the
shifted first character) in black and the composing 'ㅏ' in white
against the cursor color, and that was very difficult to read,
especially at the default font size.
To resolve this, this commit:
* Forces clustering to break around the cursor boundary, so that
we treat the cursor position as its own separately styled cluster
* Adjusts cursor/bg rendering so that we always consider the start of
the cluster for the colors of that run. We are guaranteed that a
ligatured sequence will fit in the background area anyway.
This has the effect of "breaking" programming ligatures such as '->'
when cursoring through them, and decomposing them into their individual
'-' and '>' glyphs, which is a reasonable price to pay for being able
to see things better on screen.
refs: https://github.com/wez/wezterm/issues/1504
refs: https://github.com/wez/wezterm/issues/478
When we translate a dead key, send the composed event immediately
and don't try to route the current key press via the IME.
Improve rendering when in the composing state: overlay the composing
text at the cursor position to show what the composing text would
look like, even though it hasn't been committed to the input stream
yet.
refs: https://github.com/wez/wezterm/issues/1504
For Korean text input, pressing SHIFT and then typing in certain
keys begins a composition sequence. Our logic for when to route
via the IME got so distracted by ALT that it didn't consider SHIFT
and didn't send this sequence to the IME, so we'd fail to compose
those sequences.
While poking at this, I realized that we should treat this composition
similarly to dead keys, in that we can signal the term window to
highlight the cursor color and report that status.
There's some further work to do: the composing text should be rendered
by us. So far our IME integration assumes that the IME itself will
render over the top of our window, but for this particular input
it doesn't do that.
refs: https://github.com/wez/wezterm/issues/1504
The same core code is used to render both the tab navigator
and the launcher. The context is specified using some flags
so that you don't get an unholy mess in both places.
The net result of this is that the tab navigator now supports
fuzzy matching.
refs: #664
refs: 1485
* Allow selecting the first few rows by number
* Allow scrolling through long lists of items
* Add actions from key assignments to list
refs: #1485
refs: #1413
Since we now have RawKeyEvent and a sane way to indicate handling,
we don't need these any more, and it simplifies key dispatch to
remove them.
refs: #1483
Pass down whether we are in a live resize to the gui layer, so that
we don't incorrectly assume that the scale has changed, and fight
with the window manager.
Built this on my mac: will need to fixup for windows and linux.
refs: https://github.com/wez/wezterm/issues/1491
This commit adds a couple of helper methods that provide insight into
the state of the keyboard layer.
The intent is for users to add status information about the keyboard
state.
This commit also ensures that we schedule an update when the leader
key duration expires, and ensures that we close out the leader state
for an invalid key press.
refs: #686closes: #688
```lua
local wezterm = require 'wezterm';
wezterm.on("update-right-status", function(window, pane)
local leader = ""
if window:leader_is_active() then
leader = "LEADER"
end
local dead = ""
if window:dead_key_active() then
dead = "DEAD"
end
window:set_right_status(leader .. " " .. dead)
end);
return {
leader = { key="a", mods="CTRL" },
colors = {
dead_key_cursor = "orange",
},
}
```
When set, the cursor will change to this color during dead key
or leader key processing.
```lua
return {
colors = {
dead_key_cursor = "orange",
},
}
```
refs: #686
refs: #688
on macos only (for now), we generate a RawKeyEvent prior to
dead key or IME composition and route it to the window to give it
a chance to handle the event.
RawKeyEvent handling is scoped only to key assignments, not generating
input for the terminal.
A raw key event can be marked as handled to prevent moving on to
performing composition and generating cooked key input.
refs: https://github.com/wez/wezterm/issues/877
```lua
local wezterm = require 'wezterm'
return {
debug_key_events = true,
keys = {
{key="phys:Q", action=wezterm.action{SendString="woot"}},
},
}
```
The above will send "woot" to the pane whenever the key in same
physical position as Q on an ANSI standard US keyboard is pressed.
refs: https://github.com/wez/wezterm/issues/1483
This comes from a time where our quads were always locked to grid
positions. We don't need it any more: we can simply add the adjustments
to the quad positions that we set.
Removing it makes the vertex a bit smaller and reduces the amount
of GPU accessible memory we need to use.
I'm running down a weird thing where the main font renders weirdly
when the title font is 12 pt vs the main font 10 pt.
I thought there might have been a cache invalidation issue and
realized that we could have an A-B-A style issue with the font_ptr
stuff, so I replaced it with an incrementing id.
That didn't fix the thing I was looking at, but does feel a bit
nicer overall.
The default we use on macOS looks decent. Roboto is a similar
looking font that we can use for the other platforms.
I may make it the same on all three once I've had a chance
to compare it on a mac.