Commit graph

130 commits

Author SHA1 Message Date
Stephane Fontaine
ebabab4d98 fix missing output enter/leave for fullscreen windows in foreign toplevel 2026-01-19 14:15:05 +04:00
Kenny Levinsen
56f2db062d Revert "sway/tree: Simplify sway_node teardown"
This reverts commit e28e6484e8.

This change tried to remove nodes from all points of reference to allow
immediate destruction. However, it missed things like the children lists
cloned by transaction states of parent nodes.

Adding all that extra cleanup would not be in the spirit of a PR
claiming to simplify teardown. Let's wait for someone to come up with a
cleaner approach instead.

Fixes: https://github.com/swaywm/sway/pull/8738
2025-06-28 11:26:49 +02:00
Kenny Levinsen
e28e6484e8 sway/tree: Simplify sway_node teardown
A sway_node may end up being referenced in either a queued transaction,
pending transaction or as a dirty node. To manage this, the transaction
system has been responsible for destroying containers, workspaces and
outputs at the end of their last referenced transaction.

This significantly complicates the teardown flow of surfaces and
outputs. Instead, remove the node from transactions and dirty lists so
that the callsite can remove and free the node immediately.
2025-06-26 22:05:05 +02:00
alex-huff
88c7b4a7eb transaction: fix floating fullscreen containers
8fecf3a introduced a regression where fullscreening a child of a
floating container would result in a black screen. This is because the
order of 'arrange_fullscreen' and 'arrange_worksplace_floating' was
swapped causing the fullscreen container's scene to get reparented after
it was parented in the fullscreen layer.

Fixes #8729
2025-05-21 21:38:27 -04:00
alex-huff
8fecf3aa8c transaction: reparent scenes of containers behind fullscreen containers
Currently we do a good job of reparenting the scenes of a container when
it moves into a disabled workspace. We need to do this since normally
the scenes are reparented in the 'arrange_{children,container}'
functions but these don't get called for disabled workspaces. However,
the 'arrange_{children,container}' functions also don't get called when
there is a fullscreen container hiding them.

This commit makes sure to call 'disable_workspace' on workspaces with a
fullscreen container so that when a container is moved into the
workspace its scenes will be properly reparented. Also, when there is a
fullscreen global container 'disable_workspace' is called for all
workspaces since the scenes of a previously fullscreen global container
may still be parented in the 'fullscreen_global' layer.
Fixes #8705 #8659 #8432
2025-05-19 18:46:09 -04:00
alex-huff
fb6d61b58f transaction: fix size of child container decorations in stacking layouts
Before this commit stacking containers with more than one child sized
the active container's decorations as if there was only one titlebar.
Commit a25645a introduced the local variable 'net_height' but
incorrectly calculated it for stacking containers. Fixes #8686.
2025-05-19 12:29:09 +02:00
alex-huff
a4072486de transaction: ensure border scene is enabled for floating containers
When a container that was previously an inactive child of a tabbed or
stacking layout becomes floating it's border scene-tree remains
disabled. This results in only the titlebar being rendered for the
container. This commit ensures the border scene-tree is enabled when
arranging floating containers.
Fixes #8721
2025-05-18 17:00:39 +02:00
alex-huff
4ab411cab0 transaction: Ensure all tabs are visible in tabbed mode
Before this commit when a child of a tabbed or stacking container was
taken out of fullscreen and a different sibling was focused in the same
transaction, the titlebar of the previously fullscreen container would
remain hidden. This commit makes sure that scene tree for decorations is
enabled for all containers within a tabbed or stacking container when it
is arranged.
2025-05-04 18:55:57 -04:00
Filip Vujičić
7733bf9963 Remove duplicate arrange_container 2025-04-17 19:05:36 +02:00
Claudia
a25645a5a6 Fix tabbed/stacking container height regression
Commit c2d6aff added a bounds check on `height - title_bar_height`,
repurposing the local variable `height` in an attempt to DRY out the
expression.

However, because re-assignment occurs inside the loop body, its result
would leak across loop iterations, compounding its effect and leading
to the artifact reported in issue #8625, where each child except the
first in a tabbed container would acquire a visible waterline.

Introduce a second variable and reset it in each loop iteration to get
rid of the waterline.

Fixes #8625.
2025-03-27 08:09:53 +01:00
Kenny Levinsen
c2d6aff64c Avoid crashing on too many containers
If far too many containers are created, they can become so small that
their size calculations come out negative, leading to crashes on
asserts.

Instead, set a lower bound for sizes and disable the container entirely
if it goes below it, giving whatever space it used to the last
container.

