mirror of
https://github.com/labwc/labwc.git
synced 2025-11-03 09:01:51 -05:00
Create a linked list of SSD for each view
This commit is contained in:
parent
f863e1916d
commit
2a48f2801b
8 changed files with 134 additions and 47 deletions
|
|
@ -213,7 +213,11 @@ struct view {
|
|||
uint32_t configure_serial;
|
||||
} pending_move_resize;
|
||||
|
||||
bool server_side_deco;
|
||||
struct {
|
||||
bool enabled;
|
||||
struct wl_list parts;
|
||||
struct wlr_box box; /* remember geo so we know when to update */
|
||||
} ssd;
|
||||
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef __LABWC_SSD_H
|
||||
#define __LABWC_SSD_H
|
||||
|
||||
enum ssd_part {
|
||||
enum ssd_part_type {
|
||||
LAB_SSD_NONE = 0,
|
||||
LAB_SSD_BUTTON_CLOSE,
|
||||
LAB_SSD_BUTTON_MAXIMIZE,
|
||||
|
|
@ -14,11 +14,22 @@ enum ssd_part {
|
|||
LAB_SSD_END_MARKER
|
||||
};
|
||||
|
||||
struct ssd_part {
|
||||
struct wlr_box box;
|
||||
enum ssd_part_type type;
|
||||
struct wlr_texture *texture;
|
||||
float *color;
|
||||
struct wl_list link;
|
||||
};
|
||||
|
||||
struct view;
|
||||
|
||||
struct border ssd_thickness(struct view *view);
|
||||
struct wlr_box ssd_max_extents(struct view *view);
|
||||
struct wlr_box ssd_box(struct view *view, enum ssd_part ssd_part);
|
||||
enum ssd_part ssd_at(struct view *view, double lx, double ly);
|
||||
struct wlr_box ssd_box(struct view *view, enum ssd_part_type type);
|
||||
enum ssd_part_type ssd_at(struct view *view, double lx, double ly);
|
||||
void ssd_create(struct view *view);
|
||||
void ssd_destroy(struct view *view);
|
||||
void ssd_update_geometry(struct view *view);
|
||||
|
||||
#endif /* __LABWC_SSD_H */
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ desktop_view_at(struct server *server, double lx, double ly,
|
|||
if (_view_at(view, lx, ly, surface, sx, sy)) {
|
||||
return view;
|
||||
}
|
||||
if (!view->server_side_deco) {
|
||||
if (!view->ssd.enabled) {
|
||||
continue;
|
||||
}
|
||||
*view_area = ssd_at(view, lx, ly);
|
||||
|
|
|
|||
50
src/output.c
50
src/output.c
|
|
@ -321,6 +321,7 @@ render_rect(struct output *output, pixman_region32_t *output_damage,
|
|||
output->wlr_output, &ox, &oy);
|
||||
box.x += ox;
|
||||
box.y += oy;
|
||||
scale_box(&box, wlr_output->scale);
|
||||
|
||||
pixman_region32_t damage;
|
||||
pixman_region32_init(&damage);
|
||||
|
|
@ -424,6 +425,7 @@ render_icon(struct output *output, pixman_region32_t *output_damage,
|
|||
output->wlr_output, &ox, &oy);
|
||||
button.x += ox;
|
||||
button.y += oy;
|
||||
scale_box(&button, output->wlr_output->scale);
|
||||
|
||||
float matrix[9];
|
||||
wlr_matrix_project_box(matrix, &button, WL_OUTPUT_TRANSFORM_NORMAL, 0,
|
||||
|
|
@ -433,54 +435,48 @@ render_icon(struct output *output, pixman_region32_t *output_damage,
|
|||
}
|
||||
|
||||
static bool
|
||||
isbutton(enum ssd_part ssd_part)
|
||||
isbutton(enum ssd_part_type type)
|
||||
{
|
||||
return ssd_part == LAB_SSD_BUTTON_CLOSE ||
|
||||
ssd_part == LAB_SSD_BUTTON_MAXIMIZE ||
|
||||
ssd_part == LAB_SSD_BUTTON_ICONIFY;
|
||||
return type == LAB_SSD_BUTTON_CLOSE ||
|
||||
type == LAB_SSD_BUTTON_MAXIMIZE ||
|
||||
type == LAB_SSD_BUTTON_ICONIFY;
|
||||
}
|
||||
|
||||
static void
|
||||
render_deco(struct view *view, struct output *output,
|
||||
pixman_region32_t *output_damage)
|
||||
{
|
||||
if (!view->server_side_deco) {
|
||||
if (!view->ssd.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct theme *theme = view->server->theme;
|
||||
|
||||
/* render border */
|
||||
float *color = theme->window_active_handle_bg_color;
|
||||
enum ssd_part border[4] = {
|
||||
LAB_SSD_PART_TOP,
|
||||
LAB_SSD_PART_RIGHT,
|
||||
LAB_SSD_PART_BOTTOM,
|
||||
LAB_SSD_PART_LEFT,
|
||||
};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
struct wlr_box box = ssd_box(view, border[i]);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_rect(output, output_damage, &box, color);
|
||||
struct ssd_part *part;
|
||||
wl_list_for_each_reverse(part, &view->ssd.parts, link) {
|
||||
if (part->texture) {
|
||||
; // render_texture()
|
||||
} else {
|
||||
render_rect(output, output_damage, &part->box,
|
||||
part->color);
|
||||
}
|
||||
}
|
||||
|
||||
/* render title */
|
||||
struct wlr_seat *seat = view->server->seat.seat;
|
||||
float *color;
|
||||
struct theme *theme = view->server->theme;
|
||||
if (view->surface == seat->keyboard_state.focused_surface) {
|
||||
color = theme->window_active_title_bg_color;
|
||||
} else {
|
||||
color = theme->window_inactive_title_bg_color;
|
||||
}
|
||||
struct wlr_box box = ssd_box(view, LAB_SSD_PART_TITLE);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_rect(output, output_damage, &box, color);
|
||||
|
||||
/* button background */
|
||||
struct wlr_cursor *cur = view->server->seat.cursor;
|
||||
enum ssd_part ssd_part = ssd_at(view, cur->x, cur->y);
|
||||
box = ssd_box(view, ssd_part);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
if (isbutton(ssd_part) &&
|
||||
enum ssd_part_type type = ssd_at(view, cur->x, cur->y);
|
||||
box = ssd_box(view, type);
|
||||
if (isbutton(type) &&
|
||||
wlr_box_contains_point(&box, cur->x, cur->y)) {
|
||||
color = (float[4]){ 0.5, 0.5, 0.5, 0.5 };
|
||||
render_rect(output, output_damage, &box, color);
|
||||
|
|
@ -489,28 +485,22 @@ render_deco(struct view *view, struct output *output,
|
|||
/* buttons */
|
||||
if (view->surface == seat->keyboard_state.focused_surface) {
|
||||
box = ssd_box(view, LAB_SSD_BUTTON_CLOSE);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_icon(output, output_damage, &box,
|
||||
theme->xbm_close_active_unpressed);
|
||||
box = ssd_box(view, LAB_SSD_BUTTON_MAXIMIZE);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_icon(output, output_damage, &box,
|
||||
theme->xbm_maximize_active_unpressed);
|
||||
box = ssd_box(view, LAB_SSD_BUTTON_ICONIFY);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_icon(output, output_damage, &box,
|
||||
theme->xbm_iconify_active_unpressed);
|
||||
} else {
|
||||
box = ssd_box(view, LAB_SSD_BUTTON_CLOSE);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_icon(output, output_damage, &box,
|
||||
theme->xbm_close_inactive_unpressed);
|
||||
box = ssd_box(view, LAB_SSD_BUTTON_MAXIMIZE);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_icon(output, output_damage, &box,
|
||||
theme->xbm_maximize_inactive_unpressed);
|
||||
box = ssd_box(view, LAB_SSD_BUTTON_ICONIFY);
|
||||
scale_box(&box, output->wlr_output->scale);
|
||||
render_icon(output, output_damage, &box,
|
||||
theme->xbm_iconify_inactive_unpressed);
|
||||
}
|
||||
|
|
|
|||
83
src/ssd.c
83
src/ssd.c
|
|
@ -7,6 +7,7 @@
|
|||
#include <assert.h>
|
||||
#include "config/rcxml.h"
|
||||
#include "labwc.h"
|
||||
#include "theme.h"
|
||||
#include "ssd.h"
|
||||
|
||||
#define BORDER_WIDTH (2)
|
||||
|
|
@ -37,11 +38,11 @@ ssd_max_extents(struct view *view)
|
|||
}
|
||||
|
||||
struct wlr_box
|
||||
ssd_box(struct view *view, enum ssd_part ssd_part)
|
||||
ssd_box(struct view *view, enum ssd_part_type type)
|
||||
{
|
||||
struct wlr_box box = { 0 };
|
||||
assert(view);
|
||||
switch (ssd_part) {
|
||||
switch (type) {
|
||||
case LAB_SSD_BUTTON_CLOSE:
|
||||
box.width = rc.title_height;
|
||||
box.height = rc.title_height;
|
||||
|
|
@ -96,17 +97,85 @@ ssd_box(struct view *view, enum ssd_part ssd_part)
|
|||
return box;
|
||||
}
|
||||
|
||||
enum ssd_part
|
||||
enum ssd_part_type
|
||||
ssd_at(struct view *view, double lx, double ly)
|
||||
{
|
||||
enum ssd_part ssd_part;
|
||||
for (ssd_part = 0; ssd_part < LAB_SSD_END_MARKER; ++ssd_part) {
|
||||
struct wlr_box box = ssd_box(view, ssd_part);
|
||||
enum ssd_part_type type;
|
||||
for (type = 0; type < LAB_SSD_END_MARKER; ++type) {
|
||||
struct wlr_box box = ssd_box(view, type);
|
||||
if (wlr_box_contains_point(&box, lx, ly)) {
|
||||
return ssd_part;
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return LAB_SSD_NONE;
|
||||
}
|
||||
|
||||
static struct ssd_part *
|
||||
add_part(struct view *view, enum ssd_part_type type)
|
||||
{
|
||||
struct ssd_part *part = calloc(1, sizeof(struct ssd_part));
|
||||
part->type = type;
|
||||
wl_list_insert(&view->ssd.parts, &part->link);
|
||||
return part;
|
||||
}
|
||||
|
||||
void
|
||||
ssd_create(struct view *view)
|
||||
{
|
||||
struct theme *theme = view->server->theme;
|
||||
struct ssd_part *part;
|
||||
|
||||
view->ssd.box.x = view->x;
|
||||
view->ssd.box.y = view->y;
|
||||
view->ssd.box.width = view->w;
|
||||
view->ssd.box.height = view->h;
|
||||
|
||||
/* border */
|
||||
float *color = theme->window_active_handle_bg_color;
|
||||
enum ssd_part_type border[4] = {
|
||||
LAB_SSD_PART_TOP,
|
||||
LAB_SSD_PART_RIGHT,
|
||||
LAB_SSD_PART_BOTTOM,
|
||||
LAB_SSD_PART_LEFT,
|
||||
};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
part = add_part(view, border[i]);
|
||||
part->box = ssd_box(view, border[i]);
|
||||
part->color = color;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ssd_destroy(struct view *view)
|
||||
{
|
||||
struct ssd_part *part, *next;
|
||||
wl_list_for_each_safe(part, next, &view->ssd.parts, link) {
|
||||
wl_list_remove(&part->link);
|
||||
free(part);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
geometry_changed(struct view *view)
|
||||
{
|
||||
return view->x != view->ssd.box.x || view->y != view->ssd.box.y ||
|
||||
view->w != view->ssd.box.width ||
|
||||
view->h != view->ssd.box.height;
|
||||
}
|
||||
|
||||
void
|
||||
ssd_update_geometry(struct view *view)
|
||||
{
|
||||
if (!geometry_changed(view)) {
|
||||
return;
|
||||
}
|
||||
struct ssd_part *part;
|
||||
wl_list_for_each(part, &view->ssd.parts, link) {
|
||||
part->box = ssd_box(view, part->type);
|
||||
}
|
||||
view->ssd.box.x = view->x;
|
||||
view->ssd.box.y = view->y;
|
||||
view->ssd.box.width = view->w;
|
||||
view->ssd.box.height = view->h;
|
||||
damage_all_outputs(view->server);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ view_maximize(struct view *view, bool maximize)
|
|||
.width = output->width,
|
||||
.height = output->height,
|
||||
};
|
||||
if (view->server_side_deco) {
|
||||
if (view->ssd.enabled) {
|
||||
struct border border = ssd_thickness(view);
|
||||
box.x += border.left;
|
||||
box.y += border.top;
|
||||
|
|
|
|||
10
src/xdg.c
10
src/xdg.c
|
|
@ -69,6 +69,7 @@ handle_commit(struct wl_listener *listener, void *data)
|
|||
view->pending_move_resize.configure_serial = 0;
|
||||
}
|
||||
}
|
||||
ssd_update_geometry(view);
|
||||
damage_view_part(view);
|
||||
}
|
||||
|
||||
|
|
@ -91,6 +92,7 @@ handle_destroy(struct wl_listener *listener, void *data)
|
|||
{
|
||||
struct view *view = wl_container_of(listener, view, destroy);
|
||||
wl_list_remove(&view->link);
|
||||
ssd_destroy(view);
|
||||
free(view);
|
||||
}
|
||||
|
||||
|
|
@ -151,6 +153,7 @@ xdg_toplevel_view_configure(struct view *view, struct wlr_box geo)
|
|||
} else if (view->pending_move_resize.configure_serial == 0) {
|
||||
view->x = geo.x;
|
||||
view->y = geo.y;
|
||||
ssd_update_geometry(view);
|
||||
damage_all_outputs(view->server);
|
||||
}
|
||||
}
|
||||
|
|
@ -160,6 +163,7 @@ xdg_toplevel_view_move(struct view *view, double x, double y)
|
|||
{
|
||||
view->x = x;
|
||||
view->y = y;
|
||||
ssd_update_geometry(view);
|
||||
damage_all_outputs(view->server);
|
||||
}
|
||||
|
||||
|
|
@ -253,9 +257,10 @@ xdg_toplevel_view_map(struct view *view)
|
|||
*/
|
||||
view_maximize(view, false);
|
||||
|
||||
view->server_side_deco = has_ssd(view);
|
||||
if (view->server_side_deco) {
|
||||
view->ssd.enabled = has_ssd(view);
|
||||
if (view->ssd.enabled) {
|
||||
view->margin = ssd_thickness(view);
|
||||
ssd_create(view);
|
||||
}
|
||||
update_padding(view);
|
||||
position_xdg_toplevel_view(view);
|
||||
|
|
@ -310,6 +315,7 @@ xdg_surface_new(struct wl_listener *listener, void *data)
|
|||
view->type = LAB_XDG_SHELL_VIEW;
|
||||
view->impl = &xdg_toplevel_view_impl;
|
||||
view->xdg_surface = xdg_surface;
|
||||
wl_list_init(&view->ssd.parts);
|
||||
|
||||
view->map.notify = handle_map;
|
||||
wl_signal_add(&xdg_surface->events.map, &view->map);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ handle_commit(struct wl_listener *listener, void *data)
|
|||
view->pending_move_resize.height - view->h;
|
||||
view->pending_move_resize.update_y = false;
|
||||
}
|
||||
ssd_update_geometry(view);
|
||||
damage_view_whole(view);
|
||||
}
|
||||
|
||||
|
|
@ -49,6 +50,7 @@ handle_destroy(struct wl_listener *listener, void *data)
|
|||
wl_list_remove(&view->destroy.link);
|
||||
wl_list_remove(&view->request_configure.link);
|
||||
wl_list_remove(&view->request_maximize.link);
|
||||
ssd_destroy(view);
|
||||
free(view);
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +97,7 @@ move(struct view *view, double x, double y)
|
|||
struct wlr_xwayland_surface *s = view->xwayland_surface;
|
||||
wlr_xwayland_surface_configure(s, (int16_t)x, (int16_t)y,
|
||||
(uint16_t)s->width, (uint16_t)s->height);
|
||||
ssd_update_geometry(view);
|
||||
damage_all_outputs(view->server);
|
||||
}
|
||||
|
||||
|
|
@ -147,9 +150,12 @@ map(struct view *view)
|
|||
view->w = view->xwayland_surface->width;
|
||||
view->h = view->xwayland_surface->height;
|
||||
view->surface = view->xwayland_surface->surface;
|
||||
view->server_side_deco = want_deco(view);
|
||||
view->ssd.enabled = want_deco(view);
|
||||
|
||||
if (view->ssd.enabled) {
|
||||
view->margin = ssd_thickness(view);
|
||||
ssd_create(view);
|
||||
}
|
||||
|
||||
top_left_edge_boundary_check(view);
|
||||
|
||||
|
|
@ -209,6 +215,7 @@ xwayland_surface_new(struct wl_listener *listener, void *data)
|
|||
view->type = LAB_XWAYLAND_VIEW;
|
||||
view->impl = &xwl_view_impl;
|
||||
view->xwayland_surface = xsurface;
|
||||
wl_list_init(&view->ssd.parts);
|
||||
|
||||
view->map.notify = handle_map;
|
||||
wl_signal_add(&xsurface->events.map, &view->map);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue