Currently, when sway sends a configure with some geometry and the
client responds with a different geometry in a commit that acks that
configure, sway ignores the new size. Sway applies the surface
geometry it had requested to the container, not what was actually
committed, in the following transaction.
This change allows any client commit to change its surface geometry,
even if it is a response to a configure event.
Sway maintains a list of pending transactions, and tries to merge
consecutive transactions applying to the same views into one. Given
a pending transactions list on views {A, B, C} of:
A -> A' -> A'' -> B -> B' -> B''
Sway will collapse the transactions into just A'' -> B''. This works
fine when doing things like resizing views by their border. However,
when interactively resizing layouts like H[V[A B] C], we end up with
pending transaction lists like:
A -> B -> C -> A' -> B' -> C' -> A'' -> B'' -> C''
Previously, Sway would not be able to simplify this transaction list,
and execute many more transactions than would be necessary (the final
state is determined by {A'', B'', C''}).
After this commit, the transaction list gets simplified to A'' -> B'' ->
C'', resolving performance problems (that were particularly noticeable
with high-refresh-rate mice).
Fixes#5736.
Xwayland views are aware of their coordinates, so validating transaction
completions should take into account the reported coordinates of the
view. Prior to this commit they didn't, and matching dimensions would
suffice to validate the transaction.
Also introduced `transaction_notify_view_ready_immediately` to support
the fix from d0f7e0f without jumping through hoops to figure out the
geometry of an `xdg_shell` view.
Sway logical coordinates are doubles, but they get truncated to integers
when sent to Xwayland through `xcb_configure_window`. X11 apps will not
respond to duplicate configure requests (from their truncated point of
view) and cause transactions to time out.
Fixes#5035.
i3 shows indicators for the workspace-level pseudo-split, but Sway does
not, as of b977c02. This commit replaces the floating container check
with a call to `container_is_floating`, which has some more robust
checks in place.
Fixes#5699.
My primary issue was IntelliJ IDEA's code suggestion pop-up not returning focus
to the active editing window.
I have spent some time looking at the changes of @Xyene (#5398) and
@RyanDwyer (#2103). I think my proposed change maintains the status
quo for the most part whilst fixing my focus issue.
I have verified that @Xyene's fix for IntelliJ sub-menus still works.
I have done basic testing which consists of:
- Chrome
- IntelliJ IDEA 2020.2.1
- VSCode
- Alacritty
It seems to hold up. I at least didn't see any obvious errors.
Relates to #3007
Instead of listening to both transform and scale events, we can listen
to the commit event and use the new wlr_output_event_commit struct to
decide what to do.
This de-duplicates some of the work we were doing twice when an output
was re-configured.
Depends on [1].
[1]: https://github.com/swaywm/wlroots/pull/2315
Usually it should be enough to simply not grant a client's
minimize request, however some applications (Steam, fullscreen
games in Wine) don't wait for the compositor and minimize anyway,
getting them stuck in an unrecoverable state.
Restoring them immediately lead to heavy flickering when unfocused
on my test application (Earth Defense Force 5 via Steam), so it's
preferable to grant their request without actually minimizing and
then restoring them once they are in focus again.
Previously, we called output_disable prior to wlr_output_commit. This
mutates Sway's output state before the output commit actually succeeds.
This results in Sway's state getting out-of-sync with wlroots'.
An alternative fix [1] was to revert the changes made by output_disable
in case of failure. This is a little complicated. Instead, this patch
makes it so Sway's internal state is never changed before a successful
wlr_output commit.
We had two output flags: enabled and configured. However enabled was set
prior to the output becoming enabled, and was used to prevent the output
event handlers (specifically, the mode handler) from calling
apply_output_config again (infinite loop).
Rename enabled to enabling and use it exclusively for this purpose.
Rename configure to enabled, because that's what it really means.
[1]: https://github.com/swaywm/sway/pull/5521
Closes: https://github.com/swaywm/sway/issues/5483
If a client commits a new size on its own, we create a transaction for
the resize like any other. However, this involves sending a configure
and waiting for the ack, and wlroots will not send configure events when
there has been no change. This leads to transactions timing out.
Instead, just mark the view ready immediately by size when the client
is already ready, so that we avoid waiting for an ack that will never
come.
Closes: https://github.com/swaywm/sway/issues/5490
The centering logic needs to take borders, titlebars and CSDs into
account. Instead of using the main surface geometry, use the container
and view geometry, which account for this.
During the execution of a resize transaction, the buffer associated
with a view's surface is saved and reused until the client acknowledges
the resulting configure event.
However, only one the main buffer of the main surface was stored and
rendered, meaning that subsurfaces disappear during resize.
Iterate over all, store and render buffers from all surfaces in the view
to ensure that correct rendering is preserved.
This is necessary because some applications (e.g. Jetbrains IDEs)
represent their multi-level menus as unmanaged surfaces, and when
closing a submenu, the main menu should get input focus.
Closes#5347.
Instead of removing the destroy listeners in the output destroy, remove
them in the damage destroy handler. Fixes the following use after free:
==646625==ERROR: AddressSanitizer: heap-use-after-free on address 0x61200017cab8 at pc 0x0000004f8f29 bp 0x7ffdf465ad30 sp 0x7ffdf465ad20
WRITE of size 8 at 0x61200017cab8 thread T0
#0 0x4f8f28 in wl_list_remove ../common/list.c:181
#1 0x43dd24 in handle_destroy ../sway/desktop/output.c:790
(`wl_list_remove(&output->damage_destroy.link);` here, 214e3030e1dce master branch)
#2 0x7f0e573a1c93 in wlr_signal_emit_safe ../util/signal.c:29
#3 0x7f0e57390954 in wlr_output_destroy ../types/wlr_output.c:365
#4 0x7f0e5735e37f in backend_destroy ../backend/x11/backend.c:128
#5 0x7f0e57348147 in wlr_backend_destroy ../backend/backend.c:47
#6 0x7f0e57356f75 in multi_backend_destroy ../backend/multi/backend.c:54
#7 0x7f0e5735710e in handle_display_destroy ../backend/multi/backend.c:107
#8 0x7f0e573f23e4 in wl_display_destroy (/lib64/libwayland-server.so.0+0x93e4)
#9 0x42f0b2 in server_fini ../sway/server.c:177
#10 0x42dd01 in main ../sway/main.c:414
#11 0x7f0e570f7041 in __libc_start_main (/lib64/libc.so.6+0x27041)
#12 0x40e3bd in _start (/opt/wayland/bin/sway+0x40e3bd)
0x61200017cab8 is located 120 bytes inside of 320-byte region [0x61200017ca40,0x61200017cb80)
freed by thread T0 here:
#0 0x7f0e57aa9357 in __interceptor_free (/lib64/libasan.so.6+0xb0357)
#1 0x7f0e5738b877 in wlr_output_damage_destroy ../types/wlr_output_damage.c:143
#2 0x7f0e5738b2b9 in output_handle_destroy ../types/wlr_output_damage.c:13
#3 0x7f0e573a1c93 in wlr_signal_emit_safe ../util/signal.c:29
#4 0x7f0e57390954 in wlr_output_destroy ../types/wlr_output.c:365
#5 0x7f0e5735e37f in backend_destroy ../backend/x11/backend.c:128
#6 0x7f0e57348147 in wlr_backend_destroy ../backend/backend.c:47
#7 0x7f0e57356f75 in multi_backend_destroy ../backend/multi/backend.c:54
#8 0x7f0e5735710e in handle_display_destroy ../backend/multi/backend.c:107
#9 0x7f0e573f23e4 in wl_display_destroy (/lib64/libwayland-server.so.0+0x93e4)
previously allocated by thread T0 here:
#0 0x7f0e57aa9887 in __interceptor_calloc (/lib64/libasan.so.6+0xb0887)
#1 0x7f0e5738b532 in wlr_output_damage_create ../types/wlr_output_damage.c:91
#2 0x43e4a7 in handle_new_output ../sway/desktop/output.c:875
#3 0x7f0e573a1c93 in wlr_signal_emit_safe ../util/signal.c:29
#4 0x7f0e57357261 in new_output_reemit ../backend/multi/backend.c:143
#5 0x7f0e573a1c93 in wlr_signal_emit_safe ../util/signal.c:29
#6 0x7f0e5736030a in wlr_x11_output_create ../backend/x11/output.c:253
#7 0x7f0e5735e309 in backend_start ../backend/x11/backend.c:113
#8 0x7f0e573480fb in wlr_backend_start ../backend/backend.c:36
#9 0x7f0e57356e61 in multi_backend_start ../backend/multi/backend.c:31
#10 0x7f0e573480fb in wlr_backend_start ../backend/backend.c:36
#11 0x42f4ba in server_start ../sway/server.c:205
#12 0x42dbd7 in main ../sway/main.c:394
#13 0x7f0e570f7041 in __libc_start_main (/lib64/libc.so.6+0x27041)
Fixes#5158
With these changes, sway will respect positive exclusive zones of layer
surfaces anchored to one or three sides.
This matches the protocol, which states that a positive exclusive zone
should be respected, "if the surface is anchored to one edge or an
edge and both perpendicular edges". If the surfaces is "anchored to
only two perpendicular edges (a corner), anchored to only two
parallel edges or anchored to all edges a positive value will be
treated the same as zero".
apply_output_config will call output_enable if necessary.
This fixes a lone wlr_output_enable call (without a matching
wlr_output_commit call) which was a no-op.
This fixes the following crash:
#0 0x00007f7daac3af25 in raise () at /usr/lib/libc.so.6
#1 0x00007f7daac24897 in abort () at /usr/lib/libc.so.6
#2 0x00007f7daac24767 in _nl_load_domain.cold () at /usr/lib/libc.so.6
#3 0x00007f7daac33526 in () at /usr/lib/libc.so.6
#4 0x0000555bfbc35029 in seat_set_focus_layer (seat=0x555bfd76d860, layer=0x555bfdda2ff0)
at ../sway/input/seat.c:1164
__PRETTY_FUNCTION__ = "seat_set_focus_layer"
__PRETTY_FUNCTION__ = "seat_set_focus_layer"
#5 0x0000555bfbc35029 in seat_set_focus_layer (seat=seat@entry=0x555bfd76d860, layer=0x555bfdda2ff0)
at ../sway/input/seat.c:1164
__PRETTY_FUNCTION__ = "seat_set_focus_layer"
#6 0x0000555bfbc25899 in handle_output_destroy (listener=0x555bfdb90688, data=<optimized out>)
at ../sway/desktop/layer_shell.c:263
layer = 0x555bfdd6b040
sway_layer = 0x555bfdb90610
seat = 0x555bfd76d860
client = 0x555bfdb76d70
set_focus = <optimized out>
#7 0x0000555bfbc5b669 in wl_signal_emit (data=0x555bfd795930, signal=0x555bfd795ae0)
at /usr/include/wayland-server-core.h:472
l = <optimized out>
next = 0x555bfdb6a3e8
__PRETTY_FUNCTION__ = "output_disable"
index = <optimized out>
#8 0x0000555bfbc5b669 in output_disable (output=output@entry=0x555bfd795930)
at ../sway/tree/output.c:263
__PRETTY_FUNCTION__ = "output_disable"
index = <optimized out>
#9 0x0000555bfbc3b890 in apply_output_config (oc=0x555bfd7d73d0, output=output@entry=0x555bfd795930)
at ../sway/config/output.c:321
wlr_output = 0x555bfd7afaf0
scale = <optimized out>
output_box = <optimized out>
#10 0x0000555bfbc28309 in handle_output_manager_apply
(listener=0x555bfbc7f148 <server+488>, data=0x555bfdca6eb0) at ../sway/desktop/output.c:936
wlr_output = <optimized out>
output = 0x555bfd795930
oc = <optimized out>
server = 0x555bfbc7ef60 <server>
config = 0x555bfdca6eb0
config_head = 0x555bfdb79350
ok = true
#11 0x00007f7dab4fbf7c in wlr_signal_emit_safe (signal=<optimized out>, data=0x555bfdca6eb0)
at ../subprojects/wlroots/util/signal.c:29
pos = 0x555bfbc7f148 <server+488>
l = 0x555bfbc7f148 <server+488>
cursor =
{link = {prev = 0x555bfbc7f148 <server+488>, next = 0x7fff238a8390}, notify = 0x7f7dab4fbef0 <handle_noop>}
end =
{link = {prev = 0x7fff238a8370, next = 0x555bfd7419f8}, notify = 0x7f7dab4fbef0 <handle_noop>}
#12 0x00007f7daa45469a in ffi_call_unix64 () at /usr/lib/libffi.so.6
#13 0x00007f7daa453fb6 in ffi_call () at /usr/lib/libffi.so.6
#14 0x00007f7daae6f82f in () at /usr/lib/libwayland-server.so.0
#15 0x00007f7daae6c193 in () at /usr/lib/libwayland-server.so.0
#16 0x00007f7daae6d7f2 in wl_event_loop_dispatch () at /usr/lib/libwayland-server.so.0
#17 0x00007f7daae6c39c in wl_display_run () at /usr/lib/libwayland-server.so.0
This crash happens because focus can only be set on mapped surfaces.
This fixes a memory leak of oc (the output config) in handle_new_output.
Output configs returned from find_output_config are not stored and need
to be freed after use.
Two changes were made:
- Bind the texture before glTexParameteri
- Set the scaling filter before each wlr_render_texture_with_matrix call
Logging in wlroots allows to check that the scaling filter is properly
set prior to rendering.
Fixes: 6968fb3123 ("add scale_filter output config option")
Closes: https://github.com/swaywm/sway/issues/4798
This adds a check to make it so the indicator is only rendered on views
with a parent, which floating views do not. Since floating views do not
have a parent, the workspace layout was being incorrectly used to
determine whether to show the split indicator previously. This has no
impact on floating containers and a view within a floating container
will still have indicators rendered appropriately.
In case xcb-iccm is not installed on the system, size_hints will be
null. Handle this as if the get_constraints functions was not
implemented and return the defaults.
Fixes#4870
When arranging layer-shell layers, verify that the currently focused
layer, if any, for each seat is still keyboard interactive. If the layer
is no longer keyboard interactive and there is not a keyboard
interactive overlay or top layer to change the focus to, refocus the
focus inactive node for the seat.
When many surfaces are created, sway can run out of file descriptors,
making wl_event_loop_add_timer (which creates a timerfd) fail and
return NULL. This patch posts a "no memory" error when that is the case,
and only removes the timer if it was created.
(Why "no memory"? It is not easy to distinguish between failures due to
running out of memory and failures due to running out of file
descriptors. Also, using the newer `wl_client_post_implementation_error`
function would lead to an increased version requirement for the
libwayland-server dependency.)
If a layer is focused by any seat, it needs to be unfocused on unmap. If
the unmap was due to an output being disabled, there would not be a
sway_output and unmap would do an early return. This results in a
use-after-free if the layer was focused by any seat prior to being
unmapped. This change just moves the refocusing code above the early
returns.
Repaint scheduling delays output render and frame done events from
output frame events, and block idle frame events from being scheduled in
between output frame done and output render in this period of time.
If a surface is committed after its frame done event, but before output
render, idle frame requests will be blocked, and the surface relies on
the upcoming render to schedule a frame.
If when the repaint timer expires, output render is deemed unnecessary,
no frame will be scheduled. This can lead to surfaces never having their
frame callbacks fire.
To fix this, we store that a surface has requested a frame in
surface_needs_frame. When the repaint expires, if no render is deemed
necessary, we check this flag and schedule an idle frame.
Fixes#4768
max_render_time can be set on output, view, or both. However, if only
applied to the output, send_frame_done_iterator would erroneously send
frame_done immediately, ignoring the output max_render_time. As
damage_handle_frame processed max_render_time correctly, idle frames
would be blocked in anticipation of the delay that was meant to happen.
Without the delay, frame events would be dispatched during the idle
frame block, and some clients would never receive the frame done events
they had requested, at least not until something else actively drove
another render.
Respecting both view and output max_render_time in
send_frame_done_iterator ensures that the frame events are always
correctly delayed.
Fixes#4756
It's possible for the output to be disconnected in just the right moment
for wlr_output to be NULL in the repaint handler, causing a crash. This
check fixes that crash.
Previously, Xwayland windows did not have size_constraints implemented,
resulting in the window being resizable. This implements the constraints
through the X11 size hints supplied by the window itself.
Calling wlr_output_manager_v1_set_configuration with an enabled output
and a NULL mode is incorrect if the output doesn't support modes.
When DPMS'ing an output, wlr_output_enable(output, false) is called.
This de-allocates the CRTC and sets wlr_output.current_mode to NULL.
Because we mark DPMS'ed outputs as enabled, we also need to provide a
correct output mode. Add a field to sway_output to hold the current
mode.
Closes: https://github.com/swaywm/wlroots/issues/1867
When applying config, value mode->refresh is mHz; convert it to Hz before
assigning it to the temporary output config. oc->refresh_rate will
be converted back to mHz in set_mode function.
Fix debug log printing GHz instead of Hz.
When changing a surface from managed to unmanaged in handle_map(), the
call to handle_destroy(.., view) causes the sway_xwayland_view pointed
to by the untyped wlr_xwayland_surface.data field to become invalid
garbage, yet the untyped wlr_xwayland_surface.data continues to point
at it. In particular: view_get_*(view_from_wlr_surface(..)), even
with appropriate NULL checking, will crash sway when this codepath is
exercised (reliable test case: drop-down menus in Google Earth).
Popups are positioned relative to local surface coordinates of the
parent surface. There's no need to consider values set with
xdg_surface.set_window_geometry for parent surfaces.
Sometimes when using direct scan-out, some flickering between the
fullscreen app and the regular desktop could be seen.
This happened because we called wlr_output_attach_render and then
wlr_output_attach_buffer for direct scan-out. wlr_output_attach_render
makes the OpenGL context current but also attaches the OpenGL buffer to
the primary plane apparently (all of this happens inside
eglMakeCurrent).
This patch moves the scan-out logic outside of output_render, before
wlr_output_attach_render. This lines it up with rootston's
implementation. This also makes more sense since no rendering is
involved when using direct scan-out.
Sorry about that, I should've tested this with more clients. The new
code has been tested with mpv and a GLFW demo.
Focused layers are not cleared when destroyed, they are cleared on unmap.
Giving focus to an unmapped layer surface is (1) incorrect and (2) triggers a
use-after-free.
Closes: https://github.com/swaywm/sway/issues/4517
The documentation for wayland-server.h says:
> Use of this header file is discouraged. Prefer including
> wayland-server-core.h instead, which does not include the server protocol
> header and as such only defines the library PI, excluding the deprecated API
> below.
Replacing wayland-server.h with wayland-server-core.h allows us to drop the
WL_HIDE_DEPRECATED declaration.
This commit si similar to wlroots' ca45f4490ccc ("Remove all wayland-server.h
includes").
handle_destroy would mark the output es being destroyed and commit the
transaction. Committing the transaction results in the output being
freed, the output manager can not retrieve the server reference
afterwards, resulting in the following use-after-free:
==22746==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000017088 at pc 0x560c1ac17136 bp 0x7ffeab146f20 sp 0x7ffeab146f10
READ of size 8 at 0x614000017088 thread T0
#0 0x560c1ac17135 in handle_destroy ../sway/desktop/output.c:566
#1 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#2 0x7f38af5d3dfc in drm_connector_cleanup ../subprojects/wlroots/backend/drm/drm.c:1448
#3 0x7f38af5d2058 in scan_drm_connectors ../subprojects/wlroots/backend/drm/drm.c:1240
#4 0x7f38af5c6a59 in drm_invalidated ../subprojects/wlroots/backend/drm/backend.c:135
#5 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#6 0x7f38af5e827a in udev_event ../subprojects/wlroots/backend/session/session.c:52
#7 0x7f38aef5d7f1 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa7f1)
#8 0x7f38aef5c39b in wl_display_run (/usr/lib/libwayland-server.so.0+0x939b)
#9 0x560c1ac0afbe in server_run ../sway/server.c:225
#10 0x560c1ac09382 in main ../sway/main.c:397
#11 0x7f38aed35ce2 in __libc_start_main (/usr/lib/libc.so.6+0x23ce2)
#12 0x560c1abea10d in _start (/usr/local/bin/sway+0x3910d)
0x614000017088 is located 72 bytes inside of 432-byte region [0x614000017040,0x6140000171f0)
freed by thread T0 here:
#0 0x7f38af82df89 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:66
#1 0x560c1acbd1ed in output_destroy ../sway/tree/output.c:243
#2 0x560c1ac23ce5 in transaction_destroy ../sway/desktop/transaction.c:66
#3 0x560c1ac26b71 in transaction_progress_queue ../sway/desktop/transaction.c:348
#4 0x560c1ac284ca in transaction_commit_dirty ../sway/desktop/transaction.c:539
#5 0x560c1ac17110 in handle_destroy ../sway/desktop/output.c:564
#6 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#7 0x7f38af5d3dfc in drm_connector_cleanup ../subprojects/wlroots/backend/drm/drm.c:1448
#8 0x7f38af5d2058 in scan_drm_connectors ../subprojects/wlroots/backend/drm/drm.c:1240
#9 0x7f38af5c6a59 in drm_invalidated ../subprojects/wlroots/backend/drm/backend.c:135
#10 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#11 0x7f38af5e827a in udev_event ../subprojects/wlroots/backend/session/session.c:52
#12 0x7f38aef5d7f1 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa7f1)
previously allocated by thread T0 here:
#0 0x7f38af82e5a1 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:95
#1 0x560c1acbc228 in output_create ../sway/tree/output.c:91
#2 0x560c1ac17ba2 in handle_new_output ../sway/desktop/output.c:656
#3 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#4 0x7f38af5e4ce8 in new_output_reemit ../subprojects/wlroots/backend/multi/backend.c:143
#5 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#6 0x7f38af5d26d4 in scan_drm_connectors ../subprojects/wlroots/backend/drm/drm.c:1294
#7 0x7f38af5c6a59 in drm_invalidated ../subprojects/wlroots/backend/drm/backend.c:135
#8 0x7f38af69330e in wlr_signal_emit_safe ../subprojects/wlroots/util/signal.c:29
#9 0x7f38af5e827a in udev_event ../subprojects/wlroots/backend/session/session.c:52
#10 0x7f38aef5d7f1 in wl_event_loop_dispatch (/usr/lib/libwayland-server.so.0+0xa7f1)
SUMMARY: AddressSanitizer: heap-use-after-free ../sway/desktop/output.c:566 in handle_destroy
Shadow bytes around the buggy address:
0x0c287fffadc0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c287fffadd0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fffade0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fffadf0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fffae00: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c287fffae10: fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fffae20: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c287fffae30: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
0x0c287fffae40: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c287fffae50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c287fffae60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Retrieve the reference before the output is destroyed and update the
output_management state with the saved reference.
When setting fullscreen on a hidden scratchpad container, there was a
check to see if there was an existing fullscreen container on the
workspace so it could be fullscreen disabled first. Since the workspace
is NULL, it would cause a SIGSEGV. This adds a NULL check to avoid the
crash.
This also changes the behavior of how fullscreen is handled when adding
a container to the scratchpad or changing visibility of a scratchpad
container to match i3's. The behavior is as follows:
- When adding a container to the scratchpad or hiding a container back
into the scratchpad, there is an implicit fullscreen disable
- When setting fullscreen on a container that is hidden in the
scratchpad, it will be fullscreen when shown (and fullscreen disabled
when hidden as stated above)
- When setting fullscreen global on a container that is hidden in the
scratchpad, it will be shown immediately as fullscreen global. The
container is not moved to a workspace and remains in the
scratchpad. The container will be visible until fullscreen disabled
or killed. Since the container is in the scratchpad, running
`scratchpad show` or `move container to scratchpad` will have no
effect
This also changes `container_replace` to transfer fullscreen and
scratchpad status.
This honors the fullscreen output request for
`xdg_toplevel_set_fullscreen` and `zxdg_toplevel_v6_set_fullscreen`.
If the request was sent before mapping, the fullscreen output request
will be retrieved from the client_pending state for the toplevel. The
output will be passed to `view_map` and if there is a workspace on the
output, the view will be placed on that workspace.
If the request comes in after being mapped, the view will be moved to
the workspace on the output (if there is one) before becoming
fullscreen.
This makes it so there will only be one swaybg instance running
instead of one per output. swaybg's cli has been changed to a xrandr
like interface, where you select an output and then change properties
for that output and then select another output and repeat. This also
makes it so swaybg is only killed and respawned when a background
changes or when reloading.
This fixes a crash for application set idle inhibitors when their
associated view is being destroyed. There is a call to
`view_is_visible` to determine is the view is visible and it assumes
that the view has an container, but it is possible for the container
to already have been destroyed at this point. There is a NULL check for
the view in `check_active` and this re-adds the NULL check for the
container that I accidentally dropped when refactoring during the
inhibit_idle command PR
This fixes a crash in `container_init_floating` when a xwayland view
sends a configure request while in the scratchpad.
`container_init_floating` gets called so the configured minimum and
maximum sizes gets respected when resizing to the requested size. Since
the workspace was NULL, it would SIGSEGV when attempting to get the
workspace's output for the output box retrieval.
This extracts the resizing portion of `container_init_floating` into a
separate function. If the container is in the scratchpad, it will just
be resized and skip the centering.
Additionally, `container_init_floating` has been renamed to
`container_floating_resize_and_center` to more accurately describe what
it does.
This implements the following command to set/unset a user idle
inhibitor for a view:
`inhibit_idle focus|fullscreen|open|none|visible`
The modes are as follows:
- focus: inhibited when the view is focused by any seat
- fullscreen: inhibited when the view is fullscreen (or a descendant of
a fullscreen container) and is visible on any output
- open: inhibited until the view is closed or the inhibitor is unset or
changed
- none: unsets any user set idle inhibitors for the view
- visible: inhibited when the view is visible on any output
This should have no effect on idle inhibitors set by the applications
themselves and those should still work as intended.
Since this operates on the view in the handler context, it is possible
to set it on the currently focused view, on any existing view with
criteria, or for any future view with for_window.
This introduces a `default` seat operation which is used when no mouse
buttons are being held. This means there is now always a seat operation
in progress. It allows us to separate `default` code from the standard
cursor management code.
The sway_seatop_impl struct has gained callbacks `axis`, `rebase` and
`end`, and lost callbacks `finish` and `abort`. `axis` and `rebase` are
only used by the default seatop. `end` is called when a seatop is being
replaced by another one and allows the seatop to free any resources,
though no seatop currently needs to do this. `finish` is no longer
required, as each seatop can gracefully finish in their `button`
callback. And `abort` is not needed, as calling `end` would achieve the
same thing. The struct has also gained a bool named allow_set_cursor
which allows the client to set a new cursor during `default` and `down`
seatops.
Seatops would previously store which button they were started with and
stop when that button was released. This behaviour is changed so that it
only ends once all buttons are released. So you can start a drag with
$mod+left, then click and hold right, release left and it'll continue
dragging while the right button is held.
The motion callback now accepts dx and dy. Most seatops don't use this
as they store the cursor position when the seatop is started and compare
it with the current cursor position. This approach doesn't make sense
for the default seatop though, hence why dx and dy are needed.
The pressed_buttons array has been moved from the sway_cursor struct to
the default seatop's data. This is only used for the default seatop to
check bindings. The total pressed button count remains in the
sway_cursor struct though, because all the other seatops check it to
know if they should end.
The `down` seatop no longer has a `moved` property. This was used to
track if the cursor moved and to recheck focus_follows_mouse, but seems
to work without it.
The logic for focus_follows_mouse has been refactored. As part of this
I've removed the call to wlr_seat_keyboard_has_grab as we don't appear
to use keyboard grabs.
The functions for handling relative motion, absolute motion and tool
axis have been changed. Previously the handler functions were
handle_cursor_motion, handle_cursor_motion_absolute and
handle_tool_axis. The latter two both called cursor_motion_absolute.
Both handle_cursor_motion and cursor_motion_absolute did very similar
things. These are now simplified into three handlers and a single common
function called cursor_motion. All three handlers call cursor_motion. As
cursor_motion works with relative distances, the absolute and tool axis
handlers convert them to relative first.
This removes `output_find_config`, which would take the first matching
output config it found. This is fine if only a name output config,
identifier output config, or even just wildcard exist, but if there is
a name output config and identifier output config, they are not merged.
Instead, this introduces find_output_config, which is just a wrapper
for `get_output_config`. This ensures that both the name and identifier
output configs are respected.
This fixes the following case:
- For simplicity in this example, remove all output configs from config
- Run `swaymsg output <name> bg #ff0000 solid_color`
- Run `swaymsg output <identifier> scale 2`
- Disconnect and reconnect output
Without this, the output will have the background, but not the scale.
With this, the output will have both the background and scale
This makes it so the container gets resized by a configure request for
xwayland floating views. The minimum and maximum sizes are also
respected. Previously, the configure request was resizing the surface
to the size requested, but never changing the container size. This
caused the surface to be rendered outside of the container or to be
smaller than the container. The former is never ideal and the latter
makes no sense for floating views since the container itself can just
be shrunk.
This removes `output_damage_view` since it is unnecessary. The logic
has been moved into its only caller `output_damage_from_view`. When
damaging the whole view, `output_damage_whole_container` should be used
instead
This adds an iterative call in `output_damage_whole_container` to
damage the subsurfaces for all visible views that are inside of the
container. This is needed to damage subsurfaces that extend outside the
box of the container. Without this, those subsurfaces will create
artifacts when moving or resizing.
If a floater is fullscreen either on a workspace or globally, it
should not be rendered on any output is is not fullscreened on. When
rendering it on an output it should not be rendered on, there will be
an extraneous border along the adjacent side of the output. This adds
a check in render_floating to skip all fullscreened floaters
Enables i3-compatible behavior regarding hiding the title bar on tabbed and
stacked containers with one child.
Related issues and merge requests: #3031, #3002, #2912, #2987.
If the noop output is focused (all other outputs disabled/disconnected),
do not auto assign a layer surface to it. The noop output is not enabled
and does not have the `output->layers` list initialized. It also does
not make sense to map the layer surfaces to something that is not
visible.
Fixes heap-use-after-free:
==32046==ERROR: AddressSanitizer: heap-use-after-free on address 0x615000064d20 at pc 0x55571ce4d303 bp 0x7fff545c64c0 sp 0x7fff545c64b0
WRITE of size 8 at 0x615000064d20 thread T0
#0 0x55571ce4d302 in xdg_decoration_handle_destroy ../sway/xdg_decoration.c:13
#1 0x7f64009d6f36 in wlr_signal_emit_safe ../util/signal.c:29
#2 0x7f64009d3c46 in toplevel_decoration_handle_resource_destroy ../types/wlr_xdg_decoration_v1.c:65
#3 0x7f6400a19f8d (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x7f8d)
#4 0x7f6400a19fed in wl_resource_destroy (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x7fed)
#5 0x7f64009d3d1f in toplevel_decoration_handle_surface_destroy ../types/wlr_xdg_decoration_v1.c:82
#6 0x7f64009d6f36 in wlr_signal_emit_safe ../util/signal.c:29
#7 0x7f64009b059c in reset_xdg_surface ../types/xdg_shell/wlr_xdg_surface.c:453
#8 0x7f64009b0688 in destroy_xdg_surface ../types/xdg_shell/wlr_xdg_surface.c:483
#9 0x7f64009af08c in xdg_client_handle_resource_destroy ../types/xdg_shell/wlr_xdg_shell.c:71
#10 0x7f6400a19f8d (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x7f8d)
#11 0x7f6400a1e211 (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0xc211)
#12 0x7f6400a1e6fe (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0xc6fe)
#13 0x7f6400a1a0ec in wl_client_destroy (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x80ec)
#14 0x7f6400a1a1c4 (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x81c4)
#15 0x7f6400a1b941 in wl_event_loop_dispatch (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x9941)
#16 0x7f6400a1a569 in wl_display_run (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x8569)
#17 0x55571ce4c7fd in server_run ../sway/server.c:214
#18 0x55571ce4ad59 in main ../sway/main.c:405
#19 0x7f640071109a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2409a)
#20 0x55571ce2cfa9 in _start (/usr/local/bin/sway+0x35fa9)
0x615000064d20 is located 32 bytes inside of 504-byte region [0x615000064d00,0x615000064ef8)
freed by thread T0 here:
#0 0x7f6401531b70 in free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xedb70)
#1 0x55571ce6c72b in destroy ../sway/desktop/xdg_shell.c:252
#2 0x55571cee3f7b in view_destroy ../sway/tree/view.c:60
#3 0x55571cee4090 in view_begin_destroy ../sway/tree/view.c:73
#4 0x55571ce6dd95 in handle_destroy ../sway/desktop/xdg_shell.c:464
#5 0x7f64009d6f36 in wlr_signal_emit_safe ../util/signal.c:29
#6 0x7f64009b059c in reset_xdg_surface ../types/xdg_shell/wlr_xdg_surface.c:453
#7 0x7f64009b0688 in destroy_xdg_surface ../types/xdg_shell/wlr_xdg_surface.c:483
#8 0x7f64009af08c in xdg_client_handle_resource_destroy ../types/xdg_shell/wlr_xdg_shell.c:71
#9 0x7f6400a19f8d (/usr/lib/x86_64-linux-gnu/libwayland-server.so.0+0x7f8d)
previously allocated by thread T0 here:
#0 0x7f6401532138 in calloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xee138)
#1 0x55571ce6df39 in handle_xdg_shell_surface ../sway/desktop/xdg_shell.c:485
#2 0x7f64009d6f36 in wlr_signal_emit_safe ../util/signal.c:29
#3 0x7f64009b0167 in handle_xdg_surface_commit ../types/xdg_shell/wlr_xdg_surface.c:350
#4 0x7f64009ce2a5 in surface_commit_pending ../types/wlr_surface.c:372
#5 0x7f64009ce523 in surface_commit ../types/wlr_surface.c:444
#6 0x7f63ff63ddad in ffi_call_unix64 (/usr/lib/x86_64-linux-gnu/libffi.so.6+0x5dad)
Fixes#3759
This modifies the places where output_get_active_workspace is called to
handle a NULL result. Some places already handled it and did not need a
change, some just have guard off code blocks, others return errors, and
some have sway_asserts since the case should never happen. A lot of this
is probably just safety precautions since they probably will never be
called when `output_get_active_workspace` is not fully configured with a
workspace.
If an output's node was dirty and the transaction was committed before a
workspace was moved to or created for the output, the instruction would
have a bad value for `state->active_workspace` due to a missing
length check in `output_get_active_workspace`. If there was no focus on
the output, the first workspace was being returned. If the workspace
list was currently empty, the value was either garbage, or in the case of
an output being disabled and re-enabled, a workspace that may have been
previously freed. This just adds the length check to avoid returning out
of bounds value.
wlr_xdg_popup_destroy will destroy popups, so we need to walk the tree
carefully. It's enough to just destroy all direct children, since destroying
the parent will also destroy all children.
Don't access xdg_surface->toplevel if xdg_surface->role is equal to
WLR_XDG_SURFACE_ROLE_NONE, since this could lead to crash. The same
checks are added for xdg_surface_v6.
Fixes#3311
Just a convenience function that improves readability of the code.
Other things worth noting:
* container_get_siblings and container_sibling_index no longer use the
const keyword
* container_handle_fullscreen_reparent is only ever called after
attaching the container to a workspace, so its con->workspace check has
been changed to an assertion
The goal here is to center fullscreen views when they are both too small
for the output and refuse to resize to the output's dimensions. It has
the side effect of also centering the view when it's too small for its
container.
Example clients that have this behaviour are emersion's hello-wayland
and weston.
It works by introducing surface_{x,y,width,height} properties to the
container struct. The x and y represent layout-local coordinates where
the surface will be rendered. The width and height are only used to
track the surface's previous dimensions so we can detect when the client
has resized it and recenter and apply damage accordingly.
The new surface properties are calculated when a transaction is applied,
as well as when a view resizes itself unexpectedly. The latter is done
in view_update_size. This function was previously restricted to views
which are floating, but can now be called for any views.
For views which refuse to resize *smaller* than a particular size, such
as gnome-calculator, the surface is still anchored to the top left as
per the current behaviour.
In addition to removing unused code, two minor problems are fixed:
(1) `resize set` and `resize adjust` did not error when given
too many arguments.
(2) `orientation` was incorrectly overridden to be 'U' for
scroll events in the swaybar tray `handle_click` function.
This commit mostly duplicates the wlr_log functions, although
with a sway_* prefix. (This is very similar to PR #2009.)
However, the logging function no longer needs to be replaceable,
so sway_log_init's second argument is used to set the exit
callback for sway_abort.
wlr_log_init is still invoked in sway/main.c
This commit makes it easier to remove the wlroots dependency for
the helper programs swaymsg, swaybg, swaybar, and swaynag.
If output->configured is true, then the output has been modeset correctly and
we don't need to try again. If output->enabled is true, then we are in the
process of configuring the output and we shouldn't do anything.
This happens if you plug in more outputs than supported by your GPU.
This patch makes it so outputs without CRTCs appear as disabled. As soon as
they get a CRTC (signalled via the mode event), we can enable them.
This splits each seat operation (drag/move tiling/floating etc) into a
separate file and introduces a struct sway_seatop_impl to abstract the
operation.
The move_tiling_threshold operation has been merged into move_tiling.
The main logic for each operation is untouched aside from variable
renames.
The following previously-static functions have been made public:
* node_at_coords
* container_raise_floating
* render_rect
* premultiply_alpha
* scale_box
../sway/desktop/transaction.c:367:17: error: format specifies type 'long' but the argument has type 'size_t' (aka 'unsigned int') [-Werror,-Wformat]
transaction, transaction->num_waiting);
^~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/wlr/util/log.h:56:72: note: expanded from macro 'wlr_log'
_wlr_log(verb, "[%s:%d] " fmt, _wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
^~~~~~~~~~~
../sway/desktop/transaction.c:477:5: error: format specifies type 'long' but the argument has type 'unsigned int' [-Werror,-Wformat]
transaction->num_configures - transaction->num_waiting + 1,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/wlr/util/log.h:56:72: note: expanded from macro 'wlr_log'
_wlr_log(verb, "[%s:%d] " fmt, _wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
^~~~~~~~~~~
../sway/desktop/transaction.c:478:5: error: format specifies type 'long' but the argument has type 'size_t' (aka 'unsigned int') [-Werror,-Wformat]
transaction->num_configures, ms,
^~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/wlr/util/log.h:56:72: note: expanded from macro 'wlr_log'
_wlr_log(verb, "[%s:%d] " fmt, _wlr_strip_path(__FILE__), __LINE__, ##__VA_ARGS__)
^~~~~~~~~~~
See issue #3359 for reproduction details. When a fullscreen view is
unmapped and there's a preceding transaction waiting, there may be
neither a saved buffer or a surface to render. This change matches
the equivalent code in render_view.
This combines `output_by_name` and `output_by_identifier` into a single
function called `output_by_name_or_id`. This allows for output
identifiers to be used in all commands, simplifies the logic of the
callers, and is more efficient since worst case is a single pass through
the output list.
This adds support for `i3 4.16`'s ability to set the title alignment.
The command is `title_align left|center|right`.
When the title is on the right, marks are moved to the left. Otherwise,
they are on the right.
This renames/moves the following properties:
* sway_view.{x,y,width,height} ->
sway_container.content_{x,y,width,height}
* This is required to support placeholder containers as they don't
have a view.
* sway_container_state.view_{x,y,width,height} ->
sway_container_state.content_{x,y,width,height}
* To remain consistent with the above.
* sway_container_state.con_{x,y,width,height} ->
sway_container_state.{x,y,width,height}
* The con prefix was there to give it contrast from the view
properties, and is no longer useful.
The function container_set_geometry_from_floating_view has also been
renamed to container_set_geometry_from_content.
In i3, when a child of a tabbed or stacked container has no siblings,
its border settings are respected.
This patch achieves the same effect by rendering a lone tabbed/stacked
child as if it's a linear container. This makes the border settings be
respected.
Over in view_autoconfigure, we compensate for this by only adjusting
`y_offset` if there's multiple children.
This approaches cursor rebasing from a different angle. Rather than
littering the codebase with cursor_rebase calls and using transaction
callbacks, this just runs cursor_rebase after applying every transaction
- but only if there's outputs connected, because otherwise it causes a
crash during shutdown.
There is one known case where we still need to call cursor_rebase
directly, and that's when running `seat seat0 cursor move ...`. This
command doesn't set anything as dirty so no transaction occurs.
I originally put the rebase at the end of view_map, but at this point
the view is still at its native size and will ignore the motion event if
it falls outside of its native size. The only way to do this properly is
to rebase the cursor later - either after sending the configure, after
the view commits with the new size, or after applying the transaction. I
chose to do it after applying the transaction for simplicity.
I then attempted to just call cursor_rebase after applying every
transaction, but this causes crashes when exiting sway (and possibly
other places) because cursor_rebase assumes the tree is in a valid
state.
So my chosen solution introduces transaction_commit_dirty_with_callback
which allows handle_map to register a callback which will run when the
transaction is applied.
window_properties is documented to contain a subset of the X11 properties
of a window (its title, class, instance, role, and transient ID). This
commit adds the missing json object from the get_tree output for
xwayland windows only.
This is a follow-up of #2911.
Signed-off-by: Franklin "Snaipe" Mathieu <me@snai.pe>
The wlr_xdg_popup_get_toplevel_coords function has the following quirks:
* It does not do anything with the coordinates of the passed popup.
Instead, we are required to add them ourselves, which we do by passing
them to the function as the surface local values.
* It adds the geometry (shadows etc) of the toplevel itself, so the
coordinates are surface local rather than content local. For this
reason, we have to negate the toplevel's geometry
(child->view->geometry).
* I may be wrong, but the popup positions appear to be stored in surface
local coordinates rather than content local coordinates. The geometry
(shadows etc) of the popup itself must be negated (surface->geometry).
The input manager is a singleton object. Passing the sway_input_manager
argument to each of its functions is unnecessary, while removing the
argument makes it obvious to the caller that it's a singleton. This
patch removes the argument and makes the input manager use server.input
instead.
On a similar note:
* sway_input_manager.server is removed in favour of using the server
global.
* seat.input is removed because it can get it from server.input.
Due to a circular dependency, creating seat0 is now done directly in
server_init rather than in input_manager_create. This is because
creating seats must be done after server.input is set.
Lastly, it now stores the default seat name using a constant and removes
a second reference to seat0 (in input_manager_get_default_seat).
For mouse_warping cursor to correctly work on newly spawned containers,
the workspace needs to be arranged before the cursor is warped.
The shell functions each implement their own fullscreen and arrange checks,
move them into the view_map function and pass their states via boolean arguments.
Fixes#2819
The basic idea here is to apply rounding after scaling. It's not as
simple as this, though, and I've detailed it in the comments for a
function.
In order to fix some pixel leaks in the title bar, I found it easier to
change how we place rectangles to fill the area. Instead of placing two
rectangles across the full width above and below the title and having
shorter rectangles in the inner area, it's now pieced together in
vertical chunks. This method involves drawing two less rectangles per
container.
This introduces a new view_impl function: is_transient_for. Similar to
container_has_ancestor but works using the surface parents rather than
the tree.
This patch modifies view_is_visible, container_at and so on to allow
transient views to function normally when they're in front of a
fullscreen view.
The previous behaviour was to damage the entire view, which would
recurse into each popup. This patch makes it damage only the popup's
surface, and respect the surface damage given by the client.
This adds listeners to the popup's map and unmap events rather than
doing the damage in the create and destroy functions. To get the popup's
position relative to the view, a new child_impl function get_root_coords
has been introduced, which traverses up the parents.
* Have multiple outputs
* Launch swaylock
* Unplug an output (possibly has to be the last "connected" one)
* The swaylock surface on the remaining output would not respond to key
events
This was happening because when the output destroys, focus was not given
to the other swaylock surface.
This patch makes focus be transferred to another surface owned by the
same Wayland client, but only if input was inhibited by the surface
being destroyed, and only if it's in the overlay layer. I figure it's
best to be overly specific and relax the requirements later if needed.
This patch removes a check in seat_set_focus_surface which was
preventing focus from being passed from a layer surface to any other
surface. I don't know of a use case for this check, but it's possible
that this change could produce issues.
This replaces view.using_csd with a new border mode: B_CSD. This also
removes sway_xdg_shell{_v6}_view.deco_mode and
view->has_client_side_decorations as we can now get these from the
border.
You can use `border toggle` to cycle through the modes including CSD, or
use `border csd` to set it directly. The client must support the
xdg-decoration protocol, and the only client I know of that does is the
example in wlroots.
If the client switches from SSD to CSD without us expecting it (via the
server-decoration protocol), we stash the previous border type into
view.saved_border so we can restore it if the client returns to SSD. I
haven't found a way to test this though.
This adds a `con` argument to `execute_command` which allows you to
specify the container to execute the command on. In most cases it leaves
it as `NULL` which makes it use the focused node. We only set it when
executing `for_window` criteria such as when a view maps. This means we
don't send unnecessary IPC focus events, and fixes a crash when the
criteria command is `move scratchpad` (because we can't give focus to a
hidden scratchpad container).
Each of the shell map handlers now check to see if the view has a
workspace. It won't have a workspace if criteria has moved it to the
scratchpad.
When destroying an idle-inhibiting client, idle_inhibit_v1_check_active can get
called from transaction_progress_queue on a view with a null container.
view_is_visible does not handle a view in this state.
This does the following:
* Adds a baseline argument to get_text_size (the baseline is the
distance from the top of the texture to the baseline).
* Stores the baseline in the container when calculating the title
height.
* Takes the baseline into account when calculating the config's max font
height.
* When rendering, pads the textures according to the baseline so they
line up.
There was code that attempted to fill in the gap below the title texture
when the texture isn't tall enough, but this only worked when the output
was positioned at 0,0. The reason is that render_rect expects a box
passed in a hybrid layout-local/output-buffer-local system, and we were
passing purely output-buffer-local. I've added a comment documenting
this.
By the way, we can't use layout-local coordinates for the rectangle box
because in some cases we set the box based on a texture size. Texture
sizes are buffer-local, and we'd have to divide them to bring it back to
layout-local which means losing precision. We could use
output-buffer-local coordinates for the box, but this would require
translating the coordinates from layout-local to output-buffer-local in
many places during rendering.
This patch also vertically centers the text inside the title bar.
This fixes pinentry-gtk-2, but might make other views floating which
would otherwise be tiled. This patch is more of a trial which could end
up becoming a permanent fix.
When rendering, the workspace for the output needs to be retrieved from
the output's `current` state. output_get_active_workspace returns the
pending workspace, which crashes if the pending workspace is new and
hasn't completed a transaction yet.
Suppose the following:
* Transactions are already in progress - say transaction A.
* View A maps, which creates transaction B and appends it to the
transaction queue.
* View B maps, which creates transaction C and appends it to the queue.
* View A unmaps, which creates transaction D and appends it to the
queue.
* Transaction A completes, so transaction B attempts to save View A's
buffer, but this doesn't exist so it saves nothing.
* Rendering code attempts to render View A, but there is no saved buffer
nor live buffer that it can use.
Rather than implement an elaborate solution for a rare circumstance,
I've take the safe option of just not rendering anything for that view.
It means that if you reproduce the scenario above, you might get the
title and borders rendered but no surface.