Commit graph

106 commits

Author SHA1 Message Date
John Lindgren
a2e0de7676 tree-wide: rename seat->seat to seat->wlr_seat for clarity
As we use "seat" to refer to the labwc struct, this makes it clearer
at a quick glance which code is using the wlr struct instead.
2026-03-22 00:56:49 +01:00
John Lindgren
4f72e6775e tree-wide: rename g_server to just server 2026-03-21 21:35:33 +00:00
John Lindgren
cb49bddf63 tree-wide: auto-replace of (struct server *)
#!/bin/bash
    read -r -d '' EXPRS << EOF
    s/xwayland->server/xwayland->svr/g;

    s/\t*struct server \*server;\n//g;
    s/\t*struct server \*server =.*?;\n//gs;
    s/\t*.* = ([a-z_]*->)*server[;,]\n//g;
    s/\{\n\n/\{\n/g;
    s/\n\n+/\n\n/g;

    s/\(\s*struct server \*server\)/(void)/g;
    s/\(\s*struct server \*server,\s*/(/g;
    s/,\s*struct server \*server\)/)/g;
    s/,\s*struct server \*server,\s*/, /g;

    s/\(\s*([a-z_]*->)*server\)/()/g;
    s/\(\s*([a-z_]*->)*server,\s*/(/g;
    s/,\s*([a-z_]*->)*server\)/)/g;
    s/,\s*([a-z_]*->)*server,\s*/, /g;

    s/([a-z_]*->)*server->/g_server./g;

    s/xwayland->svr/xwayland->server/g;
    EOF

    find src include \( -name \*.c -o -name \*.h \) -exec \
        perl -0777 -i -pe "$EXPRS" \{\} \;
2026-03-21 21:35:33 +00:00
John Lindgren
16c5373be5 tree-wide: use die_if_null() for wlr_scene alloc failures
Some checks failed
labwc.github.io / notify (push) Has been cancelled
wlr_scene_*_create() functions all allocate memory via calloc() and
return NULL if the allocation fails. Previously, the failures were
handled in any of 3 different ways:

 - sending a wayland protocol error
 - exiting labwc with an error
 - segfault (no NULL check at all)

Since labwc does not attempt to survive heap exhaustion in other
allocation paths (such as `znew`), it seems more consistent to use the
same die_if_null() check used in those paths to exit with an error.

For the three most common create() functions (tree, rect, buffer),
add small lab_wlr_ wrappers to common/scene-helpers.
2026-03-15 21:26:37 +00:00
Consolatis
628e667d4b layers.c: allow layer surfaces on disabled outputs
4f8b80700e added a check for the output
being enabled when creating a layershell surface with automatic output
selection. This causes labwc to send a `layer_surface.close()` and
`wl_surface.destroy()` to layershell clients when creating a new
layershell surface on a disabled output which is still part of the layout
(e.g. `wlopm --off`).

This MR replaces the `output_is_usable()` check with a dedicated check,
bypassing the check for the output being enabled.

Fixes: #3410
Reported-By: coruja
2026-03-02 11:20:50 -05:00
tokyo4j
b4e1c256f8 layer: update pointer focus on unmap
Ensure that pointer focus is restored to the surface below when a layer
surface or popup is unmapped. Can be tested like below:

1. Open a terminal and move the cursor over it so it becomes an I-beam
2. Open a launcher (e.g. fuzzel) so the cursor becomes an arrow
3. Close the launcher
4. The cursor should become an I-beam again

Note: this commit restores `cursor_update_focus()` in
`handle_popup_destroy()` which was removed in bdbb1be3. I don't remember
why it was removed.
2026-02-22 13:04:53 +00:00
Johan Malm
bdbb1be35a layer: focus popup rather than layer-shell surface
When a opening a layer-shell popup via IPC (like `lxVqt-qdbus openmenu` or
`xfce4-popup-applicationsmenu`), give keyboard focus to the popup, not the
parent layer-shell surface.

Written-by: @tokyo4j
2026-02-21 14:05:56 +00:00
Johan Malm
00ad5a03f2 layer: move the "locked" check to seat_force_focus_surface() 2026-02-21 14:05:56 +00:00
Johan Malm
a277c35c3d layer: on popup destory, return focus
...to whoever had it before the popop

Co-authored-by: @tokyo4j
2026-02-21 14:05:56 +00:00
Johan Malm
180293e0bb Give keyboard focus to xdg-popups of unfocused layer-shell clients
...in support of enabling panel menus to be opened by keyboard shortcuts
and get keyboard focus so that they can be operated with the keyboard.

An example use-case is the xfce4-panel applications-menu being opened by
the command xfce4-popup-applicationmenu.
2026-02-21 14:05:56 +00:00
Johan Malm
477bae1422 layer: let top-layer on-demand clients grab focus
Soften the new rule introduced by 155c153 because it broke lxqt-runner
which defaults to the top-layer, and we do not want to knowingly break
user-space without a very good reason which we do not have for this.

Fixes: #3381
2026-02-18 00:52:29 +09:00
Johan Malm
155c153658 layers: restrict layer-shell on-demand focus on map
...so that clients with on-demand keyboard interactivity in the
background/bottom/top layers do not steal focus. The reason for this is to
avoid desktop components like panels and desktops from stealing keyboard
focus if they are re-started.

We still let such clients in the overlay layer get focus on map so that
for example labnag with its default <prompt> setting take keyboard focus
on map, whilst still letting users click on something else to move focus
away.

Fixes: #3167
2026-02-11 19:33:11 +00:00
John Lindgren
4f8b80700e tree-wide: do not try to use outputs with no scene_output
- check for valid scene_output in output_is_usable()
- change many "output != NULL" checks to use output_is_usable()
- remove one now-redundant separate check for valid scene_output

Fixes a crash at startup (with autoEnableOutputs=no) due to
dereferencing null scene_output in create_output_config() since:

7d7ece21d9
("output: suppress error when output position is unavailable")

Fixes: #3357
2026-02-04 21:05:16 +00:00
John Lindgren
d2ce31fcc9 tree-wide: use forward declarations for wlr types 2025-09-07 19:34:30 +09:00
John Lindgren
b00873a988 src: remove unused #includes (via include-what-you-use) 2025-09-07 19:34:30 +09:00
John Lindgren
f129571779 ssd: unify struct ssd_part with struct node_descriptor
struct ssd_part and struct node_descriptor seem to have essentially the
same purpose: tag a wlr_scene_node with some extra data indicating what
we're using it for.

Also, as with enum ssd_part_type (now lab_node_type), ssd_part is used
for several types of nodes that are not part of SSD.

So instead of the current chaining (node_descriptor -> ssd_part), let's
flatten/unify the two structs.

In detail:

- First, merge node_descriptor_type into lab_node_type.
- Add a separate view pointer in node_descriptor, since in the case of
  SSD buttons we need separate view and button data pointers.
- Rename ssd_part_button to simply ssd_button. It no longer contains
  an ssd_part as base.
- Add node_try_ssd_button_from_node() which replaces
  node_ssd_part_from_node() + button_try_from_ssd_part().
- Factor out ssd_button_free() to be called in node descriptor destroy.
- Finally, get_cursor_context() needs a little reorganization to handle
  the unified structs.

Overall, this simplifies the code a bit, and in my opinion makes it
easier to understand. No functional change intended.
2025-09-06 16:00:20 -04:00
John Lindgren
e1475a1e47 include: reduce global includes in labwc.h 2025-07-30 21:04:31 +01:00
John Lindgren
e21fc065c4 include: split output.h from labwc.h 2025-07-30 21:04:31 +01:00
John Lindgren
31d42b50e2 src: include primary header first
This is a common practice in C projects, which simply enforces that
each header must compile cleanly without implicit dependencies on
other headers (see also the previous commit).
2025-07-29 21:51:56 +01:00
Johan Malm
e365d5eaf0 layers.c: fix UAF bug on TTY change
Call seat_set_focus_layer(seat, NULL) in node-destroy-handler to avoid
seat->focused_layer becoming invalid and causing UAF issues in certain
situations like when outputs (and therefore layer-trees) are destroyed.

Fixes: #2863

Helped-by: @Consolatis
2025-06-29 23:22:05 +02:00
tokyo4j
6f70cd0d6e layers: don't send configure events in unmap handler
Alternative to 7bf08af which was reverted in the previous commit.

7bf08af fixed the problem that layer-shell clients are terminated when
it's unmapped, by sending configure events in node-destroy handler
rather than in unmap handler. But it caused a UAF bug when an output
with layer-shell clients is destroyed.

So this patch fixes the original issue by simply skipping the surface in
arrange_one_layer() if it's being unmapped.
2025-06-27 22:03:37 +01:00
tokyo4j
cc0fe78ceb Revert "layers: arrange layers on destroy"
This reverts commit 7bf08af210.
2025-06-27 22:03:37 +01:00
Consolatis
30248e1ba3 Destroy xdg_popups when its parent is destroyed
Fixes: #2845
2025-06-18 20:19:48 +01:00
Johan Malm
7bf08af210 layers: arrange layers on destroy
...rather than unmap because that is the approach of sway and it also
avoids wshowkeys crashing.

Fixes: #1153
2025-06-02 22:00:43 +01:00
Consolatis
8ba14891fa src/layers.c: send fractional scale before map 2025-05-28 14:15:03 +09:00
tokyo4j
c4f683c70d Rename some handler functions to be more consistent 2025-05-27 13:13:51 +02:00
alex-huff
fbb92e2e30 layer-shell: only configure initialized layer surfaces
Fixes #2736
2025-05-22 22:35:03 +01:00
Consolatis
9e6aaa689a project wide: clean up event listeners on shutdown
This ensures all event listeners are removed before the emitting
wlroots object is being destroyed. This will be enforced with asserts
in wlroots 0.19 but there is no reason to not do it right now either.

This change in wlroots 0.19 is implemented via commit
8f56f7ca43257cc05c7c4eb57a0f541e05cf9a79
"Assert (almost all) signals have no attached listeners on destroy"
2025-03-13 17:33:51 +09:00
Consolatis
bb64dc81d6 src/layers: handle unmap without any outputs left 2025-02-12 15:38:18 +01:00
tokyo4j
e707e16130 layer: update pointer focus on popup destruction
Same as previous commit
2024-12-20 00:43:06 +09:00
tokyo4j
1765bf8cc2 layer-shell: stop sending configure events on surface creation
With wlroots 0.18, layer-shell's new_surface event is emitted on
zwlr_layer_shell_v1.get_layer_surface request rather than the first
commit. This change layer-shell clients like fuzzel to flicker on launch
because labwc was sending a configure event with fullscreen geometry due
to the absence of geometry hints on get_layer_surface requests.

This commit removes the code that updates the usable area from
new_surface handler, preventing unintended configure events with
fullscreen geometry.
2024-07-23 14:47:56 +02:00
Consolatis
3b2ab4a48e chase: move xdg destroy signal to toplevel / popup
https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4345
2024-07-17 21:28:59 +01:00
John Lindgren
a98f2635ea xdg: support xdg-shell v3 with popup repositioning
See https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3514
which added support on the wlroots side.

We now re-run popup positioning (for both xdg-shell and layer-shell
popups) when the "reposition" event is received. This allows popups that
change size (such as qmpanel's applications menu) to be positioned
correctly.

xdg-shell v3 also gives the compositor some additional "hints" for popup
positioning (reactive, parent_size, and parent_configure_serial) which
are available but we don't make use of currently.
2024-07-01 20:16:31 +01:00
Consolatis
c80b55eb69 src/layer.c: deal with wlroots scene graph running out of memory
This fixes an issue detected by the static analyzer.

Rather than setting up the new popup as usual return
a wayland error to the client and destroy the popup.
2024-04-10 08:14:59 +02:00
Johan Malm
4fc6bce3ea layer: try to set keyboard focus on map
...for the following reasons:

1. We interpret 'normal input-focus semantics' for clients with on-demand
   keyboard interactivity to means that a surface receives input focus on
   cursor-button-press AND on map (the latter previously missing), just
   like a normal window would. In this regard, we do not differentiate
   between layers.

2. Most layer-surfaces set the keyboard interactivity at a similar time to
   their first (and normally only) map, so the absence of an explicit
   attempt to focus on map does not make a difference. However, for a
   long-running layer-shell client (such as lxqt-runner) which sets the
   interactivity on launch and then maps/unmaps many times throughout its
   lifetime, a specific focus-attempt is required on map to avoid the
   client itself having to keep resetting its interactivity to grab the
   keyboard on map.

3. Compositors like sway and river process focus (for clients with
   keyboard-interactivity)  in their map-handlers, so this makes for a
   common approach.

Fixes: #1653
2024-03-24 23:00:13 +01:00
Johan Malm
6990ff713b layer: do not focus on-demand clients in commit-handler
...because we should only try to focus them as part of normal input
handling semantics, for example when receiving a cursor-button-press.
2024-03-17 21:18:47 +00:00
Johan Malm
e67e8d6ed0 layer: do not change keyboard-focus in map-handler
If a client wants keyboard-interactivity this will be processed in the
commit handler.

Remove duplicate (and incorrect) requrests for focus.
2024-03-17 21:18:47 +00:00
Johan Malm
cb361fbb55 layer: change focus better on 'none' keyboard-interactivity request
...and on unmap.

Add `try_to_focus_next_layer_or_toplevel()` which does the following
(in order of precedence):

- Give focus to last added overlay/top layer-shell client with exclusive
  interactivity on the output nearest the pointer (normally the one where
  the users is currently working). The reason for not considering clients
  on all outputs is that giving focus to a client on another output may be
  confusing to the user.

- Give focus to topmost toplevel if one exists (this was done previously
  anyway).
2024-03-17 21:18:47 +00:00
Johan Malm
36058a63e2 layer: change logic for giving keyboard-interactivity
Use the following logic:
 - Exclusive: Grant regardless of layer (previously it was only given if
   in top or overlay layers) AND grant if in the same or higher layer
   (nearer overlay) compared with other clients with exclusive
   interactivity.
 - On-demand: Grant only if no other layer-shell client has exclusive
   keyboard interactivity. Previously it was treated the same as
   exclusive.
 - None: Unset focus if the commit associated with the 'none' came from
   the currently focused layer. Previously it was just unset regardless.
2024-03-17 21:18:47 +00:00
tokyo4j
b6d576922b IME: support IME popup 2024-03-14 20:11:03 +00:00
Consolatis
598ab9bcff src/layers.c: delay popup unconstrain until after first commit
Fixes: #1372
2024-02-25 11:49:03 +00:00
kyak
266690091f Remove headers not being used directly
Fix clangd warnings regarding headers not being used directly.
2023-12-22 20:19:39 +00:00
Consolatis
02aa000b0d src/layers.c: move popups from the background layer to the top layer
Previously we would only do that for the bottom layer.

Fixes #1293

Reported-by: @spl237
2023-12-07 11:11:47 +01:00
Consolatis
d59b1d0966 src/layers.c: calculate usable_area before positioning clients
This ensures that the usable area is completely calculated
before non exclusive-zone clients are positioned / resized.

Fixes #1285
Reported-by: @spl237
2023-12-06 22:04:07 +00:00
Christopher Snowhill
d7dc6e01b4 Chase wlroots: Unified mapping
Need to handle new unified mapping, where mapping is attached to the
wlr_surface objects instead of their parents. Also, most of them require
a new associate event for xsurface objects, their surface member will be
NULL before this event is received.

Refactored by jlindgren:
- add struct mappable
- unify map/unmap logic
2023-11-27 21:01:53 +00:00
Consolatis
b4fc72b460 Chase wlroots: Layershell version
Chases 9f793d350379872aeee56ea5c476adfeedc8bc88
layer-shell-v1: specify version in constructor
2023-11-27 21:01:53 +00:00
John Lindgren
a036d985d7 common: rename array-size.h to macros.h 2023-10-21 12:37:42 +01:00
Johan Malm
cf72d01f0c layers: remove redundant function argument 2023-10-16 17:10:09 -04:00
Johan Malm
8d3b15576b Add ARRAY_SIZE() macro 2023-09-19 22:03:59 +01:00
Johan Malm
4a531daef8 config: support <margin top="" bottom="" left="" right="" output="" /> 2023-06-26 06:04:07 +01:00