#ifndef __LABWC_SSD_H
#define __LABWC_SSD_H
-#include "buffer.h"
-#include <wlr/util/box.h>
+#include <wayland-server-core.h>
#define BUTTON_COUNT 4
#define BUTTON_WIDTH 26
/* Forward declare arguments */
struct view;
-struct wl_list;
-struct wlr_box;
+struct wlr_buffer;
+struct wlr_scene;
+struct wlr_scene_node;
struct wlr_scene_tree;
-struct scaled_font_buffer;
struct border {
int top;
struct ssd_hover_state *hover_state);
/* Public SSD helpers */
-enum ssd_part_type ssd_at(struct view *view, double lx, double ly);
-enum ssd_part_type ssd_get_part_type(
- struct view *view, struct wlr_scene_node *node);
+enum ssd_part_type ssd_at(const struct ssd *ssd,
+ struct wlr_scene *scene, double lx, double ly);
+enum ssd_part_type ssd_get_part_type(const struct ssd *ssd,
+ struct wlr_scene_node *node);
uint32_t ssd_resize_edges(enum ssd_part_type type);
bool ssd_is_button(enum ssd_part_type type);
bool ssd_part_contains(enum ssd_part_type whole, enum ssd_part_type candidate);
void ssd_destroy_parts(struct wl_list *list);
/* SSD internal */
-void ssd_titlebar_create(struct view *view);
-void ssd_titlebar_update(struct view *view);
-void ssd_titlebar_destroy(struct view *view);
+void ssd_titlebar_create(struct ssd *ssd);
+void ssd_titlebar_update(struct ssd *ssd);
+void ssd_titlebar_destroy(struct ssd *ssd);
-void ssd_border_create(struct view *view);
-void ssd_border_update(struct view *view);
-void ssd_border_destroy(struct view *view);
+void ssd_border_create(struct ssd *ssd);
+void ssd_border_update(struct ssd *ssd);
+void ssd_border_destroy(struct ssd *ssd);
-void ssd_extents_create(struct view *view);
-void ssd_extents_update(struct view *view);
-void ssd_extents_destroy(struct view *view);
+void ssd_extents_create(struct ssd *ssd);
+void ssd_extents_update(struct ssd *ssd);
+void ssd_extents_destroy(struct ssd *ssd);
/* TODO: clean up / update */
struct border ssd_thickness(struct view *view);
if (!view) {
return;
}
- enum ssd_part_type type = ssd_at(view, server->seat.cursor->x,
- server->seat.cursor->y);
+ enum ssd_part_type type = ssd_at(&view->ssd, server->scene,
+ server->seat.cursor->x, server->seat.cursor->y);
if (type == LAB_SSD_BUTTON_WINDOW_MENU) {
force_menu_top_left = true;
} else if (ssd_part_contains(LAB_SSD_PART_TITLEBAR, type)) {
case LAB_NODE_DESC_VIEW:
case LAB_NODE_DESC_XDG_POPUP:
ret.view = desc->data;
- ret.type = ssd_get_part_type(ret.view, ret.node);
+ ret.type = ssd_get_part_type(&ret.view->ssd, ret.node);
if (ret.type == LAB_SSD_CLIENT) {
ret.surface = lab_wlr_surface_from_node(ret.node);
}
}
enum ssd_part_type
-ssd_get_part_type(struct view *view, struct wlr_scene_node *node)
+ssd_get_part_type(const struct ssd *ssd, struct wlr_scene_node *node)
{
if (!node) {
return LAB_SSD_NONE;
} else if (node->type == WLR_SCENE_NODE_BUFFER
&& lab_wlr_surface_from_node(node)) {
return LAB_SSD_CLIENT;
- } else if (!view->ssd.tree) {
+ } else if (!ssd->tree) {
return LAB_SSD_NONE;
}
- struct wl_list *part_list = NULL;
+ const struct wl_list *part_list = NULL;
struct wlr_scene_tree *grandparent =
node->parent ? node->parent->node.parent : NULL;
struct wlr_scene_tree *greatgrandparent =
grandparent ? grandparent->node.parent : NULL;
/* active titlebar */
- if (node->parent == view->ssd.titlebar.active.tree) {
- part_list = &view->ssd.titlebar.active.parts;
- } else if (grandparent == view->ssd.titlebar.active.tree) {
- part_list = &view->ssd.titlebar.active.parts;
- } else if (greatgrandparent == view->ssd.titlebar.active.tree) {
- part_list = &view->ssd.titlebar.active.parts;
+ if (node->parent == ssd->titlebar.active.tree) {
+ part_list = &ssd->titlebar.active.parts;
+ } else if (grandparent == ssd->titlebar.active.tree) {
+ part_list = &ssd->titlebar.active.parts;
+ } else if (greatgrandparent == ssd->titlebar.active.tree) {
+ part_list = &ssd->titlebar.active.parts;
/* extents */
- } else if (node->parent == view->ssd.extents.tree) {
- part_list = &view->ssd.extents.parts;
+ } else if (node->parent == ssd->extents.tree) {
+ part_list = &ssd->extents.parts;
/* active border */
- } else if (node->parent == view->ssd.border.active.tree) {
- part_list = &view->ssd.border.active.parts;
+ } else if (node->parent == ssd->border.active.tree) {
+ part_list = &ssd->border.active.parts;
/* inactive titlebar */
- } else if (node->parent == view->ssd.titlebar.inactive.tree) {
- part_list = &view->ssd.titlebar.inactive.parts;
- } else if (grandparent == view->ssd.titlebar.inactive.tree) {
- part_list = &view->ssd.titlebar.inactive.parts;
- } else if (greatgrandparent == view->ssd.titlebar.inactive.tree) {
- part_list = &view->ssd.titlebar.inactive.parts;
+ } else if (node->parent == ssd->titlebar.inactive.tree) {
+ part_list = &ssd->titlebar.inactive.parts;
+ } else if (grandparent == ssd->titlebar.inactive.tree) {
+ part_list = &ssd->titlebar.inactive.parts;
+ } else if (greatgrandparent == ssd->titlebar.inactive.tree) {
+ part_list = &ssd->titlebar.inactive.parts;
/* inactive border */
- } else if (node->parent == view->ssd.border.inactive.tree) {
- part_list = &view->ssd.border.inactive.parts;
+ } else if (node->parent == ssd->border.inactive.tree) {
+ part_list = &ssd->border.inactive.parts;
}
if (part_list) {
}
enum ssd_part_type
-ssd_at(struct view *view, double lx, double ly)
+ssd_at(const struct ssd *ssd, struct wlr_scene *scene, double lx, double ly)
{
double sx, sy;
struct wlr_scene_node *node = wlr_scene_node_at(
- &view->server->scene->tree.node, lx, ly, &sx, &sy);
- return ssd_get_part_type(view, node);
+ &scene->tree.node, lx, ly, &sx, &sy);
+ return ssd_get_part_type(ssd, node);
}
uint32_t
void
ssd_create(struct view *view, bool active)
{
- assert(!view->ssd.tree);
+ struct ssd *ssd = &view->ssd;
+ assert(!ssd->tree);
- view->ssd.tree = wlr_scene_tree_create(view->scene_tree);
- wlr_scene_node_lower_to_bottom(&view->ssd.tree->node);
- ssd_extents_create(view);
- ssd_border_create(view);
- ssd_titlebar_create(view);
- view->ssd.margin = ssd_thickness(view);
+ ssd->tree = wlr_scene_tree_create(view->scene_tree);
+ wlr_scene_node_lower_to_bottom(&ssd->tree->node);
+ ssd_extents_create(ssd);
+ ssd_border_create(ssd);
+ ssd_titlebar_create(ssd);
+ ssd->margin = ssd_thickness(view);
ssd_set_active(view, active);
- view->ssd.state.width = view->w;
- view->ssd.state.height = view->h;
- view->ssd.state.x = view->x;
- view->ssd.state.y = view->y;
+ ssd->state.width = view->w;
+ ssd->state.height = view->h;
+ ssd->state.x = view->x;
+ ssd->state.y = view->y;
}
void
ssd_update_geometry(struct view *view)
{
- if (!view->ssd.tree) {
+ struct ssd *ssd = &view->ssd;
+ if (!ssd->tree) {
return;
}
- if (view->w == view->ssd.state.width && view->h == view->ssd.state.height) {
- if (view->x != view->ssd.state.x || view->y != view->ssd.state.y) {
+ if (view->w == ssd->state.width && view->h == ssd->state.height) {
+ if (view->x != ssd->state.x || view->y != ssd->state.y) {
/* Dynamically resize extents based on position and usable_area */
- ssd_extents_update(view);
- view->ssd.state.x = view->x;
- view->ssd.state.y = view->y;
+ ssd_extents_update(ssd);
+ ssd->state.x = view->x;
+ ssd->state.y = view->y;
}
return;
}
- ssd_extents_update(view);
- ssd_border_update(view);
- ssd_titlebar_update(view);
+ ssd_extents_update(ssd);
+ ssd_border_update(ssd);
+ ssd_titlebar_update(ssd);
- view->ssd.state.width = view->w;
- view->ssd.state.height = view->h;
- view->ssd.state.x = view->x;
- view->ssd.state.y = view->y;
+ ssd->state.width = view->w;
+ ssd->state.height = view->h;
+ ssd->state.x = view->x;
+ ssd->state.y = view->y;
}
void
ssd_destroy(struct view *view)
{
- if (!view->ssd.tree) {
+ struct ssd *ssd = &view->ssd;
+ if (!ssd->tree) {
return;
}
}
/* Destroy subcomponents */
- ssd_titlebar_destroy(view);
- ssd_border_destroy(view);
- ssd_extents_destroy(view);
- wlr_scene_node_destroy(&view->ssd.tree->node);
- view->ssd.tree = NULL;
- view->ssd.margin = (struct border){ 0 };
+ ssd_titlebar_destroy(ssd);
+ ssd_border_destroy(ssd);
+ ssd_extents_destroy(ssd);
+ wlr_scene_node_destroy(&ssd->tree->node);
+ ssd->tree = NULL;
+ ssd->margin = (struct border){ 0 };
}
bool
void
ssd_set_active(struct view *view, bool active)
{
- if (!view->ssd.tree) {
+ struct ssd *ssd = &view->ssd;
+ if (!ssd->tree) {
return;
}
- wlr_scene_node_set_enabled(&view->ssd.border.active.tree->node, active);
- wlr_scene_node_set_enabled(&view->ssd.titlebar.active.tree->node, active);
- wlr_scene_node_set_enabled(&view->ssd.border.inactive.tree->node, !active);
- wlr_scene_node_set_enabled(&view->ssd.titlebar.inactive.tree->node, !active);
+ wlr_scene_node_set_enabled(&ssd->border.active.tree->node, active);
+ wlr_scene_node_set_enabled(&ssd->titlebar.active.tree->node, active);
+ wlr_scene_node_set_enabled(&ssd->border.inactive.tree->node, !active);
+ wlr_scene_node_set_enabled(&ssd->titlebar.inactive.tree->node, !active);
}
#include "theme.h"
#include "view.h"
-#define FOR_EACH_STATE(view, tmp) FOR_EACH(tmp, \
- &(view)->ssd.border.active, \
- &(view)->ssd.border.inactive)
+#define FOR_EACH_STATE(ssd, tmp) FOR_EACH(tmp, \
+ &(ssd)->border.active, \
+ &(ssd)->border.inactive)
void
-ssd_border_create(struct view *view)
+ssd_border_create(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
struct theme *theme = view->server->theme;
int width = view->w;
int height = view->h;
struct wlr_scene_tree *parent;
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
- subtree->tree = wlr_scene_tree_create(view->ssd.tree);
+ FOR_EACH_STATE(ssd, subtree) {
+ subtree->tree = wlr_scene_tree_create(ssd->tree);
parent = subtree->tree;
wlr_scene_node_set_position(&parent->node, -theme->border_width, 0);
- if (subtree == &view->ssd.border.active) {
+ if (subtree == &ssd->border.active) {
color = theme->window_active_border_color;
} else {
color = theme->window_inactive_border_color;
}
void
-ssd_border_update(struct view *view)
+ssd_border_update(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
struct theme *theme = view->server->theme;
int width = view->w;
struct ssd_part *part;
struct wlr_scene_rect *rect;
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
+ FOR_EACH_STATE(ssd, subtree) {
wl_list_for_each(part, &subtree->parts, link) {
rect = lab_wlr_scene_get_rect(part->node);
switch (part->type) {
}
void
-ssd_border_destroy(struct view *view)
+ssd_border_destroy(struct ssd *ssd)
{
- if (!view->ssd.border.active.tree) {
+ if (!ssd->border.active.tree) {
return;
}
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
+ FOR_EACH_STATE(ssd, subtree) {
ssd_destroy_parts(&subtree->parts);
wlr_scene_node_destroy(&subtree->tree->node);
subtree->tree = NULL;
}
void
-ssd_extents_create(struct view *view)
+ssd_extents_create(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
struct theme *theme = view->server->theme;
- struct wl_list *part_list = &view->ssd.extents.parts;
+ struct wl_list *part_list = &ssd->extents.parts;
int extended_area = EXTENDED_AREA;
int corner_size = extended_area + theme->border_width + BUTTON_WIDTH / 2;
- view->ssd.extents.tree = wlr_scene_tree_create(view->ssd.tree);
- struct wlr_scene_tree *parent = view->ssd.extents.tree;
+ ssd->extents.tree = wlr_scene_tree_create(ssd->tree);
+ struct wlr_scene_tree *parent = ssd->extents.tree;
if (view->maximized || view->fullscreen) {
wlr_scene_node_set_enabled(&parent->node, false);
}
- wl_list_init(&view->ssd.extents.parts);
+ wl_list_init(&ssd->extents.parts);
wlr_scene_node_set_position(&parent->node,
-(theme->border_width + extended_area),
-(theme->title_height + theme->border_width + extended_area));
p->geometry->height = corner_size;
/* Initial manual update to keep X11 applications happy */
- ssd_extents_update(view);
+ ssd_extents_update(ssd);
}
void
-ssd_extents_update(struct view *view)
+ssd_extents_update(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
if (view->maximized || view->fullscreen) {
- wlr_scene_node_set_enabled(&view->ssd.extents.tree->node, false);
+ wlr_scene_node_set_enabled(&ssd->extents.tree->node, false);
return;
}
- if (!view->ssd.extents.tree->node.enabled) {
- wlr_scene_node_set_enabled(&view->ssd.extents.tree->node, true);
+ if (!ssd->extents.tree->node.enabled) {
+ wlr_scene_node_set_enabled(&ssd->extents.tree->node, true);
}
if (!view->output) {
/* Remember base layout coordinates */
int base_x, base_y;
- wlr_scene_node_coords(&view->ssd.extents.tree->node, &base_x, &base_y);
+ wlr_scene_node_coords(&ssd->extents.tree->node, &base_x, &base_y);
struct wlr_box *target;
- wl_list_for_each(part, &view->ssd.extents.parts, link) {
+ wl_list_for_each(part, &ssd->extents.parts, link) {
rect = lab_wlr_scene_get_rect(part->node);
target = part->geometry;
switch (part->type) {
}
void
-ssd_extents_destroy(struct view *view)
+ssd_extents_destroy(struct ssd *ssd)
{
- if (!view->ssd.extents.tree) {
+ if (!ssd->extents.tree) {
return;
}
- ssd_destroy_parts(&view->ssd.extents.parts);
- wlr_scene_node_destroy(&view->ssd.extents.tree->node);
- view->ssd.extents.tree = NULL;
+ ssd_destroy_parts(&ssd->extents.parts);
+ wlr_scene_node_destroy(&ssd->extents.tree->node);
+ ssd->extents.tree = NULL;
}
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <string.h>
+#include "buffer.h"
#include "common/mem.h"
#include "common/scaled_font_buffer.h"
#include "common/scene-helpers.h"
#include "theme.h"
#include "view.h"
-#define FOR_EACH_STATE(view, tmp) FOR_EACH(tmp, \
- &(view)->ssd.titlebar.active, \
- &(view)->ssd.titlebar.inactive)
+#define FOR_EACH_STATE(ssd, tmp) FOR_EACH(tmp, \
+ &(ssd)->titlebar.active, \
+ &(ssd)->titlebar.inactive)
void
-ssd_titlebar_create(struct view *view)
+ssd_titlebar_create(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
struct theme *theme = view->server->theme;
int width = view->w;
struct wlr_buffer *close_button_unpressed;
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
- subtree->tree = wlr_scene_tree_create(view->ssd.tree);
+ FOR_EACH_STATE(ssd, subtree) {
+ subtree->tree = wlr_scene_tree_create(ssd->tree);
parent = subtree->tree;
wlr_scene_node_set_position(&parent->node, 0, -theme->title_height);
- if (subtree == &view->ssd.titlebar.active) {
+ if (subtree == &ssd->titlebar.active) {
color = theme->window_active_title_bg_color;
corner_top_left = &theme->corner_top_left_active_normal->base;
corner_top_right = &theme->corner_top_right_active_normal->base;
}
void
-ssd_titlebar_update(struct view *view)
+ssd_titlebar_update(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
int width = view->w;
- if (width == view->ssd.state.width) {
+ if (width == ssd->state.width) {
return;
}
struct theme *theme = view->server->theme;
struct ssd_part *part;
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
+ FOR_EACH_STATE(ssd, subtree) {
wl_list_for_each(part, &subtree->parts, link) {
switch (part->type) {
case LAB_SSD_PART_TITLEBAR:
}
void
-ssd_titlebar_destroy(struct view *view)
+ssd_titlebar_destroy(struct ssd *ssd)
{
- if (!view->ssd.titlebar.active.tree) {
+ if (!ssd->titlebar.active.tree) {
return;
}
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
+ FOR_EACH_STATE(ssd, subtree) {
ssd_destroy_parts(&subtree->parts);
wlr_scene_node_destroy(&subtree->tree->node);
subtree->tree = NULL;
} FOR_EACH_END
- if (view->ssd.state.title.text) {
- free(view->ssd.state.title.text);
- view->ssd.state.title.text = NULL;
+ if (ssd->state.title.text) {
+ free(ssd->state.title.text);
+ ssd->state.title.text = NULL;
}
}
*/
static void
-ssd_update_title_positions(struct view *view)
+ssd_update_title_positions(struct ssd *ssd)
{
+ struct view *view = wl_container_of(ssd, view, ssd);
struct theme *theme = view->server->theme;
int width = view->w;
int title_bg_width = width - BUTTON_WIDTH * BUTTON_COUNT;
int buffer_height, buffer_width;
struct ssd_part *part;
struct ssd_sub_tree *subtree;
- FOR_EACH_STATE(view, subtree) {
+ FOR_EACH_STATE(ssd, subtree) {
part = ssd_get_part(&subtree->parts, LAB_SSD_PART_TITLE);
if (!part || !part->node) {
/* view->surface never been mapped */
void
ssd_update_title(struct view *view)
{
- if (!view->ssd.tree) {
+ struct ssd *ssd = &view->ssd;
+ if (!ssd->tree) {
return;
}
}
struct theme *theme = view->server->theme;
- struct ssd_state_title *state = &view->ssd.state.title;
+ struct ssd_state_title *state = &ssd->state.title;
bool title_unchanged = state->text && !strcmp(title, state->text);
float *text_color;
struct ssd_state_title_width *dstate;
int title_bg_width = view->w - BUTTON_WIDTH * BUTTON_COUNT;
- FOR_EACH_STATE(view, subtree) {
- if (subtree == &view->ssd.titlebar.active) {
+ FOR_EACH_STATE(ssd, subtree) {
+ if (subtree == &ssd->titlebar.active) {
dstate = &state->active;
text_color = theme->window_active_label_text_color;
} else {
}
state->text = xstrdup(title);
}
- ssd_update_title_positions(view);
+ ssd_update_title_positions(ssd);
}
void
base_height = usable.height - 2 * rc.gap;
break;
}
+
+ struct border margin = view->ssd.margin;
struct wlr_box dst = {
- .x = x_offset + usable.x + view->ssd.margin.left,
- .y = y_offset + usable.y + view->ssd.margin.top,
- .width = base_width - view->ssd.margin.left - view->ssd.margin.right,
- .height = base_height - view->ssd.margin.top - view->ssd.margin.bottom,
+ .x = x_offset + usable.x + margin.left,
+ .y = y_offset + usable.y + margin.top,
+ .width = base_width - margin.left - margin.right,
+ .height = base_height - margin.top - margin.bottom,
};
return dst;
return false;
}
+ struct border margin = view->ssd.margin;
struct wlr_box usable = output_usable_area_in_layout_coords(output);
- int width = w + view->ssd.margin.left + view->ssd.margin.right;
- int height = h + view->ssd.margin.top + view->ssd.margin.bottom;
+ int width = w + margin.left + margin.right;
+ int height = h + margin.top + margin.bottom;
*x = usable.x + (usable.width - width) / 2;
*y = usable.y + (usable.height - height) / 2;
#if HAVE_XWAYLAND
/* TODO: refactor xwayland.c functions to get rid of this */
if (view->type == LAB_XWAYLAND_VIEW) {
- *x += view->ssd.margin.left;
- *y += view->ssd.margin.top;
+ *x += margin.left;
+ *y += margin.top;
}
#endif
wlr_log(WLR_ERROR, "invalid edge");
return;
}
+
+ struct border margin = view->ssd.margin;
struct wlr_box usable = output_usable_area_in_layout_coords(output);
if (usable.height == output->wlr_output->height
&& output->wlr_output->scale != 1) {
int x = 0, y = 0;
if (!strcasecmp(direction, "left")) {
- x = usable.x + view->ssd.margin.left + rc.gap;
+ x = usable.x + margin.left + rc.gap;
y = view->y;
} else if (!strcasecmp(direction, "up")) {
x = view->x;
- y = usable.y + view->ssd.margin.top + rc.gap;
+ y = usable.y + margin.top + rc.gap;
} else if (!strcasecmp(direction, "right")) {
- x = usable.x + usable.width - view->w - view->ssd.margin.right
+ x = usable.x + usable.width - view->w - margin.right
- rc.gap;
y = view->y;
} else if (!strcasecmp(direction, "down")) {
x = view->x;
- y = usable.y + usable.height - view->h - view->ssd.margin.bottom
+ y = usable.y + usable.height - view->h - margin.bottom
- rc.gap;
} else {
wlr_log(WLR_ERROR, "invalid edge");
#include <stdlib.h>
#include <string.h>
#include <strings.h>
+#include "buffer.h"
#include "common/font.h"
#include "common/graphic-helpers.h"
#include "common/list.h"
#include "common/mem.h"
#include "labwc.h"
-#include "view.h"
#include "workspaces.h"
/* Internal helpers */