Before this commit, we assumed `ShowMenu` action is not bound to any
buttons other than window menu button and always place the client-menu
under the window-menu button when atCursor="no". Also, it was going to be
difficult to distinguish whether the action is executed from the window
menu button or the window icon, which will be added soon.
This commit fixes it to open the menu under the actually-clicked button by
passing `cursor_context` to `actions_run()`, with some refactoring:
- `seat->pressed.resize_edges` is removed and it's calculated from the
cursor position and `seat->pressed.type` just before running Resize
action. This slightly changes the existing logic to determine the
resizing edges with Alt-Right + Drag mousebinding, but
`seat->pressed.type` is still stored on button press so it doesn't bring
back the issue #543.
- `seat->pressed.toplevel` is removed and `get_toplevel()` in
`update_pressed_surface()` may be called more often, but its overhead
will be negligible.
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.
This implementation is nearly identical to Sway's, except that
it also reloads the configuration, to spur on reloading the
server-side decorations.
v2: Fix style.
v3: Add a reset to the magnifier.
v4: Oops, restructure reset handler a bit.
v5: Commit the magnifier reset immediately, before freeing the
lost allocator and renderer.
v6: Also check for failed render pass, which may return NULL.
v7: Add a second NULL test, just in case.
Currently, initially maximized (or fullscreen) xdg-shell views exhibit
one of two issues:
- some (e.g. GTK and Qt apps) paint an initial frame un-maximized
(before the "map" event) and only maximize in a later commit
- others (e.g. foot) maximize immediately without flicker, but never
store a valid natural size, so we end up using a fallback (640x480)
Under KWin, neither of these issues occur, so I looked into what labwc
is doing wrong. It seems that:
- wlroots internally sends an initial configure event with a size of
0x0 to all xdg-shell views. This requests the client to set its own
preferred (a.k.a. natural) size.
- For an initially maximized/fullscreen view, the initial configure
event should contain the maximized/fullscreen size rather than 0x0.
In labwc, this means we have to call wlr_xdg_toplevel_set_size()
earlier, i.e. from the new_surface event. Tracing with WAYLAND_DEBUG
shows that the initial configure event now has the correct geometry,
matching KWin behavior. With this change, GTK and Qt apps no longer
paint an incorrect un-maximized frame.
- However, this means that all xdg-shell views now suffer from the same
issue as foot, where we never receive a commit with the un-maximized
(natural) geometry. The correct way to get the natural geometry seems
to be to wait until we want to un-maximize, and send a configure
event of 0x0 at that point.
Sending a configure event of 0x0 when un-maximizing is a bit annoying as
it breaks some assumptions in labwc code. In particular:
- view->natural_geometry may now be unknown (0x0), requiring various
wlr_box_empty() checks sprinkled around. I added these in all the
obvious places, but there could be some code paths that I missed.
- Positioning the newly un-maximized view within view_maximize() no
longer works since we don't know the natural size. Instead we have to
run the positioning logic from the surface commit handler. This
results in some extra complexity, especially for interactive move.
See the new do_late_positioning() function in xdg.c.
Some TODOs/FIXMEs (non-blocking in my opinion):
- The view_wants_decorations() check is now duplicated in both the
new_surface and map event handlers. I'm not sure if this is necessary
but it seemed like the safest approach for now. More testing would be
nice, particularly with various combinations of config and client SSD
preferences.
- Aside from the interactive move case, the "late positioning" logic
always centers the view when un-maximizing, and does not invoke any
of the smart placement logic. If we want to invoke smart placement
here, I'd appreciate someone with more knowledge of that code to take
a look and figure out how to do that correctly.
wlroots < 0.17 didn't allow to reliably check the source surface of
an xdg activation request as it reset the surface to NULL when it
was destroyed before the token was used. This happens regularly for
notifications for example. Thus we treated the token as valid even
without checking for the source surface.
wlroots 0.17 added a new_token signal where we can attach information
to the existing token which we can then use when evaluating activation
requests. This patch implements that check.
...when cycling windows. Also make the toggling of direction when shift
is pressed relative to the initial direction. For example if W-j is
bound to PreviousWindow, subsequent key presses will continue to
cycle backwards unless shift if pressed.
Add documentation for using shift/arrow keys in Next/Previous
... at the same time. Omit cursor notifications from
a pointer when a tablet tool (stylus/pen) is in
proximity. We expect to get cursor notifications
from the tablet tool instead.
- Replaced `session_lock` with `session_lock_manager` which is
persistent throughout the session.
- Replaced `session_lock->abandoned` with `session_lock_manager->locked`.
Old `session_lock->abandoned` is equal to
`!session_lock_manager->lock && session_lock_manager->locked`.
- Eliminated the use of global variables in `session-lock.c`.
- Changed some function names.
There were some missing headers like <stddef.h> for `NULL`, <wayland-util.h>
for `wl_link` and <stdbool.h> for `true`/`false`.
Also this commit fixes that `labwc.h` and `ime.h` included each other.
...to start <command> on startup and to terminate the compositor when
<command> exits.
This is useful for session management as it allows the session client (for
example `lxqt-session`) to terminate labwc - be exiting itself.
Under X, xinit starts the server and keeps it alive for as long as
lxqt-session runs. Thus either the session client starts the Window
Manager, or the Window Manager can be launched independently first. On
Wayland, the Compositor is both Display Server and Window Manager, so the
described session management mechanisms do not work because the Compositor
needs to be running before the session can function.
As some session clients support both X11 and Wayland, this command line
option avoids re-writes and fragmentation.
Co-authored-by: @Consolatis
Add custom field with subset of printf style formatting
to replace the original field formats.
Example:
<windowSwitcher preview="no" outlines="no" allWorkspaces="yes">
<fields>
<field content="custom" format="foobar %b %3s %-10o %-20W %-10i%t" width="100%" />
</fields>
</windowSwitcher>
Mono space font recommended. May need OSD width adjusted
Co-authored-by: @Consolatis (based on work done by them)
...and unify region overlay and snap-to-edge overlay into overlay.c.
Snap-to-edge overlay is delayed for 500ms to prevent flickering when
the view is dragged from an output to another (demo in discussion labwc#1613).
This also fixes a bug that region overlay is not shown when a modifier
key is re-pressed.
Move/resize requests from xwayland views and xdg toplevels should be
ignored when the view is not pressed.
This is relevant for touchpad taps with <tapAndDrag> disabled.
When the user taps the client surface (e.g. chromium and mpv) with the
setting above, libinput sends button press & release signals so quickly
that the compositor receives move/resize request from the client AFTER
the button release signal is processed, so `interactive_finish()` is
never called.
This commit moves the virtual output related functions
into their own file at `src/output-virtual.c` with its
own include file to reduce `include/labwc.h` bit by bit.
Additionally, it removes the need to keep the
`server->headless.pending_output_name` char array around
by temporarily disconnecting the handler when creating a
new virtual output. This allows to set the output name
right in the `output_virtual_add()` call rather than to
store the pending name until the new output event handler
has been called.
It also makes adding a virtual fallback output easier in
a follow-up PR.
Chases: 756ecf8ee9f1e75bc7b8297dc84f97c7d699174b
backend/wayland: use request_state when toplevel is resized
Chases: 3ef68a484243555b020200c6f95246d994932c3f
backend/x11: use request_state when window is resized
Ref: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/2693
We now delay requested resolution changes by the backend until
the next frame event which causes us to render the new content
on the already enlarged buffer. Before this change, an empty
(black) buffer would have been shown instead before the next
frame event caused a new render of the actual contents.
Keep commiting the new state and then scheduling a frame event
would not help as due to the commit call it would still show an
empty buffer in the meantime.
Just modifying wlr_output->pending wouldn't work either because
wlr_scene_output_commit() *completely* ignores it (and it will
be removed in future wlroots commits). For this reason we move
to wlr_scene_output_build_state() directly because it allows us
to supply the current wlr_output->pending state and thus apply
any resolution change in lockstep with new rendering. Result:
No more flickering in the wayland backend and resizing is again
smooth as butter.
This prevents constant flicker while resizing
when running nested via the wayland backend.
For the X11 backend (can be tested via `WLR_BACKENDS=x11 labwc`),
it is still rather janky but at least doesn't cause endless self-
resizing anymore.
Fixes#1076
It can be enabled with a config like
~/.config/labwc/rc.xml:
<keyboard layoutScope="window">
~/.config/labwc/environment:
XKB_DEFAULT_LAYOUT=de,us
XKB_DEFAULT_OPTIONS=grp:alt_shift_toggle,grp_led:scroll
With a configuration like this each window should now remember
the active keyboard layout when switching between windows.
By default, the keyboard layout keeps being a global state.
We already allow some xwayland-unmanaged surfaces to take focus on map,
if indicated by wlr_xwayland_or_surface_wants_focus(). But once these
surfaces lose focus, they never regain it again.
Add desktop_focus_view_or_surface() and call it in the appropriate
places to allow these views to regain focus in the usual ways (e.g.
clicking on them or focus-follows-mouse).