2022-11-21 10:10:39 -05:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
2023-05-13 16:10:33 +03:00
|
|
|
#ifndef LABWC_VIEW_H
|
|
|
|
|
#define LABWC_VIEW_H
|
2022-11-21 10:10:39 -05:00
|
|
|
|
2024-08-21 07:38:44 +03:00
|
|
|
#include "config/rcxml.h"
|
2022-11-21 10:10:39 -05:00
|
|
|
#include "config.h"
|
2024-04-26 20:08:08 +09:00
|
|
|
#include "ssd.h"
|
2022-11-21 10:10:39 -05:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <wayland-util.h>
|
|
|
|
|
#include <wlr/util/box.h>
|
2023-09-07 16:41:47 +02:00
|
|
|
#include <xkbcommon/xkbcommon.h>
|
2024-12-31 15:21:47 +00:00
|
|
|
#include "common/three-state.h"
|
2022-11-21 10:10:39 -05:00
|
|
|
|
2024-04-26 20:08:08 +09:00
|
|
|
#define LAB_MIN_VIEW_HEIGHT 60
|
2023-08-05 23:53:01 +02:00
|
|
|
|
2024-10-01 10:16:29 -04:00
|
|
|
/*
|
|
|
|
|
* Fallback view geometry used in some cases where a better position
|
|
|
|
|
* and/or size can't be determined. Try to avoid using these except as
|
|
|
|
|
* a last resort.
|
|
|
|
|
*/
|
|
|
|
|
#define VIEW_FALLBACK_X 100
|
|
|
|
|
#define VIEW_FALLBACK_Y 100
|
|
|
|
|
#define VIEW_FALLBACK_WIDTH 640
|
|
|
|
|
#define VIEW_FALLBACK_HEIGHT 480
|
|
|
|
|
|
2022-11-22 20:13:06 +00:00
|
|
|
/*
|
|
|
|
|
* In labwc, a view is a container for surfaces which can be moved around by
|
|
|
|
|
* the user. In practice this means XDG toplevel and XWayland windows.
|
|
|
|
|
*/
|
|
|
|
|
|
2022-11-21 10:10:39 -05:00
|
|
|
enum view_type {
|
|
|
|
|
LAB_XDG_SHELL_VIEW,
|
|
|
|
|
#if HAVE_XWAYLAND
|
|
|
|
|
LAB_XWAYLAND_VIEW,
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
2023-03-22 19:53:17 +01:00
|
|
|
enum ssd_preference {
|
|
|
|
|
LAB_SSD_PREF_UNSPEC = 0,
|
|
|
|
|
LAB_SSD_PREF_CLIENT,
|
|
|
|
|
LAB_SSD_PREF_SERVER,
|
|
|
|
|
};
|
|
|
|
|
|
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
2023-10-26 00:38:29 -04:00
|
|
|
/**
|
|
|
|
|
* Directions in which a view can be maximized. "None" is used
|
|
|
|
|
* internally to mean "not maximized" but is not valid in rc.xml.
|
|
|
|
|
* Therefore when parsing rc.xml, "None" means "Invalid".
|
|
|
|
|
*/
|
|
|
|
|
enum view_axis {
|
|
|
|
|
VIEW_AXIS_NONE = 0,
|
|
|
|
|
VIEW_AXIS_HORIZONTAL = (1 << 0),
|
|
|
|
|
VIEW_AXIS_VERTICAL = (1 << 1),
|
|
|
|
|
VIEW_AXIS_BOTH = (VIEW_AXIS_HORIZONTAL | VIEW_AXIS_VERTICAL),
|
2024-10-18 02:07:52 +03:00
|
|
|
/*
|
|
|
|
|
* If view_axis is treated as a bitfield, INVALID should never
|
|
|
|
|
* set the HORIZONTAL or VERTICAL bits.
|
|
|
|
|
*/
|
|
|
|
|
VIEW_AXIS_INVALID = (1 << 2),
|
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
2023-10-26 00:38:29 -04:00
|
|
|
};
|
|
|
|
|
|
2023-08-02 04:30:50 +02:00
|
|
|
enum view_edge {
|
|
|
|
|
VIEW_EDGE_INVALID = 0,
|
|
|
|
|
|
|
|
|
|
VIEW_EDGE_LEFT,
|
|
|
|
|
VIEW_EDGE_RIGHT,
|
|
|
|
|
VIEW_EDGE_UP,
|
|
|
|
|
VIEW_EDGE_DOWN,
|
|
|
|
|
VIEW_EDGE_CENTER,
|
|
|
|
|
};
|
|
|
|
|
|
2023-10-15 01:11:12 -04:00
|
|
|
enum view_wants_focus {
|
|
|
|
|
/* View does not want focus */
|
|
|
|
|
VIEW_WANTS_FOCUS_NEVER = 0,
|
|
|
|
|
/* View wants focus */
|
|
|
|
|
VIEW_WANTS_FOCUS_ALWAYS,
|
|
|
|
|
/*
|
2025-06-09 11:11:32 -04:00
|
|
|
* The following values apply only to XWayland views using the
|
|
|
|
|
* Globally Active input model per the ICCCM. These views are
|
|
|
|
|
* offered focus and will voluntarily accept or decline it.
|
|
|
|
|
*
|
|
|
|
|
* In some cases, labwc needs to decide in advance whether to
|
|
|
|
|
* focus the view. For this purpose, these views are classified
|
|
|
|
|
* (by a heuristic) as likely or unlikely to want focus. However,
|
|
|
|
|
* it is still ultimately up to the client whether the view gets
|
|
|
|
|
* focus or not.
|
2023-10-15 01:11:12 -04:00
|
|
|
*/
|
2025-06-09 11:11:32 -04:00
|
|
|
VIEW_WANTS_FOCUS_LIKELY,
|
|
|
|
|
VIEW_WANTS_FOCUS_UNLIKELY,
|
2023-10-15 01:11:12 -04:00
|
|
|
};
|
|
|
|
|
|
2025-05-21 11:43:50 -04:00
|
|
|
/*
|
|
|
|
|
* Window types are based on the NET_WM constants from X11. See:
|
|
|
|
|
* https://specifications.freedesktop.org/wm-spec/1.4/ar01s05.html#id-1.6.7
|
|
|
|
|
*
|
|
|
|
|
* The enum constants are intended to match wlr_xwayland_net_wm_window_type.
|
|
|
|
|
* Redefining the same constants here may seem redundant, but is necessary
|
|
|
|
|
* to make them available even in builds with xwayland support disabled.
|
|
|
|
|
*/
|
2024-04-19 20:15:49 +02:00
|
|
|
enum window_type {
|
|
|
|
|
NET_WM_WINDOW_TYPE_DESKTOP = 0,
|
|
|
|
|
NET_WM_WINDOW_TYPE_DOCK,
|
|
|
|
|
NET_WM_WINDOW_TYPE_TOOLBAR,
|
|
|
|
|
NET_WM_WINDOW_TYPE_MENU,
|
|
|
|
|
NET_WM_WINDOW_TYPE_UTILITY,
|
|
|
|
|
NET_WM_WINDOW_TYPE_SPLASH,
|
|
|
|
|
NET_WM_WINDOW_TYPE_DIALOG,
|
|
|
|
|
NET_WM_WINDOW_TYPE_DROPDOWN_MENU,
|
|
|
|
|
NET_WM_WINDOW_TYPE_POPUP_MENU,
|
|
|
|
|
NET_WM_WINDOW_TYPE_TOOLTIP,
|
|
|
|
|
NET_WM_WINDOW_TYPE_NOTIFICATION,
|
|
|
|
|
NET_WM_WINDOW_TYPE_COMBO,
|
|
|
|
|
NET_WM_WINDOW_TYPE_DND,
|
|
|
|
|
NET_WM_WINDOW_TYPE_NORMAL,
|
|
|
|
|
|
|
|
|
|
WINDOW_TYPE_LEN
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-26 16:46:28 -05:00
|
|
|
struct view;
|
2023-10-15 00:15:16 -04:00
|
|
|
struct wlr_surface;
|
2024-08-12 20:31:52 +02:00
|
|
|
struct foreign_toplevel;
|
2023-09-22 01:22:19 -04:00
|
|
|
|
2023-06-15 02:35:43 -07:00
|
|
|
/* Common to struct view and struct xwayland_unmanaged */
|
|
|
|
|
struct mappable {
|
|
|
|
|
bool connected;
|
|
|
|
|
struct wl_listener map;
|
|
|
|
|
struct wl_listener unmap;
|
|
|
|
|
};
|
|
|
|
|
|
2023-09-22 01:22:19 -04:00
|
|
|
/* Basic size hints (subset of XSizeHints from X11) */
|
|
|
|
|
struct view_size_hints {
|
|
|
|
|
int min_width;
|
|
|
|
|
int min_height;
|
|
|
|
|
int width_inc;
|
|
|
|
|
int height_inc;
|
|
|
|
|
int base_width;
|
|
|
|
|
int base_height;
|
|
|
|
|
};
|
|
|
|
|
|
2022-11-21 10:10:39 -05:00
|
|
|
struct view_impl {
|
|
|
|
|
void (*configure)(struct view *view, struct wlr_box geo);
|
|
|
|
|
void (*close)(struct view *view);
|
|
|
|
|
const char *(*get_string_prop)(struct view *view, const char *prop);
|
|
|
|
|
void (*map)(struct view *view);
|
|
|
|
|
void (*set_activated)(struct view *view, bool activated);
|
|
|
|
|
void (*set_fullscreen)(struct view *view, bool fullscreen);
|
2024-01-22 22:11:53 -05:00
|
|
|
void (*notify_tiled)(struct view *view);
|
2023-07-01 12:37:47 -04:00
|
|
|
/*
|
|
|
|
|
* client_request is true if the client unmapped its own
|
|
|
|
|
* surface; false if we are just minimizing the view. The two
|
|
|
|
|
* cases are similar but have subtle differences (e.g., when
|
|
|
|
|
* minimizing we don't destroy the foreign toplevel handle).
|
|
|
|
|
*/
|
|
|
|
|
void (*unmap)(struct view *view, bool client_request);
|
2024-11-27 03:53:28 +01:00
|
|
|
void (*maximize)(struct view *view, enum view_axis maximized);
|
2023-06-25 11:37:56 +01:00
|
|
|
void (*minimize)(struct view *view, bool minimize);
|
2023-08-02 20:57:39 +01:00
|
|
|
struct view *(*get_root)(struct view *self);
|
|
|
|
|
void (*append_children)(struct view *self, struct wl_array *children);
|
2023-09-22 01:22:19 -04:00
|
|
|
struct view_size_hints (*get_size_hints)(struct view *self);
|
2023-10-15 01:11:12 -04:00
|
|
|
/* if not implemented, VIEW_WANTS_FOCUS_ALWAYS is assumed */
|
|
|
|
|
enum view_wants_focus (*wants_focus)(struct view *self);
|
2024-07-20 11:25:10 -04:00
|
|
|
void (*offer_focus)(struct view *self);
|
2023-11-27 17:11:29 -05:00
|
|
|
/* returns true if view reserves space at screen edge */
|
|
|
|
|
bool (*has_strut_partial)(struct view *self);
|
2024-04-19 20:15:49 +02:00
|
|
|
/* returns true if view declared itself a window type */
|
2025-05-21 11:43:50 -04:00
|
|
|
bool (*contains_window_type)(struct view *view,
|
|
|
|
|
enum window_type window_type);
|
2024-04-22 17:43:46 +02:00
|
|
|
/* returns the client pid that this view belongs to */
|
|
|
|
|
pid_t (*get_pid)(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct view {
|
|
|
|
|
struct server *server;
|
|
|
|
|
enum view_type type;
|
|
|
|
|
const struct view_impl *impl;
|
|
|
|
|
struct wl_list link;
|
2023-02-21 08:14:11 -05:00
|
|
|
|
|
|
|
|
/*
|
2024-01-31 22:07:13 +01:00
|
|
|
* The primary output that the view is displayed on. Specifically:
|
2023-02-21 08:14:11 -05:00
|
|
|
*
|
|
|
|
|
* - For floating views, this is the output nearest to the
|
|
|
|
|
* center of the view. It is computed automatically when the
|
|
|
|
|
* view is moved or the output layout changes.
|
|
|
|
|
*
|
|
|
|
|
* - For fullscreen/maximized/tiled views, this is the output
|
|
|
|
|
* used to compute the view's geometry. The view remains on
|
|
|
|
|
* the same output unless it is disabled or disconnected.
|
|
|
|
|
*
|
|
|
|
|
* Many view functions (e.g. view_center(), view_fullscreen(),
|
|
|
|
|
* view_maximize(), etc.) allow specifying a particular output
|
2023-02-28 11:46:48 -05:00
|
|
|
* by calling view_set_output() beforehand.
|
2023-02-21 08:14:11 -05:00
|
|
|
*/
|
2022-11-21 10:10:39 -05:00
|
|
|
struct output *output;
|
2024-01-31 22:07:13 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* The outputs that the view is displayed on.
|
|
|
|
|
* This is used to notify the foreign toplevel
|
|
|
|
|
* implementation and to update the SSD invisible
|
|
|
|
|
* resize area.
|
|
|
|
|
* It is a bitset of output->scene_output->index.
|
|
|
|
|
*/
|
|
|
|
|
uint64_t outputs;
|
|
|
|
|
|
2022-11-21 10:10:39 -05:00
|
|
|
struct workspace *workspace;
|
|
|
|
|
struct wlr_surface *surface;
|
|
|
|
|
struct wlr_scene_tree *scene_tree;
|
2025-01-19 15:49:39 +09:00
|
|
|
struct wlr_scene_tree *content_tree;
|
2022-11-21 10:10:39 -05:00
|
|
|
|
|
|
|
|
bool mapped;
|
|
|
|
|
bool been_mapped;
|
2022-11-21 15:38:20 -05:00
|
|
|
bool ssd_enabled;
|
2023-04-14 09:01:13 +02:00
|
|
|
bool ssd_titlebar_hidden;
|
2023-03-22 19:53:17 +01:00
|
|
|
enum ssd_preference ssd_preference;
|
2023-08-08 03:39:35 +02:00
|
|
|
bool shaded;
|
2022-11-21 10:10:39 -05:00
|
|
|
bool minimized;
|
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
2023-10-26 00:38:29 -04:00
|
|
|
enum view_axis maximized;
|
2023-02-15 02:12:22 -05:00
|
|
|
bool fullscreen;
|
2024-01-08 22:58:58 +02:00
|
|
|
bool tearing_hint;
|
2024-08-06 22:23:10 +02:00
|
|
|
enum three_state force_tearing;
|
2023-11-25 17:54:36 -06:00
|
|
|
bool visible_on_all_workspaces;
|
2023-10-31 22:12:12 +02:00
|
|
|
enum view_edge tiled;
|
2024-02-08 14:23:06 +01:00
|
|
|
uint32_t edges_visible; /* enum wlr_edges bitset */
|
2023-03-05 10:35:56 +01:00
|
|
|
bool inhibits_keybinds;
|
2023-09-07 16:41:47 +02:00
|
|
|
xkb_layout_index_t keyboard_layout;
|
2022-07-07 19:05:54 +02:00
|
|
|
|
2023-01-01 18:12:20 +01:00
|
|
|
/* Pointer to an output owned struct region, may be NULL */
|
2022-07-06 17:04:21 +02:00
|
|
|
struct region *tiled_region;
|
2022-07-07 19:05:54 +02:00
|
|
|
/* Set to region->name when tiled_region is free'd by a destroying output */
|
|
|
|
|
char *tiled_region_evacuate;
|
|
|
|
|
|
2023-02-08 23:19:14 -05:00
|
|
|
/*
|
|
|
|
|
* Geometry of the wlr_surface contained within the view, as
|
|
|
|
|
* currently displayed. Should be kept in sync with the
|
|
|
|
|
* scene-graph at all times.
|
|
|
|
|
*/
|
|
|
|
|
struct wlr_box current;
|
|
|
|
|
/*
|
|
|
|
|
* Expected geometry after any pending move/resize requests
|
|
|
|
|
* have been processed. Should match current geometry when no
|
|
|
|
|
* move/resize requests are pending.
|
|
|
|
|
*/
|
|
|
|
|
struct wlr_box pending;
|
|
|
|
|
/*
|
|
|
|
|
* Saved geometry which will be restored when the view returns
|
|
|
|
|
* to normal/floating state after being maximized/fullscreen/
|
|
|
|
|
* tiled. Values are undefined/out-of-date when the view is not
|
|
|
|
|
* maximized/fullscreen/tiled.
|
|
|
|
|
*/
|
2022-11-21 10:10:39 -05:00
|
|
|
struct wlr_box natural_geometry;
|
2023-12-31 21:39:06 -05:00
|
|
|
/*
|
|
|
|
|
* Whenever an output layout change triggers a view relocation, the
|
|
|
|
|
* last pending position (or natural geometry) will be saved so the
|
|
|
|
|
* view may be restored to its original location on a subsequent layout
|
|
|
|
|
* change.
|
|
|
|
|
*/
|
|
|
|
|
struct wlr_box last_layout_geometry;
|
2022-11-21 10:10:39 -05:00
|
|
|
|
2023-02-08 23:19:14 -05:00
|
|
|
/* used by xdg-shell views */
|
|
|
|
|
uint32_t pending_configure_serial;
|
2023-02-28 11:30:42 -05:00
|
|
|
struct wl_event_source *pending_configure_timeout;
|
2022-11-21 10:10:39 -05:00
|
|
|
|
2022-11-26 16:46:28 -05:00
|
|
|
struct ssd *ssd;
|
2023-08-17 18:59:29 +02:00
|
|
|
struct resize_indicator {
|
|
|
|
|
int width, height;
|
|
|
|
|
struct wlr_scene_tree *tree;
|
|
|
|
|
struct wlr_scene_rect *border;
|
|
|
|
|
struct wlr_scene_rect *background;
|
|
|
|
|
struct scaled_font_buffer *text;
|
|
|
|
|
} resize_indicator;
|
2024-05-29 11:06:39 +09:00
|
|
|
struct resize_outlines {
|
|
|
|
|
struct wlr_box view_geo;
|
2025-06-09 16:27:17 +09:00
|
|
|
struct lab_scene_rect *rect;
|
2024-05-29 11:06:39 +09:00
|
|
|
} resize_outlines;
|
2022-11-21 10:10:39 -05:00
|
|
|
|
2023-06-15 02:35:43 -07:00
|
|
|
struct mappable mappable;
|
|
|
|
|
|
2022-11-21 10:10:39 -05:00
|
|
|
struct wl_listener destroy;
|
|
|
|
|
struct wl_listener surface_destroy;
|
|
|
|
|
struct wl_listener commit;
|
|
|
|
|
struct wl_listener request_move;
|
|
|
|
|
struct wl_listener request_resize;
|
|
|
|
|
struct wl_listener request_minimize;
|
|
|
|
|
struct wl_listener request_maximize;
|
|
|
|
|
struct wl_listener request_fullscreen;
|
|
|
|
|
struct wl_listener set_title;
|
2024-08-12 20:19:45 +02:00
|
|
|
|
2024-08-12 20:31:52 +02:00
|
|
|
struct foreign_toplevel *foreign_toplevel;
|
|
|
|
|
|
2025-05-30 20:58:48 +09:00
|
|
|
/* used by scaled_icon_buffer */
|
|
|
|
|
struct {
|
|
|
|
|
char *name;
|
|
|
|
|
struct wl_array buffers; /* struct lab_data_buffer * */
|
|
|
|
|
} icon;
|
|
|
|
|
|
2024-08-12 20:19:45 +02:00
|
|
|
struct {
|
|
|
|
|
struct wl_signal new_app_id;
|
|
|
|
|
struct wl_signal new_title;
|
|
|
|
|
struct wl_signal new_outputs;
|
|
|
|
|
struct wl_signal maximized;
|
|
|
|
|
struct wl_signal minimized;
|
|
|
|
|
struct wl_signal fullscreened;
|
|
|
|
|
struct wl_signal activated; /* bool *activated */
|
2025-05-30 20:58:48 +09:00
|
|
|
/*
|
|
|
|
|
* This is emitted when app_id, or icon set via xdg_toplevel_icon
|
|
|
|
|
* is updated. This is listened by scaled_icon_buffer.
|
|
|
|
|
*/
|
|
|
|
|
struct wl_signal set_icon;
|
2025-05-24 08:31:08 +09:00
|
|
|
struct wl_signal destroy;
|
2024-08-12 20:19:45 +02:00
|
|
|
} events;
|
2022-11-22 20:13:06 +00:00
|
|
|
};
|
|
|
|
|
|
2023-08-28 18:55:29 +03:00
|
|
|
struct view_query {
|
|
|
|
|
struct wl_list link;
|
|
|
|
|
char *identifier;
|
|
|
|
|
char *title;
|
2024-04-20 07:57:35 +02:00
|
|
|
int window_type;
|
2024-05-16 12:52:47 +03:00
|
|
|
char *sandbox_engine;
|
|
|
|
|
char *sandbox_app_id;
|
2024-10-18 02:07:52 +03:00
|
|
|
enum three_state shaded;
|
|
|
|
|
enum view_axis maximized;
|
|
|
|
|
enum three_state iconified;
|
|
|
|
|
enum three_state focused;
|
|
|
|
|
enum three_state omnipresent;
|
|
|
|
|
enum view_edge tiled;
|
|
|
|
|
char *tiled_region;
|
|
|
|
|
char *desktop;
|
|
|
|
|
enum ssd_mode decoration;
|
|
|
|
|
char *monitor;
|
2023-08-28 18:55:29 +03:00
|
|
|
};
|
|
|
|
|
|
2022-11-22 20:13:06 +00:00
|
|
|
struct xdg_toplevel_view {
|
|
|
|
|
struct view base;
|
2022-11-25 13:41:12 -05:00
|
|
|
struct wlr_xdg_surface *xdg_surface;
|
2022-11-22 20:13:06 +00:00
|
|
|
|
|
|
|
|
/* Events unique to xdg-toplevel views */
|
|
|
|
|
struct wl_listener set_app_id;
|
2024-09-17 00:32:02 +09:00
|
|
|
struct wl_listener request_show_window_menu;
|
2022-11-22 20:13:06 +00:00
|
|
|
struct wl_listener new_popup;
|
|
|
|
|
};
|
|
|
|
|
|
2023-11-21 03:08:04 +01:00
|
|
|
/* All criteria is applied in AND logic */
|
2023-08-10 15:46:00 +01:00
|
|
|
enum lab_view_criteria {
|
2023-11-21 03:08:04 +01:00
|
|
|
/* No filter -> all focusable views */
|
2023-08-18 22:18:59 +01:00
|
|
|
LAB_VIEW_CRITERIA_NONE = 0,
|
2023-11-21 03:08:04 +01:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Includes always-on-top views, e.g.
|
|
|
|
|
* what is visible on the current workspace
|
|
|
|
|
*/
|
|
|
|
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
|
|
|
|
|
|
|
|
|
/* Positive criteria */
|
|
|
|
|
LAB_VIEW_CRITERIA_FULLSCREEN = 1 << 1,
|
|
|
|
|
LAB_VIEW_CRITERIA_ALWAYS_ON_TOP = 1 << 2,
|
2024-01-30 18:04:43 +00:00
|
|
|
LAB_VIEW_CRITERIA_ROOT_TOPLEVEL = 1 << 3,
|
2023-11-21 03:08:04 +01:00
|
|
|
|
|
|
|
|
/* Negative criteria */
|
|
|
|
|
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 6,
|
|
|
|
|
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 7,
|
2025-06-05 19:33:12 +08:00
|
|
|
LAB_VIEW_CRITERIA_NO_OMNIPRESENT = 1 << 8,
|
2023-08-10 15:46:00 +01:00
|
|
|
};
|
|
|
|
|
|
2023-09-27 18:24:35 -04:00
|
|
|
/**
|
|
|
|
|
* view_from_wlr_surface() - returns the view associated with a
|
|
|
|
|
* wlr_surface, or NULL if the surface has no associated view.
|
|
|
|
|
*/
|
|
|
|
|
struct view *view_from_wlr_surface(struct wlr_surface *surface);
|
|
|
|
|
|
2024-05-27 19:55:16 +02:00
|
|
|
/**
|
|
|
|
|
* view_query_create() - Create a new heap allocated view query with
|
|
|
|
|
* all members initialized to their default values (window_type = -1,
|
|
|
|
|
* NULL for strings)
|
|
|
|
|
*/
|
|
|
|
|
struct view_query *view_query_create(void);
|
|
|
|
|
|
2023-08-28 18:55:29 +03:00
|
|
|
/**
|
|
|
|
|
* view_query_free() - Free a given view query
|
|
|
|
|
* @query: Query to be freed.
|
|
|
|
|
*/
|
|
|
|
|
void view_query_free(struct view_query *view);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* view_matches_query() - Check if view matches the given criteria
|
|
|
|
|
* @view: View to checked.
|
|
|
|
|
* @query: Criteria to match against.
|
|
|
|
|
*
|
|
|
|
|
* Returns true if %view matches all of the criteria given in %query, false
|
|
|
|
|
* otherwise.
|
|
|
|
|
*/
|
|
|
|
|
bool view_matches_query(struct view *view, struct view_query *query);
|
|
|
|
|
|
2023-08-10 15:46:00 +01:00
|
|
|
/**
|
2023-08-18 22:18:59 +01:00
|
|
|
* for_each_view() - iterate over all views which match criteria
|
|
|
|
|
* @view: Iterator.
|
|
|
|
|
* @head: Head of list to iterate over.
|
|
|
|
|
* @criteria: Criteria to match against.
|
|
|
|
|
* Example:
|
|
|
|
|
* struct view *view;
|
|
|
|
|
* for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NONE) {
|
|
|
|
|
* printf("%s\n", view_get_string_prop(view, "app_id"));
|
|
|
|
|
* }
|
|
|
|
|
*/
|
2024-11-12 20:34:29 +01:00
|
|
|
#define for_each_view(view, head, criteria) \
|
|
|
|
|
for (view = view_next(head, NULL, criteria); \
|
|
|
|
|
view; \
|
2023-08-18 22:18:59 +01:00
|
|
|
view = view_next(head, view, criteria))
|
|
|
|
|
|
2024-11-12 20:34:29 +01:00
|
|
|
/**
|
|
|
|
|
* for_each_view_reverse() - iterate over all views which match criteria
|
|
|
|
|
* @view: Iterator.
|
|
|
|
|
* @head: Head of list to iterate over.
|
|
|
|
|
* @criteria: Criteria to match against.
|
|
|
|
|
* Example:
|
|
|
|
|
* struct view *view;
|
|
|
|
|
* for_each_view_reverse(view, &server->views, LAB_VIEW_CRITERIA_NONE) {
|
|
|
|
|
* printf("%s\n", view_get_string_prop(view, "app_id"));
|
|
|
|
|
* }
|
|
|
|
|
*/
|
|
|
|
|
#define for_each_view_reverse(view, head, criteria) \
|
|
|
|
|
for (view = view_prev(head, NULL, criteria); \
|
|
|
|
|
view; \
|
|
|
|
|
view = view_prev(head, view, criteria))
|
|
|
|
|
|
2023-08-18 22:18:59 +01:00
|
|
|
/**
|
|
|
|
|
* view_next() - Get next view which matches criteria.
|
|
|
|
|
* @head: Head of list to iterate over.
|
|
|
|
|
* @view: Current view from which to find the next one. If NULL is provided as
|
|
|
|
|
* the view argument, the start of the list will be used.
|
|
|
|
|
* @criteria: Criteria to match against.
|
|
|
|
|
*
|
|
|
|
|
* Returns NULL if there are no views matching the criteria.
|
|
|
|
|
*/
|
|
|
|
|
struct view *view_next(struct wl_list *head, struct view *view,
|
|
|
|
|
enum lab_view_criteria criteria);
|
|
|
|
|
|
2024-11-12 20:34:29 +01:00
|
|
|
/**
|
|
|
|
|
* view_prev() - Get previous view which matches criteria.
|
|
|
|
|
* @head: Head of list to iterate over.
|
|
|
|
|
* @view: Current view from which to find the previous one. If NULL is provided
|
|
|
|
|
* as the view argument, the end of the list will be used.
|
|
|
|
|
* @criteria: Criteria to match against.
|
|
|
|
|
*
|
|
|
|
|
* Returns NULL if there are no views matching the criteria.
|
|
|
|
|
*/
|
|
|
|
|
struct view *view_prev(struct wl_list *head, struct view *view,
|
|
|
|
|
enum lab_view_criteria criteria);
|
|
|
|
|
|
2024-01-25 19:52:54 +00:00
|
|
|
/*
|
|
|
|
|
* Same as `view_next()` except that they iterate one whole cycle rather than
|
|
|
|
|
* stopping at the list-head
|
|
|
|
|
*/
|
|
|
|
|
struct view *view_next_no_head_stop(struct wl_list *head, struct view *from,
|
|
|
|
|
enum lab_view_criteria criteria);
|
|
|
|
|
struct view *view_prev_no_head_stop(struct wl_list *head, struct view *from,
|
|
|
|
|
enum lab_view_criteria criteria);
|
|
|
|
|
|
2023-08-18 22:18:59 +01:00
|
|
|
/**
|
|
|
|
|
* view_array_append() - Append views that match criteria to array
|
2023-08-10 15:46:00 +01:00
|
|
|
* @server: server context
|
|
|
|
|
* @views: arrays to append to
|
|
|
|
|
* @criteria: criteria to match against
|
|
|
|
|
*
|
2023-08-18 22:18:59 +01:00
|
|
|
* This function is useful in cases where the calling function may change the
|
|
|
|
|
* stacking order or where it needs to iterate over the views multiple times,
|
|
|
|
|
* for example to get the number of views before processing them.
|
|
|
|
|
*
|
2023-08-10 15:46:00 +01:00
|
|
|
* Note: This array has a very short shelf-life so it is intended to be used
|
|
|
|
|
* with a single-use-throw-away approach.
|
|
|
|
|
*
|
|
|
|
|
* Example usage:
|
|
|
|
|
* struct view **view;
|
|
|
|
|
* struct wl_array views;
|
|
|
|
|
* wl_array_init(&views);
|
|
|
|
|
* view_array_append(server, &views, LAB_VIEW_CRITERIA_CURRENT_WORKSPACE);
|
|
|
|
|
* wl_array_for_each(view, &views) {
|
|
|
|
|
* // Do something with *view
|
|
|
|
|
* }
|
|
|
|
|
* wl_array_release(&views);
|
|
|
|
|
*/
|
|
|
|
|
void view_array_append(struct server *server, struct wl_array *views,
|
|
|
|
|
enum lab_view_criteria criteria);
|
|
|
|
|
|
2023-10-15 01:11:12 -04:00
|
|
|
enum view_wants_focus view_wants_focus(struct view *view);
|
2024-04-19 20:15:49 +02:00
|
|
|
bool view_contains_window_type(struct view *view, enum window_type window_type);
|
2023-10-15 01:11:12 -04:00
|
|
|
|
2024-02-02 14:43:52 -05:00
|
|
|
/**
|
|
|
|
|
* view_edge_invert() - select the opposite of a provided edge
|
|
|
|
|
*
|
|
|
|
|
* VIEW_EDGE_CENTER and VIEW_EDGE_INVALID both map to VIEW_EDGE_INVALID.
|
|
|
|
|
*
|
|
|
|
|
* @edge: edge to be inverted
|
|
|
|
|
*/
|
|
|
|
|
enum view_edge view_edge_invert(enum view_edge edge);
|
|
|
|
|
|
2023-08-20 16:43:29 +01:00
|
|
|
/**
|
2023-09-25 22:42:06 -04:00
|
|
|
* view_is_focusable() - Check whether or not a view can be focused
|
2023-08-20 16:43:29 +01:00
|
|
|
* @view: view to be checked
|
|
|
|
|
*
|
|
|
|
|
* The purpose of this test is to filter out views (generally Xwayland) which
|
|
|
|
|
* are not meant to be focused such as those with surfaces
|
|
|
|
|
* a. that have been created but never mapped;
|
|
|
|
|
* b. set to NULL after client minimize-request.
|
|
|
|
|
*
|
2024-03-08 21:59:20 +09:00
|
|
|
* The only views that are allowed to be focused are those that have a surface
|
2023-08-20 16:43:29 +01:00
|
|
|
* and have been mapped at some point since creation.
|
|
|
|
|
*/
|
2024-02-13 22:35:56 -05:00
|
|
|
bool view_is_focusable(struct view *view);
|
2023-08-20 16:43:29 +01:00
|
|
|
|
2024-07-20 11:25:10 -04:00
|
|
|
/*
|
|
|
|
|
* For use by desktop_focus_view() only - please do not call directly.
|
|
|
|
|
* See the description of VIEW_WANTS_FOCUS_OFFER for more information.
|
|
|
|
|
*/
|
|
|
|
|
void view_offer_focus(struct view *view);
|
|
|
|
|
|
2023-06-15 02:35:43 -07:00
|
|
|
void mappable_connect(struct mappable *mappable, struct wlr_surface *surface,
|
|
|
|
|
wl_notify_func_t notify_map, wl_notify_func_t notify_unmap);
|
|
|
|
|
void mappable_disconnect(struct mappable *mappable);
|
|
|
|
|
|
2023-03-05 10:35:56 +01:00
|
|
|
void view_toggle_keybinds(struct view *view);
|
|
|
|
|
|
2023-09-27 18:24:35 -04:00
|
|
|
void view_set_activated(struct view *view, bool activated);
|
2023-02-28 11:46:48 -05:00
|
|
|
void view_set_output(struct view *view, struct output *output);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_close(struct view *view);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* view_move_resize - resize and move view
|
|
|
|
|
* @view: view to be resized and moved
|
|
|
|
|
* @geo: the new geometry
|
|
|
|
|
* NOTE: Only use this when the view actually changes width and/or height
|
|
|
|
|
* otherwise the serials might cause a delay in moving xdg-shell clients.
|
|
|
|
|
* For move only, use view_move()
|
|
|
|
|
*/
|
|
|
|
|
void view_move_resize(struct view *view, struct wlr_box geo);
|
2023-06-27 21:20:04 +03:00
|
|
|
void view_resize_relative(struct view *view,
|
|
|
|
|
int left, int right, int top, int bottom);
|
2023-07-23 12:04:36 +03:00
|
|
|
void view_move_relative(struct view *view, int x, int y);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_move(struct view *view, int x, int y);
|
2023-10-14 14:57:44 +02:00
|
|
|
void view_move_to_cursor(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_moved(struct view *view);
|
|
|
|
|
void view_minimize(struct view *view, bool minimized);
|
2023-10-17 23:06:12 -04:00
|
|
|
bool view_compute_centered_position(struct view *view,
|
|
|
|
|
const struct wlr_box *ref, int w, int h, int *x, int *y);
|
xdg: handle initially maximized xdg-shell views better
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.
2024-07-02 07:24:29 -04:00
|
|
|
void view_set_fallback_natural_geometry(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_store_natural_geometry(struct view *view);
|
2023-03-05 01:58:24 -05:00
|
|
|
|
2024-09-21 15:51:37 +02:00
|
|
|
/**
|
|
|
|
|
* view_apply_natural_geometry - adjust view->natural_geometry if it doesn't
|
|
|
|
|
* intersect with view->output and then apply it
|
|
|
|
|
*/
|
|
|
|
|
void view_apply_natural_geometry(struct view *view);
|
|
|
|
|
|
2023-08-08 03:39:35 +02:00
|
|
|
/**
|
|
|
|
|
* view_effective_height - effective height of view, with respect to shaded state
|
|
|
|
|
* @view: view for which effective height is desired
|
|
|
|
|
* @use_pending: if false, report current height; otherwise, report pending height
|
|
|
|
|
*/
|
|
|
|
|
int view_effective_height(struct view *view, bool use_pending);
|
|
|
|
|
|
2023-03-05 01:58:24 -05:00
|
|
|
/**
|
|
|
|
|
* view_center - center view within some region
|
|
|
|
|
* @view: view to be centered
|
|
|
|
|
* @ref: optional reference region (in layout coordinates) to center
|
|
|
|
|
* within; if NULL, view is centered within usable area of its output
|
|
|
|
|
*/
|
2023-02-20 16:23:53 -05:00
|
|
|
void view_center(struct view *view, const struct wlr_box *ref);
|
2023-12-10 21:00:05 -05:00
|
|
|
|
|
|
|
|
/**
|
2024-05-07 09:46:05 -04:00
|
|
|
* view_place_by_policy - apply placement strategy to view
|
2023-12-10 21:00:05 -05:00
|
|
|
* @view: view to be placed
|
2024-05-07 09:46:05 -04:00
|
|
|
* @allow_cursor: set to false to ignore center-on-cursor policy
|
|
|
|
|
* @policy: placement policy to apply
|
2023-12-10 21:00:05 -05:00
|
|
|
*/
|
2024-05-07 09:46:05 -04:00
|
|
|
void view_place_by_policy(struct view *view, bool allow_cursor,
|
2024-08-21 07:38:44 +03:00
|
|
|
enum view_placement_policy policy);
|
2024-01-06 21:36:12 +00:00
|
|
|
void view_constrain_size_to_that_of_usable_area(struct view *view);
|
2023-12-10 21:00:05 -05:00
|
|
|
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_restore_to(struct view *view, struct wlr_box geometry);
|
2022-11-21 13:17:14 -05:00
|
|
|
void view_set_untiled(struct view *view);
|
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
2023-10-26 00:38:29 -04:00
|
|
|
void view_maximize(struct view *view, enum view_axis axis,
|
2022-11-21 10:10:39 -05:00
|
|
|
bool store_natural_geometry);
|
2023-02-20 13:36:15 -05:00
|
|
|
void view_set_fullscreen(struct view *view, bool fullscreen);
|
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
2023-10-26 00:38:29 -04:00
|
|
|
void view_toggle_maximize(struct view *view, enum view_axis axis);
|
2024-04-19 13:35:16 +02:00
|
|
|
bool view_wants_decorations(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_toggle_decorations(struct view *view);
|
2023-05-11 22:26:41 +01:00
|
|
|
|
2022-12-29 04:50:21 +01:00
|
|
|
bool view_is_always_on_top(struct view *view);
|
2023-10-14 23:42:56 +02:00
|
|
|
bool view_is_always_on_bottom(struct view *view);
|
2023-11-25 17:54:36 -06:00
|
|
|
bool view_is_omnipresent(struct view *view);
|
2023-05-11 22:26:41 +01:00
|
|
|
void view_toggle_always_on_top(struct view *view);
|
|
|
|
|
void view_toggle_always_on_bottom(struct view *view);
|
2023-11-25 17:54:36 -06:00
|
|
|
void view_toggle_visible_on_all_workspaces(struct view *view);
|
2023-05-11 22:26:41 +01:00
|
|
|
|
2023-01-01 18:12:20 +01:00
|
|
|
bool view_is_tiled(struct view *view);
|
2024-06-22 23:40:19 +02:00
|
|
|
bool view_is_tiled_and_notify_tiled(struct view *view);
|
2023-02-11 09:36:42 +01:00
|
|
|
bool view_is_floating(struct view *view);
|
2022-11-21 13:03:49 -05:00
|
|
|
void view_move_to_workspace(struct view *view, struct workspace *workspace);
|
2024-04-18 09:46:36 +02:00
|
|
|
enum ssd_mode view_get_ssd_mode(struct view *view);
|
|
|
|
|
void view_set_ssd_mode(struct view *view, enum ssd_mode mode);
|
2024-04-20 06:29:51 +02:00
|
|
|
void view_set_decorations(struct view *view, enum ssd_mode mode, bool force_ssd);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_toggle_fullscreen(struct view *view);
|
2023-12-31 21:39:06 -05:00
|
|
|
void view_invalidate_last_layout_geometry(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_adjust_for_layout_change(struct view *view);
|
2023-08-05 23:58:40 +02:00
|
|
|
void view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_windows);
|
2023-08-05 23:58:40 +02:00
|
|
|
void view_grow_to_edge(struct view *view, enum view_edge direction);
|
|
|
|
|
void view_shrink_to_edge(struct view *view, enum view_edge direction);
|
2023-11-07 14:43:53 +09:00
|
|
|
void view_snap_to_edge(struct view *view, enum view_edge direction,
|
|
|
|
|
bool across_outputs, bool store_natural_geometry);
|
2023-08-02 04:30:50 +02:00
|
|
|
void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry);
|
2024-01-21 23:44:27 +01:00
|
|
|
void view_move_to_output(struct view *view, struct output *output);
|
2023-04-01 14:06:52 -04:00
|
|
|
|
|
|
|
|
void view_move_to_front(struct view *view);
|
|
|
|
|
void view_move_to_back(struct view *view);
|
2023-08-02 20:57:39 +01:00
|
|
|
struct view *view_get_root(struct view *view);
|
|
|
|
|
void view_append_children(struct view *view, struct wl_array *children);
|
2024-01-31 22:07:13 +01:00
|
|
|
bool view_on_output(struct view *view, struct output *output);
|
2023-04-01 14:06:52 -04:00
|
|
|
|
2023-11-27 17:11:29 -05:00
|
|
|
/**
|
|
|
|
|
* view_has_strut_partial() - returns true for views that reserve space
|
|
|
|
|
* at a screen edge (e.g. panels). These views are treated as if they
|
|
|
|
|
* have the fixedPosition window rule: i.e. they are not restricted to
|
|
|
|
|
* the usable area and cannot be moved/resized interactively.
|
|
|
|
|
*/
|
|
|
|
|
bool view_has_strut_partial(struct view *view);
|
|
|
|
|
|
2022-11-21 10:10:39 -05:00
|
|
|
const char *view_get_string_prop(struct view *view, const char *prop);
|
|
|
|
|
void view_update_title(struct view *view);
|
|
|
|
|
void view_update_app_id(struct view *view);
|
2022-11-26 02:13:42 -05:00
|
|
|
void view_reload_ssd(struct view *view);
|
2024-09-09 17:43:38 +02:00
|
|
|
int view_get_min_width(void);
|
2022-11-21 10:10:39 -05:00
|
|
|
|
2023-08-08 03:39:35 +02:00
|
|
|
void view_set_shade(struct view *view, bool shaded);
|
|
|
|
|
|
2025-05-30 20:58:48 +09:00
|
|
|
/* Icon buffers set with this function are dropped later */
|
|
|
|
|
void view_set_icon(struct view *view, const char *icon_name,
|
|
|
|
|
struct wl_array *buffers);
|
|
|
|
|
|
2023-09-22 01:22:19 -04:00
|
|
|
struct view_size_hints view_get_size_hints(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_adjust_size(struct view *view, int *w, int *h);
|
|
|
|
|
|
2023-02-16 11:54:18 -05:00
|
|
|
void view_evacuate_region(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_on_output_destroy(struct view *view);
|
2023-06-15 02:35:43 -07:00
|
|
|
void view_connect_map(struct view *view, struct wlr_surface *surface);
|
2024-08-12 20:19:45 +02:00
|
|
|
|
|
|
|
|
void view_init(struct view *view);
|
2022-11-21 10:10:39 -05:00
|
|
|
void view_destroy(struct view *view);
|
|
|
|
|
|
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
2023-10-26 00:38:29 -04:00
|
|
|
enum view_axis view_axis_parse(const char *direction);
|
2023-08-02 04:30:50 +02:00
|
|
|
enum view_edge view_edge_parse(const char *direction);
|
2024-05-07 09:46:05 -04:00
|
|
|
enum view_placement_policy view_placement_parse(const char *policy);
|
2023-08-02 04:30:50 +02:00
|
|
|
|
2022-11-25 13:41:12 -05:00
|
|
|
/* xdg.c */
|
|
|
|
|
struct wlr_xdg_surface *xdg_surface_from_view(struct view *view);
|
|
|
|
|
|
2023-05-13 16:10:33 +03:00
|
|
|
#endif /* LABWC_VIEW_H */
|