Instead of having each search function print its various test decisions,
print the full state at the end of every search. This makes it much
clearer what state a particular test includes.
The original sway output config implementation enabled one output at a
time, testing modes, render formats and VRR support as it went along.
While this sort of fallback is easy to do, it has the downside of not
considering the effect of neighbor outputs on the configuration
viability.
With backend-wide commits, we can now better consider the effect of
neighbor outputs, but to handle the fact that we commit all outputs at
once we need to perform a more elaborate search of viable
configurations.
Implement a recursive configuration search for when the primary
configuration failed to apply.
When storing a config, we need to find the output that is being
configured to extract its identifier. output_by_name_or_id does not
return outputs that are disabled, and using this makes it impossible to
merge configurations related to disabled outputs.
Switch to all_outputs_by_name_or_id.
Fixes: https://github.com/swaywm/sway/issues/8141
We want to check if a config_head existed for the current
matched_output_config, so we should check cfg->output. sway_output is a
temporary variable from a previous wl_list_for_each, and does not
contain anything useful to us.
Fixes: https://github.com/swaywm/sway/issues/8128
If there is no output currently connected, we still want to merge
to any existing config.
It shouldn't matter to iterate over the list of outputs to do
nothing anwyays.
../sway/config/output.c:33:21: runtime error: member access within null pointer of type 'struct sway_output'
AddressSanitizer:DEADLYSIGNAL
=================================================================
==7856==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000080 (pc 0x63da8558205c bp 0x7ffdc35881a0 sp 0x7ffdc3588160 T0)
==7856==The signal is caused by a READ memory access.
==7856==Hint: address points to the zero page.
#0 0x63da8558205c in output_get_identifier ../sway/config/output.c:33
#1 0x63da855865c3 in store_output_config ../sway/config/output.c:220
#2 0x63da855d4066 in cmd_output ../sway/commands/output.c:106
#3 0x63da8547f2e3 in config_command ../sway/commands.c:425
#4 0x63da8548f3fc in read_config ../sway/config.c:822
#5 0x63da8548a224 in load_config ../sway/config.c:435
#6 0x63da8548b065 in load_main_config ../sway/config.c:507
#7 0x63da854bee8d in main ../sway/main.c:351
#8 0x77e2ea643ccf (/usr/lib/libc.so.6+0x25ccf) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
#9 0x77e2ea643d89 in __libc_start_main (/usr/lib/libc.so.6+0x25d89) (BuildId: c0caa0b7709d3369ee575fcd7d7d0b0fc48733af)
#10 0x63da8547ad64 in _start (/home/simon/src/sway/build/sway/sway+0x372d64) (BuildId: 3fa2e8838c1c32713b40aec6b1e84bbe4db5bde8)
Fixes: 1267e47de9 ("config/output: Refactor handling of tiered configs")
Output configuration can be applied to a particular output in three
ways: As a wildcard, by connector name and by identifier. This in turn
means that three different configurations must be handled at any given
time.
In the current model, this is managed by merging new configuration into
every other matching configuration. At the same time, an additional
synthetic configuration is made which matchehes both identifier and name
at the same time, further complicating logic.
Instead, manage and store each configuration independently and merge
them in order when retrieving configuration for an output. When changes
are made to a less specific configuration, clear these fields from more
specific configurations to allow the change to take effect regardless of
precedence.
Fixes: https://github.com/swaywm/sway/issues/8048
Without this change, i see the following in the sway-ipc manpage:
```
9. GET_CONFIG
MESSAGE
Retrieve the contents of the config that was last loaded
REPLY
An object with a single string property containing the contents of the
config
Example Reply:
{
"config": "set $mod Mod4nbindsym $mod+q exitn"
}
```
apply_output_config_to_outputs uses the specified output config to check
which outputs to apply to, and to use as backup when no config is found.
If any config matches the output, the specified config will be
disregarded.
The only remaining user of apply_output_config_to_outputs is
reset_outputs, which called apply_output_config_to_outputs with either
the first stored wildcard config, or a new empty wildcard config.
Providing a stored or empty wildcard config is practically the same as
calling `apply_all_output_configs`. Replace uses of `reset_outputs` with
`apply_all_output_configs` and remove the now unused functions.
Introduce apply_output_configs, which applies the specified matched
output configs as a single backend commit.
Reimplement apply_output_config_to_outputs using apply_output_configs.
Applying an output config has two stages: Atomic application of
wlr_output_state, and applicaiton of non-atomic state like output
layout.
Split the latter out into finalize_output_config for use in a later
commit.
If we can't create the XKB keymap used for keysym translation,
gracefully error out instead of crashing. This can happen if the
XKB_DEFAULT_LAYOUT is set to an invalid value, for instance.
Closes: https://github.com/swaywm/sway/issues/7789
My code archaeology isn't good enough to determine what this is here
for, but it isn't correct. We should be able to move containers in a
direction without focusing them. AFAICT i3 doesn't do this, so we
shouldn't either.
This fixes ipc commands like move <dir> with criteria that apply to
containers which are not the current focus.
i3 has had this property for over a decade but it wasn't documented
until a couple of years ago, so it was likely missed when developing
sway. Add the property to get us closer to ipc parity with i3.
Check if the app that requested a token has provided a valid input
serial and a focused surface. Downgrade activation request to urgency
otherwise.
This is mostly in line with what other Wayland compositors decided to
do, and offers a better security than the original logic.
We tried to synchronize layer shell popups with the parent layer shell
on commits, but this is subtly wrong because we would only update
the position for one layer shell that was committed, but not any other
layer that might be affected. By moving handling to the scene descriptor
we can iterate all popups and ensure they are synchronized.
This doesn't catch the error if a background changing command is
executed via swaymsg, but improves logging.
The additional checks at least propagate if e.g. forking failed.
```
Program terminated with signal SIGSEGV, Segmentation fault.
144 struct wlr_layer_surface_v1 *layer_surface = surface->layer_surface;
[Current thread is 1 (Thread 0x7f1f7c5b3ac0 (LWP 2473))]
(gdb) bt
```
Add a NULL check in `find_mapped_layer_by_client` like the one in `arrange_surface`.
7e69a7076f ("Drop wl_drm") has dropped wl_drm, however a lot of
software wasn't quite ready for this (Xwayland, libva, amdvlk).
Keep wl_drm disabled by default to pressure the wl_drm phase-out,
but add a -Dlegacy-wl-drm flag for users to restore the previous
behavior in the meantime.
References: https://github.com/swaywm/sway/issues/7897
```
Program terminated with signal SIGSEGV, Segmentation fault.
warning: Section `.reg-xstate/3960717' in core file too small.
0 container_get_siblings (container=0x55bcde4797f0) at ../sway/tree/container.c:1228
1228 if (list_find(container->pending.workspace->tiling, container) != -1) {
[Current thread is 1 (Thread 0x7fa23b4a2940 (LWP 3960717))]
(gdb) bt full=
No symbol "full" in current context.
(gdb) bt full
0 container_get_siblings (container=0x55bcde4797f0) at ../sway/tree/container.c:1228
1 0x000055bcdb62c704 in edge_is_external (cont=0x55bcde4797f0, edge=(WLR_EDGE_TOP | WLR_EDGE_LEFT))
at ../sway/input/seatop_default.c:54
siblings = 0x55bcde4797f0
index = 32766
layout = L_NONE
__PRETTY_FUNCTION__ = "edge_is_external"
2 0x000055bcdb62c96f in find_resize_edge (cont=0x55bcde4797f0, surface=0x0, cursor=0x55bcddd5c2e0)
at ../sway/input/seatop_default.c:106
edge = (WLR_EDGE_TOP | WLR_EDGE_LEFT)
3 0x000055bcdb620b3c in cursor_update_image (cursor=0x55bcddd5c2e0, node=0x55bcde4797f0) at ../sway/input/cursor.c:144
edge = WLR_EDGE_NONE
4 0x000055bcdb62eb8f in handle_rebase (seat=0x55bcddd5a740, time_msec=488992944) at ../sway/input/seatop_default.c:773
e = 0x55bcddd5c8e0
cursor = 0x55bcddd5c2e0
surface = 0x0
sx = 0
sy = 0
5 0x000055bcdb62c531 in seatop_rebase (seat=0x55bcddd5a740, time_msec=488992944) at ../sway/input/seat.c:1585
6 0x000055bcdb620a7d in cursor_rebase (cursor=0x55bcddd5c2e0) at ../sway/input/cursor.c:126
time_msec = 488992944
7 0x000055bcdb620ac4 in cursor_rebase_all () at ../sway/input/cursor.c:136
seat = 0x55bcddd5a740
8 0x000055bcdb61cc95 in transaction_apply (transaction=0x55bcde5b28c0) at ../sway/desktop/transaction.c:704
9 0x000055bcdb61ccdb in transaction_progress () at ../sway/desktop/transaction.c:716
10 0x000055bcdb61d1f9 in transaction_commit_pending () at ../sway/desktop/transaction.c:836
transaction = 0x55bcde5b28c0
11 0x000055bcdb61d596 in _transaction_commit_dirty (server_request=true) at ../sway/desktop/transaction.c:912
12 0x000055bcdb61d5ac in transaction_commit_dirty () at ../sway/desktop/transaction.c:916
13 0x000055bcdb65f579 in view_unmap (view=0x55bcde2ff180) at ../sway/tree/view.c:847
parent = 0x55bcde489010
ws = 0x55bcdde19080
seat = 0x55bcddd5a198
14 0x000055bcdb61e461 in handle_unmap (listener=0x55bcde2ff368, data=0x0) at ../sway/desktop/xdg_shell.c:394
xdg_shell_view = 0x55bcde2ff180
view = 0x55bcde2ff180
__PRETTY_FUNCTION__ = "handle_unmap"
15 0x00007fa23c4ae87f in wlr_signal_emit_safe (signal=0x55bcde46cf38, data=0x0) at ../util/signal.c:29
pos = 0x55bcde2ff368
l = 0x55bcde2ff368
cursor = {link = {prev = 0x55bcde2ff368, next = 0x7ffe240702a0}, notify = 0x7fa23c4ae7c9 <handle_noop>}
end = {link = {prev = 0x7ffe24070280, next = 0x55bcde46cf38}, notify = 0x7fa23c4ae7c9 <handle_noop>}
16 0x00007fa23c47c3c7 in unmap_xdg_surface (surface=0x55bcde46ce30) at ../types/xdg_shell/wlr_xdg_surface.c:40
__PRETTY_FUNCTION__ = "unmap_xdg_surface"
popup = 0x55bcde46ce60
popup_tmp = 0x55bcde46ce60
configure = 0x7ffe24070360
tmp = 0x55bcde488020
17 0x00007fa23c47cd47 in xdg_surface_role_precommit (wlr_surface=0x55bcde488020, state=0x55bcde4881a8)
at ../types/xdg_shell/wlr_xdg_surface.c:330
surface = 0x55bcde46ce30
18 0x00007fa23c4813b2 in surface_commit_state (surface=0x55bcde488020, next=0x55bcde4881a8) at ../types/wlr_compositor.c:407
__PRETTY_FUNCTION__ = "surface_commit_state"
invalid_buffer = false
subsurface = 0xbd8e9aecae023300
--Type <RET> for more, q to quit, c to continue without paging--
19 0x00007fa23c48192a in surface_handle_commit (client=0x55bcde488850, resource=0x55bcde2fdb80) at ../types/wlr_compositor.c:523
surface = 0x55bcde488020
20 0x00007fa23bb5ed4a in () at /usr/lib/libffi.so.8
21 0x00007fa23bb5e267 in () at /usr/lib/libffi.so.8
22 0x00007fa23c517323 in () at /usr/lib/libwayland-server.so.0
23 0x00007fa23c5125cc in () at /usr/lib/libwayland-server.so.0
24 0x00007fa23c5151ca in wl_event_loop_dispatch () at /usr/lib/libwayland-server.so.0
25 0x00007fa23c512d37 in wl_display_run () at /usr/lib/libwayland-server.so.0
26 0x000055bcdb616885 in server_run (server=0x55bcdb68c5c0 <server>) at ../sway/server.c:307
27 0x000055bcdb61594e in main (argc=3, argv=0x7ffe24070af8) at ../sway/main.c:433
```
It seems to be happening because of this set of events all happening
in the span of a single transaction:
1. You kill a tiled window that is the only window in a workplace.
2. Sway will destroy the workspace but not yet the container - this
makes `con->pending.workspace` NULL.
3. Cursor glyphs get recomputed causing sway to recompute if the cursor
is on a container edge.
4. That computation causes an access to the NULL workspace. Crash.
Instead of doing this roundabout thing where we get the surface from the
view, let's instead get it from the `wlr_surface_state` that we already
track in `handle_commit`. This makes the NULL state impossible which is
what the old `get_geometry` is checking for and generally cleans
things up a little bit.
Also don't check if the geometry x/y changed, those will always
be 0 for xwayland.
Across a wayland compositor, there are multiple shells: It can be
a toplevel, or a layer_shell, or even something more meta like a drag
icon or highlight indicators when dragging windows around.
This object lets us store values that represent these modes of operation
and keep track of what object is being represented.
Since output layout is destroyed when the wayland display is destroyed
we run into a destroy listener order problem: Either the display starts
destroying the outputs first, in which case we're good: The existing
handling will clean up. However, things go wrong if the display decides
to destroy the output layout first. In this case, sway will hold
invalid references to the output layout as part of each output so that
when it finally goes to destroy them, sway will dereference destroyed
output layout bits.
Ref: https://github.com/swaywm/sway/pull/6844#issuecomment-1843599513
`gcc-14` added a new warning around dangerous use of `strncpy()` withi
known overflow:
../sway/config.c: In function 'do_var_replacement':
../sway/config.c:983:33: error: '__builtin___strncpy_chk' specified bound depends on the length of the source argument [-Werror=stringop-truncation]
983 | strncpy(newptr, var->value, vvlen);
| ^
../sway/config.c:971:45: note: length computed here
971 | int vvlen = strlen(var->value);
| ^~~~~~~~~~~~~~~~~~
It's a bit fishy to rely on truncating behaviour of `strncpy()`. The
change uses `memcpy()` as more explicit way to express copy of `vvlen`
bytes.
Remove any existing executed criteria items at unmap time. If a window
gets unmapped but not destroyed, we want to reapply 'for_window'
criteria. Fixes#6905.
This reverts commit afde6369
"seat: avoid unneeded reloading xcursor theme".
Always avoiding to reload the xcursor theme prevents reloading the
cursor even when this is desired. Instead seat_configure_xcursor
can determine whether a full reload is necessary.
To stay with the spirit of the reverted change, cursors are only fully
reloaded, if the theme has changed.
Fixes#6931
3d5ae9813d added logic to change the
underlying wlr_toplevel size for floating containers, but it does it
even if the container has no actual coordinates yet. This doesn't really
make sense to update the toplevel size in this case since there's many
things that could affect the initial coordinates (sway commands,
fullscreen state, etc.). Skip this by doing a crude check to see if the
current container state has any width.
Previous behavior was that only if resolution and refresh rate match
exactly, the mode was accepted. As fallback, the mode with the highest
refresh rate and the same resolution was chosen.
New behavior is that the mode with the closest match for the refresh
rate is used with a limit of up to 1Hz. The fallback behavior stays the same.
Additionally, the logging was made more verbose.
When using the `map_from_region` for pen tables, we will usually make
the available area as big as possible while maintaining the proportions
with the screen.
As most of the tablets uses a 16:10 ratios while the most popular screen
ratios is still 16:9, the argument for most people should be `0x0 1x0.9`
to have the maximum effective area.
However, the argument above won't work because the current code will
treat `0x...` as a hexadecimal number, instead of setting both `x` and
`y` to `0`.
This fix allows the use of the following syntax:
```
input type:tablet_tool {
map_from_region 0x0 1x0.9
}
```
If a floating client resizes itself, sway updates several of its
internal dimensions to match but not wlr_toplevel. This means that the
next time wlroots sends a toplevel configure event, it can have wrong
coordinates that resize the client back to its old size. To fix this,
let's just use wlr_xdg_toplevel_set_size so the wlr_toplevel has the
same dimensions as sway.
Exactly the same as 0183b9d35d0ce750588e700e536b7d2e367b0d0a but the
logic is onlly applied to xdg_shell and not xwayland.
This isn't the right fix for this issue because the xwayland code also
uses this function and updating the wlr_toplevel there doesn't make
sense and also causes problems. Fixes#7722.
This reverts commit bf44690ee8.
If a floating client resizes itself, sway updates several of its
internal dimensions to match but not wlr_toplevel. This means that the
next time wlroots sends a toplevel configure event, it can have wrong
coordinates that resize the client back to its old size. To fix this,
let's just use wlr_xdg_toplevel_set_size so the wlr_toplevel has the
same dimensions as sway. Fixes#5266.
Regular clients are not allowed to use this interface. wlroots
already sends a protocol error if a non-Xwayland client tries to
use this interface, but let's remove all temptation by hiding it
completely.