This is a useful (if lesser-known) feature of at least a few popular X11
window managers, for example Openbox and XFWM4. Typically right-click on
the maximize button toggles horizontal maximize, while middle-click
toggles vertical maximize.
Support in labwc uses the same configuration syntax as Openbox, where the
Maximize/ToggleMaximize actions have an optional "direction" argument:
horizontal, vertical, or both (default). The default mouse bindings match
the XFWM4 defaults (not sure what Openbox has by default).
Most of the external protocols still assume "maximized" is a Boolean,
which is no longer true internally. For the sake of the outside world,
a view is only "maximized" if maximized in both directions.
Internally, I've taken the following approach:
- SSD code decorates the view as "maximized" (i.e. hiding borders) only
if maximized in both directions.
- Layout code (interactive move/resize, tiling, etc.) generally treats
the view as "maximized" (with the restrictions that entails) if
maximized in either direction. For example, moving a vertically-
maximized view first restores the natural geometry (this differs from
Openbox, which instead allows the view to move only horizontally.)
v2: use enum view_axis for view->maximized
v3:
- update docs
- allow resizing if partly maximized
- add TODOs & corrections noted by Consolatis
Currently xwayland views are restacked on top of the XWayland server
stacking order when activated (i.e. focused). This is wrong because
focus/raise are independent concepts (though often occurring together).
The stacking order should be updated when the view is raised/lowered,
not when the view is focused.
Work is in progress elsewhere (draft PR) that will result in views more
often being raised without being focused. Without this fix, those views
don't get restacked properly, resulting in clicks "passing through" to
views underneath.
The logic was the same for xdg-shell and xwayland views, so move it from
the view->impl layer out to the view_move_to_front/back() functions.
view->impl->move_to_front/back() still exist for now, in case we want to
add xdg/xwayland-specific logic in future, but they now move only one
view and not sub-views.
This makes the code a bit more readable IMHO (and forces us to be
consistent with event handler function names).
Adjust scripts/checkpatch.pl to not complain.
Adds functions for calculation of distances between window edges, as
well as for window growing and shrinking.
All calculations are based on the "pending" geometry.
Ignored from snapping:
- views that do not share the same output
- minimized views
- maximized views
- views that are neither:
- part of the current workspace
- part of the always-on-top tree
For views that are initially maximized or fullscreen and have no
explicitly specified position, we need to center the stored natural
geometry, or the view may end up partially offscreen once unmaximized/
unfullscreened.
X11 clients may request to be initially fullscreen or maximized by
setting hints in the _NET_WM_STATE property. For some reason, we are
currently only honoring fullscreen requests but not maximize.
The fixes issues with GTK apps (notably Firefox, but others as well)
not starting maximized.
There is a remaining issue that the window position may not be set
correctly after unmaximizing. This will be fixed in a follow-up commit.
When a parent view has multiple sub-views (dialogs) visible, focusing
one sub-view ought to raise it above the others. This doesn't currently
happen -- focusing a sub-view raises the whole group of views together,
but has no effect on the relative stacking order between them.
This seems like a simple oversight in xdg/xwayland_view_move_to_front()
that's pretty easy to fix.
Add FIXMEs to deduplicate this logic in future.
Tested with HomeBank: the Import dialog pops up an additional Open File
dialog, which before this change appears behind the Import dialog (and
clicking on it does not raise it to the front). After this change, the
Open File dialog appears in front as expected.
Assume that Globally Active xwayland views do want focus if they want
window decorations (according to _MOTIF_WM_HINTS). This is a stop-gap
fix to ensure that various applications (mainly Java-based ones such as
IntelliJ IDEA) get focus normally and appear in the window switcher. It
would be better to match based on _NET_WM_WINDOW_TYPE instead, but that
property isn't currently available through wlroots API.
Fixes (partially): 7e72bf975f
("view/xwayland: avoid focusing views that don't want focus")
Commit 7e72bf975f changed behavior to not automatically focus xwayland
views using the "Globally Active" input model (WM_HINTS.inputs = false
but WM_TAKE_FOCUS listed in WM_PROTOCOLS).
One undesired side effect of this change is that when a dialog is
closed, the parent window is not re-focused if "Globally Active". This
issue is seen for example with JDownloader. It can be solved taking a
similar approach to what is done for unmanaged xwayland views: allow
automatic re-focus between views sharing the same PID.
Note that it's difficult to completely solve all of the focus issues
with Globally Active views without proper WM_TAKE_FOCUS support.
Implementing proper support is difficult since it requires wlroots
changes and would also mean waiting for a message round-trip in
desktop_focus_topmost_view().
Fixes (partially): 7e72bf975f
("view/xwayland: avoid focusing views that don't want focus")
This allows identifying XWayland views using the ICCCM "Globally Active"
input model. Later commits will improve handling of these views.
No functional change in this commit.
We were checking for a locked session in desktop_focus_view(), but there
are several other call sites of seat_focus_surface() which were missing
such a check. Any one of those could cause the lock screen to lose focus
(making the session impossible to unlock) or another surface to gain it
(breaching the session lock).
To fix the issue, make any call to seat_focus_surface() no-op when the
session is locked. Add a specific seat_focus_lock_surface() function
which is the only way to bypass the check and is called only from
session-lock.c.
The unmap() handlers should only call desktop_focus_topmost_view() if
the unmapped view was the focused view. Unmapping a view that was not
focused should not change the focus.
I expect this rarely had any effect in practice; it would only matter in
a focus-follows-mouse config where some view other than the one on top
was focused. But it still seems better to fix.
Rather than repeating the logic in two places, create a small
view_impl_unmap() helper. Perhaps more common "unmap" logic could be
moved there in future.
Check that wlr_layer_surface_v1_from_wlr_surface() doesn't return NULL.
This may be unnecessary with wlroots 0.16 (not sure) but doesn't hurt
and reduces the delta to the wlroots-0.17 branch.
If an xwayland-unmanaged surface was focused belonging to the same
application as the focused view, allow the view to remain active. This
fixes an issue with menus immediately closing in some X11 apps (try
LibreOffice with SAL_USE_VCLPLUGIN=gen).
Fixes: 4028a9482f
("seat: use focus_change event to update focused/active view")
Use the same fix/workaround as in output_update_for_layout_change() to
make sure that the cursor is also visible after (re-)enabling an output
in handle_output_power_manager_set_mode().
This was forgotten in 65bd32d625
Reported-by: @jonhiggs (thanks)
Also stop treating the synthetic layout change sym as modifier
but still prevent it from being added to the set of pressed keys.
Additionally slightly reformat the code.