1
1
mirror of https://github.com/wez/wezterm.git synced 2024-12-24 22:01:47 +03:00
Commit Graph

343 Commits

Author SHA1 Message Date
Wez Furlong
c72af9547a window: record raw key code in KeyEvent on Windows 2020-12-09 22:19:54 -08:00
Wez Furlong
c6334a45dd extract window::input to wezterm-input-types 2020-12-09 13:48:23 -08:00
Wez Furlong
92827a1bea wezterm: default dpi on macOS is now 72
https://wiki.lazarus.freepascal.org/Cocoa_DPI states that the dpi
on macOS is 72.  That matches up to the experimental results reported
in #332 (in which 74.0 appears about the right size).

This commit introduces a `DEFAULT_DPI` constant that is set to 72 on
macOS and 96 on other operating systems.

The result of this is that a 10 point Menlo font now appears to be
the same size in Terminal.app and WezTerm.app.

refs: https://github.com/wez/wezterm/issues/332
2020-12-06 18:34:06 -08:00
Wez Furlong
b2be2963a1 wezterm: fixup input processing for Option/dead keys
This commit improves input processing on macOS; passing the keyUp
events to the input context is required for dead keys to correct
process their state transitions.

In addition, we weren't passing key events through if any modifiers
were down; for dead keys we need to allow Option through.

This commit rigs up a little bit of extra state to avoid double-emitting
key outputs from the input context.

Lastly, the virtual key code is passed through to the KeyEvent to
enable binding to raw keys per 61c52af491

refs: #357
2020-12-06 17:49:26 -08:00
Wez Furlong
61c52af491 wezterm: add raw_code concept to input layer
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
2020-12-06 13:41:29 -08:00
Wez Furlong
4e7f3cc75a window: add optional KeyCode::raw_code field
This allows stashing the raw key identifier from the keyboard layer.
Interpreting this value is hardware and OS dependent.

At this time, only X11/Wayland implementations populate this value,
and there is no way to do key assignment based upon it.
2020-12-06 13:41:29 -08:00
Wez Furlong
d6a9ed5ae7 window: x11: remove a little redundant code from key processing 2020-12-06 13:41:29 -08:00
Wez Furlong
9bebc811d0 window: fix build when opengl is not enabled 2020-11-22 09:24:07 -08:00
Wez Furlong
fba2159839 deps: remove unused deps
Not all of these are needed in these crates (copypasta resulting
from splitting out modules)
2020-11-20 12:37:38 -08:00
Wez Furlong
fd3c062daf cargo fmt
latest rust changed the formatting options, so reformat to
avoid the CI being unhappy.
2020-11-20 09:06:21 -08:00
Wez Furlong
18e010f1df deps: normalize the lazy-static version 2020-11-13 08:15:35 -08:00
Jeremy Fitzhardinge
e95c7ad855 Fix compiler warning by moving x86-64 specific variable into the guard 2020-11-11 20:31:18 -08:00
Wez Furlong
5b8b41adbb window: macos: fix mouse cursor for dragging splits 2020-11-06 15:02:38 -08:00
Wez Furlong
403d002d0a window: fix potential crash with multiple egl windows on windows
I didn't actually see this crash, but the same potential problem
was present, so adjust the code as per 9712d4d03c

refs: #316
2020-11-01 10:28:17 -08:00
Wez Furlong
9712d4d03c window: fix crash with multiple egl windows on macos
This is basically the same issue as
70fc76a040 but on macOS.   Now that we're
using EGL in more places, the same sort of check needs to used in more
places!

Will need to do the same on Windows in a follow-up commit.

refs: #316
2020-11-01 10:18:40 -08:00
Wez Furlong
92bdc4a3b0 Revert "window: alternative shadow/ghost/macos fix"
This reverts commit f2b504ee1f9a607fe8965e96b659bca282147672;
we prefer the overall snappier perf from not having a shadow.

refs: #310
2020-10-28 17:55:15 -07:00
Wez Furlong
f2b504ee1f window: alternative shadow/ghost/macos fix
This one invalidates the shadow when we invalidate the window,
so we should get to keep the shadow and lose the ghosts.

refs: #310
2020-10-28 16:08:33 -07:00
Wez Furlong
e3100c937f window: maybe fix ghostly artifacts on macos
Not 100% sure that this is it, but it seems much less likely that
artifacts will appear in conjunction with transparency when the window
shadow effect is disabled; I didn't see the ghosting with this disabled,
but I sometimes dididn't see it with it enabled, so I'm not sure that we
have a 100% reliable reproduction, and thus am not sure that this is a
fix.