The splits are not recalculated, so currently the effect is that if all
containers have the same width fraction, they keep getting narrower
until at some point they all round to zero and the last container will
be given all the available space.

A better behavior would have been if the additional container did not
contribute to size and fraction calculations at all, but it's an extreme
edge-case, anything is better than crashing, and this is easier to
implement.
2025-03-21 21:08:04 -04:00
melvinm1
2f5b3c0999 Fix output repositioning in global fullscreen
Call wlr_scene_output_set_position when in global fullscreen to
correctly set output positions when repositioning outputs (using
swaymsg output or similar).
2025-03-16 17:48:30 +01:00
mtvare6
62fd8c4d01 desktop/transaction: clamp vertical border length to 0
Fixes #8120
2024-11-07 22:41:14 -05:00
Alexander Orzechowski
023f6b0a50 transaction: Allow no popup descriptor in popup list
Input method popups in the future will destroy the scene descriptor when
it isn't mapped and therefore shouldn't be tampered with here.
2024-09-20 19:40:18 +02:00
Kenny Levinsen
14bff7b451 desktop/transaction: Deactivate workspace on inactive outputs
If the output is not active, it might not have a valid geometry to
arrange for. Outputs do not gain a geometry until modeset, so if an
output is connected with a configuration present to disable it, it will
not have a geometry. If the output has a past workspace restored, this
will be attemtped arranged to fit a 0x0 rectangle, which asserts when
trying to sort out borders.

Consider the workspace activated only if the output itself is active to
get the scene nodes disabled.
2024-09-07 20:11:30 -04:00
Alexander Orzechowski
b881c2e84c transaction: Reparent all container children when disabling for scratchpad
Fixes: #8205
2024-08-04 18:08:28 +02:00
novenary
a0a078f75e transaction: fix missing top border with hide_lone_tab
Regressed by scene graph.
2024-07-03 10:10:30 -04:00
Simon Ser
d0bd591ee7 Drop server.h include from input/input-manager.h
The only reason it's included there is for a declaration of
struct sway_server, but we can just forward-declare it.

This avoids rebuilding almost all of Sway when touching server.h.
All other server.h includes are from source files, not headers.
2024-05-27 09:28:43 -04:00
Simon Ser
9704152414 build: drop xwayland option
Instead of having a build-time option to enable/disable xwayland
support, just use the wlroots build config: enable xwayland in
Sway if it was enabled when building wlroots. I don't see any
use-case for disabling xwayland in Sway when enabled in wlroots:
Sway doesn't pull in any additional dependency (just pulls in
dependencies that wlroots already needs). We have a config command
to disable xwayland at runtime anyways.

This makes it so xwayland behaves the same way as other features
such as libinput backend and session support. This also reduces
the build matrix (less combinations of build options).

