Commit graph

3460 commits

Author SHA1 Message Date
Consolatis
4faab834f9 xwayland: make X11 always-on-top request opt-in
Fixes: #3441
2026-03-15 13:09:05 +01:00
tokyo4j
a3646721bc view: clear view->{title,app_id} later in view_destroy()
...as it *feels* unsafe to call functions like `undecorate()` after
clearing view->{title,app_id}, which are expected to be non-NULL.
2026-03-11 19:30:50 +01:00
tokyo4j
ab60379c7f ssd-titlebar: update title buffer when title gets empty
Before this commit, ssd_update_title() returned early and the title was
not updated when the title gets empty. Furthermore, this caused the
title buffer to be misplaced outside of the titlebar when the window is
resized.

Reproducer:
1. Build and launch https://github.com/tokyo4j/wayland-demo/tree/repro-labwc-ssd-title-not-updated
2. One second later, the window title gets empty. But the title in
   SSD is not updated.
3. Un-minimize the window. Now the title buffer is misplaced outside of
   the titlebar.
2026-03-11 19:30:50 +01:00
Consolatis
93029ca583 src/output.c: guard against wlroots not providing the X11 backend
Reported-By: Flrian via IRC
2026-03-11 15:57:44 +01:00
Consolatis
89574772d0 src/output.c: handle outputs with all modes failing
- To reset the mode request we were using wlr_output_state_set_mode(NULL) which is not
  allowed in wlroots. Replace it with removing the mode from the commit manually.

- Before this patch, we would assume that we can't configure an output if it doesn't have
  any fixed mode. This is not true for wayland backed nested outputs. Replace the fixed
  return false with wlr_output_test_state().

- Prevent configuring the output if the test fails as the current behavior was a
  workaround for the hardcoded return false in case there were no fixed modes available.

Fixes: #3428
Reported-By: kode54
2026-03-11 09:34:34 +01:00
Jonathan Marler
b36b4ab816 output: exit compositor when last nested output is destroyed
When running on the X11 or Wayland backend, each output corresponds
to a window in the parent compositor. Unlike DRM outputs, these
cannot be reconnected after being destroyed.

Terminate the compositor when the last output is destroyed on these
nested backends, matching the expected behavior when the user closes
the window.
2026-03-11 09:31:23 +01:00
Consolatis
f0589810ad src/cycle: handle views without output
Fixes: #3425
Reported-By: kode54
2026-03-10 22:34:16 +09:00
tokyo4j
3bb4ccd22d view: save view->last_placement on initial positioning
Fix a regression introduced in 3f223fe5 where output layout changes may
move xdg views outside of the output layout with the error:
`view has no last placement info`. This happens also for X11 views if
they don't specify its own geometry on map.

Recent changes introduced `view->last_placement` which is used to
restore view positions after layout changes. This is supposed to be
updated when a view is mapped or manually moved by the user.

However, 3f223fe5 replaced `view_place_by_policy()` with
`view_compute_position_by_policy()` in the xdg view map handler. Unlike
`view_place_by_policy()`, this function does not update
`view->last_placement`, leaving it unset at the time of output layout
changes.

Therefore, this patch adds explicit calls to `view_save_last_placement()`
in the map handler to ensure `view->last_placement` is always set for
mapped views.
2026-03-10 21:05:53 +09:00
Alexander Ziaee
1f776466a8 labwc-config.5: document mouse cursor variables
Some checks failed
labwc.github.io / notify (push) Has been cancelled
It was written that mouse cursor size can be set with XCURSOR_SIZE.
However, XCURSOR_THEME is also required, which exists in the context
of XCURSOR_PATH. Break them down in the ENVIRONMENT VARIABLES section.