I found mention of disabling the shadow in some example code on
stackoverflow when I was first researching this, but it wasn't supplied
with an explanation. Perhaps this is why?

Longer term we might want to be smarter about turning off the shadow
only when the opacity is != 1.0, but at the moment the window layer
can't see the config, so let's just default it off for the moment
until we see if it does the trick.

refs: #310
2020-10-28 14:08:04 -07:00
Wez Furlong
284a4ebfbb window: fix mouse wheel reporting on Windows
Wheel events wouldn't get reported to eg: vim in wsl if the
window's X position was larger than the window width due to
mouse wheel messages being reported with screen coordinates
rather than client coordinates.

This commit addresses that.
2020-10-24 21:41:11 -07:00
Wez Furlong
52908712c6 wezterm: add excess padding for image protocols
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
2020-10-24 12:46:49 -07:00
Wez Furlong
f4066747d2 wezterm: improve texture atlas allocation
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
2020-10-23 13:57:58 -07:00
Wez Furlong
627d21cbac cargo fmt 2020-10-23 09:07:11 -07:00
Wez Furlong
e2311aaa73 window: more fun with dead keys on Windows
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
2020-10-23 08:47:11 -07:00
Wez Furlong
f12df0be9b window: add cursors for resizing up/down left/right
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.
2020-10-22 09:23:05 -07:00
Wez Furlong
aa660d5d06 wezterm: apply transparency tint to all background colors
refs: https://github.com/wez/wezterm/issues/141#issuecomment-711442986
2020-10-18 21:51:12 -07:00
Wez Furlong
191b047126 macos: implement opacity for CGL and Metal
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
2020-10-18 14:00:06 -07:00
Wez Furlong
2364b0a20e Windows: enable window_background_opacity
This causes DWM to respect the alpha channel we set during rendering,
allowing the window opacity to be respected on Windows.

refs: #141
2020-10-18 11:13:34 -07:00
Wez Furlong
cac02b3bbb Windows: fix enabling dark mode
This got broken by a recentish windows update.
2020-10-17 19:48:43 -07:00
Wez Furlong
b7e303f39c Windows: prefer to use Direct3D11 via ANGLE
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
2020-10-17 19:08:16 -07:00
Wez Furlong
f6afec27f5 windows: lowercase the raw key
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.
2020-10-17 14:02:06 -07:00
Wez Furlong
6c5a996423 windows: set KeyEvent::raw_key in key processing
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.
2020-10-17 10:25:55 -07:00
Wez Furlong
4d71a7913a macOS: bundle and use MetalANGLE to enable Metal rendering
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
2020-10-17 09:34:01 -07:00
Wez Furlong
13cd24d9b5 Windows: improve ALT + dead key handling, part 2
This changes the ALT/dead key behavior a little bit more,
and in a way that is likely more useful to terminal users.

The default behavior is that system dead key processing is enabled.
For example, with DEU keyboard layout activated:

* `^` `<SPACE>` results in a single `^`
* `^` `e` result in those two characters combining into an e with a
  diacritic.

If the config sets `use_dead_keys = false` then the behavior changes;
wezterm probes the active keymap to determine which keys are marked
as dead keys and computes their single character expansion.  When
the dead key is pressed then that expansion is substituted instead.
So `^` is simply `^`.

In order to pull this off, the window layer needs to selectively
call `TranslateMessage` for the system dead key expansion case
instead of unconditionally in the global message loop.

As a result of *that*, it means that we don't perform the default ALT
key translation for every key press any more.  I looked to see how old
friend putty handles this and found that it only allows default system
processing for ALT-space and ALT-F4.  I was resistent to selectively
processing system shortcuts because the full set are effectively
unknowable to an application and I didn't want to try to replicate
a wide selection of varying keypresses.  I'm fine to only allow
these two, so this commit does that, and reverts the portion of
the prior commit that prevented passing general ALT key combinations
through.

refs: #275
refs: #296
2020-10-15 17:06:09 -07:00
Wez Furlong
5088c62954 Windows: improve ALT and dead key handling
For some definition of improve, at least.

On Windows, ALT is basically reserved by the Window management
layer for functions such as ALT-space, ALT-F4 and so on.
Windows doesn't provide a method by which an application can
test whether a given key would be processed by the default
window procedure so we're in a bit of a bind in terms of
allowing ALT+a keypress to do something meaningful in the
terminal.

What I've settled on for now is:

On Windows only, if ALT is pressed, allow matching key assignments that
include ALT to be matched.  If there are no key assignments, then DON'T
pass the key press to the active pane, and instead allow it to be passed
to DefWindowProc.  This allows ALT-space to be handled correctly,
provided the user hasn't defined an ALT-space key assignment of their
own.

