Commit graph

253 commits

Author SHA1 Message Date
John Lindgren
ef766d16f0 common: flesh out enum lab_edge and prefer over wlr_edges/wlr_direction
I like the new common/edge.h. I don't like how inconsistently we use it.

Current situation:

 - enum wlr_edges and wlr_direction are designed to be used as bitset,
   and are defined compatibly

 - enum lab_edge is *also* designed to be used as bitset, but
   incompatible with the others (LEFT/RIGHT come before UP/DOWN)

 - we use an inconsistent mix of all three *AND* uint32_t (usually with
   the WLR_EDGE constants rather than the LAB_EDGE constants), and
   convert between them on an ad-hoc basis, sometimes implicitly

Let's clean this up:

 - reorder enum lab_edge to be compatible with the two wlr enums
   (check this by static_assert)

 - use TOP/BOTTOM naming rather than UP/DOWN (matches wlr_edges)

 - add constants for the remaining possible combinations of the 4 edges

 - use lab_edge for all internal edge/direction fields, consistently

 - add lab_edge_is_cardinal() as a sanity check before casting to
   enum wlr_direction, and then eliminate all of direction.c/h

Instead of "enum wlr_edges direction", we now have
"enum lab_edge direction" which is not that much better. At least we
are now clear that we're overloading one enum with two meanings.
2025-08-26 20:36:43 -04:00
John Lindgren
9d49d19cd2 include: add config/types.h 2025-08-21 16:55:25 +09:00
John Lindgren
02df0a15d7 foreign-toplevel: simplify and fully separate ext-foreign/wlr-foreign
Currently, the dependencies between foreign-toplevel[-internal],
ext-foreign, and wlr-foreign are cyclical and a bit complex.

I suggest we reorganize it into a simpler hierarchy:

  foreign-toplevel/
    -> foreign.c/h
      -> (depends on) ext-foreign.c/h
      -> (depends on) wlr-foreign.c/h

The refactored code is smaller and (IMO) easier to follow.

In detail:

- Add include/foreign-toplevel folder mirroring src/foreign-toplevel
- Split foreign-toplevel-internal.h to ext-foreign.h and wlr-foreign.h
- Eliminate ext-/wlr-foreign.c -> foreign.c reverse dependencies
  (including internal signals and foreign_request* functions)
- Make struct foreign_toplevel private to foreign.c

Lightly tested with qmpanel (which uses wlr-foreign-toplevel).

v2: reorder foreign-toplevel internal API funcs
2025-08-07 23:27:04 -04:00
John Lindgren
508df093c4 xdg: try to keep view on the same output in timeout case 2025-08-06 18:14:24 +09:00
John Lindgren
9557091a1a xdg: don't try to reposition unmapped view in timeout handler 2025-08-06 18:14:24 +09:00
tokyo4j
2f183cdcb6 interactive: allow snapping to corner edges
In addition to <snapping><range>, <snapping><cornerRange> configures the
distance from the screen corner to trigger quater window snapping.

Also, new values "up-left", "up-right", "down-left" and "down-right" are
allowed for <action name="(Toggle)SnapToEdge" direction="[value]"> and
<query tiled="[value]">.
2025-08-04 21:24:12 +01: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
tokyo4j
bdaf85eda1 Fix some warnings from clang-tidy
Notably this fixes a possible null pointer dereference in warp_cursor()
when output_nearest_to_cursor() returns null.
2025-07-28 15:27:45 +02:00
Consolatis
f7702af9e4 src/xdg.c: prevent interacting with un-initialized xdg toplevels after unmap
Fixes: #2937
Fixes: #2944

Originally-Reported-By: tranzystorekk via IRC
2025-07-27 23:51:28 +09:00
tokyo4j
0d9384de74 style: remove newlines after wl_list_for_each_reverse() 2025-07-27 08:26:39 +09:00
tokyo4j
75bd188592 Strictly use handle_ prefix for signal handlers 2025-06-28 19:36:29 +09:00
Consolatis
30248e1ba3 Destroy xdg_popups when its parent is destroyed
Fixes: #2845
2025-06-18 20:19:48 +01:00
Consolatis
a8df2487b2 xwayland: support _NET_WM_ICON 2025-06-18 14:31:05 +09:00
tokyo4j
ab9cf4dc97 Bump xdg-shell version from 3 to 6
- Send xdg_toplevel.wm_capabilities
- Send xdg_toplevel.configure_bounds so that clients can map a window that
  fits within the usable area, without relying on
  view_constrain_size_to_that_of_usable_area() which is called after map.