I think we originally introduced the xwayland option when we didn't
have a good way to figure out the wlroots build config from the
Sway build system.
2024-05-21 11:44:39 -04:00
Simon Ser
fc640d5f6c Define _POSIX_C_SOURCE globally
See discussion in https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4555
2024-02-23 17:43:19 +03:00
Alexander Orzechowski
09c360d503 layer_shell: Handle popups through popup descriptor
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.
2024-02-12 19:19:22 +03:00
Alexander Orzechowski
1846944f04 xdg_shell: Extract struct for popup descriptor 2024-02-12 19:19:22 +03:00
Alexander Orzechowski
1dc661af17 layer_shell: Arrange popups even if exclusive zone doesn't change 2024-02-12 19:19:22 +03:00
Alexander Orzechowski
5fc85c5066 scene_graph: port wlr_forgein_toplevel_management output enter/leave events 2024-01-18 18:36:54 +03:00
Alexander Orzechowski
9da295c11f scene_graph: Implement toplevel clipping 2024-01-18 18:36:54 +03:00
Alexander Orzechowski
2e53de80bb scene_graph: Arrange scene graph on transaction apply 2024-01-18 18:36:54 +03:00
Alexander Orzechowski
5f0801b6f2 container: Don't track outputs
The scene graph abstraction does this for us
2024-01-18 18:36:54 +03:00
Alexander Orzechowski
1e018e72b4 Delete old damage tracking code
The new scene graph abstraction handles this for us.
2024-01-18 18:36:54 +03:00
Alexander Orzechowski
06ad734e70 scene_graph: Port view saved buffers 2024-01-18 18:36:54 +03:00
Alexander Orzechowski
08c484f46f transaction: ready signals will return success bools 2024-01-18 18:36:54 +03:00
Simon Ser
b762f455d9 idle-inhibit-v1: simplify with server global
We only have a single running server, no need to keep track of
multiple server instances. Also no need to support multiple
idle inhibit managers.
2023-06-23 12:32:38 +02:00
Rouven Czerwinski
e4909ab4a3 transaction: destroying nodes aren't hidden
Commit 37d7bc6998 ("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
2022-01-18 19:42:15 +01:00
Kenny Levinsen
1989b18ff2 transaction: Remove unused ready_immediately 2021-02-23 19:38:05 +01:00
Kenny Levinsen
35b9a41720 transaction: Note if instructions are server requests
On server request, we need to send configure events to inform the client
of the new intended size. If the client changes size itself, sending a
configure event will only cause problems.

Use transaction_commit_dirty_client to distinguish between the two
transaction causes.
2021-02-23 19:38:05 +01:00
Tadeo Kondrak
f58f054c87 Fix incorrect damage being applied on popups
To reproduce:

- Open a floating window and a popup that hangs over the bottom or right
- Move the window in the direction of the popup overhang
- The previous position of the popup is damaged, not the new one
2021-02-21 17:30:49 -05:00
Kenny Levinsen
a047b5ee4a container: Move pending state to state struct
Pending state is currently inlined directly in the container struct,
while the current state is in a state struct. A side-effect of this is
that it is not immediately obvious that pending double-buffered state is
accessed, nor is it obvious what state is double-buffered.

Instead, use the state struct for both current and pending.
2021-02-16 22:05:00 -05:00
Kenny Levinsen
c8bf84c82d transactions: Amend pending transactions
The transaction system contains a necessary optimization where a popped
transaction is combined with later, similar transactions. This breaks
the chronological order of states, and can lead to desynchronized
geometries.

To fix this, we replace the queue with only 2 transactions: current and
pending. If a pending transaction exists, it is updated with new state
instead of creating additional transactions.

As we never have more than a single waiting transaction, we no longer
need the queue optimization that is causing problems.

Closes: https://github.com/swaywm/sway/issues/6012
2021-02-16 00:18:26 +01:00
Kenny Levinsen
37d7bc6998 transaction: Only wait for ack from visible views
Transactions currently wait for all configures to be acked, regardless
fo what they were sent to. This includes views that are hidden in tabbed
or stacked containers. If these views do not ack the configure in
response to a single frame callback, they can cause transaction
timeouts.

Check if a container is hidden before registering the configure serial
and saving any view buffers.

Closes: https://github.com/swaywm/sway/issues/6023
2021-02-15 16:58:19 -05:00
Kenny Levinsen
50205ade9d transaction: Move centering to view_center_surface
This will allow us to reuse it for centering elsewhere.
2021-02-09 09:37:10 +01:00
Kenny Levinsen
cf1e3be228 view: Save surface x and y on saved buffers
We need to use surface_x and surface_y when rendering and damaging saved
buffers as these compensate for views that have been centered due to
being smaller than their container.

Add them to the surface positions on the saved buffer so we have the
values from the time the buffer was saved.
2021-02-09 09:37:10 +01:00
Tudor Brindus
cc8d318aa1 transaction: make transaction collapsing smarter with > 2 views
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.
2020-10-19 01:40:10 +02:00
Tudor Brindus
8355884fbd transaction: validate X transaction completions by geometry, not size
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.
2020-10-18 22:37:42 +02:00
Tudor Brindus
5bd6a5ce3f transaction: don't reconfigure X views unless integral coords changed
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.
2020-10-18 22:12:16 +02:00
Kenny Levinsen
d0f7e0f481 transaction: Mark client resize immediately ready
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
2020-06-30 10:59:33 +02:00
Kenny Levinsen
5a4a7bc0da container: Remove useless surface dimensions
The adjustments to resize logic left them unnecessary.
2020-06-03 16:41:17 +02:00
Kenny Levinsen
7670f1a521 transaction: Improve transaction commentary
Some comments where slightly misleading.
2020-06-03 16:41:17 +02:00
Kenny Levinsen
645cf76f8a transaction: Account for full size when centering content
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.
2020-06-03 16:41:17 +02:00
Kenny Levinsen
fcd0ab8f33 view: Save all buffers associated with view
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.
2020-06-03 16:41:17 +02:00
Scott Anderson
e3d94cb83e Fix uninitialized read for wlr_surface_send_frame 2019-04-21 14:06:15 +03:00
Brian Ashworth
d9de5b8758 Implement inhibit_idle command
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.
2019-03-24 19:26:12 -06:00