Reported by: Consolatis (PATH)
Reported by: Jan Beich <jbeich@FreeBSD.org> (THEME)
Reported by: Thomas Dickey <dickey@invisible-island.net> (SIZE)
2026-03-08 08:08:02 +01:00
Tobias Bengfort
9de35d7b4f
src/server.c: fix name of xdg-dialog-v1 global for sandbox permission 2026-03-07 04:29:29 +01:00
Consolatis
8d8654db02 action: sync action arrays
The previous commit desynchronized the action type arrays
causing Move operations to be treated as Raise actions.

Fixes: #3398
Reported-By: Domo via IRC
2026-03-06 03:12:18 +09:00
tokyo4j
d6dab9139f action: reorder ACTION_TYPE_MOVE enum entry
This makes the code a bit easier to read by aligning ACTION_TYPE_MOVE
and ACTION_TYPE_MOVE together.
2026-03-05 19:19:01 +09:00
tokyo4j
00f63622b5 interactive: subtle refactor to interactive_set_grab_context()
- Add `server` argument to `interactive_set_grab_context()` to clarify
  it updates something in `server`.
- Add `const` qualifier to `ctx` argument of
  `interactive_set_grab_context()` and `cursor_get_resize_edges()`
2026-03-05 19:19:01 +09:00
John Lindgren
df73a97efa view: add/improve some comments 2026-03-05 19:06:59 +09:00
John Lindgren
3f223fe5b0 xdg: unify initial positioning logic 2026-03-05 19:06:59 +09:00
John Lindgren
658df83280 xdg: set initial output at initial commit
This seems to be the best point to do it, since the parent view is known
but initial maximized/fullscreen state hasn't been applied yet.
2026-03-05 19:06:59 +09:00
John Lindgren
1211c43a47 view: honor placement policy in more scenarios 2026-03-05 19:06:59 +09:00
John Lindgren
5238dcaa08 view: factor out view_compute_position_by_policy() 2026-03-05 19:06:59 +09:00
John Lindgren
6a9e6dcae1 view: factor out view_compute_cascaded_position() 2026-03-05 19:06:59 +09:00
John Lindgren
04cd38f251 view: factor out view_compute_near_cursor_position() 2026-03-05 19:06:59 +09:00
John Lindgren
7be407c8e4 view: un-fullscreen/maximize/tile before any placement policy 2026-03-05 19:06:59 +09:00
John Lindgren
d4ca1dfb69 view: make view_move_to_cursor() static 2026-03-05 19:06:59 +09:00
Johan Malm
3131c71acd build: bump version to 0.9.5 2026-03-04 20:56:03 +00:00
Johan Malm
9192bdab0e NEWS.md: update notes for 0.9.5 2026-03-04 20:53:38 +00:00
Johan Malm
d4ef6a5ac6 README.md: add link to release video for 0.9.4
Some checks failed
labwc.github.io / notify (push) Has been cancelled
2026-03-03 20:50:32 +00:00
Birger Schacht
50d9385906 docs: fix typos in labwc-config.5.scd 2026-03-03 20:44:31 +00:00
John Lindgren
72cdd02eb1 xwayland: handle client close request 2026-03-02 17:58:33 +01: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
John Lindgren
079b3b8a10 xwayland: honor client request for always-on-top 2026-03-01 01:40:46 +01:00
John Lindgren
13200cc0d7 view: add view_set_layer() 2026-03-01 01:40:46 +01:00
Johan Malm
68c826e082 build: bump version to 0.9.4 2026-02-27 18:19:10 +00:00
Johan Malm
2be713ece7 NEWS.md: update notes for 0.9.4 2026-02-27 18:02:27 +00:00
Consolatis
651ffe5744 src/server.c: increase max client buffer size to 1 MiB
Allows slow clients to better deal with large amounts of events
coming in from labwc like from high refresh rate mice. Without
this patch, the client is likely to get disconnected because the
labwc side client write buffer is full.
2026-02-25 19:34:01 +00:00
Weblate
74ab7e1779 Translation updates from weblate
Co-authored-by: Peter  Jespersen <flywheel@illogical.dk>
Translate-URL: https://translate.lxqt-project.org/projects/labwc/labwc/da/
Translation: Labwc/labwc
2026-02-22 21:08:40 +00: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
Consolatis
89325fbff8
CI: force c11 for wlroots compilation (#3385)
Works around `initialization discards ‘const’ qualifier from pointer target type`
Already fixed in wlroots master and 0.19.3 but that one has not yet been merged.
2026-02-19 02:57:25 +01: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
tokyo4j
654da8c8a9 workspaces: keep unfocusable omnipresent views visible
When switching between workspaces, we need to migrate omnipresent views
to the new workspace so that they are kept visible.
However, by using for_each_view_reverse() macro, we were not migrating
omnipresent views that view_is_focusable() return false (e.g. Conky).

Use wl_list_for_each_reverse() macro instead to catch all the
omnipresent views.
2026-02-13 22:28:29 +01:00
tokyo4j
a2eae22fc2 view: decouple always-on-top windows from the omnipresent state
Before this commit, always-on-{top,bottom} windows were always visible
on all workspaces (omnipresent) because the they were not in
per-workspace trees like normal windows.

This commit fixes this by introducing per-layer trees in
`struct workspace`.

I also added `enum view_layer` and `view->layer` for simplicity.
2026-02-12 14:44:20 +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
a672e8a9fd interactive: set grab parameters at cursor press
Add interactive_set_grab_context() which is called when the mouse button
is first pressed, before interactive_begin(). This fixes two small issues:

- The cursor origin position for interactive move/resize was slightly
  off (depending on mouse resolution), because it was set after the
  mouse had already moved slightly. Now it's exact.

- If app- or keybind-initiated maximize (etc.) happened after the button
  press but before the mouse was moved, then interactive_begin() would
  still start move/resize even though the view might now be far away
  from the cursor. Now interactive_cancel() works as expected, even if
  called before interactive_begin().

Also, make sure to call interactive_cancel() for un-maximize as well.
2026-02-10 21:29:16 +00:00
Johan Malm
3ea46ba45a labwc-theme(5): describe button hover overlay
Some checks failed
labwc.github.io / notify (push) Has been cancelled
...in more detail to explain that the effect is only shown if there is no
associated hover icon.
2026-02-08 18:45:48 +00:00
Johan Malm
54554f43dd theme: add option window.button.hover.bg.color 2026-02-08 18:45:48 +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
81778a16bb xwayland: flush X11 connection after focus/activate
This mitigates a race where the XWayland server may generate an unwanted
FocusOut event for the newly activated window, if it receives mouse/
pointer events over the parallel wayland connection first.

In particular, this fixes an issue with certain fullscreen applications
(such as Minecraft) that self-minimize when receiving FocusOut.

Also limit a previous similar workaround to apply only to XWayland views.

Fixes: #3344

See also: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/4044
2026-02-04 18:53:45 +01:00
tokyo4j
12b6d05481 view: fix error messages on region or usable area changes
f58b532 implemented output-relative position saving/restoring on output
un-plugging/re-plugging. It worked as follows:

1. Store the output-relative view geometry in `view->last_placement`
  (if not set) before adding/removing an output from the layout.
2. After adding/removing an output, call `view_adjust_for_layout_change()`
  after the layout change to restore the output-relative view geometry
  based on `view->last_placement`.

However, it didn't consider `view_adjust_for_layout_change()` being
called from other places such as `regions_reconfigure()` and
`output_update_all_usable_areas()`, causing an error message "view has
no last placement info". This can happen when a panel is mapped or
unmapped, or on Reconfigure.

This commit fixes it by changing the life cycle of
`view->last_placement`. It used to be set only before output layout
changes and cleared on user-initiated moves/resizes, but now it is set
and updated on user-initiated moves/resizes. I think this is more
intuitive, too.
2026-02-04 19:14:51 +09:00