view: implement separate horizontal/vertical maximize

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
This commit is contained in:
John Lindgren 2023-10-26 00:38:29 -04:00 committed by Consolatis
parent 7b644b3b94
commit 0430f6f818
15 changed files with 193 additions and 78 deletions

View file

@ -351,7 +351,7 @@ handle_request_maximize(struct wl_listener *listener, void *data)
view_set_decorations(view,
want_deco(xwayland_surface_from_view(view)));
}
view_toggle_maximize(view);
view_toggle_maximize(view, VIEW_AXIS_BOTH);
}
static void
@ -540,14 +540,17 @@ xwayland_view_map(struct view *view)
* 1. set fullscreen state
* 2. set decorations (depends on fullscreen state)
* 3. set maximized (geometry depends on decorations)
*
* TODO: support separate horizontal/vertical maximize
*/
bool maximize = xwayland_surface->maximized_horz
&& xwayland_surface->maximized_vert;
view_set_fullscreen(view, xwayland_surface->fullscreen);
view_set_decorations(view, want_deco(xwayland_surface));
view_maximize(view, maximize, /*store_natural_geometry*/ true);
enum view_axis axis = VIEW_AXIS_NONE;
if (xwayland_surface->maximized_horz) {
axis |= VIEW_AXIS_HORIZONTAL;
}
if (xwayland_surface->maximized_vert) {
axis |= VIEW_AXIS_VERTICAL;
}
view_maximize(view, axis, /*store_natural_geometry*/ true);
if (view->surface != xwayland_surface->surface) {
if (view->surface) {