- (The new "suspended" state should be handled by wlr_scene in the future)
2025-06-13 20:43:12 +01:00
Consolatis
4d79f0057f Ensure the view signals are initialized early
This prevents a crash observed by the scaled-icon-buffer listening
to the `view->events.set_icons` signal before it is initialized.
For this to happen, the application needs to use the kde decoration
protocol and set it on the xdg_surface before creating the xdg_toplevel.

Fixes: #2798
2025-06-07 05:03:57 +02:00
tokyo4j
fb077c0095 Support xdg-toplevel-icon protocol
This patch also changes the semantics of scaled_icon_buffer: rather than
calling scaled_icon_buffer_set_app_id() every time an app_id is set, we
can now call scaled_icon_buffer_set_view() just once so that multiple
scaled_icon_buffers bound to a window are automatically updated when an
app_id is set or new icon is set via xdg-toplevel-icon-v1.
2025-06-07 02:12:56 +09:00
John Lindgren
0908bb5dd1 xdg: add missing tracking of configure serials
In some cases, we would schedule a configure event but not record that
we had done so, leaving view->pending_configure_serial incorrect. This
caused incorrect handling of in-flight commits that had not yet taken
the new configure into account, such as assuming that the client had
ignored the configured size and incorrectly resetting view->pending.

Fixes: #2774
2025-06-05 05:49:17 +09:00
tokyo4j
c4f683c70d Rename some handler functions to be more consistent 2025-05-27 13:13:51 +02:00
tokyo4j
68bf55d724 Add -Wshadow + reformat switch cases
Adding -Wshadow will prevent unintentional variable overrides.

Also, wrapping switch cases with declarations with braces will make our
logic more robust by limiting lifetimes of variables.
2025-05-23 21:32:17 +01:00
John Lindgren
fd5031731e xwayland: use wlr_xwayland_surface_has_window_type()
This eliminates a bit of logic, including an extra XWayland connection.

See also:
https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4553
2025-05-22 23:09:41 +01:00
Consolatis
1dc4e7ed28 chase wlroots: wlr_xdg_surface_get_geometry remove MR 4788
Ref: 5c98d1a04a1439bf40c6e516086cfaff2d67f135
("xdg-surface: fix window geometry handling")
2025-05-21 06:36:08 +01:00
Consolatis
1eaba4af33 chase wlroots: xwayland separate maximized axis MR 4670
Ref: ceb4fcedca30d323a05836b0872bfe773a047ccc
("xwm: expose individual axis for _set_maximized()")
2025-05-21 06:36:08 +01:00
tokyo4j
81204b0537 xwayland: notify correct window stacking order to xwayland
Before this commit, when a normal window is raised, xwayland thought it's
above always-on-top (AOT) windows even though it's actually below AOT
windows in the scene. This means mouse scroll events may be unexpectedly
sent to normal windows below AOT windows even when the cursor is hovering
over a AOT window.

So this commit fixes it by notifying the correct stacking order (where AOT
windows are placed above normal windows) to xwayland every time the
stacking order is updated.

Other benefits of this commit are:
- It makes the code more readable and predictable by aggregating logic
  about stacking order management in xwayland (e.g. shaded windows or
  windows in other workspaces should be notified to xwayland as being
  placed at the bottom).
- As server->last_raised_view is removed in the previous commit, we were
  notifying the stacking order to xwayland every time a window with dialog
  windows is clicked (not when clicking a topmost window without dialogs,
  due to some optimization in wlroots). This commit fixes this by caching
  the window stacking order in xwayland_view->stacking_order and notifying
  it to xwayland only when it's updated.
2025-04-01 16:48:40 +09: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
tokyo4j
270b45da88 desktop: harden window stacking order while window switching
This commit moves the check against server->input_mode from the callers
of desktop_focus_view() into desktop_focus_view() itself. This
eliminates code duplications and makes it harder to mess up the window
stacking order while window switching.