This may have some unforeseen consequences.  For example, ALT-<number>
is a readline binding that repeats an argument a number of times.
This change "breaks" that, but the user can provide a key assignment
to `SendString` the equivalent sequence to restore that behavior.
I'm kindof hoping that no one notices, but I'm prepared to explicitly
add default key assignments for that.

The other aspect of this commit is that I now understand a bit better
what a dead key is and how they should be handled.  I've tested the
behavior of wezterm with these changes and the behavior is consistent
with a regular CMD window when I have the DEU keymap active.
Specifically, using the on-screen keyboard, if I click `^` then click
`e` wezterm will emit `ê`.  If I click `^` then `^` then wezterm emits
`^^`.

refs: #275
refs: #296
2020-10-14 20:02:23 -07:00
Wez Furlong
5f0c859caa windows: fix an issue processing ctrl+shift for non-alpha keys
This appears to be an unexpected consequence of 6708ea4b36
but thankfully that change allows de-coupling shift processing
from the ctrl processing in this block of code.

refs: #275
2020-10-14 18:12:03 -07:00
Wez Furlong
9e46ac83be Windows: force Mesa/Software mode when started in an RDP session
refs: #265
2020-10-14 09:21:30 -07:00
Wez Furlong
05b02e178b window: fix Hide action on Windows
This was hiding the window completely with no way to show it again(!).
Change it instead to minimize, which was the intent.

refs: #296
2020-10-14 08:42:55 -07:00
Wez Furlong
8fcad1c1ee egl: improve trace logging of successful choice
refs: #272
2020-10-13 19:45:43 -07:00
Wez Furlong
baebc81432 egl: try all configs one by one in case first choice fails
It's not clear why the first choice isn't always the right choice
for some users.

This commit changes the logic to try all potential configs,
one after the other, until we find one that sticks.

I don't know if this will work in practice: I suspect that
trying to configure one of them may prevent later configs from
being used.

But maybe it will, and it may reveal more information about
what the real cause of the problem is.

refs: #272
2020-10-13 19:22:37 -07:00
Wez Furlong
0a39328e9d macos: adjust trackpad scroll sensitivity
This is imperfect in that it may feel slightly off for very large
or very small font sizes, but it feels more similar to the scroll
speed in eg: iTerm2 with these changes.

refs: #206
2020-10-12 19:24:23 -07:00
Wez Furlong
ce44ec2e70 macos: improve positioning for new windows
We used to always create them in the center of the screen,
but now subsequently created windows are offset slightly.
2020-10-12 17:54:44 -07:00
Wez Furlong
c8d59dffb6 macos: fix an issue where new windows created cocoa tabs
To reproduce the problem, maximize wezterm, then press CMD-N.

This commit tells the window not to use cocoa native tabs and
instead really create a new window when we ask it to create
a new window.

closes: #254
2020-10-12 17:20:12 -07:00
Wez Furlong
da2bba866d window: macos: trigger resize event when screen resolution changes
The easiest repro for this is dragging a window between monitors.

refs: #161
2020-10-12 11:29:17 -07:00
Wez Furlong
5257e34e2c window: update to latest glium version 2020-10-11 17:07:47 -07:00
Wez Furlong
dedfc4513b wayland: clear modifiers when keyboard focus changes
refs: #222
2020-10-11 10:02:37 -07:00
Wez Furlong
807ed3ba1e wayland: fixup timing issue on startup
025732d00f introduced deferred
window creation; the creation would get scheduled into the
spawn queue and then get run again a few milliseconds later
on the main thread.

For reasons that I don't understand, returning to the scheduler
loop to flush or otherwise process messages causes a wayland
protocol error.

Adjusting the notify routine to dispatch immediately if we're
already on the mux thread seems to resolve this.

While looking at this, I cleaned up a destruction order issue
with the opengl state that was then causing a segfault on shutdown.

I also removed a bit of dead paint related code that doesn't
appear to be needed any more.

refs: #293
2020-10-10 16:09:04 -07:00
Wez Furlong
5fb1414b69 fix clipboard on x11
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.
2020-10-09 11:07:18 -07:00
Wez Furlong
f497391958 gah, cargo fmt 2020-10-05 11:57:27 -07:00
Wez Furlong
bf266a326d maybe fixup build for windows 2020-10-05 11:57:08 -07:00
Wez Furlong
5eb4d32004 upgrade misc deps, notably, async-task 2020-10-05 00:06:01 -07:00