This is undesired when a focusable popup (e.g. applications menu) of an
unfocusable view (e.g. XWayland panel) is closed.
This reverts commit f6e3527767.
Support `wrap` in view_get_adjacent_output(). This means that when seeking
an adjacent output in a particular direction from an output that is
already furthest in that direction within the layout, rather than
returning NULL, wrap around from the leftmost to the rightmost, or topmost
to the bottommost and vice versa.
Example usage:
<action name="MoveToOutput" direction="right" wrap="yes" />
Wrap is disabled by default to keep the user interface consistent.
...to edges actually encountered by motion during interactive moves and
resizes.
In addition, ignore edge resistance and attraction for minimized views.
This builds on the work of @Consolatis in #1018.
Co-authored-by: Consolatis <35009135+Consolatis@users.noreply.github.com>
Co-authored-by: Andrew J. Hesford <ajh@sideband.org>
Whenever the output layout changes, each view's original geometry will
be captured as last_layout_geometry (if it has not already been captured
by a previous layout change), which will remain valid unless the user
modifies the view's geometry (i.e., by tiling, maximizing, moving,
resizing or full-screening). On subsequent output layout changes, views
with valid last_layout_geometry will be back to their original position
if possible, or else to the closest possible output.
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
1. Prevent window snapping triggered by mouse from moving the window
into the adjacent output.
2. Make the coordinates used to check whether window snapping is
triggered relative to the output the cursor is at, not the output the
view is belonging to. This allows users to grab a tiled window and move
it into another output or tile it again in another output in a single
drag.
The top_left_edge_boundary_check() function in xwayland.c ensures that
views trying to position themselves at 0,0 don't end up with a titlebar
offscreen. However, it doesn't take into account the usable area and
thus these views can still end up overlapping a top panel.
Also, there is no good reason for top_left_edge_boundary_check() to be
xwayland-specific. This logic should really be part of
view_adjust_for_layout_change().
To fix all this, add a new view_adjust_floating_geometry() function,
which replaces the existing similar (and duplicated) logic in
view_apply_natural_geometry() and view_adjust_for_layout_change().
view_adjust_for_layout_change() is already being called from xwayland's
set_initial_position(), so top_left_edge_boundary_check() is now
redundant and can just be deleted.
Lightly tested with waybar and feh --geometry 640x480+0+0. The feh
window is now correctly positioned below waybar, even if started before
waybar (in that case, the feh window is moved when waybar starts).
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.
The type enum view_edge used to be defined in a .c file, so a
structure member 'tiled' in struct view had to be defined to
use another type.
Later (2023-08-02, commit 1ee8715) the definition of enum view_edge
was moved to view.h, so now 'tiled' can be defined to use that type.
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
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.
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.
... especially regarding whether a (view *) parameter may be NULL. It's
confusing when some functions accept NULL and others don't, and could
trip someone up.
I'm partly to blame for the inconsistency, since (if memory serves) I
added view_is_tiled() and view_is_floating(), which do accept NULL.
In detail:
- Make view_is_tiled() and view_is_floating() no longer accept NULL.
- Rename view_isfocusable -> view_is_focusable for consistency with
other view_is_ functions.
- Eliminate view_inhibits_keybinds() as it only existed to safely accept
NULL and check a single flag, which can be checked directly.
- Add assert(view) to remaining public view_ functions to catch
accidentally passing NULL.
- Inline inhibit_keybinds() into view_toggle_keybinds(). It is closely
related and not called from anywhere else; inlining it allows
eliminating an extra assert() which is now impossible.
XWayland views can self-declare that they don't want keyboard focus via
the ICCCM WM_HINTS property. Most of the logic is already in place to
avoid giving focus to such views (e.g. taskbars).
Add a couple of missing pieces to make this work:
- Hook up view_isfocusable() to look at WM_HINTS for XWayland views
- Adjust desktop_focus_topmost_mapped_view() to skip unfocusable views
- Connect to wlr_seat_keyboard_state's focus_change event.
- Add view_from_wlr_surface(), which does what the name says.
- Use focus_change event along with view_from_wlr_surface() to update
server->focused_view and set SSD states via view_set_activated().
- Eliminate desktop_focused_view() since server->focused_view should be
reliably up-to-date now.
- Eliminate view_focus/defocus() since we can now just call
seat_focus_surface() directly.
Our current approach to handling the focused/active view is a bit
confusing. In particular, it's hard to be sure when server->focused_view
is or isn't in sync with the real wlroots keyboard focus.
Try to clean things up a bit. In particular:
- Add comments to server->focused_view and desktop_focused_view() to
clarify that they should match, but it's not guaranteed.
- desktop_focused_view() now prints a warning if it detects that
server->focused_view is out of sync. We should keep an eye out for
this warning, and if we see it, try to figure out why it happened.
- For consistency, use only "focus/defocus" as the verbs in function
names rather than "activate". This is a bit arbitrary, but the idea is
that focus is the primary action while the active/inactive state is a
side effect.
- view_focus/defocus() replace view_set_activated() and now update both
focus and active/inactive state, to try to keep them in sync.
- Add comments at view_focus/defocus() to warn against calling them
directly (we should generally call the desktop.c functions).
- desktop_focus_view(NULL) is now forbidden and is no longer handled as
a special case to clear the focus. This was (at least to me) a
surprising behavior and caused trouble when working on another change.
- To maintain existing behavior, desktop_focus_topmost_mapped_view() now
explicitly clears the focus if there are no mapped views.
There should be no behavioral change here.
For views with a non-pixel size increment (e.g. X11 terminals), it's
helpful to subtract the base size of the window (typically including
menu bar, scrollbars, etc.) before computing the number of size
increments (e.g. cells/characters). This way, the displayed size will
exactly match the terminal grid (e.g. 80x25 or whatever).
wlr_box isn't really the best fit for size hints, so let's define a
struct view_size_hints and a nice view_get_size_hints() function,
wrapping view->impl->get_size_hints().
This also seems like a great opportunity to make view_adjust_size()
window-system-agnostic and eliminate xwayland_apply_size_hints().
...to reduce code duplication.
The function populates an array with views which meet any set of critera
from:
- current-workspace
- no-always-on-top
- no-skipWindowSwitcher (window-rule)
Make src/osd.c use this new interface. Note that always-on-top views are
still filtered out from the window-switcher and that desktop_cycle_view()
needs to be re-worked before always-on-top views can be opted in.
With the new keepBorder option enabled, the
ToggleDecorations action now has 3 states:
- the first time only disables the titlebar
- the second time disables the whole SSD
- the third time enables the whole SSD again
When the keepBorder action is disabled, the old 2-state
behavior is restored, e.g. the ToggleDecorations action
only toggles between on and off.
Fixes#813