I also added the same check in view_minimize() so that minimize requests
from panels never messes up the window stacking order (I think only this
should be described in the release note).
2025-03-09 20:41:26 +00:00
tokyo4j
4b7c502ace view: replace content_node with content_tree 2025-01-22 18:02:54 +01:00
yuiiio
f4d581ef91 xdg: cleanup request_show_window_menu listener when destroy 2025-01-16 00:08:56 +01:00
Johan Malm
023427b4f4 view: fix NULL string_prop crash
...when app_id is NULL.

Make sure view_get_string_prop() never returns NULL because it is so easy
to misuse. Same for the respective xwayland/xdg impl methods in case
anyone decides to (incorrectly) call them directly in future.

Fixes: #2453
2024-12-29 13:06:30 +00:00
tokyo4j
5d3ce3e190 Check input_mode to see whether window switcher is active or not
...rather than "if (server->osd_state.cycle_view){..}".
2024-12-28 21:28:22 +00:00
tokyo4j
daae379433 view: s/scene_node/content_node/ 2024-12-14 12:03:58 +09:00
Consolatis
2a825008c6 foreign-toplevel: create generic abstraction 2024-11-09 20:06:19 +00:00
Consolatis
5e1f91c9d1 view: add state change signals 2024-11-09 20:06:19 +00:00
Hiroaki Yamamoto
a5d89a2e4c
xdg: take into account minimum window size for resizing (#2221)
This is especially relavant for <resize drawContents="no">.
2024-10-06 16:58:54 +01:00
tokyo4j
c413e65a20 xdg: fix crash on actions from menu opened by show_window_menu requests
Also removed a redundant line in show_menu() in action.c.
2024-10-05 07:40:09 +09:00
Johan Malm
d18e67eea8
Merge pull request #2030 from Consolatis/wip/cosmic_workspaces
Initial implementation of cosmic-workspace-unstable-v1
2024-10-01 21:31:04 +01:00
John Lindgren
452f45cd3d xdg: try to handle slow un-maximize with empty natural geometry better
In the case of an initially-maximized view which is taking a long time
to un-maximize (seen for example with Thunderbird on slow machines), we
may end up in handle_configure_timeout() with an empty pending geometry.
In that case we have no great options (we can't center the view since we
don't know the un-maximized size yet), so set a fallback position.

v2: check wlr_box_empty() before comparing pending and current

Fixes: #2191
2024-10-01 21:22:00 +01:00
tokyo4j
014d07651f xdg: fix de-synced SSD when shrinking Thunderbird window
On a slow mechine or heavy load, we sometimes see de-synced SSD with
Thunderbird windows when shrinking it. Here's how it happened:

1. Labwc sends a configure event.
2. The configure event timeouts and labwc resets view->{pending,current}
   with the old geometry.
3. Thunderbird updates the toplevel window geometry and the toplevel
   surface size, but not the subsurface size. Then it sends a commit.
4. Since now the committed window geometry and view->pending are
   different, the workaround for Qt apps is applied and the whole surface
   extent is set to view->current. Thus SSD stays in the old geometry.
5. Thunderbird finally updates the subsurface size.

So, this commit fixes this conflict between Thunderbird and the workaround
for Qt apps by using the toplevel surface size instead of the whole
surface extent to update view->current.
2024-09-30 10:19:54 +09:00
David Turner
ff012fa331 Don't detect edge-resizes in configure timeout
If a client times out responding to a configure request then the
handle_configure_timeout() callback is run.  This cleans up the pending
state and moves the view to the pending location, but keeps the current
size. The idea is to stop slow applications causing too much lag when
the user manipulates the window.  This callback used
view_impl_apply_geometry() to actually apply the changes.

view_impl_apply_geometry() contains some heuristics to detect if we're
resizing a window from the top, left, or top-left, and if so to do the
expected behaviour of keeping the window's bottom/right corner in the
same place.  However, that code was erroneously triggering in the case
when the user requests to change a window from maximized to fullscreen
but the client times out on the configure request.
handle_configure_timeout() decides to enact the movement of the window
but keep its size at the old size and tells view_impl_apply_geometry()
to do that.

The current view position and size is 0,64 1920x1016, the pending
position/size is 0,0 1920x1080, and the last committed size is
1920x1016.  Looking at the current and pending position and size, the
height changes while the bottom edge stays in the same place so this
looks like a top-edge-resize and view_impl_apply_geometry() decides to
keep the window's bottom edge in the same place while setting the
position according to the last-committed size.  This results in the
window staying at position 0,64 size 1920x1016 despite being marked as
fullscreen.

My solution to this is just to change handle_configure_timeout() to
directly change the view's position and call view_moved() if necessary.
The idea of handle_configure_timeout() is to action the window movement
now while discarding the size change, and let the size change take place
later on when the client catches up.  The logic of
view_impl_apply_geometry() doesn't make sense in this case so just avoid
it entirely.

Fixes #1922
2024-09-24 19:45:16 +01:00
tokyo4j
80e7b64a41 xdg: handle show_window_menu requests 2024-09-21 18:34:17 +01:00
tokyo4j
31fec2f9cb xdg: don't always adjust the window size before configure
This fixes the small flicker when the client initially submits a window
size smaller than the minimum value.
2024-09-21 18:08:29 +01:00
tokyo4j
1f1bdad087 interactive: allow moving horizontally/vertically maximized window
Applies drag resistance unidirectionally for horizontally/vertically
maximized windows, allowing them to be dragged without being untiled
immediately. When the distance of cursor movement orthogonal to the
maximized direction exceeds <resistance><unMaximizeThreshold>.

While dragging a horizontally/vertically maximized window, edge/region
snapping is disabled to prevent unintentional snapping and overlays.

This commit also includes some refactoring to simplify the logic.
2024-08-26 20:30:22 +02:00
tokyo4j
8b12b50137 xdg: destroy foreign toplevel handle on unmap
xdg-shell protocol says:
    All active operations (e.g., move, resize) are canceled and all
    attributes (e.g. title, state, stacking, ...) are discarded for an
    xdg_toplevel surface when it is unmapped.
So, when a xdg-toplevel is unmapped (not minimized), the corresponding
foreign handler should be destroyed to reset attributes.
2024-08-16 21:38:15 +01:00
tokyo4j
6687640665 xdg: fix error when launching windowed Chromium
Chromium sends 2 commits before the commit with a buffer attached. We
were just checking `wlr_box_empty(&view->pending)` to handle the cases
where an initially maximized/fullscreen client is windowed, but that
check was also returning true on the 2nd commit from Chromium, resulting
in an error message: "view has empty geometry, not centering".
2024-08-11 16:48:40 -04:00
tokyo4j
de38c771fc xdg-activation: temporarily disable source surface verification
71451173 validates the xdg-activation token more strictly by verifying
the source surface attached to the token. That  improves the security by
preventing arbitrary focus-stealing.

However, not all clients attach a right source surface to the token or
use the received token for activation. For example, when a notification
client requests thunderbird to activate its window, thunderbird doesn't
use the token passed by the notification client and instead use their own
token, thus the activation is rejected as the surface attached to the
token is not focused.

We will add options to configure the policy for activation requests or
implement urgency hint in some way in the future and reland the source
surface verification.
2024-08-11 09:33:26 +02:00
John Lindgren
1a339f9c7e xdg: account for drag resistance in do_late_positioning()
The position where the view should be anchored can now be slightly
different from the current cursor position.

Addresses a TODO from #2009.
2024-08-06 13:51:35 +09:00
tokyo4j
c202d77c2d Add resistance when dragging tiled windows
Adds a config option <snapping><dragResistance> with default value 20.
This prevents tiled/maximized windows from being unintentionally untiled.
2024-08-02 23:40:26 +02:00
Consolatis
d9866aafa5 workspaces: slight struct reordering 2024-08-02 19:35:36 +02:00
John Lindgren
a75301dae5 xdg: remove useless view_set_ssd_mode() in xdg_toplevel_new()
The desired SSD mode is not known at this point. When it is known,
kde-deco/xdg-deco will call view_set_ssd_mode() themselves.
2024-07-20 10:57:44 -04:00
John Lindgren
2b7d0e17fc xdg: update initial maximize logic for wlroots 0.18
The initial configure event is now sent explicitly by labwc rather
than by wlroots. We need to move the maximize/fullscreen logic to
the initial commit handling accordingly.

Updates #1956, fixes #1994, replaces #1995.
2024-07-20 10:57:44 -04:00