Age | Commit message (Collapse) | Author |
|
|
|
Our layer shell implementation assigns every layer surface to an output
on creation. It tracks this output using the output field on the
underlying wlr_layer_surface_v1 structure. As such, much of the existing
code assumes that output is always non-NULL and omits NULL checks
accordingly.
However, there are currently two cases where we destroy a
sway_layer_surface and output is NULL. The first is when we can't find
an output to assign the surface to and destroy it immediately after
creation. The second is when we destroy a surface in response to its
output getting destroyed, as we set output to NULL in
handle_output_destroy() before we call wlr_layer_surface_v1_destroy(),
which is what calls the appropriate unmap and destroy callbacks.
The former case doesn't cause any problems, since we haven't even
allocated a sway_layer_surface at that point or registered any
callbacks. The latter case, however, currently triggers a crash (#6120)
if a popup is visible, since our popup_handle_unmap() implementation
can't handle a NULL output.
To fix this issue, keep output set until right before we free the
sway_layer_surface. All we need to do is remove some of the cleanup
logic from handle_output_destroy(), since as of commit c9060bcc12d0
("layer-shell: replace close() with destroy()") that same logic is
guaranteed to be happen later when wlroots calls handle_destroy() as
part of wlr_layer_surface_v1_destroy().
This lets us remove some NULL checks from other unmap/destroy callbacks,
which is nice. We also don't need to check that the wlr_output points to
a valid sway_output anymore, since we unset that pointer after disabling
the output as of commit a0bbe67076b8 ("Address emersions comments on
output re-enabling") Just to be safe, I've added assertions that the
wlr_output is non-NULL wherever we use it.
Fixes #6120.
|
|
This also fixes an invalid strlen invocation on uninitialized memory.
|
|
The existing code gives this error when compiled with GCC 12:
../sway/server.c: In function ‘server_init’:
../sway/server.c:217:75: error: ‘%d’ directive output may be truncated writing between 1 and 11 bytes into a region of size 8 [-Werror=format-truncation=]
217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i);
| ^~
../sway/server.c:217:66: note: directive argument in the range [-2147483647, 32]
217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i);
| ^~~~~~~~~~~~
../sway/server.c:217:17: note: ‘snprintf’ output between 10 and 20 bytes into a destination of size 16
217 | snprintf(name_candidate, sizeof(name_candidate), "wayland-%d", i);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Because i is never negative, this is a false positive, but it is easy to
change i to unsigned to silence the error.
|
|
This makes stack traces from gdb slightly easier to read.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Closes: https://github.com/swaywm/sway/issues/6838
|
|
Ref [1].
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/4792446ee8f50104bd207d9ccd8558a7e4eb4514
|
|
Fixes #6690.
|
|
Fix: #6861
Added seat_device_destroy function to seat_device_destroy function.
|
|
active_keyboard may be NULL, in which case an invalid pointer could be
passed to wlr_input_method_keyboard_grab_v2_send_modifiers. This
procedure call is unnecessary since wlroots commit 372a52ec "input
method: send modifiers in set_keyboard", so the call can simply be
removed.
Fixes #6836.
|
|
Currently, a floating window that's been fullscreened can send us
xdg_toplevel::move, and we'll enter seatop_move_floating, which lets us
drag the surface around while it's fullscreen. We don't want
this--fullscreen surfaces should always be aligned to the screen--so add
the same check that seatop_default already does when entering this mode.
Tested with Weston's weston-fullscreen demo, which sends a move request
if you click anywhere on its surface.
|
|
|
|
|
|
|
|
Replace them with snprintf, which ensures buffer overflows won't
happen.
|
|
|
|
Improved type safety.
|
|
Improved type safety.
Closes: https://github.com/swaywm/sway/issues/6813
|
|
Removed xwayland limitation since wayland clients are supported via xdg-activation.
|
|
|
|
https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3439
|
|
When REAPER submenu is closed `XCB_CLIENT_MESSAGE` with type
`NET_ACTIVE_WINDOW` is sent to set focus to parent menu.
Closes: https://github.com/swaywm/sway/issues/6324
|
|
|
|
This just follows swaywm/wlroots#3047, so `wl_pointer_gestures_v1`
clients can be notified of these events.
|
|
|
|
Commit 37d7bc69986f ("transaction: Only wait for ack from visible
views") introduced a check which uses view_is_visible() to check if a view
is still visible on the screen. However view_is_visible() will early
return in case the node is in the destroying state. This is incorrect
for transactions, since a destroying view which is visible will trigger
configure events for other clients. This bug was visible when repeatedly
opening and closing two views side by side, since we ignore the
destroying node we get a frame where the still open view is shown with
the old configure values and the rest is the desktop background. The
next frame is than correct again.
Fix this by considering destroying views as visible, we correctly wait
for them and send the configure events to other views in time, fixing
the background flicker.
Fixes #6473
|
|
|
|
Accidentally overlooked in fd53f80.
|
|
Fixes https://github.com/swaywm/sway/issues/6765.
|
|
|
|
See [1] for details.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3412
|
|
`popup_unconstrain` uses view coordinates to init the output box for
popups. However wlroots expects the box to be set in a toplevel surface
coordinate system, which is not always equal to view. The difference
between those is a window geometry set via xdg-shell.
GTK4 reserves some space for client-side decoration and thus has a
window with top left corner not matching to (0, 0) of a surface. The box
calculated without taking that into account was slightly shifted
compared to the actual output and allowed to position part of the popup
off screen.
|
|
SUID privilege drop is needed for the "builtin"-backend of libseat,
which copied our old "direct" backend behavior for the sake of
compatibility and ease of transition.
libseat now has a better alternative in the form of seatd-launch. It
uses the normal seatd daemon and libseat backend and takes care of SUID
for us.
Add a soft deprecation warning to highlight our future intent of
removing this code. The deprecation cycle is needed to avoid surprises
when sway no longer drops privileges.
|
|
Closes: https://github.com/swaywm/sway/issues/6337
|
|
Fixes #6737
|
|
Followup on 4e4898e90f.
If a view quickly maps and unmaps repeatedly, there will be multiple
destroyed containers with same view in a single transaction. Each of
these containers will then try to destroy this view, resulting in use
after free.
The container should only destroy the view if the view still belongs
to the container.
Simple reproducer: couple XMapWindow + XUnmapWindow in a loop followed
by XDestroyWindow.
See #6605
|
|
We currently track the focus of a seat in two ways: we use a list called
focus_stack to track the order in which nodes have been focused, with
the first node representing what's currently focused, and we use a
variable called has_focus to indicate whether anything has focus--i.e.
whether we should actually treat that first node as focused at any given
time.
In a number of places, we treat has_focus as implying that a focused
node exists. If it's true, we attempt to dereference the return value of
seat_get_focus(), our helper function for getting the first node in
focus_list, with no further checks. But this isn't quite correct with
the current implementation of seat_get_focus(): not only does it return
NULL when has_focus is false, it also returns NULL when focus_stack
contains no items.
In most cases, focus_stack never becomes empty and so this doesn't
matter at all. Since focus_stack stores a history of focused nodes, we
rarely remove nodes from it. The exception to this is when a node itself
goes away. In that case, we call seat_node_destroy() to remove it from
focus_stack and free it. But we don't unset has_focus if we've removed
the final node! This lets us get into a state where has_focus is true
but seat_get_focus() returns NULL, leading to a segfault when we try to
dereference it.
Fix the issue both by updating has_focus in seat_node_destroy() and by
adding an assertion in seat_get_focus() that ensures focus_stack and
has_focus are in sync, which will make it easier to track down similar
issues in the future.
Fixes #6395.
[1] There's some discussion in #1585 from when this was implemented
about whether has_focus is actually necessary; it's possible we could
remove it entirely, but for the moment this is the architecture we have.
|
|
Closes #6735
wlroots already has the info in the struct so let's access it and print it out.
|
|
cairo_image_surface_create can fail, e.g. when running out of
memory or when the size is too big. Avoid crashing in this case.
Closes: https://github.com/swaywm/sway/issues/6531
|
|
Now output_begin_destroy emits the node::destroy event similar to
workspace_begin_destroy. It currently has no listeners, since they
listen to output::disable or wlr_output::destroy instead.
|
|
This changes output::destroy to output::disable and emits it only
once when an output is disabled, instead of twice in succession.
|
|
This fixes: https://github.com/swaywm/sway/issues/5337
Co-authored-by: Moon Sungjoon <sumoon@seoulsaram.org>
|
|
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/1376
|
|
There seems to be a null pointer access that can happen. I was able to
reproduce this by running the cemu emulator[1] with the new collabora
wine wayland driver[2] and opening and closing some sub menus.
Adding a trival null check seems to do the trick to stop sway from
crashing and returning to tty and everything else works normally.
[1]: http://cemu.info/
[2]: https://www.winehq.org/pipermail/wine-devel/2021-December/203035.html
Stack trace from lldb:
* thread #1, name = 'sway', stop reason = signal SIGSEGV: invalid address (fault address: 0xf8)
frame #0: 0x00005555555c3fc3 sway`view_child_init(child=0x0000555555f67940, impl=0x00005555555ee030, view=0x00005555565bc590, surface=0x00005555565b6940) at view.c:1117:25
1114 wl_signal_add(&view->events.unmap, &child->view_unmap);
1115 child->view_unmap.notify = view_child_handle_view_unmap;
1116
-> 1117 struct sway_workspace *workspace = child->view->container->pending.workspace;
1118 if (workspace) {
1119 wlr_surface_send_enter(child->surface, workspace->output->wlr_output);
1120 }
(lldb) up
error: sway {0x000342ab}: DIE has DW_AT_ranges(DW_FORM_sec_offset 0x67) attribute, but range extraction failed (invalid range list offset 0x67), please file a bug and attach the file at the start of this error message
frame #1: 0x00005555555c39f8 sway`view_child_subsurface_create(child=0x00005555564a10d0, wlr_subsurface=0x0000555556586910) at view.c:985:2
982 }
983 subsurface->child.parent = child;
984 wl_list_insert(&child->children, &subsurface->child.link);
-> 985 view_child_init(&subsurface->child, &subsurface_impl, child->view,
986 wlr_subsurface->surface);
987
988 wl_signal_add(&wlr_subsurface->events.destroy, &subsurface->destroy);
(lldb) up
frame #2: 0x00005555555c3c2a sway`view_child_handle_surface_new_subsurface(listener=0x00005555564a1130, data=0x0000555556586910) at view.c:1031:2
1028 struct sway_view_child *child =
1029 wl_container_of(listener, child, surface_new_subsurface);
1030 struct wlr_subsurface *subsurface = data;
-> 1031 view_child_subsurface_create(child, subsurface);
1032 }
1033
1034 static void view_child_handle_surface_destroy(struct wl_listener *listener,
(lldb) up
frame #3: 0x00007ffff78f4bfe libwlroots.so.10`wlr_signal_emit_safe(signal=0x00005555565b2470, data=0x0000555556586910) at signal.c:29:3
26 wl_list_remove(&cursor.link);
27 wl_list_insert(pos, &cursor.link);
28
-> 29 l->notify(l, data);
30 }
31
32 wl_list_remove(&cursor.link);
(lldb) up
frame #4: 0x00007ffff78e5a41 libwlroots.so.10`subsurface_parent_commit(subsurface=0x0000555556586910) at wlr_surface.c:517:3
514
515 if (!subsurface->added) {
516 subsurface->added = true;
-> 517 wlr_signal_emit_safe(&subsurface->parent->events.new_subsurface,
518 subsurface);
519 }
520 }
(lldb) up
frame #5: 0x00007ffff78e56fa libwlroots.so.10`surface_commit_state(surface=0x00005555565b21b0, next=0x00005555565b2338) at wlr_surface.c:439:3
436 wl_list_insert(&surface->current.subsurfaces_above,
437 &subsurface->current.link);
438
-> 439 subsurface_parent_commit(subsurface);
440 }
441 wl_list_for_each_reverse(subsurface, &surface->pending.subsurfaces_below,
442 pending.link) {
(lldb) up
frame #6: 0x00007ffff78e5b88 libwlroots.so.10`surface_handle_commit(client=0x0000555556564c80, resource=0x0000555556599a20) at wlr_surface.c:555:3
552 if (surface->pending.cached_state_locks > 0 || !wl_list_empty(&surface->cached)) {
553 surface_cache_pending(surface);
554 } else {
-> 555 surface_commit_state(surface, &surface->pending);
556 }
557 }
558
(lldb) up
frame #7: 0x00007ffff7000d4a libffi.so.8`___lldb_unnamed_symbol118 + 82
libffi.so.8`___lldb_unnamed_symbol118:
-> 0x7ffff7000d4a <+82>: leaq 0x18(%rbp), %rsp
0x7ffff7000d4e <+86>: movq (%rbp), %rcx
0x7ffff7000d52 <+90>: movq 0x8(%rbp), %rdi
0x7ffff7000d56 <+94>: movq 0x10(%rbp), %rbp
(lldb) up
frame #8: 0x00007ffff7000267 libffi.so.8`___lldb_unnamed_symbol115 + 439
libffi.so.8`___lldb_unnamed_symbol115:
-> 0x7ffff7000267 <+439>: movq -0x38(%rbp), %rax
0x7ffff700026b <+443>: subq %fs:0x28, %rax
0x7ffff7000274 <+452>: jne 0x7ffff70004e7 ; <+1079>
0x7ffff700027a <+458>: leaq -0x28(%rbp), %rsp
(lldb) up
frame #9: 0x00007ffff795a173 libwayland-server.so.0`___lldb_unnamed_symbol271 + 371
libwayland-server.so.0`___lldb_unnamed_symbol271:
-> 0x7ffff795a173 <+371>: movq 0x8(%r12), %rax
0x7ffff795a178 <+376>: movq 0x8(%rax), %rdi
0x7ffff795a17c <+380>: movl (%r12), %eax
0x7ffff795a180 <+384>: testl %eax, %eax
(lldb) up
frame #10: 0x00007ffff795555c libwayland-server.so.0`___lldb_unnamed_symbol210 + 588
libwayland-server.so.0`___lldb_unnamed_symbol210:
-> 0x7ffff795555c <+588>: jmp 0x7ffff7955435 ; <+293>
0x7ffff7955561 <+593>: nopl (%rax)
0x7ffff7955568 <+600>: callq *0xd76a(%rip)
0x7ffff795556e <+606>: cmpl $0xb, (%rax)
(lldb) up
frame #11: 0x00007ffff795804a libwayland-server.so.0`wl_event_loop_dispatch + 202
libwayland-server.so.0`wl_event_loop_dispatch:
-> 0x7ffff795804a <+202>: addq $0xc, %r15
0x7ffff795804e <+206>: cmpq %r15, %rbp
0x7ffff7958051 <+209>: jne 0x7ffff7958038 ; <+184>
0x7ffff7958053 <+211>: movq 0x8(%rsp), %rcx1
(lldb) up
frame #12: 0x00007ffff7955bc7 libwayland-server.so.0`wl_display_run + 39
libwayland-server.so.0`wl_display_run:
-> 0x7ffff7955bc7 <+39>: movl 0x8(%rbx), %eax
0x7ffff7955bca <+42>: testl %eax, %eax
0x7ffff7955bcc <+44>: jne 0x7ffff7955bb0 ; <+16>
0x7ffff7955bce <+46>: popq %rbx
(lldb) up
frame #13: 0x00005555555756eb sway`server_run(server=0x00005555555f0640) at server.c:296:2
293 void server_run(struct sway_server *server) {
294 sway_log(SWAY_INFO, "Running compositor on wayland display '%s'",
295 server->socket);
-> 296 wl_display_run(server->wl_display);
297 }
(lldb) up
frame #14: 0x0000555555574947 sway`main(argc=1, argv=0x00007fffffffe8d8) at main.c:428:2
425 swaynag_show(&config->swaynag_config_errors);
426 }
427
-> 428 server_run(&server);
429
430 shutdown:
431 sway_log(SWAY_INFO, "Shutting down sway");
(lldb) up
frame #15: 0x00007ffff761db25 libc.so.6`__libc_start_main + 213
libc.so.6`__libc_start_main:
-> 0x7ffff761db25 <+213>: movl %eax, %edi
0x7ffff761db27 <+215>: callq 0x7ffff7635630 ; exit
0x7ffff761db2c <+220>: movq (%rsp), %rax
0x7ffff761db30 <+224>: leaq 0x163929(%rip), %rdi
(lldb) up
frame #16: 0x00005555555656be sway`_start + 46
sway`_start:
-> 0x5555555656be <+46>: hlt
0x5555555656bf: nop
sway`deregister_tm_clones:
0x5555555656c0 <+0>: leaq 0x8aeb9(%rip), %rdi ; optind@GLIBC_2.2.5
0x5555555656c7 <+7>: leaq 0x8aeb2(%rip), %rax ; optind@GLIBC_2.2.5
Signed-off-by: Alexander Orzechowski <orzechowski.alexander@gmail.com>
|