This ensures we _always_ commit a **new** buffer in response to a
configured event.
This fixes an issue in Gnome where e.g. tiling the window (on the
left/right side) only worked if that caused the windows size to
change.
The way things works right now, we cannot enable the ptmx FDM callback
right away. We need to wait for the Wayland window to have been
configured.
Before the window is configured, we don't have a size, and no
grid. Thus, if we try to process ptmx data we'll crash since we have
no where to write it to.
So, registering the ptmx fd with the FDM is now delayed until we've
received the first 'configure' event from Wayland.
That is, deal with monitors being unplugged.
At least on Sway 1.4, surfaces are not unmapped before the output is
removed. Thus, in addition to free:ing the monitor resources, we also
need to update all terminals that are mapped on this output - remove
the output from their "mapped on" list.
They aren't really user configurable. At least not yet.
However, with this, we now handle raw key codes just like the normal
key bindings. Meaning, e.g. ctrl+g, ctrl+a, ctrl+e etc now works while
searching with e.g. a russian layout.
Before, when looking for a matching user key binding, we only
matched *symbols*.
This means that the physical keys that generate a specific key binding
is layout dependent. What's worse, it may not even be possible to
generate the key binding at all.
Russian is one such layout, where all the "normal" (us) symbols are
replaced.
By using raw key codes, we can get around this - the key code has a
direct mapping to the physical key.
However, matching raw key codes **only** doesn't always make sense
either. For now, match **both** symbols _and_ key codes. Symbols take
precedence.
TODO: we might have to make this configurable _per binding_.
Note: 'search' mode still uses mostly hardcoded shortcuts that still
have this problem (i.e. ctrl+g doesn't work with a russian layout).
This way we:
* Don't have to call wl_display_get_fd() all the time
* No longer call fdm_del_no_close() even though the FD hasn't been
added to the FDM.
This fixes an issue where the fonts were rendered too small when the
output had fractional scaling.
For integral scaling, using the logical (scaled) DPI multiplied with
the scaling factor results in the same final DPI value as if we had
used the physical DPI.
But for fractional scaling, this works around the fact that the
compositor downscales the surface after we've rendered it.
Closes#5
New actions defined and implemented:
* scrollback up/down
* font size up/down/reset
* spawn terminal
Break out key combo parsing to a new function,
parse_key_binding_for_action(). This function parses a string
containing one or more space separated key combo definitions on the
form (mod1+mod2+...+key), where key is a XKB key name (e.g. KP_Add).
Convert all hardcoded key bindings to configuration based
bindings. These still cannot actually be configured by the user, but
at least lives in the conf struct.
This adds initial support for defining key and mouse bindings that are
applied in different terminal modes/states.
For example, there are two arrays dealing with key and mouse bindings
in the "normal" mode. Most bindings will go here.
There's also an array for "search" mode. These bindings will be used
when the user has started a scrollback search.
In the future, there may be a model selection mode as well. Or maybe
"search" and "modal selection" will be combined into a single
"keyboard" mode. We'll see.
Since the keyboard bindings depend on the current XKB keymap,
translation from the user specified key combination string cannot be
done when loading the configuration, but must be done when we've
received a keymap from the wayland server.
We should explore if it's possible to load some kind of default keymap
just to be able to verify the validity of the key combination strings
at configuration load time, to be able to reject the configuration at
startup.
A couple of key bindings have been added as proof of concept.
Mouse bindings aren't handled at all yet, and is likely to be
re-written. For example, we can probably translate the configuration
strings at configuration load time.
But it *does* include the title bar. This simplifies the 'adjustment'
needed to be done to the configured window size.
It also fixes a number of issues:
* the compositor will now properly snap the window to screen
edges (before, there was an empty space between the edge and the
window - the CSD border).
* This also removes the need for the mutter 'commit' workaround. We
must be doing something right now.
When the seat capabilities change, we used to destroy all pointers and
keyboards, and then re-creating them as necessary.
This caused a crash on mutter - probably because we removed a keyboard
device the compositor had already sent an event for (or was about to).
Now, we only destroy and create devices when it's needed.
The user can now configure the following:
* Whether to prefer CSDs or SSDs. But note that this is only a hint to
the compositor - it may deny our request. Furthermore, not all
compositors implement the decoration manager protocol, meaning CSDs
will be used regardless of the user configuration (GNOME/mutter
being the most prominent one).
* Title bar size and color, including transparency
* Border size and color, including transparency
Also drop support for rendering the CSDs inside the main surface.
Normally, we resize and update the font's DPI whenever our window
enters or leaves an output.
This is since a change in the outputs we're mapped on means the scale
factor to use, or the DPI to use for the fonts may have changed.
However, a special case is when we're removed from the last
output. This should only happen at shutdown, when we're un-mapping
ourselves.
In this case, we typically don't have a access to e.g. the PTMX
fd (often, the reason we're shutting down is because the client
exited). This resulted in (harmless) error messages when emitting the
TIOCSWINSZ event.
Since we're shutting down anyway, we can simply skip the resize and
everything. This gets rid of the error message, and also means we're
shutting down faster.
When resizing the window under mutter, mutter seems to expect a
configure ack *and* a surface commit *right* away, or things get out
of sync.
Unlike kwin, which is requires a commit for each configure ack, but is
fine with having the commit arrive later (after we've rendered it),
mutter is not.
I even tried delaying the configure ack until just before the commit,
but still no go.
So for now, detect when we're running under mutter and always do a
surface commit right away.
This can *not* be done on any other compositor as it breaks the CSD
and main surface synchronization; we've resized the CSDs, but not the
main surface.
I.e. this *should* not work, but for some reason is the *only* way to
make things work on mutter.
Interestingly, doing it any other way on mutter causes visual
glitches; window jumping around when resizing, or de-synchronized
CSDs/main surface.
When we position CSDs inside the main surface, and CSDs are switched
on run-time, we need to force a grid resize, since the actual window
content will now be smaller.
Alternative solution: call resize with width/height increased, to
account for the CSDs. This would increase the window size, but would
keep the grid size fixed.
The size (width, height) arguments provided by the compositor in the
XDG toplevel configure event *include* the surrounding CSDs.
Since our code assumes the size is for the main surface only (and then
positions the sub-surfaces *outside* the main surface), adjust the
provided size when using CSDs.
This ensures our actual window size ends up being what the compositor
wants it to be, and it fixes resize-glitches when resizing using CSDs.
While most compositors handle instantiated but not-yet-mapped
sub-surfaces correctly, e.g. kwin does not.
For example, it will incorrectly offset the main surface both
horizontally and vertically with a couple of pixels, leaving two
transparent areas at the top and left, between the SSDs and the main
surface.
Note that a workaround is to position the sub-surfaces inside the main
surface while they're unmapped. However, since the surfaces may be
larger than the main surface (the CSDs, for examples, always are),
this doesn't quite work since kwin, at least, resizes the window to
include the sub-surfaces, even when unmapped.
So, instead we instantiate all sub-surfaces on demand, when we know
where to position them, and when they should be mapped.
For now, this behavior is controlled with an ifdef. At least kwin
seems very buggy when the decorations are positioned like this (but
normally you'd use server-side decorations with kwin anyway).
This commit also changes 'use_csd' to be a tri-state variable;
when instantiating a window it is set to 'unknown'.
If there's no decoration manager available (e.g. weston), we
immediately set it to 'yes' (use CSDs).
Otherwise, we wait for the decoration manager callback to indicate
whether we should use CSDs or not.