mirror of
https://github.com/labwc/labwc.git
synced 2025-10-31 22:25:34 -04:00
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.
403 lines
13 KiB
C
403 lines
13 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
#ifndef LABWC_VIEW_H
|
|
#define LABWC_VIEW_H
|
|
|
|
#include "config.h"
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <wayland-util.h>
|
|
#include <wlr/util/box.h>
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
|
|
enum view_type {
|
|
LAB_XDG_SHELL_VIEW,
|
|
#if HAVE_XWAYLAND
|
|
LAB_XWAYLAND_VIEW,
|
|
#endif
|
|
};
|
|
|
|
enum ssd_preference {
|
|
LAB_SSD_PREF_UNSPEC = 0,
|
|
LAB_SSD_PREF_CLIENT,
|
|
LAB_SSD_PREF_SERVER,
|
|
};
|
|
|
|
enum view_edge {
|
|
VIEW_EDGE_INVALID = 0,
|
|
|
|
VIEW_EDGE_LEFT,
|
|
VIEW_EDGE_RIGHT,
|
|
VIEW_EDGE_UP,
|
|
VIEW_EDGE_DOWN,
|
|
VIEW_EDGE_CENTER,
|
|
};
|
|
|
|
enum view_wants_focus {
|
|
/* View does not want focus */
|
|
VIEW_WANTS_FOCUS_NEVER = 0,
|
|
/* View wants focus */
|
|
VIEW_WANTS_FOCUS_ALWAYS,
|
|
/*
|
|
* View should be offered focus and may accept or decline
|
|
* (a.k.a. ICCCM Globally Active input model). Labwc generally
|
|
* avoids focusing these views automatically (e.g. when another
|
|
* view on top is closed) but they may be focused by user action
|
|
* (e.g. mouse click).
|
|
*/
|
|
VIEW_WANTS_FOCUS_OFFER,
|
|
};
|
|
|
|
struct view;
|
|
struct wlr_surface;
|
|
|
|
/* 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;
|
|
};
|
|
|
|
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);
|
|
/*
|
|
* 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);
|
|
void (*maximize)(struct view *view, bool maximize);
|
|
void (*minimize)(struct view *view, bool minimize);
|
|
void (*move_to_front)(struct view *view);
|
|
void (*move_to_back)(struct view *view);
|
|
struct view *(*get_root)(struct view *self);
|
|
void (*append_children)(struct view *self, struct wl_array *children);
|
|
/* determines if view and surface are owned by the same process */
|
|
bool (*is_related)(struct view *self, struct wlr_surface *surface);
|
|
struct view_size_hints (*get_size_hints)(struct view *self);
|
|
/* if not implemented, VIEW_WANTS_FOCUS_ALWAYS is assumed */
|
|
enum view_wants_focus (*wants_focus)(struct view *self);
|
|
};
|
|
|
|
struct view {
|
|
struct server *server;
|
|
enum view_type type;
|
|
const struct view_impl *impl;
|
|
struct wl_list link;
|
|
|
|
/*
|
|
* The output that the view is displayed on. Specifically:
|
|
*
|
|
* - 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
|
|
* by calling view_set_output() beforehand.
|
|
*/
|
|
struct output *output;
|
|
struct workspace *workspace;
|
|
struct wlr_surface *surface;
|
|
struct wlr_scene_tree *scene_tree;
|
|
struct wlr_scene_node *scene_node;
|
|
|
|
bool mapped;
|
|
bool been_mapped;
|
|
bool ssd_enabled;
|
|
bool ssd_titlebar_hidden;
|
|
enum ssd_preference ssd_preference;
|
|
bool minimized;
|
|
bool maximized;
|
|
bool fullscreen;
|
|
uint32_t tiled; /* private, enum view_edge in src/view.c */
|
|
bool inhibits_keybinds;
|
|
|
|
/* Pointer to an output owned struct region, may be NULL */
|
|
struct region *tiled_region;
|
|
/* Set to region->name when tiled_region is free'd by a destroying output */
|
|
char *tiled_region_evacuate;
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
struct wlr_box natural_geometry;
|
|
|
|
/* used by xdg-shell views */
|
|
uint32_t pending_configure_serial;
|
|
struct wl_event_source *pending_configure_timeout;
|
|
|
|
struct ssd *ssd;
|
|
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;
|
|
|
|
struct foreign_toplevel {
|
|
struct wlr_foreign_toplevel_handle_v1 *handle;
|
|
struct wl_listener maximize;
|
|
struct wl_listener minimize;
|
|
struct wl_listener fullscreen;
|
|
struct wl_listener activate;
|
|
struct wl_listener close;
|
|
struct wl_listener destroy;
|
|
} toplevel;
|
|
|
|
struct wl_listener map;
|
|
struct wl_listener unmap;
|
|
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;
|
|
};
|
|
|
|
struct view_query {
|
|
struct wl_list link;
|
|
char *identifier;
|
|
char *title;
|
|
};
|
|
|
|
struct xdg_toplevel_view {
|
|
struct view base;
|
|
struct wlr_xdg_surface *xdg_surface;
|
|
|
|
/* Events unique to xdg-toplevel views */
|
|
struct wl_listener set_app_id;
|
|
struct wl_listener new_popup;
|
|
};
|
|
|
|
enum lab_view_criteria {
|
|
LAB_VIEW_CRITERIA_NONE = 0,
|
|
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE = 1 << 0,
|
|
LAB_VIEW_CRITERIA_NO_ALWAYS_ON_TOP = 1 << 1,
|
|
LAB_VIEW_CRITERIA_NO_SKIP_WINDOW_SWITCHER = 1 << 2,
|
|
};
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* 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"));
|
|
* }
|
|
*/
|
|
#define for_each_view(view, head, criteria) \
|
|
for (view = view_next(head, NULL, criteria); \
|
|
view; \
|
|
view = view_next(head, view, criteria))
|
|
|
|
/**
|
|
* 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);
|
|
|
|
/**
|
|
* view_array_append() - Append views that match criteria to array
|
|
* @server: server context
|
|
* @views: arrays to append to
|
|
* @criteria: criteria to match against
|
|
*
|
|
* 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.
|
|
*
|
|
* 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);
|
|
|
|
enum view_wants_focus view_wants_focus(struct view *view);
|
|
|
|
/**
|
|
* view_is_focusable_from() - variant of view_is_focusable()
|
|
* that takes into account the previously focused surface
|
|
* @view: view to be checked
|
|
* @prev_surface: previously focused surface
|
|
*/
|
|
bool view_is_focusable_from(struct view *view, struct wlr_surface *prev);
|
|
|
|
/**
|
|
* view_is_focusable() - Check whether or not a view can be focused
|
|
* @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.
|
|
*
|
|
* The only views that are allowed to be focusd are those that have a surface
|
|
* and have been mapped at some point since creation.
|
|
*/
|
|
static inline bool
|
|
view_is_focusable(struct view *view) {
|
|
return view_is_focusable_from(view, NULL);
|
|
}
|
|
|
|
void view_toggle_keybinds(struct view *view);
|
|
|
|
void view_set_activated(struct view *view, bool activated);
|
|
void view_set_output(struct view *view, struct output *output);
|
|
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);
|
|
void view_resize_relative(struct view *view,
|
|
int left, int right, int top, int bottom);
|
|
void view_move_relative(struct view *view, int x, int y);
|
|
void view_move(struct view *view, int x, int y);
|
|
void view_move_to_cursor(struct view *view);
|
|
void view_moved(struct view *view);
|
|
void view_minimize(struct view *view, bool minimized);
|
|
bool view_compute_centered_position(struct view *view,
|
|
const struct wlr_box *ref, int w, int h, int *x, int *y);
|
|
void view_store_natural_geometry(struct view *view);
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
void view_center(struct view *view, const struct wlr_box *ref);
|
|
void view_restore_to(struct view *view, struct wlr_box geometry);
|
|
void view_set_untiled(struct view *view);
|
|
void view_maximize(struct view *view, bool maximize,
|
|
bool store_natural_geometry);
|
|
void view_set_fullscreen(struct view *view, bool fullscreen);
|
|
void view_toggle_maximize(struct view *view);
|
|
void view_toggle_decorations(struct view *view);
|
|
|
|
bool view_is_always_on_top(struct view *view);
|
|
bool view_is_always_on_bottom(struct view *view);
|
|
void view_toggle_always_on_top(struct view *view);
|
|
void view_toggle_always_on_bottom(struct view *view);
|
|
|
|
bool view_is_tiled(struct view *view);
|
|
bool view_is_floating(struct view *view);
|
|
void view_move_to_workspace(struct view *view, struct workspace *workspace);
|
|
void view_set_decorations(struct view *view, bool decorations);
|
|
void view_toggle_fullscreen(struct view *view);
|
|
void view_adjust_for_layout_change(struct view *view);
|
|
void view_move_to_edge(struct view *view, enum view_edge direction);
|
|
void view_snap_to_edge(struct view *view, enum view_edge direction, bool store_natural_geometry);
|
|
void view_snap_to_region(struct view *view, struct region *region, bool store_natural_geometry);
|
|
|
|
void view_move_to_front(struct view *view);
|
|
void view_move_to_back(struct view *view);
|
|
struct view *view_get_root(struct view *view);
|
|
void view_append_children(struct view *view, struct wl_array *children);
|
|
|
|
/**
|
|
* view_is_related() - determine if view and surface are owned by the
|
|
* same application/process. Currently only implemented for xwayland
|
|
* views/surfaces.
|
|
*/
|
|
bool view_is_related(struct view *view, struct wlr_surface *surface);
|
|
|
|
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);
|
|
void view_reload_ssd(struct view *view);
|
|
|
|
struct view_size_hints view_get_size_hints(struct view *view);
|
|
void view_adjust_size(struct view *view, int *w, int *h);
|
|
|
|
void view_evacuate_region(struct view *view);
|
|
void view_on_output_destroy(struct view *view);
|
|
void view_destroy(struct view *view);
|
|
|
|
enum view_edge view_edge_parse(const char *direction);
|
|
|
|
/* xdg.c */
|
|
struct wlr_xdg_surface *xdg_surface_from_view(struct view *view);
|
|
|
|
#endif /* LABWC_VIEW_H */
|