mirror of
https://github.com/labwc/labwc.git
synced 2026-02-15 22:05:25 -05:00
ssd: clean up scene management
Our codebase for ssd scenes has grown with a lot of technical debts: - We needed to call `ssd_get_part()` everywhere to get the scene node of a ssd part. We then needed to cast it to `wlr_scene_rect` and `wlr_scene_buffer`. This bloated our codebase and even blocked duplicated button types in `<titlebar><layout>`. - `ssd_get_part_type()` was a dirty hack. It compared parent, grandparent and grandgrandparent of a node with each subtree in the ssd to get the part type of the node. To resolve this issues, this commit changes how ssd scenes are managed: - Access scene rects and scene buffers just as a member of `struct ssd`. - `ssd_part` is now a attachment to a scene node that can be accessed via node_descriptor->data, with a new node-descriptor type `LAB_NODE_DESC_SSD_PART`. `LAB_NODE_DESC_SSD_BUTTON` is unified into it. Now the scene graph under ssd->tree looks like below. The parentheses indicate the type of ssd_part attached to the node: ssd->tree (LAB_SSD_NONE) +--titlebar (LAB_SSD_PART_TITLEBAR) | +--inactive | | +--background bar | | +--left corner | | +--right corner | | +--title (LAB_SSD_PART_TITLE) | | +--iconify button (LAB_SSD_BUTTON_ICONIFY) | | | +--normal close icon image | | | +--hovered close icon image | | | +--... | | +--window icon (LAB_SSD_BUTTON_WINDOW_ICON) | | | +--window icon image | | +--... | +--active | +--... +--border | +--inactive | | +--top | | +--... | +--active | +--top | +--... +--shadow | +--inactive | | +--top | | +--... | +--active | +--top | +--... +--extents +--top +--... When hovering on SSD, `get_cursor_context()` traverses this scene node from the leaf. If it finds a `ssd_part` attached to the node, it returns `ssd_part_type` that represents the resizing direction, button types or `Title`/`Titlebar`.
This commit is contained in:
parent
aa3dbb4f85
commit
f347a818e3
13 changed files with 516 additions and 726 deletions
|
|
@ -7,7 +7,7 @@ struct view;
|
|||
struct lab_layer_surface;
|
||||
struct lab_layer_popup;
|
||||
struct menuitem;
|
||||
struct ssd_button;
|
||||
struct ssd_part;
|
||||
struct scaled_scene_buffer;
|
||||
|
||||
enum node_descriptor_type {
|
||||
|
|
@ -21,7 +21,7 @@ enum node_descriptor_type {
|
|||
LAB_NODE_DESC_MENUITEM,
|
||||
LAB_NODE_DESC_TREE,
|
||||
LAB_NODE_DESC_SCALED_SCENE_BUFFER,
|
||||
LAB_NODE_DESC_SSD_BUTTON,
|
||||
LAB_NODE_DESC_SSD_PART,
|
||||
};
|
||||
|
||||
struct node_descriptor {
|
||||
|
|
@ -44,7 +44,7 @@ struct node_descriptor {
|
|||
* - LAB_NODE_DESC_LAYER_SURFACE struct lab_layer_surface
|
||||
* - LAB_NODE_DESC_LAYER_POPUP struct lab_layer_popup
|
||||
* - LAB_NODE_DESC_MENUITEM struct menuitem
|
||||
* - LAB_NODE_DESC_SSD_BUTTON struct ssd_button
|
||||
* - LAB_NODE_DESC_SSD_PART struct ssd_part
|
||||
*/
|
||||
void node_descriptor_create(struct wlr_scene_node *scene_node,
|
||||
enum node_descriptor_type type, void *data);
|
||||
|
|
@ -77,10 +77,10 @@ struct menuitem *node_menuitem_from_node(
|
|||
struct wlr_scene_node *wlr_scene_node);
|
||||
|
||||
/**
|
||||
* node_ssd_button_from_node - return ssd_button struct from node
|
||||
* node_ssd_part_from_node - return ssd_part struct from node
|
||||
* @wlr_scene_node: wlr_scene_node from which to return data
|
||||
*/
|
||||
struct ssd_button *node_ssd_button_from_node(
|
||||
struct ssd_part *node_ssd_part_from_node(
|
||||
struct wlr_scene_node *wlr_scene_node);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -3,52 +3,53 @@
|
|||
#define LABWC_SSD_INTERNAL_H
|
||||
|
||||
#include <wlr/util/box.h>
|
||||
#include "common/macros.h"
|
||||
#include "ssd.h"
|
||||
#include "theme.h"
|
||||
#include "view.h"
|
||||
|
||||
#define FOR_EACH(tmp, ...) \
|
||||
{ \
|
||||
__typeof__(tmp) _x[] = { __VA_ARGS__, NULL }; \
|
||||
size_t _i = 0; \
|
||||
for ((tmp) = _x[_i]; _i < ARRAY_SIZE(_x) - 1; (tmp) = _x[++_i])
|
||||
|
||||
#define FOR_EACH_END }
|
||||
|
||||
struct ssd_button {
|
||||
struct view *view;
|
||||
enum ssd_part_type type;
|
||||
/*
|
||||
* Bitmap of lab_button_state that represents a combination of
|
||||
* hover/toggled/rounded states.
|
||||
*/
|
||||
uint8_t state_set;
|
||||
/*
|
||||
* Image buffers for each combination of hover/toggled/rounded states.
|
||||
* img_buffers[state_set] is displayed. Some of these can be NULL
|
||||
* (e.g. img_buffers[LAB_BS_ROUNDED] is set only for corner buttons).
|
||||
*
|
||||
* When "type" is LAB_SSD_BUTTON_WINDOW_ICON, these are all NULL and
|
||||
* window_icon is used instead.
|
||||
*/
|
||||
struct scaled_img_buffer *img_buffers[LAB_BS_ALL + 1];
|
||||
|
||||
struct scaled_icon_buffer *window_icon;
|
||||
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct ssd_sub_tree {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wl_list parts; /* ssd_part.link */
|
||||
};
|
||||
|
||||
struct ssd_state_title_width {
|
||||
int width;
|
||||
bool truncated;
|
||||
};
|
||||
|
||||
/*
|
||||
* The scene-graph of SSD looks like below. The parentheses indicate the type of
|
||||
* ssd_part attached to the node.
|
||||
*
|
||||
* ssd->tree (LAB_SSD_NONE)
|
||||
* +--titlebar (LAB_SSD_PART_TITLEBAR)
|
||||
* | +--inactive
|
||||
* | | +--background bar
|
||||
* | | +--left corner
|
||||
* | | +--right corner
|
||||
* | | +--title (LAB_SSD_PART_TITLE)
|
||||
* | | +--iconify button (LAB_SSD_BUTTON_ICONIFY)
|
||||
* | | | +--normal close icon image
|
||||
* | | | +--hovered close icon image
|
||||
* | | | +--...
|
||||
* | | +--window icon (LAB_SSD_BUTTON_WINDOW_ICON)
|
||||
* | | | +--window icon image
|
||||
* | | +--...
|
||||
* | +--active
|
||||
* | +--...
|
||||
* +--border
|
||||
* | +--inactive
|
||||
* | | +--top
|
||||
* | | +--...
|
||||
* | +--active
|
||||
* | +--top
|
||||
* | +--...
|
||||
* +--shadow
|
||||
* | +--inactive
|
||||
* | | +--top
|
||||
* | | +--...
|
||||
* | +--active
|
||||
* | +--top
|
||||
* | +--...
|
||||
* +--extents
|
||||
* +--top
|
||||
* +--...
|
||||
*/
|
||||
struct ssd {
|
||||
struct view *view;
|
||||
struct wlr_scene_tree *tree;
|
||||
|
|
@ -81,33 +82,49 @@ struct ssd {
|
|||
struct wlr_box geometry;
|
||||
struct ssd_state_title {
|
||||
char *text;
|
||||
struct ssd_state_title_width active;
|
||||
struct ssd_state_title_width inactive;
|
||||
/* indexed by enum ssd_active_state */
|
||||
struct ssd_state_title_width dstates[2];
|
||||
} title;
|
||||
} state;
|
||||
|
||||
/* An invisible area around the view which allows resizing */
|
||||
struct ssd_sub_tree extents;
|
||||
struct ssd_extents_scene {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||
} extents;
|
||||
|
||||
/* The top of the view, containing buttons, title, .. */
|
||||
struct {
|
||||
struct ssd_titlebar_scene {
|
||||
int height;
|
||||
struct wlr_scene_tree *tree;
|
||||
struct ssd_sub_tree active;
|
||||
struct ssd_sub_tree inactive;
|
||||
struct ssd_titlebar_subtree {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_buffer *corner_left;
|
||||
struct wlr_scene_buffer *corner_right;
|
||||
struct wlr_scene_buffer *bar;
|
||||
struct scaled_font_buffer *title;
|
||||
/* List of ssd_parts that represent buttons */
|
||||
struct wl_list buttons_left;
|
||||
struct wl_list buttons_right;
|
||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||
} titlebar;
|
||||
|
||||
/* Borders allow resizing as well */
|
||||
struct {
|
||||
struct ssd_border_scene {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct ssd_sub_tree active;
|
||||
struct ssd_sub_tree inactive;
|
||||
struct ssd_border_subtree {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||
} border;
|
||||
|
||||
struct {
|
||||
struct ssd_shadow_scene {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct ssd_sub_tree active;
|
||||
struct ssd_sub_tree inactive;
|
||||
struct ssd_shadow_subtree {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_buffer *top, *bottom, *left, *right,
|
||||
*top_left, *top_right, *bottom_left, *bottom_right;
|
||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||
} shadow;
|
||||
|
||||
/*
|
||||
|
|
@ -118,46 +135,61 @@ struct ssd {
|
|||
struct border margin;
|
||||
};
|
||||
|
||||
/*
|
||||
* ssd_part wraps a scene-node with ssd-specific information and can be
|
||||
* accessed with node_ssd_part_from_node(wlr_scene_node *).
|
||||
* This allows get_cursor_context() in desktop.c to see which SSD part is under
|
||||
* the cursor.
|
||||
*/
|
||||
struct ssd_part {
|
||||
enum ssd_part_type type;
|
||||
|
||||
/* Buffer pointer. May be NULL */
|
||||
struct scaled_font_buffer *buffer;
|
||||
struct view *view;
|
||||
|
||||
/* This part represented in scene graph */
|
||||
struct wlr_scene_node *node;
|
||||
|
||||
struct wl_list link;
|
||||
struct wl_listener node_destroy;
|
||||
};
|
||||
|
||||
struct ssd_part_button {
|
||||
struct ssd_part base;
|
||||
/*
|
||||
* Bitmap of lab_button_state that represents a combination of
|
||||
* hover/toggled/rounded states.
|
||||
*/
|
||||
uint8_t state_set;
|
||||
/*
|
||||
* Image buffers for each combination of hover/toggled/rounded states.
|
||||
* img_buffers[state_set] is displayed. Some of these can be NULL
|
||||
* (e.g. img_buffers[LAB_BS_ROUNDED] is set only for corner buttons).
|
||||
*
|
||||
* When the type of ssd_part pointing to ssd_button is
|
||||
* LAB_SSD_BUTTON_WINDOW_ICON, these are all NULL and window_icon is
|
||||
* used instead.
|
||||
*/
|
||||
struct scaled_img_buffer *img_buffers[LAB_BS_ALL + 1];
|
||||
|
||||
struct scaled_icon_buffer *window_icon;
|
||||
|
||||
struct wl_list link; /* ssd_titlebar_subtree.buttons_{left,right} */
|
||||
};
|
||||
|
||||
/* FIXME: This structure is redundant as ssd_part contains view */
|
||||
struct ssd_hover_state {
|
||||
struct view *view;
|
||||
struct ssd_button *button;
|
||||
struct ssd_part_button *button;
|
||||
};
|
||||
|
||||
struct wlr_buffer;
|
||||
struct wlr_scene_tree;
|
||||
|
||||
/* SSD internal helpers to create various SSD elements */
|
||||
/* TODO: Replace some common args with a struct */
|
||||
struct ssd_part *add_scene_part(
|
||||
struct wl_list *part_list, enum ssd_part_type type);
|
||||
struct ssd_part *add_scene_rect(
|
||||
struct wl_list *list, enum ssd_part_type type,
|
||||
struct wlr_scene_tree *parent, int width, int height, int x, int y,
|
||||
float color[4]);
|
||||
struct ssd_part *add_scene_buffer(
|
||||
struct wl_list *list, enum ssd_part_type type,
|
||||
struct wlr_scene_tree *parent, struct wlr_buffer *buffer, int x, int y);
|
||||
struct ssd_part *add_scene_button(struct wl_list *part_list,
|
||||
struct ssd_part *attach_ssd_part(enum ssd_part_type type, struct view *view,
|
||||
struct wlr_scene_node *node);
|
||||
struct ssd_part_button *attach_ssd_part_button(struct wl_list *button_parts,
|
||||
enum ssd_part_type type, struct wlr_scene_tree *parent,
|
||||
struct lab_img *buffers[LAB_BS_ALL + 1], int x, int y,
|
||||
struct lab_img *imgs[LAB_BS_ALL + 1], int x, int y,
|
||||
struct view *view);
|
||||
|
||||
/* SSD internal helpers */
|
||||
struct ssd_part *ssd_get_part(
|
||||
struct wl_list *part_list, enum ssd_part_type type);
|
||||
void ssd_destroy_parts(struct wl_list *list);
|
||||
struct ssd_part_button *button_try_from_ssd_part(struct ssd_part *part);
|
||||
|
||||
/* SSD internal */
|
||||
void ssd_titlebar_create(struct ssd *ssd);
|
||||
|
|
|
|||
|
|
@ -6,6 +6,13 @@
|
|||
#include "common/edge.h"
|
||||
#include "config/types.h"
|
||||
|
||||
enum ssd_active_state {
|
||||
SSD_INACTIVE = 0,
|
||||
SSD_ACTIVE = 1,
|
||||
};
|
||||
|
||||
#define FOR_EACH_ACTIVE_STATE(active) for (active = SSD_INACTIVE; active <= SSD_ACTIVE; active++)
|
||||
|
||||
struct wlr_cursor;
|
||||
|
||||
/*
|
||||
|
|
@ -36,11 +43,8 @@ enum ssd_part_type {
|
|||
LAB_SSD_BUTTON,
|
||||
|
||||
LAB_SSD_PART_TITLEBAR,
|
||||
LAB_SSD_PART_TITLEBAR_CORNER_RIGHT,
|
||||
LAB_SSD_PART_TITLEBAR_CORNER_LEFT,
|
||||
LAB_SSD_PART_TITLE,
|
||||
|
||||
/* shared by shadows, borders and extents */
|
||||
LAB_SSD_PART_CORNER_TOP_LEFT,
|
||||
LAB_SSD_PART_CORNER_TOP_RIGHT,
|
||||
LAB_SSD_PART_CORNER_BOTTOM_RIGHT,
|
||||
|
|
@ -64,8 +68,8 @@ enum ssd_part_type {
|
|||
|
||||
/* Forward declare arguments */
|
||||
struct ssd;
|
||||
struct ssd_button;
|
||||
struct ssd_hover_state;
|
||||
struct ssd_part;
|
||||
struct view;
|
||||
struct wlr_scene;
|
||||
struct wlr_scene_node;
|
||||
|
|
@ -96,12 +100,17 @@ struct ssd_hover_state *ssd_hover_state_new(void);
|
|||
void ssd_update_button_hover(struct wlr_scene_node *node,
|
||||
struct ssd_hover_state *hover_state);
|
||||
|
||||
enum ssd_part_type ssd_button_get_type(const struct ssd_button *button);
|
||||
struct view *ssd_button_get_view(const struct ssd_button *button);
|
||||
enum ssd_part_type ssd_part_get_type(const struct ssd_part *part);
|
||||
struct view *ssd_part_get_view(const struct ssd_part *part);
|
||||
|
||||
/* Public SSD helpers */
|
||||
enum ssd_part_type ssd_get_part_type(const struct ssd *ssd,
|
||||
struct wlr_scene_node *node, struct wlr_cursor *cursor);
|
||||
|
||||
/*
|
||||
* Returns a part type that represents a mouse context like "Top", "Left" and
|
||||
* "TRCorner" when the cursor is on the window border or resizing handle.
|
||||
*/
|
||||
enum ssd_part_type ssd_get_resizing_type(const struct ssd *ssd,
|
||||
struct wlr_cursor *cursor);
|
||||
enum lab_edge ssd_resize_edges(enum ssd_part_type type);
|
||||
bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate);
|
||||
enum lab_ssd_mode ssd_mode_parse(const char *mode);
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ struct theme {
|
|||
int mag_border_width;
|
||||
};
|
||||
|
||||
/* TODO: replace with enum ssd_active_state */
|
||||
#define THEME_INACTIVE 0
|
||||
#define THEME_ACTIVE 1
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue