mirror of
https://github.com/labwc/labwc.git
synced 2026-04-07 08:21:20 -04:00
Merge 2591661005 into c9b4da2ce2
This commit is contained in:
commit
7cd2f4184d
22 changed files with 1215 additions and 54 deletions
|
|
@ -6,7 +6,9 @@
|
||||||
# make sure all other lines are commented out or deleted.
|
# make sure all other lines are commented out or deleted.
|
||||||
|
|
||||||
# general
|
# general
|
||||||
border.width: 1
|
border.width: 6
|
||||||
|
border.beveled: yes
|
||||||
|
border.bevel_width:2
|
||||||
|
|
||||||
#
|
#
|
||||||
# The global padding.{width,height} of openbox are not supported because
|
# The global padding.{width,height} of openbox are not supported because
|
||||||
|
|
|
||||||
61
include/common/borderset.h
Normal file
61
include/common/borderset.h
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
|
||||||
|
#ifndef LABWC_BORDERSET_H
|
||||||
|
#define LABWC_BORDERSET_H
|
||||||
|
|
||||||
|
enum border_type {
|
||||||
|
BORDER_NONE, BORDER_SINGLE, BORDER_DOUBLE, BORDER_INSET, BORDER_DOUBLE_INSET, BORDER_FLAT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct borderset {
|
||||||
|
// Base colour, but could be used as a tracking hash for images or whatever in the future
|
||||||
|
uint32_t id;
|
||||||
|
// width (since I suspect a 2px border scaled up to 20px might look weird)
|
||||||
|
int size;
|
||||||
|
// Single or double bevel, etc.
|
||||||
|
enum border_type type;
|
||||||
|
// So we can disambiguate multiple possible designs cached together
|
||||||
|
int bevelSize;
|
||||||
|
struct lab_data_buffer *top;
|
||||||
|
struct lab_data_buffer *left;
|
||||||
|
struct lab_data_buffer *right;
|
||||||
|
struct lab_data_buffer *bottom;
|
||||||
|
struct lab_data_buffer *tl;
|
||||||
|
struct lab_data_buffer *tr;
|
||||||
|
struct lab_data_buffer *bl;
|
||||||
|
struct lab_data_buffer *br;
|
||||||
|
struct borderset *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct bufferset {
|
||||||
|
enum border_type type;
|
||||||
|
int border_width;
|
||||||
|
struct wlr_scene_buffer *top;
|
||||||
|
struct wlr_scene_buffer *left;
|
||||||
|
struct wlr_scene_buffer *right;
|
||||||
|
struct wlr_scene_buffer *bottom;
|
||||||
|
struct wlr_scene_buffer *tl;
|
||||||
|
struct wlr_scene_buffer *tr;
|
||||||
|
struct wlr_scene_buffer *bl;
|
||||||
|
struct wlr_scene_buffer *br;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct borderset *border_cache;
|
||||||
|
|
||||||
|
struct borderset *get_borders(uint32_t id, int size, enum border_type, int bevelSize);
|
||||||
|
|
||||||
|
struct borderset *create_buffer(uint32_t id, int size, enum border_type, int bevelSize);
|
||||||
|
|
||||||
|
struct bufferset *generate_bufferset(struct wlr_scene_tree *tree,
|
||||||
|
struct borderset *borderset, int bw);
|
||||||
|
|
||||||
|
void renderBufferset(struct bufferset *bufferset, int width, int height, int y);
|
||||||
|
|
||||||
|
void renderBuffersetXY(struct bufferset *bufferset, int width, int height, int x, int y);
|
||||||
|
|
||||||
|
void clearborder_cache(struct borderset *borderset);
|
||||||
|
|
||||||
|
#endif /* LABWC_BORDERSET_H */
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
#ifndef LABWC_LAB_SCENE_RECT_H
|
#ifndef LABWC_LAB_SCENE_RECT_H
|
||||||
#define LABWC_LAB_SCENE_RECT_H
|
#define LABWC_LAB_SCENE_RECT_H
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
struct wlr_scene_tree;
|
struct wlr_scene_tree;
|
||||||
|
|
||||||
|
|
@ -12,6 +13,8 @@ struct lab_scene_rect_options {
|
||||||
float *bg_color; /* can be NULL */
|
float *bg_color; /* can be NULL */
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
enum border_type border_type;
|
||||||
|
int bevel_width;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lab_scene_rect {
|
struct lab_scene_rect {
|
||||||
|
|
|
||||||
|
|
@ -65,4 +65,15 @@
|
||||||
#define LAB_WLR_VERSION_AT_LEAST(major, minor, micro) \
|
#define LAB_WLR_VERSION_AT_LEAST(major, minor, micro) \
|
||||||
(WLR_VERSION_NUM >= (((major) << 16) | ((minor) << 8) | (micro)))
|
(WLR_VERSION_NUM >= (((major) << 16) | ((minor) << 8) | (micro)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PIXEL () - calculate pixel offset in an array
|
||||||
|
*
|
||||||
|
* @param x x-coordinate
|
||||||
|
* @param y y-coordinate
|
||||||
|
* @param size width of the buffer in pixes
|
||||||
|
* Assumes "bw" was defined externally
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIXEL(x, y, size) (size * y + x)
|
||||||
|
|
||||||
#endif /* LABWC_MACROS_H */
|
#endif /* LABWC_MACROS_H */
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ struct ssd {
|
||||||
struct scaled_font_buffer *title;
|
struct scaled_font_buffer *title;
|
||||||
struct wl_list buttons_left; /* ssd_button.link */
|
struct wl_list buttons_left; /* ssd_button.link */
|
||||||
struct wl_list buttons_right; /* ssd_button.link */
|
struct wl_list buttons_right; /* ssd_button.link */
|
||||||
|
struct bufferset *textured_borders;
|
||||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||||
} titlebar;
|
} titlebar;
|
||||||
|
|
||||||
|
|
@ -115,6 +116,7 @@ struct ssd {
|
||||||
struct ssd_border_subtree {
|
struct ssd_border_subtree {
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||||
|
struct bufferset *textured_borders;
|
||||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||||
} border;
|
} border;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "common/node-type.h"
|
#include "common/node-type.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
struct lab_img;
|
struct lab_img;
|
||||||
|
|
||||||
|
|
@ -56,6 +57,10 @@ struct theme_background {
|
||||||
float color_split_to[4];
|
float color_split_to[4];
|
||||||
float color_to[4];
|
float color_to[4];
|
||||||
float color_to_split_to[4];
|
float color_to_split_to[4];
|
||||||
|
enum border_type border_type;
|
||||||
|
int border_width;
|
||||||
|
int bevel_width;
|
||||||
|
bool exclusive;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct theme {
|
struct theme {
|
||||||
|
|
@ -92,10 +97,17 @@ struct theme {
|
||||||
|
|
||||||
/* TODO: add toggled/hover/pressed/disabled colors for buttons */
|
/* TODO: add toggled/hover/pressed/disabled colors for buttons */
|
||||||
float button_colors[LAB_NODE_BUTTON_LAST + 1][4];
|
float button_colors[LAB_NODE_BUTTON_LAST + 1][4];
|
||||||
|
enum border_type button_border_type;
|
||||||
|
int button_border_width;
|
||||||
|
int button_bevel_width;
|
||||||
|
float button_border_color[4];
|
||||||
|
float button_hover_border_color[4];
|
||||||
|
|
||||||
float border_color[4];
|
float border_color[4];
|
||||||
float toggled_keybinds_color[4];
|
float toggled_keybinds_color[4];
|
||||||
float label_text_color[4];
|
float label_text_color[4];
|
||||||
|
enum border_type border_type;
|
||||||
|
int bevel_width;
|
||||||
|
|
||||||
/* window drop-shadows */
|
/* window drop-shadows */
|
||||||
int shadow_size;
|
int shadow_size;
|
||||||
|
|
@ -142,6 +154,8 @@ struct theme {
|
||||||
int menu_max_width;
|
int menu_max_width;
|
||||||
int menu_border_width;
|
int menu_border_width;
|
||||||
float menu_border_color[4];
|
float menu_border_color[4];
|
||||||
|
enum border_type menu_border_type;
|
||||||
|
int menu_bevel_width;
|
||||||
|
|
||||||
int menu_items_padding_x;
|
int menu_items_padding_x;
|
||||||
int menu_items_padding_y;
|
int menu_items_padding_y;
|
||||||
|
|
@ -149,6 +163,12 @@ struct theme {
|
||||||
float menu_items_text_color[4];
|
float menu_items_text_color[4];
|
||||||
float menu_items_active_bg_color[4];
|
float menu_items_active_bg_color[4];
|
||||||
float menu_items_active_text_color[4];
|
float menu_items_active_text_color[4];
|
||||||
|
enum border_type menu_items_border_type;
|
||||||
|
int menu_items_bevel_width;
|
||||||
|
enum border_type menu_title_border_type;
|
||||||
|
int menu_title_bevel_width;
|
||||||
|
enum border_type menu_items_active_border_type;
|
||||||
|
int menu_items_active_bevel_width;
|
||||||
|
|
||||||
int menu_separator_line_thickness;
|
int menu_separator_line_thickness;
|
||||||
int menu_separator_padding_width;
|
int menu_separator_padding_width;
|
||||||
|
|
@ -164,6 +184,8 @@ struct theme {
|
||||||
float osd_bg_color[4];
|
float osd_bg_color[4];
|
||||||
float osd_border_color[4];
|
float osd_border_color[4];
|
||||||
float osd_label_text_color[4];
|
float osd_label_text_color[4];
|
||||||
|
enum border_type osd_border_type;
|
||||||
|
int osd_border_bevel_width;
|
||||||
|
|
||||||
struct window_switcher_classic_theme {
|
struct window_switcher_classic_theme {
|
||||||
int width;
|
int width;
|
||||||
|
|
|
||||||
|
|
@ -244,6 +244,7 @@ struct view {
|
||||||
int width, height;
|
int width, height;
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
struct wlr_scene_rect *border;
|
struct wlr_scene_rect *border;
|
||||||
|
struct bufferset *textured_borders;
|
||||||
struct wlr_scene_rect *background;
|
struct wlr_scene_rect *background;
|
||||||
struct scaled_font_buffer *text;
|
struct scaled_font_buffer *text;
|
||||||
} resize_indicator;
|
} resize_indicator;
|
||||||
|
|
|
||||||
482
src/common/borderset.c
Normal file
482
src/common/borderset.c
Normal file
|
|
@ -0,0 +1,482 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
#include <assert.h>
|
||||||
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
#include "common/borderset.h"
|
||||||
|
#include "common/mem.h"
|
||||||
|
#include "common/macros.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
struct borderset *get_borders(uint32_t id, int size, enum border_type type, int bevelSize)
|
||||||
|
{
|
||||||
|
struct borderset *current = border_cache;
|
||||||
|
struct borderset *last;
|
||||||
|
|
||||||
|
// Preventing building nonsense borders:
|
||||||
|
// If you try for a double bevel but it's so deep they would overlap,
|
||||||
|
// convert to a single bevel
|
||||||
|
if (type == BORDER_DOUBLE && (bevelSize > size/2)) {
|
||||||
|
type = BORDER_SINGLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == BORDER_DOUBLE_INSET && (bevelSize > size/2)) {
|
||||||
|
type = BORDER_INSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anything with a size of 0 is converted to a 1-pixel flat border so as to
|
||||||
|
// prevent empty allocations
|
||||||
|
|
||||||
|
if (size < 1) {
|
||||||
|
type = BORDER_FLAT;
|
||||||
|
size = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (current) {
|
||||||
|
if (current->size == size && current->id == id &&
|
||||||
|
current->type == type && current->bevelSize == bevelSize) {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
last = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
// Fall through, we need to create a buffer.
|
||||||
|
|
||||||
|
if (!border_cache) {
|
||||||
|
border_cache = create_buffer(id, size, type, bevelSize);
|
||||||
|
return border_cache;
|
||||||
|
} else {
|
||||||
|
last->next = create_buffer(id, size, type, bevelSize);
|
||||||
|
return last->next;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct borderset *create_buffer(uint32_t id, int size, enum border_type type, int bevelSize)
|
||||||
|
{
|
||||||
|
struct borderset *new_borderset = znew(*new_borderset);
|
||||||
|
|
||||||
|
new_borderset->next = NULL;
|
||||||
|
new_borderset->id = id;
|
||||||
|
new_borderset->size = size;
|
||||||
|
new_borderset->type = type;
|
||||||
|
new_borderset->bevelSize = bevelSize;
|
||||||
|
|
||||||
|
// Use ID as a AARRGGBB colour
|
||||||
|
uint8_t a = id >> 24 & 255;
|
||||||
|
uint8_t r = id >> 16 & 255;
|
||||||
|
uint8_t g = id >> 8 & 255;
|
||||||
|
uint8_t b = id & 255;
|
||||||
|
|
||||||
|
uint32_t r1 = r * 5 / 4;
|
||||||
|
if (r1 > a) {
|
||||||
|
r1 = a;
|
||||||
|
}
|
||||||
|
uint32_t g1 = g * 5 / 4;
|
||||||
|
if (g1 > a) {
|
||||||
|
g1 = a;
|
||||||
|
}
|
||||||
|
uint32_t b1 = b * 5 / 4;
|
||||||
|
if (b1 > a) {
|
||||||
|
b1 = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* darker outline */
|
||||||
|
uint32_t r0 = r / 2;
|
||||||
|
uint32_t g0 = g / 2;
|
||||||
|
uint32_t b0 = b / 2;
|
||||||
|
|
||||||
|
uint32_t hl32 = ((uint32_t)a << 24) | ((uint32_t)r1 << 16)
|
||||||
|
| ((uint32_t)g1 << 8) | (uint32_t)b1;
|
||||||
|
uint32_t ll32 = ((uint32_t)a << 24) | ((uint32_t)r0 << 16)
|
||||||
|
| ((uint32_t)g0 << 8) | (uint32_t)b0;
|
||||||
|
uint32_t temp;
|
||||||
|
|
||||||
|
// All borders have NxN corners
|
||||||
|
uint32_t *tl = znew_n(uint32_t, size*size);
|
||||||
|
uint32_t *tr = znew_n(uint32_t, size*size);
|
||||||
|
uint32_t *bl = znew_n(uint32_t, size*size);
|
||||||
|
uint32_t *br = znew_n(uint32_t, size*size);
|
||||||
|
uint32_t *top = NULL;
|
||||||
|
uint32_t *left = NULL;
|
||||||
|
uint32_t *right = NULL;
|
||||||
|
uint32_t *bottom = NULL;
|
||||||
|
size_t side_size = 0;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case BORDER_INSET:
|
||||||
|
temp = ll32;
|
||||||
|
ll32 = hl32;
|
||||||
|
hl32 = temp;
|
||||||
|
|
||||||
|
top = znew(uint32_t);
|
||||||
|
left = znew(uint32_t);
|
||||||
|
right = znew(uint32_t);
|
||||||
|
bottom = znew(uint32_t);
|
||||||
|
side_size = 1;
|
||||||
|
*top = hl32;
|
||||||
|
*left = hl32;
|
||||||
|
*right = ll32;
|
||||||
|
*bottom = ll32;
|
||||||
|
|
||||||
|
// Fill with solid
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
for (int k = 0; k < size; k++) {
|
||||||
|
tl[PIXEL(j, k, size)] = hl32;
|
||||||
|
tr[PIXEL(size - 1 - j, k, size)] = (j > k) ? hl32 : ll32;
|
||||||
|
bl[PIXEL(size - 1 -j, k, size)] = (j > k) ? hl32 : ll32;
|
||||||
|
br[PIXEL(j, k, size)] = ll32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BORDER_SINGLE: // Single bevel borders have 1x1 sides
|
||||||
|
top = znew(uint32_t);
|
||||||
|
left = znew(uint32_t);
|
||||||
|
right = znew(uint32_t);
|
||||||
|
bottom = znew(uint32_t);
|
||||||
|
side_size = 1;
|
||||||
|
*top = hl32;
|
||||||
|
*left = hl32;
|
||||||
|
*right = ll32;
|
||||||
|
*bottom = ll32;
|
||||||
|
|
||||||
|
// Fill with solid
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
for (int k = 0; k < size; k++) {
|
||||||
|
tl[PIXEL(j, k, size)] = hl32;
|
||||||
|
tr[PIXEL(size - 1 - j, k, size)] = (j > k) ? hl32 : ll32;
|
||||||
|
bl[PIXEL(size - 1 -j, k, size)] = (j > k) ? hl32 : ll32;
|
||||||
|
br[PIXEL(j, k, size)] = ll32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BORDER_DOUBLE_INSET:
|
||||||
|
temp = ll32;
|
||||||
|
ll32 = hl32;
|
||||||
|
hl32 = temp;
|
||||||
|
top = znew_n(uint32_t, size);
|
||||||
|
left = znew_n(uint32_t, size);
|
||||||
|
right = znew_n(uint32_t, size);
|
||||||
|
bottom = znew_n(uint32_t, size);
|
||||||
|
side_size = size;
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (i < bevelSize) {
|
||||||
|
left[i] = hl32;
|
||||||
|
top[i] = hl32;
|
||||||
|
right[i] = hl32;
|
||||||
|
bottom[i] = hl32;
|
||||||
|
|
||||||
|
} else if (i > (size-bevelSize-1)) {
|
||||||
|
left[i] = ll32;
|
||||||
|
top[i] = ll32;
|
||||||
|
right[i] = ll32;
|
||||||
|
bottom[i] = ll32;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
left[i] = id;
|
||||||
|
top[i] = id;
|
||||||
|
right[i] = id;
|
||||||
|
bottom[i] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blank corners...
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
tl[PIXEL(i, j, size)] = id;
|
||||||
|
tr[PIXEL(i, j, size)] = id;
|
||||||
|
bl[PIXEL(i, j, size)] = id;
|
||||||
|
br[PIXEL(i, j, size)] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main Corners
|
||||||
|
for (int i = 0; i < bevelSize; i++) {
|
||||||
|
// Solid bar parts
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
// Top left corner: Entire "bevel size" top rows are highlighted
|
||||||
|
tl[PIXEL(j, i, size)] = hl32;
|
||||||
|
// First "bevel size" top columns are highlighted
|
||||||
|
tl[PIXEL(i, j, size)] = hl32;
|
||||||
|
|
||||||
|
// Bottom Right corner: Entire "bevel size" last rows are lowlight
|
||||||
|
br[PIXEL(j, (size-1-i), size)] = ll32;
|
||||||
|
// Last "bevel size" columns are lowlight
|
||||||
|
br[PIXEL((size-1-i), j, size)] = ll32;
|
||||||
|
|
||||||
|
// Bottom left corner: Entire "bevel size" last rows are lowlight
|
||||||
|
bl[PIXEL(j, (size-1-i), size)] = ll32;
|
||||||
|
// First "bevel size" columns are highlight, except for
|
||||||
|
// the bottom right corner
|
||||||
|
bl[PIXEL(i, j, size)] = hl32;
|
||||||
|
|
||||||
|
// Top Right corner: Entire "bevel size" first rows are highlight
|
||||||
|
tr[PIXEL(j, i, size)] = hl32;
|
||||||
|
// Last "bevel size" columns are lowlight, except for the top left
|
||||||
|
tr[PIXEL((size-1-i), j, size)] = ll32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Beveled Corner Parts
|
||||||
|
for (int i = 0; i < bevelSize; i++) {
|
||||||
|
for (int j = 0; j < bevelSize; j++) {
|
||||||
|
// Outer Corners
|
||||||
|
// Bottom left corner:
|
||||||
|
// First "bevel size" columns are highlight, except
|
||||||
|
// for the bottom right corner
|
||||||
|
bl[PIXEL(i, (size - 1 - j), size)] = (j >= i) ? hl32 : ll32;
|
||||||
|
|
||||||
|
// Top Right corner:
|
||||||
|
// Last "bevel size" columns are lowlight, except for the top left
|
||||||
|
tr[PIXEL((size-1-i), j, size)] = (j > i) ? ll32 : hl32;
|
||||||
|
|
||||||
|
// Inner Corners
|
||||||
|
// Top left corner: Bottom right is all dark
|
||||||
|
tl[PIXEL((size-1-i), (size - 1 - j), size)] = ll32;
|
||||||
|
|
||||||
|
// Bottom Right corner: Top left is all light
|
||||||
|
br[PIXEL(i, j, size)] = hl32;
|
||||||
|
|
||||||
|
// Top Right corner:
|
||||||
|
// Interior bottom left is dark on top, light on bottom
|
||||||
|
tr[PIXEL(i, (size-1-j), size)] = (i > j) ? hl32 : ll32;
|
||||||
|
|
||||||
|
// Bottom Left corner:
|
||||||
|
// Interior top right is dark on top, light on bottom
|
||||||
|
bl[PIXEL((size-1-i), j, size)] = (i > j) ? ll32 : hl32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BORDER_DOUBLE:
|
||||||
|
top = znew_n(uint32_t, size);
|
||||||
|
left = znew_n(uint32_t, size);
|
||||||
|
right = znew_n(uint32_t, size);
|
||||||
|
bottom = znew_n(uint32_t, size);
|
||||||
|
side_size = size;
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
if (i < bevelSize) {
|
||||||
|
left[i] = hl32;
|
||||||
|
top[i] = hl32;
|
||||||
|
right[i] = hl32;
|
||||||
|
bottom[i] = hl32;
|
||||||
|
|
||||||
|
} else if (i > (size-bevelSize-1)) {
|
||||||
|
left[i] = ll32;
|
||||||
|
top[i] = ll32;
|
||||||
|
right[i] = ll32;
|
||||||
|
bottom[i] = ll32;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
left[i] = id;
|
||||||
|
top[i] = id;
|
||||||
|
right[i] = id;
|
||||||
|
bottom[i] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Blank corners...
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
tl[PIXEL(i, j, size)] = id;
|
||||||
|
tr[PIXEL(i, j, size)] = id;
|
||||||
|
bl[PIXEL(i, j, size)] = id;
|
||||||
|
br[PIXEL(i, j, size)] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main Corners
|
||||||
|
for (int i = 0; i < bevelSize; i++) {
|
||||||
|
// Solid bar parts
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
// Top left corner: Entire "bevel size" top rows are highlighted
|
||||||
|
tl[PIXEL(j, i, size)] = hl32;
|
||||||
|
// First "bevel size" top columns are highlighted
|
||||||
|
tl[PIXEL(i, j, size)] = hl32;
|
||||||
|
|
||||||
|
// Bottom Right corner: Entire "bevel size" last rows are lowlight
|
||||||
|
br[PIXEL(j, (size-1-i), size)] = ll32;
|
||||||
|
// Last "bevel size" columns are lowlight
|
||||||
|
br[PIXEL((size-1-i), j, size)] = ll32;
|
||||||
|
|
||||||
|
// Bottom left corner: Entire "bevel size" last rows are lowlight
|
||||||
|
bl[PIXEL(j, (size-1-i), size)] = ll32;
|
||||||
|
// First "bevel size" columns are highlight, except for
|
||||||
|
// the bottom right corner
|
||||||
|
bl[PIXEL(i, j, size)] = hl32;
|
||||||
|
|
||||||
|
// Top Right corner: Entire "bevel size" first rows are highlight
|
||||||
|
tr[PIXEL(j, i, size)] = hl32;
|
||||||
|
// Last "bevel size" columns are lowlight, except for the top left
|
||||||
|
tr[PIXEL((size-1-i), j, size)] = ll32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Beveled Corner Parts
|
||||||
|
for (int i = 0; i < bevelSize; i++) {
|
||||||
|
for (int j = 0; j < bevelSize; j++) {
|
||||||
|
// Outer Corners
|
||||||
|
// Bottom left corner:
|
||||||
|
// First "bevel size" columns are highlight, except
|
||||||
|
// for the bottom right corner
|
||||||
|
bl[PIXEL(i, (size - 1 - j), size)] = (j >= i) ? hl32 : ll32;
|
||||||
|
|
||||||
|
// Top Right corner:
|
||||||
|
// Last "bevel size" columns are lowlight, except for the top left
|
||||||
|
tr[PIXEL((size-1-i), j, size)] = (j > i) ? ll32 : hl32;
|
||||||
|
|
||||||
|
// Inner Corners
|
||||||
|
// Top left corner: Bottom right is all dark
|
||||||
|
tl[PIXEL((size-1-i), (size - 1 - j), size)] = ll32;
|
||||||
|
|
||||||
|
// Bottom Right corner: Top left is all light
|
||||||
|
br[PIXEL(i, j, size)] = hl32;
|
||||||
|
|
||||||
|
// Top Right corner:
|
||||||
|
// Interior bottom left is dark on top, light on bottom
|
||||||
|
tr[PIXEL(i, (size-1-j), size)] = (i > j) ? hl32 : ll32;
|
||||||
|
|
||||||
|
// Bottom Left corner:
|
||||||
|
// Interior top right is dark on top, light on bottom
|
||||||
|
bl[PIXEL((size-1-i), j, size)] = (i > j) ? ll32 : hl32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BORDER_FLAT: // Placeholder that uses buffers but for a flat colour
|
||||||
|
case BORDER_NONE: // Provided as a fallback but should not be actually requested/rendered
|
||||||
|
top = znew(uint32_t);
|
||||||
|
left = znew(uint32_t);
|
||||||
|
right = znew(uint32_t);
|
||||||
|
bottom = znew(uint32_t);
|
||||||
|
side_size = 1;
|
||||||
|
*top = id;
|
||||||
|
*left = id;
|
||||||
|
*right = id;
|
||||||
|
*bottom = id;
|
||||||
|
|
||||||
|
// Fill with solid
|
||||||
|
for (int j = 0; j < size; j++) {
|
||||||
|
for (int k = 0; k < size; k++) {
|
||||||
|
tl[PIXEL(j, k, size)] = id;
|
||||||
|
tr[PIXEL(size - 1 - j, k, size)] = id;
|
||||||
|
bl[PIXEL(size - 1 -j, k, size)] = id;
|
||||||
|
br[PIXEL(j, k, size)] = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(side_size > 0);
|
||||||
|
|
||||||
|
new_borderset->top = buffer_create_from_data(top, 1, side_size, 4);
|
||||||
|
new_borderset->left = buffer_create_from_data(left, side_size, 1, side_size * 4);
|
||||||
|
new_borderset->right = buffer_create_from_data(right, side_size, 1, side_size * 4);
|
||||||
|
new_borderset->bottom = buffer_create_from_data(bottom, 1, side_size, 4);
|
||||||
|
|
||||||
|
new_borderset->tl = buffer_create_from_data(tl, size, size, size * 4);
|
||||||
|
new_borderset->tr = buffer_create_from_data(tr, size, size, size * 4);
|
||||||
|
new_borderset->bl = buffer_create_from_data(bl, size, size, size * 4);
|
||||||
|
new_borderset->br = buffer_create_from_data(br, size, size, size * 4);
|
||||||
|
|
||||||
|
return new_borderset;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct bufferset *generate_bufferset(struct wlr_scene_tree *tree,
|
||||||
|
struct borderset *borderset, int bw)
|
||||||
|
{
|
||||||
|
struct bufferset *bufferset = znew(struct bufferset);
|
||||||
|
|
||||||
|
bufferset->top = wlr_scene_buffer_create(tree, &borderset->top->base);
|
||||||
|
bufferset->left = wlr_scene_buffer_create(tree, &borderset->left->base);
|
||||||
|
bufferset->right = wlr_scene_buffer_create(tree, &borderset->right->base);
|
||||||
|
bufferset->bottom = wlr_scene_buffer_create(tree, &borderset->bottom->base);
|
||||||
|
bufferset->tl = wlr_scene_buffer_create(tree, &borderset->tl->base);
|
||||||
|
bufferset->tr = wlr_scene_buffer_create(tree, &borderset->tr->base);
|
||||||
|
bufferset->bl = wlr_scene_buffer_create(tree, &borderset->bl->base);
|
||||||
|
bufferset->br = wlr_scene_buffer_create(tree, &borderset->br->base);
|
||||||
|
|
||||||
|
bufferset->border_width = bw;
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->top, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->left, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->right, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->bottom, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->tl, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->tr, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->bl, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
wlr_scene_buffer_set_filter_mode(bufferset->br, WLR_SCALE_FILTER_NEAREST);
|
||||||
|
|
||||||
|
return bufferset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderBufferset(struct bufferset *bufferset, int width, int height, int y)
|
||||||
|
{
|
||||||
|
renderBuffersetXY(bufferset, width, height, 0, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderBuffersetXY(struct bufferset *bufferset, int width, int height, int x, int y)
|
||||||
|
{
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->top,
|
||||||
|
width - 2 * bufferset->border_width, bufferset->border_width);
|
||||||
|
wlr_scene_node_set_position(&bufferset->top->node,
|
||||||
|
x+bufferset->border_width, y);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->bottom,
|
||||||
|
width - 2 * bufferset->border_width, bufferset->border_width);
|
||||||
|
wlr_scene_node_set_position(&bufferset->bottom->node,
|
||||||
|
x+bufferset->border_width, y+height - bufferset->border_width);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->left,
|
||||||
|
bufferset->border_width, height - bufferset->border_width * 2);
|
||||||
|
wlr_scene_node_set_position(&bufferset->left->node,
|
||||||
|
x, bufferset->border_width+y);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->right,
|
||||||
|
bufferset->border_width, height - bufferset->border_width * 2);
|
||||||
|
wlr_scene_node_set_position(&bufferset->right->node,
|
||||||
|
x+width - bufferset->border_width, y+bufferset->border_width);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->tl,
|
||||||
|
bufferset->border_width, bufferset->border_width);
|
||||||
|
wlr_scene_node_set_position(&bufferset->tl->node,
|
||||||
|
x, y);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->tr,
|
||||||
|
bufferset->border_width, bufferset->border_width);
|
||||||
|
wlr_scene_node_set_position(&bufferset->tr->node,
|
||||||
|
x+width-bufferset->border_width, y);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->br,
|
||||||
|
bufferset->border_width, bufferset->border_width);
|
||||||
|
wlr_scene_node_set_position(&bufferset->br->node,
|
||||||
|
x+width-bufferset->border_width, y+height-bufferset->border_width);
|
||||||
|
|
||||||
|
wlr_scene_buffer_set_dest_size(bufferset->bl,
|
||||||
|
bufferset->border_width, bufferset->border_width);
|
||||||
|
wlr_scene_node_set_position(&bufferset->bl->node,
|
||||||
|
x, height-bufferset->border_width+y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearborder_cache(struct borderset *borderset)
|
||||||
|
{
|
||||||
|
if (!borderset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (borderset->next) {
|
||||||
|
clearborder_cache(borderset->next);
|
||||||
|
}
|
||||||
|
wlr_buffer_drop(&borderset->top->base);
|
||||||
|
wlr_buffer_drop(&borderset->left->base);
|
||||||
|
wlr_buffer_drop(&borderset->right->base);
|
||||||
|
wlr_buffer_drop(&borderset->bottom->base);
|
||||||
|
wlr_buffer_drop(&borderset->tl->base);
|
||||||
|
wlr_buffer_drop(&borderset->tr->base);
|
||||||
|
wlr_buffer_drop(&borderset->bl->base);
|
||||||
|
wlr_buffer_drop(&borderset->br->base);
|
||||||
|
free(borderset);
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,15 @@
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
|
#include "common/macros.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
#include "theme.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
struct border_scene {
|
struct border_scene {
|
||||||
struct wlr_scene_tree *tree;
|
struct wlr_scene_tree *tree;
|
||||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||||
|
struct bufferset *textured_borders;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -37,10 +42,29 @@ lab_scene_rect_create(struct wlr_scene_tree *parent,
|
||||||
struct border_scene *border = &rect->borders[i];
|
struct border_scene *border = &rect->borders[i];
|
||||||
float *color = opts->border_colors[i];
|
float *color = opts->border_colors[i];
|
||||||
border->tree = lab_wlr_scene_tree_create(rect->tree);
|
border->tree = lab_wlr_scene_tree_create(rect->tree);
|
||||||
|
|
||||||
border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
border->top = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
border->right = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
border->bottom = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
border->bottom = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
border->left = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
border->left = lab_wlr_scene_rect_create(border->tree, 0, 0, color);
|
||||||
|
|
||||||
|
if (opts->border_type) {
|
||||||
|
float r = color[0];
|
||||||
|
float g = color[1];
|
||||||
|
float b = color[2];
|
||||||
|
float a = color[3];
|
||||||
|
int bw = rect->border_width;
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
opts->border_type, opts->bevel_width);
|
||||||
|
border->textured_borders = generate_bufferset(border->tree,
|
||||||
|
renderedborders, bw);
|
||||||
|
} else {
|
||||||
|
border->textured_borders = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rect->node_destroy.notify = handle_node_destroy;
|
rect->node_destroy.notify = handle_node_destroy;
|
||||||
|
|
@ -81,6 +105,9 @@ resize_border(struct border_scene *border, int border_width, int width, int heig
|
||||||
wlr_scene_rect_set_size(border->bottom, width, border_width);
|
wlr_scene_rect_set_size(border->bottom, width, border_width);
|
||||||
wlr_scene_rect_set_size(border->left, border_width, height - border_width * 2);
|
wlr_scene_rect_set_size(border->left, border_width, height - border_width * 2);
|
||||||
wlr_scene_rect_set_size(border->right, border_width, height - border_width * 2);
|
wlr_scene_rect_set_size(border->right, border_width, height - border_width * 2);
|
||||||
|
if (border->textured_borders) {
|
||||||
|
renderBufferset(border->textured_borders, width, height, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
labwc_sources += files(
|
labwc_sources += files(
|
||||||
|
'borderset.c',
|
||||||
'box.c',
|
'box.c',
|
||||||
'buf.c',
|
'buf.c',
|
||||||
'dir.c',
|
'dir.c',
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ update_preview_outlines(struct view *view)
|
||||||
},
|
},
|
||||||
.nr_borders = 3,
|
.nr_borders = 3,
|
||||||
.border_width = theme->osd_window_switcher_preview_border_width,
|
.border_width = theme->osd_window_switcher_preview_border_width,
|
||||||
|
.border_type = theme->osd_border_type,
|
||||||
|
.bevel_width = theme->osd_border_bevel_width
|
||||||
};
|
};
|
||||||
rect = lab_scene_rect_create(&server.scene->tree, &opts);
|
rect = lab_scene_rect_create(&server.scene->tree, &opts);
|
||||||
wlr_scene_node_place_above(&rect->tree->node,
|
wlr_scene_node_place_above(&rect->tree->node,
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,8 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output)
|
||||||
.bg_color = bg_color,
|
.bg_color = bg_color,
|
||||||
.width = w,
|
.width = w,
|
||||||
.height = h,
|
.height = h,
|
||||||
|
.border_type = theme->osd_border_type,
|
||||||
|
.bevel_width = theme->osd_border_bevel_width
|
||||||
};
|
};
|
||||||
lab_scene_rect_create(osd_output->tree, &bg_opts);
|
lab_scene_rect_create(osd_output->tree, &bg_opts);
|
||||||
|
|
||||||
|
|
@ -202,6 +204,8 @@ cycle_osd_classic_init(struct cycle_osd_output *osd_output)
|
||||||
.bg_color = active_bg_color,
|
.bg_color = active_bg_color,
|
||||||
.width = w - 2 * padding,
|
.width = w - 2 * padding,
|
||||||
.height = switcher_theme->item_height,
|
.height = switcher_theme->item_height,
|
||||||
|
.border_type = theme->osd_border_type,
|
||||||
|
.bevel_width = theme->osd_border_bevel_width
|
||||||
};
|
};
|
||||||
struct lab_scene_rect *highlight_rect = lab_scene_rect_create(
|
struct lab_scene_rect *highlight_rect = lab_scene_rect_create(
|
||||||
item->active_tree, &highlight_opts);
|
item->active_tree, &highlight_opts);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,9 @@
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
#include "common/lab-scene-rect.h"
|
#include "common/lab-scene-rect.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
|
#include "config/rcxml.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
|
#include "theme.h"
|
||||||
#include "cycle.h"
|
#include "cycle.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
|
|
||||||
|
|
@ -12,6 +14,8 @@ cycle_osd_scroll_init(struct cycle_osd_output *osd_output, struct wlr_box bar_ar
|
||||||
int delta_y, int nr_cols, int nr_rows, int nr_visible_rows,
|
int delta_y, int nr_cols, int nr_rows, int nr_visible_rows,
|
||||||
float *border_color, float *bg_color)
|
float *border_color, float *bg_color)
|
||||||
{
|
{
|
||||||
|
struct theme *theme = rc.theme;
|
||||||
|
|
||||||
if (nr_visible_rows >= nr_rows) {
|
if (nr_visible_rows >= nr_rows) {
|
||||||
/* OSD doesn't have so many windows to scroll through */
|
/* OSD doesn't have so many windows to scroll through */
|
||||||
return;
|
return;
|
||||||
|
|
@ -35,6 +39,8 @@ cycle_osd_scroll_init(struct cycle_osd_output *osd_output, struct wlr_box bar_ar
|
||||||
.bg_color = bg_color,
|
.bg_color = bg_color,
|
||||||
.width = bar_area.width,
|
.width = bar_area.width,
|
||||||
.height = bar_area.height * nr_visible_rows / nr_rows,
|
.height = bar_area.height * nr_visible_rows / nr_rows,
|
||||||
|
.border_type = theme->osd_border_type,
|
||||||
|
.bevel_width = theme->osd_border_bevel_width
|
||||||
};
|
};
|
||||||
scroll->bar = lab_scene_rect_create(scroll->bar_tree, &scrollbar_opts);
|
scroll->bar = lab_scene_rect_create(scroll->bar_tree, &scrollbar_opts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,6 +154,8 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
|
||||||
.bg_color = switcher_theme->item_active_bg_color,
|
.bg_color = switcher_theme->item_active_bg_color,
|
||||||
.width = switcher_theme->item_width,
|
.width = switcher_theme->item_width,
|
||||||
.height = switcher_theme->item_height,
|
.height = switcher_theme->item_height,
|
||||||
|
.border_type = theme->osd_border_type,
|
||||||
|
.bevel_width = theme->osd_border_bevel_width
|
||||||
};
|
};
|
||||||
item->active_bg = lab_scene_rect_create(tree, &opts);
|
item->active_bg = lab_scene_rect_create(tree, &opts);
|
||||||
|
|
||||||
|
|
@ -286,6 +288,8 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output)
|
||||||
.bg_color = theme->osd_bg_color,
|
.bg_color = theme->osd_bg_color,
|
||||||
.width = items_width + 2 * padding,
|
.width = items_width + 2 * padding,
|
||||||
.height = items_height + 2 * padding,
|
.height = items_height + 2 * padding,
|
||||||
|
.border_type = theme->osd_border_type,
|
||||||
|
.bevel_width = theme->osd_border_bevel_width
|
||||||
};
|
};
|
||||||
struct lab_scene_rect *bg =
|
struct lab_scene_rect *bg =
|
||||||
lab_scene_rect_create(osd_output->tree, &bg_opts);
|
lab_scene_rect_create(osd_output->tree, &bg_opts);
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "translate.h"
|
#include "translate.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
|
|
@ -40,6 +41,8 @@ static const struct option long_options[] = {
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct borderset *border_cache;
|
||||||
|
|
||||||
static const char labwc_usage[] =
|
static const char labwc_usage[] =
|
||||||
"Usage: labwc [options...]\n"
|
"Usage: labwc [options...]\n"
|
||||||
" -c, --config <file> Specify config file (with path)\n"
|
" -c, --config <file> Specify config file (with path)\n"
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@
|
||||||
#include "translate.h"
|
#include "translate.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
#define PIPEMENU_MAX_BUF_SIZE 1048576 /* 1 MiB */
|
#define PIPEMENU_MAX_BUF_SIZE 1048576 /* 1 MiB */
|
||||||
#define PIPEMENU_TIMEOUT_IN_MS 4000 /* 4 seconds */
|
#define PIPEMENU_TIMEOUT_IN_MS 4000 /* 4 seconds */
|
||||||
|
|
@ -163,10 +165,11 @@ item_create(struct menu *menu, const char *text, const char *icon_name, bool sho
|
||||||
|
|
||||||
static struct wlr_scene_tree *
|
static struct wlr_scene_tree *
|
||||||
item_create_scene_for_state(struct menuitem *item, float *text_color,
|
item_create_scene_for_state(struct menuitem *item, float *text_color,
|
||||||
float *bg_color)
|
float *bg_color, int state)
|
||||||
{
|
{
|
||||||
struct menu *menu = item->parent;
|
struct menu *menu = item->parent;
|
||||||
struct theme *theme = rc.theme;
|
struct theme *theme = rc.theme;
|
||||||
|
struct bufferset *bufferset = NULL;
|
||||||
|
|
||||||
/* Tree to hold background and label buffers */
|
/* Tree to hold background and label buffers */
|
||||||
struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(item->tree);
|
struct wlr_scene_tree *tree = lab_wlr_scene_tree_create(item->tree);
|
||||||
|
|
@ -191,6 +194,37 @@ item_create_scene_for_state(struct menuitem *item, float *text_color,
|
||||||
/* Create background */
|
/* Create background */
|
||||||
lab_wlr_scene_rect_create(tree, bg_width, theme->menu_item_height, bg_color);
|
lab_wlr_scene_rect_create(tree, bg_width, theme->menu_item_height, bg_color);
|
||||||
|
|
||||||
|
int bw = theme->menu_border_width;
|
||||||
|
if (rc.theme->menu_items_active_border_type && state) {
|
||||||
|
float r = bg_color[0];
|
||||||
|
float g = bg_color[1];
|
||||||
|
float b = bg_color[2];
|
||||||
|
float a = bg_color[3];
|
||||||
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
rc.theme->menu_items_active_border_type,
|
||||||
|
rc.theme->menu_items_active_bevel_width);
|
||||||
|
bufferset = generate_bufferset(tree, renderedborders, bw);
|
||||||
|
} else if (rc.theme->menu_items_border_type && !state) {
|
||||||
|
float r = bg_color[0];
|
||||||
|
float g = bg_color[1];
|
||||||
|
float b = bg_color[2];
|
||||||
|
float a = bg_color[3];
|
||||||
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
rc.theme->menu_items_border_type,
|
||||||
|
rc.theme->menu_items_bevel_width);
|
||||||
|
bufferset = generate_bufferset(tree, renderedborders, bw);
|
||||||
|
}
|
||||||
|
|
||||||
/* Create icon */
|
/* Create icon */
|
||||||
bool show_app_icon = !strcmp(item->parent->id, "client-list-combined-menu")
|
bool show_app_icon = !strcmp(item->parent->id, "client-list-combined-menu")
|
||||||
&& item->client_list_view;
|
&& item->client_list_view;
|
||||||
|
|
@ -219,6 +253,10 @@ item_create_scene_for_state(struct menuitem *item, float *text_color,
|
||||||
int y = (theme->menu_item_height - label_buffer->height) / 2;
|
int y = (theme->menu_item_height - label_buffer->height) / 2;
|
||||||
wlr_scene_node_set_position(&label_buffer->scene_buffer->node, x, y);
|
wlr_scene_node_set_position(&label_buffer->scene_buffer->node, x, y);
|
||||||
|
|
||||||
|
if (bufferset) {
|
||||||
|
renderBufferset(bufferset, bg_width, theme->menu_item_height, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (!item->arrow) {
|
if (!item->arrow) {
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
@ -252,10 +290,10 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
/* Create scenes for unselected/selected states */
|
/* Create scenes for unselected/selected states */
|
||||||
menuitem->normal_tree = item_create_scene_for_state(menuitem,
|
menuitem->normal_tree = item_create_scene_for_state(menuitem,
|
||||||
theme->menu_items_text_color,
|
theme->menu_items_text_color,
|
||||||
theme->menu_items_bg_color);
|
theme->menu_items_bg_color, 0);
|
||||||
menuitem->selected_tree = item_create_scene_for_state(menuitem,
|
menuitem->selected_tree = item_create_scene_for_state(menuitem,
|
||||||
theme->menu_items_active_text_color,
|
theme->menu_items_active_text_color,
|
||||||
theme->menu_items_active_bg_color);
|
theme->menu_items_active_bg_color, 1);
|
||||||
/* Hide selected state */
|
/* Hide selected state */
|
||||||
wlr_scene_node_set_enabled(&menuitem->selected_tree->node, false);
|
wlr_scene_node_set_enabled(&menuitem->selected_tree->node, false);
|
||||||
|
|
||||||
|
|
@ -338,6 +376,8 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
assert(menuitem->type == LAB_MENU_TITLE);
|
assert(menuitem->type == LAB_MENU_TITLE);
|
||||||
struct menu *menu = menuitem->parent;
|
struct menu *menu = menuitem->parent;
|
||||||
struct theme *theme = rc.theme;
|
struct theme *theme = rc.theme;
|
||||||
|
struct bufferset *bufferset = NULL;
|
||||||
|
|
||||||
float *bg_color = theme->menu_title_bg_color;
|
float *bg_color = theme->menu_title_bg_color;
|
||||||
float *text_color = theme->menu_title_text_color;
|
float *text_color = theme->menu_title_text_color;
|
||||||
|
|
||||||
|
|
@ -357,6 +397,23 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int bw = theme->menu_border_width;
|
||||||
|
if (rc.theme->menu_title_border_type) {
|
||||||
|
float r = bg_color[0];
|
||||||
|
float g = bg_color[1];
|
||||||
|
float b = bg_color[2];
|
||||||
|
float a = bg_color[3];
|
||||||
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
rc.theme->menu_title_border_type,
|
||||||
|
rc.theme->menu_title_bevel_width);
|
||||||
|
bufferset = generate_bufferset(menuitem->tree, renderedborders, bw);
|
||||||
|
}
|
||||||
|
|
||||||
/* Background */
|
/* Background */
|
||||||
lab_wlr_scene_rect_create(menuitem->normal_tree,
|
lab_wlr_scene_rect_create(menuitem->normal_tree,
|
||||||
bg_width, theme->menu_header_height, bg_color);
|
bg_width, theme->menu_header_height, bg_color);
|
||||||
|
|
@ -385,6 +442,10 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
||||||
int title_y = (theme->menu_header_height - title_font_buffer->height) / 2;
|
int title_y = (theme->menu_header_height - title_font_buffer->height) / 2;
|
||||||
wlr_scene_node_set_position(&title_font_buffer->scene_buffer->node,
|
wlr_scene_node_set_position(&title_font_buffer->scene_buffer->node,
|
||||||
title_x, title_y);
|
title_x, title_y);
|
||||||
|
|
||||||
|
if (bufferset && rc.theme->menu_title_border_type) {
|
||||||
|
renderBufferset(bufferset, bg_width, theme->menu_item_height, 0);
|
||||||
|
}
|
||||||
error:
|
error:
|
||||||
wlr_scene_node_set_position(&menuitem->tree->node,
|
wlr_scene_node_set_position(&menuitem->tree->node,
|
||||||
theme->menu_border_width, *item_y);
|
theme->menu_border_width, *item_y);
|
||||||
|
|
@ -457,6 +518,8 @@ menu_create_scene(struct menu *menu)
|
||||||
.border_width = theme->menu_border_width,
|
.border_width = theme->menu_border_width,
|
||||||
.width = menu->size.width,
|
.width = menu->size.width,
|
||||||
.height = menu->size.height,
|
.height = menu->size.height,
|
||||||
|
.border_type = theme->menu_border_type,
|
||||||
|
.bevel_width = theme->menu_bevel_width
|
||||||
};
|
};
|
||||||
struct lab_scene_rect *bg_rect =
|
struct lab_scene_rect *bg_rect =
|
||||||
lab_scene_rect_create(menu->scene_tree, &opts);
|
lab_scene_rect_create(menu->scene_tree, &opts);
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,7 @@
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
#include "workspaces.h"
|
#include "workspaces.h"
|
||||||
#include "xwayland.h"
|
#include "xwayland.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
#define LAB_EXT_DATA_CONTROL_VERSION 1
|
#define LAB_EXT_DATA_CONTROL_VERSION 1
|
||||||
#define LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
#define LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
||||||
|
|
@ -89,6 +90,9 @@ reload_config_and_theme(void)
|
||||||
|
|
||||||
scaled_buffer_invalidate_sharing();
|
scaled_buffer_invalidate_sharing();
|
||||||
rcxml_finish();
|
rcxml_finish();
|
||||||
|
clearborder_cache(border_cache);
|
||||||
|
border_cache = NULL;
|
||||||
|
|
||||||
rcxml_read(rc.config_file);
|
rcxml_read(rc.config_file);
|
||||||
theme_finish(rc.theme);
|
theme_finish(rc.theme);
|
||||||
theme_init(rc.theme, rc.theme_name);
|
theme_init(rc.theme, rc.theme_name);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
#include "ssd.h"
|
#include "ssd.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
#define PADDING rc.theme->osd_window_switcher_classic.padding
|
#define PADDING rc.theme->osd_window_switcher_classic.padding
|
||||||
|
|
||||||
|
|
@ -36,6 +38,23 @@ resize_indicator_reconfigure_view(struct resize_indicator *indicator)
|
||||||
/* Colors */
|
/* Colors */
|
||||||
wlr_scene_rect_set_color(indicator->border, theme->osd_border_color);
|
wlr_scene_rect_set_color(indicator->border, theme->osd_border_color);
|
||||||
wlr_scene_rect_set_color(indicator->background, theme->osd_bg_color);
|
wlr_scene_rect_set_color(indicator->background, theme->osd_bg_color);
|
||||||
|
|
||||||
|
if (rc.theme->osd_border_type) {
|
||||||
|
float r = theme->osd_border_color[0];
|
||||||
|
float g = theme->osd_border_color[1];
|
||||||
|
float b = theme->osd_border_color[2];
|
||||||
|
float a = theme->osd_border_color[3];
|
||||||
|
int bw = theme->osd_border_width;
|
||||||
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
theme->osd_border_type, theme->osd_border_bevel_width);
|
||||||
|
indicator->textured_borders = generate_bufferset(indicator->tree,
|
||||||
|
renderedborders, bw);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -50,6 +69,7 @@ resize_indicator_init(struct view *view)
|
||||||
indicator->tree, 0, 0, rc.theme->osd_border_color);
|
indicator->tree, 0, 0, rc.theme->osd_border_color);
|
||||||
indicator->background = lab_wlr_scene_rect_create(
|
indicator->background = lab_wlr_scene_rect_create(
|
||||||
indicator->tree, 0, 0, rc.theme->osd_bg_color);
|
indicator->tree, 0, 0, rc.theme->osd_bg_color);
|
||||||
|
|
||||||
indicator->text = scaled_font_buffer_create(indicator->tree);
|
indicator->text = scaled_font_buffer_create(indicator->tree);
|
||||||
|
|
||||||
wlr_scene_node_set_enabled(&indicator->tree->node, false);
|
wlr_scene_node_set_enabled(&indicator->tree->node, false);
|
||||||
|
|
@ -80,7 +100,9 @@ resize_indicator_reconfigure(void)
|
||||||
wl_list_for_each(view, &server.views, link) {
|
wl_list_for_each(view, &server.views, link) {
|
||||||
struct resize_indicator *indicator = &view->resize_indicator;
|
struct resize_indicator *indicator = &view->resize_indicator;
|
||||||
if (indicator->tree) {
|
if (indicator->tree) {
|
||||||
resize_indicator_reconfigure_view(indicator);
|
// Destroy the old tree so it doesn't have the leftover styling/sizing.
|
||||||
|
wlr_scene_node_destroy(&indicator->tree->node);
|
||||||
|
indicator->tree = NULL;
|
||||||
}
|
}
|
||||||
if (view != server.grabbed_view) {
|
if (view != server.grabbed_view) {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -117,6 +139,11 @@ resize_indicator_set_size(struct resize_indicator *indicator, int width)
|
||||||
wlr_scene_rect_set_size(indicator->background,
|
wlr_scene_rect_set_size(indicator->background,
|
||||||
indicator->width - 2 * rc.theme->osd_border_width,
|
indicator->width - 2 * rc.theme->osd_border_width,
|
||||||
indicator->height - 2 * rc.theme->osd_border_width);
|
indicator->height - 2 * rc.theme->osd_border_width);
|
||||||
|
|
||||||
|
if (rc.theme->osd_border_type) {
|
||||||
|
renderBufferset(indicator->textured_borders, indicator->width,
|
||||||
|
indicator->height, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,16 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
|
#include "buffer.h"
|
||||||
#include "common/macros.h"
|
#include "common/macros.h"
|
||||||
|
#include "common/mem.h"
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
#include "config/rcxml.h"
|
#include "config/rcxml.h"
|
||||||
#include "ssd.h"
|
#include "ssd.h"
|
||||||
#include "ssd-internal.h"
|
#include "ssd-internal.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
ssd_border_create(struct ssd *ssd)
|
ssd_border_create(struct ssd *ssd)
|
||||||
|
|
@ -18,6 +21,7 @@ ssd_border_create(struct ssd *ssd)
|
||||||
|
|
||||||
struct view *view = ssd->view;
|
struct view *view = ssd->view;
|
||||||
struct theme *theme = rc.theme;
|
struct theme *theme = rc.theme;
|
||||||
|
int bw = theme->border_width;
|
||||||
int width = view->current.width;
|
int width = view->current.width;
|
||||||
int height = view_effective_height(view, /* use_pending */ false);
|
int height = view_effective_height(view, /* use_pending */ false);
|
||||||
int full_width = width + 2 * theme->border_width;
|
int full_width = width + 2 * theme->border_width;
|
||||||
|
|
@ -33,26 +37,48 @@ ssd_border_create(struct ssd *ssd)
|
||||||
struct wlr_scene_tree *parent = subtree->tree;
|
struct wlr_scene_tree *parent = subtree->tree;
|
||||||
wlr_scene_node_set_enabled(&parent->node, active);
|
wlr_scene_node_set_enabled(&parent->node, active);
|
||||||
float *color = theme->window[active].border_color;
|
float *color = theme->window[active].border_color;
|
||||||
|
if (theme->window[active].border_type) {
|
||||||
|
// These will otherwise get left under the window when we reload
|
||||||
|
|
||||||
subtree->left = lab_wlr_scene_rect_create(parent,
|
subtree->left = lab_wlr_scene_rect_create(parent, 1, 1, color);
|
||||||
theme->border_width, height, color);
|
subtree->right = lab_wlr_scene_rect_create(parent, 1, 1, color);
|
||||||
wlr_scene_node_set_position(&subtree->left->node, 0, 0);
|
subtree->bottom = lab_wlr_scene_rect_create(parent, 1, 1, color);
|
||||||
|
subtree->top = lab_wlr_scene_rect_create(parent, 1, 1, color);
|
||||||
|
|
||||||
subtree->right = lab_wlr_scene_rect_create(parent,
|
/* From Pull request 3382 */
|
||||||
theme->border_width, height, color);
|
float r = color[0];
|
||||||
wlr_scene_node_set_position(&subtree->right->node,
|
float g = color[1];
|
||||||
theme->border_width + width, 0);
|
float b = color[2];
|
||||||
|
float a = color[3];
|
||||||
|
|
||||||
subtree->bottom = lab_wlr_scene_rect_create(parent,
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
full_width, theme->border_width, color);
|
(uint32_t)(r*255) << 16 |
|
||||||
wlr_scene_node_set_position(&subtree->bottom->node,
|
(uint32_t)(g*255) << 8 |
|
||||||
0, height);
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
theme->window[active].border_type,
|
||||||
|
theme->window[active].bevel_width);
|
||||||
|
subtree->textured_borders = generate_bufferset(subtree->tree,
|
||||||
|
renderedborders, bw);
|
||||||
|
} else {
|
||||||
|
subtree->left = lab_wlr_scene_rect_create(parent,
|
||||||
|
theme->border_width, height, color);
|
||||||
|
subtree->right = lab_wlr_scene_rect_create(parent,
|
||||||
|
theme->border_width, height, color);
|
||||||
|
subtree->bottom = lab_wlr_scene_rect_create(parent,
|
||||||
|
full_width, theme->border_width, color);
|
||||||
|
subtree->top = lab_wlr_scene_rect_create(parent,
|
||||||
|
MAX(width - 2 * corner_width, 0), theme->border_width, color);
|
||||||
|
|
||||||
subtree->top = lab_wlr_scene_rect_create(parent,
|
wlr_scene_node_set_position(&subtree->left->node, 0, 0);
|
||||||
MAX(width - 2 * corner_width, 0), theme->border_width, color);
|
wlr_scene_node_set_position(&subtree->right->node,
|
||||||
wlr_scene_node_set_position(&subtree->top->node,
|
theme->border_width + width, 0);
|
||||||
theme->border_width + corner_width,
|
wlr_scene_node_set_position(&subtree->bottom->node,
|
||||||
-(ssd->titlebar.height + theme->border_width));
|
0, height);
|
||||||
|
wlr_scene_node_set_position(&subtree->top->node,
|
||||||
|
theme->border_width + corner_width,
|
||||||
|
-(ssd->titlebar.height + theme->border_width));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view->maximized == VIEW_AXIS_BOTH) {
|
if (view->maximized == VIEW_AXIS_BOTH) {
|
||||||
|
|
@ -132,26 +158,28 @@ ssd_border_update(struct ssd *ssd)
|
||||||
enum ssd_active_state active;
|
enum ssd_active_state active;
|
||||||
FOR_EACH_ACTIVE_STATE(active) {
|
FOR_EACH_ACTIVE_STATE(active) {
|
||||||
struct ssd_border_subtree *subtree = &ssd->border.subtrees[active];
|
struct ssd_border_subtree *subtree = &ssd->border.subtrees[active];
|
||||||
|
if (theme->window[active].border_type) {
|
||||||
wlr_scene_rect_set_size(subtree->left,
|
renderBufferset(subtree->textured_borders, full_width,
|
||||||
theme->border_width, side_height);
|
side_height+(ssd->titlebar.height + 2*theme->border_width),
|
||||||
wlr_scene_node_set_position(&subtree->left->node,
|
-ssd->titlebar.height-theme->border_width);
|
||||||
0, side_y);
|
} else {
|
||||||
|
wlr_scene_rect_set_size(subtree->left,
|
||||||
wlr_scene_rect_set_size(subtree->right,
|
theme->border_width, side_height);
|
||||||
theme->border_width, side_height);
|
wlr_scene_node_set_position(&subtree->left->node,
|
||||||
wlr_scene_node_set_position(&subtree->right->node,
|
0, side_y);
|
||||||
theme->border_width + width, side_y);
|
wlr_scene_rect_set_size(subtree->right,
|
||||||
|
theme->border_width, side_height);
|
||||||
wlr_scene_rect_set_size(subtree->bottom,
|
wlr_scene_node_set_position(&subtree->right->node,
|
||||||
full_width, theme->border_width);
|
theme->border_width + width, side_y);
|
||||||
wlr_scene_node_set_position(&subtree->bottom->node,
|
wlr_scene_rect_set_size(subtree->bottom,
|
||||||
0, height);
|
full_width, theme->border_width);
|
||||||
|
wlr_scene_node_set_position(&subtree->bottom->node,
|
||||||
wlr_scene_rect_set_size(subtree->top,
|
0, height);
|
||||||
top_width, theme->border_width);
|
wlr_scene_rect_set_size(subtree->top,
|
||||||
wlr_scene_node_set_position(&subtree->top->node,
|
top_width, theme->border_width);
|
||||||
top_x, -(ssd->titlebar.height + theme->border_width));
|
wlr_scene_node_set_position(&subtree->top->node,
|
||||||
|
top_x, -(ssd->titlebar.height + theme->border_width));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "ssd-internal.h"
|
#include "ssd-internal.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
|
|
||||||
static void set_squared_corners(struct ssd *ssd, bool enable);
|
static void set_squared_corners(struct ssd *ssd, bool enable);
|
||||||
static void set_alt_button_icon(struct ssd *ssd, enum lab_node_type type, bool enable);
|
static void set_alt_button_icon(struct ssd *ssd, enum lab_node_type type, bool enable);
|
||||||
|
|
@ -36,6 +37,7 @@ ssd_titlebar_create(struct ssd *ssd)
|
||||||
LAB_NODE_TITLEBAR, view, /*data*/ NULL);
|
LAB_NODE_TITLEBAR, view, /*data*/ NULL);
|
||||||
|
|
||||||
enum ssd_active_state active;
|
enum ssd_active_state active;
|
||||||
|
bool should_force_update = FALSE;
|
||||||
FOR_EACH_ACTIVE_STATE(active) {
|
FOR_EACH_ACTIVE_STATE(active) {
|
||||||
struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[active];
|
struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[active];
|
||||||
subtree->tree = lab_wlr_scene_tree_create(ssd->titlebar.tree);
|
subtree->tree = lab_wlr_scene_tree_create(ssd->titlebar.tree);
|
||||||
|
|
@ -52,6 +54,30 @@ ssd_titlebar_create(struct ssd *ssd)
|
||||||
|
|
||||||
/* Background */
|
/* Background */
|
||||||
subtree->bar = lab_wlr_scene_buffer_create(parent, titlebar_fill);
|
subtree->bar = lab_wlr_scene_buffer_create(parent, titlebar_fill);
|
||||||
|
if (theme->window[active].title_bg.border_type) {
|
||||||
|
/* Beveled Titlebar */
|
||||||
|
float *color = theme->window[active].title_bg.color;
|
||||||
|
float r = color[0];
|
||||||
|
float g = color[1];
|
||||||
|
float b = color[2];
|
||||||
|
float a = color[3];
|
||||||
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32,
|
||||||
|
theme->window[active].title_bg.border_width,
|
||||||
|
theme->window[active].title_bg.border_type,
|
||||||
|
theme->window[active].title_bg.bevel_width);
|
||||||
|
subtree->textured_borders = generate_bufferset(subtree->tree,
|
||||||
|
renderedborders, theme->window[active].title_bg.border_width);
|
||||||
|
|
||||||
|
// If we have the beveled borders, we actually have to run
|
||||||
|
// ssd_titlebar_update() to make sure we render the updated borders.
|
||||||
|
// Otherwise they disappear on reconfigure
|
||||||
|
should_force_update = true;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Work around the wlroots/pixman bug that widened 1px buffer
|
* Work around the wlroots/pixman bug that widened 1px buffer
|
||||||
* becomes translucent when bilinear filtering is used.
|
* becomes translucent when bilinear filtering is used.
|
||||||
|
|
@ -73,9 +99,17 @@ ssd_titlebar_create(struct ssd *ssd)
|
||||||
width - corner_width, -rc.theme->border_width);
|
width - corner_width, -rc.theme->border_width);
|
||||||
|
|
||||||
/* Title */
|
/* Title */
|
||||||
subtree->title = scaled_font_buffer_create_for_titlebar(
|
if (theme->window[active].title_bg.border_type) {
|
||||||
subtree->tree, theme->titlebar_height,
|
// Use a blank background pattern so it doesn't overlay
|
||||||
theme->window[active].titlebar_pattern);
|
// a pattern on the order.
|
||||||
|
subtree->title = scaled_font_buffer_create_for_titlebar(
|
||||||
|
subtree->tree, theme->titlebar_height,
|
||||||
|
NULL);
|
||||||
|
} else {
|
||||||
|
subtree->title = scaled_font_buffer_create_for_titlebar(
|
||||||
|
subtree->tree, theme->titlebar_height,
|
||||||
|
theme->window[active].titlebar_pattern);
|
||||||
|
}
|
||||||
assert(subtree->title);
|
assert(subtree->title);
|
||||||
node_descriptor_create(&subtree->title->scene_buffer->node,
|
node_descriptor_create(&subtree->title->scene_buffer->node,
|
||||||
LAB_NODE_TITLE, view, /*data*/ NULL);
|
LAB_NODE_TITLE, view, /*data*/ NULL);
|
||||||
|
|
@ -122,7 +156,10 @@ ssd_titlebar_create(struct ssd *ssd)
|
||||||
if (squared) {
|
if (squared) {
|
||||||
ssd->state.was_squared = true;
|
ssd->state.was_squared = true;
|
||||||
}
|
}
|
||||||
set_squared_corners(ssd, maximized || squared);
|
set_squared_corners(ssd, maximized ||
|
||||||
|
squared ||
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_type ||
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_type);
|
||||||
|
|
||||||
if (view->shaded) {
|
if (view->shaded) {
|
||||||
set_alt_button_icon(ssd, LAB_NODE_BUTTON_SHADE, true);
|
set_alt_button_icon(ssd, LAB_NODE_BUTTON_SHADE, true);
|
||||||
|
|
@ -131,6 +168,10 @@ ssd_titlebar_create(struct ssd *ssd)
|
||||||
if (view->visible_on_all_workspaces) {
|
if (view->visible_on_all_workspaces) {
|
||||||
set_alt_button_icon(ssd, LAB_NODE_BUTTON_OMNIPRESENT, true);
|
set_alt_button_icon(ssd, LAB_NODE_BUTTON_OMNIPRESENT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (should_force_update) {
|
||||||
|
ssd_titlebar_update(ssd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -280,7 +321,10 @@ ssd_titlebar_update(struct ssd *ssd)
|
||||||
|
|
||||||
if (ssd->state.was_maximized != maximized
|
if (ssd->state.was_maximized != maximized
|
||||||
|| ssd->state.was_squared != squared) {
|
|| ssd->state.was_squared != squared) {
|
||||||
set_squared_corners(ssd, maximized || squared);
|
set_squared_corners(ssd, maximized ||
|
||||||
|
squared ||
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_type ||
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_type);
|
||||||
if (ssd->state.was_maximized != maximized) {
|
if (ssd->state.was_maximized != maximized) {
|
||||||
set_alt_button_icon(ssd, LAB_NODE_BUTTON_MAXIMIZE, maximized);
|
set_alt_button_icon(ssd, LAB_NODE_BUTTON_MAXIMIZE, maximized);
|
||||||
}
|
}
|
||||||
|
|
@ -308,7 +352,11 @@ ssd_titlebar_update(struct ssd *ssd)
|
||||||
/* Center buttons vertically within titlebar */
|
/* Center buttons vertically within titlebar */
|
||||||
int y = (theme->titlebar_height - theme->window_button_height) / 2;
|
int y = (theme->titlebar_height - theme->window_button_height) / 2;
|
||||||
int x;
|
int x;
|
||||||
int bg_offset = maximized || squared ? 0 : corner_width;
|
int bg_offset = (maximized ||
|
||||||
|
squared ||
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_type ||
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_type)
|
||||||
|
? 0 : corner_width;
|
||||||
|
|
||||||
enum ssd_active_state active;
|
enum ssd_active_state active;
|
||||||
FOR_EACH_ACTIVE_STATE(active) {
|
FOR_EACH_ACTIVE_STATE(active) {
|
||||||
|
|
@ -318,10 +366,14 @@ ssd_titlebar_update(struct ssd *ssd)
|
||||||
|
|
||||||
x = theme->window_titlebar_padding_width;
|
x = theme->window_titlebar_padding_width;
|
||||||
struct ssd_button *button;
|
struct ssd_button *button;
|
||||||
|
int button_count = 0;
|
||||||
|
|
||||||
wl_list_for_each(button, &subtree->buttons_left, link) {
|
wl_list_for_each(button, &subtree->buttons_left, link) {
|
||||||
wlr_scene_node_set_position(button->node, x, y);
|
wlr_scene_node_set_position(button->node, x, y);
|
||||||
x += theme->window_button_width + theme->window_button_spacing;
|
x += theme->window_button_width + theme->window_button_spacing;
|
||||||
|
button_count++;
|
||||||
}
|
}
|
||||||
|
int exclusive_x = x;
|
||||||
|
|
||||||
x = width - corner_width;
|
x = width - corner_width;
|
||||||
wlr_scene_node_set_position(&subtree->corner_right->node,
|
wlr_scene_node_set_position(&subtree->corner_right->node,
|
||||||
|
|
@ -331,6 +383,25 @@ ssd_titlebar_update(struct ssd *ssd)
|
||||||
wl_list_for_each(button, &subtree->buttons_right, link) {
|
wl_list_for_each(button, &subtree->buttons_right, link) {
|
||||||
x -= theme->window_button_width + theme->window_button_spacing;
|
x -= theme->window_button_width + theme->window_button_spacing;
|
||||||
wlr_scene_node_set_position(button->node, x, y);
|
wlr_scene_node_set_position(button->node, x, y);
|
||||||
|
button_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme->window[active].title_bg.border_type) {
|
||||||
|
int titlebar_x = 0;
|
||||||
|
int titlebar_width = MAX(view->current.width, 0);
|
||||||
|
if (theme->window[active].title_bg.exclusive) {
|
||||||
|
titlebar_x = exclusive_x+theme->window_titlebar_padding_width;
|
||||||
|
titlebar_width = MAX(
|
||||||
|
(theme->window_button_width + theme->window_button_spacing)
|
||||||
|
* button_count,
|
||||||
|
titlebar_width -
|
||||||
|
(theme->window_button_width + theme->window_button_spacing)
|
||||||
|
* button_count
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
renderBuffersetXY(subtree->textured_borders, titlebar_width,
|
||||||
|
theme->titlebar_height, titlebar_x, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
281
src/theme.c
281
src/theme.c
|
|
@ -91,6 +91,89 @@ draw_hover_overlay_on_button(cairo_t *cairo, int w, int h)
|
||||||
cairo_fill(cairo);
|
cairo_fill(cairo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw_beveled_border_on_button(cairo_t *cairo, int w, int h, int active, int hover)
|
||||||
|
{
|
||||||
|
if (rc.theme->window[active].button_border_type) {
|
||||||
|
int bw = rc.theme->window[active].button_border_width;
|
||||||
|
float r, g, b, a;
|
||||||
|
if (!hover) {
|
||||||
|
r = rc.theme->window[active].button_border_color[0];
|
||||||
|
g = rc.theme->window[active].button_border_color[1];
|
||||||
|
b = rc.theme->window[active].button_border_color[2];
|
||||||
|
a = rc.theme->window[active].button_border_color[3];
|
||||||
|
} else {
|
||||||
|
r = rc.theme->window[active].button_hover_border_color[0];
|
||||||
|
g = rc.theme->window[active].button_hover_border_color[1];
|
||||||
|
b = rc.theme->window[active].button_hover_border_color[2];
|
||||||
|
a = rc.theme->window[active].button_hover_border_color[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
rc.theme->window[active].button_border_type,
|
||||||
|
rc.theme->window[active].button_bevel_width);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->top->surface, 0, 0);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, bw, 0, w-bw*2, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->bottom->surface, bw, h-bw);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, bw, h-bw, w-bw*2, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->left->surface, 0, 0);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, 0, bw, bw, h-bw*2);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->right->surface, w-bw, bw);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, w-bw, bw, bw, h-bw*2);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->tl->surface, 0, 0);
|
||||||
|
cairo_rectangle(cairo, 0, 0, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->tr->surface, w-bw, 0);
|
||||||
|
cairo_rectangle(cairo, w - bw, 0, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->bl->surface, 0, h - bw);
|
||||||
|
cairo_rectangle(cairo, 0, h - bw, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->br->surface, w - bw, h -bw);
|
||||||
|
cairo_rectangle(cairo, w - bw, h - bw, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_hover_active_border_on_button(cairo_t *cairo, int w, int h)
|
||||||
|
{
|
||||||
|
draw_beveled_border_on_button(cairo, w, h, SSD_ACTIVE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_hover_inactive_border_on_button(cairo_t *cairo, int w, int h)
|
||||||
|
{
|
||||||
|
draw_beveled_border_on_button(cairo, w, h, SSD_INACTIVE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_nonhover_active_border_on_button(cairo_t *cairo, int w, int h)
|
||||||
|
{
|
||||||
|
draw_beveled_border_on_button(cairo, w, h, SSD_ACTIVE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void draw_nonhover_inactive_border_on_button(cairo_t *cairo, int w, int h)
|
||||||
|
{
|
||||||
|
draw_beveled_border_on_button(cairo, w, h, SSD_INACTIVE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Round the buffer for the leftmost button in the titlebar */
|
/* Round the buffer for the leftmost button in the titlebar */
|
||||||
static void
|
static void
|
||||||
round_left_corner_button(cairo_t *cairo, int w, int h)
|
round_left_corner_button(cairo_t *cairo, int w, int h)
|
||||||
|
|
@ -222,6 +305,21 @@ load_button(struct theme *theme, struct button *b, enum ssd_active_state active)
|
||||||
draw_hover_overlay_on_button);
|
draw_hover_overlay_on_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theme->window[active].button_border_type) {
|
||||||
|
if (active) {
|
||||||
|
if (b->state_set & LAB_BS_HOVERED) {
|
||||||
|
lab_img_add_modifier(*img, draw_hover_active_border_on_button);
|
||||||
|
} else {
|
||||||
|
lab_img_add_modifier(*img, draw_nonhover_active_border_on_button);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (b->state_set & LAB_BS_HOVERED) {
|
||||||
|
lab_img_add_modifier(*img, draw_hover_inactive_border_on_button);
|
||||||
|
} else {
|
||||||
|
lab_img_add_modifier(*img, draw_nonhover_inactive_border_on_button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* If the loaded button is at the corner of the titlebar, also create
|
* If the loaded button is at the corner of the titlebar, also create
|
||||||
* rounded variants.
|
* rounded variants.
|
||||||
|
|
@ -450,6 +548,28 @@ parse_hexstrs(const char *hexes, float colors[3][4])
|
||||||
g_strfreev(elements);
|
g_strfreev(elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum border_type parse_border_type(const char *str)
|
||||||
|
{
|
||||||
|
char *lower = g_ascii_strdown(str, -1);
|
||||||
|
enum border_type border_type;
|
||||||
|
if (strstr(lower, "doublesunken")) {
|
||||||
|
border_type = BORDER_DOUBLE_INSET;
|
||||||
|
} else if (strstr(lower, "sunken")) {
|
||||||
|
border_type = BORDER_INSET;
|
||||||
|
} else if (strstr(lower, "doubleraised")) {
|
||||||
|
border_type = BORDER_DOUBLE;
|
||||||
|
} else if (strstr(lower, "raised")) {
|
||||||
|
border_type = BORDER_SINGLE;
|
||||||
|
} else if (strstr(lower, "flat")) {
|
||||||
|
border_type = BORDER_FLAT;
|
||||||
|
} else {
|
||||||
|
border_type = BORDER_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(lower);
|
||||||
|
return border_type;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
parse_color(const char *str, float *rgba)
|
parse_color(const char *str, float *rgba)
|
||||||
{
|
{
|
||||||
|
|
@ -550,6 +670,28 @@ theme_builtin(struct theme *theme)
|
||||||
theme->window[SSD_INACTIVE].title_bg.color_to[0] = FLT_MIN;
|
theme->window[SSD_INACTIVE].title_bg.color_to[0] = FLT_MIN;
|
||||||
theme->window[SSD_ACTIVE].title_bg.color_to_split_to[0] = FLT_MIN;
|
theme->window[SSD_ACTIVE].title_bg.color_to_split_to[0] = FLT_MIN;
|
||||||
theme->window[SSD_INACTIVE].title_bg.color_to_split_to[0] = FLT_MIN;
|
theme->window[SSD_INACTIVE].title_bg.color_to_split_to[0] = FLT_MIN;
|
||||||
|
theme->window[SSD_ACTIVE].bevel_width = 0;
|
||||||
|
theme->window[SSD_ACTIVE].border_type = BORDER_NONE;
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.bevel_width = 0;
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_width = 0;
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.exclusive = FALSE;
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_type = BORDER_NONE;
|
||||||
|
theme->window[SSD_INACTIVE].bevel_width = 0;
|
||||||
|
theme->window[SSD_INACTIVE].border_type = BORDER_NONE;
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.bevel_width = 0;
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_width = 0;
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.exclusive = FALSE;
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_type = BORDER_NONE;
|
||||||
|
theme->window[SSD_ACTIVE].button_border_type = BORDER_NONE;
|
||||||
|
theme->window[SSD_ACTIVE].button_border_width = 0;
|
||||||
|
theme->window[SSD_ACTIVE].button_bevel_width = 0;
|
||||||
|
theme->window[SSD_ACTIVE].button_border_color[0] = FLT_MIN;
|
||||||
|
theme->window[SSD_ACTIVE].button_hover_border_color[0] = FLT_MIN;
|
||||||
|
theme->window[SSD_INACTIVE].button_border_type = BORDER_NONE;
|
||||||
|
theme->window[SSD_INACTIVE].button_border_width = 0;
|
||||||
|
theme->window[SSD_INACTIVE].button_bevel_width = 0;
|
||||||
|
theme->window[SSD_INACTIVE].button_border_color[0] = FLT_MIN;
|
||||||
|
theme->window[SSD_INACTIVE].button_hover_border_color[0] = FLT_MIN;
|
||||||
|
|
||||||
parse_hexstr("#000000", theme->window[SSD_ACTIVE].label_text_color);
|
parse_hexstr("#000000", theme->window[SSD_ACTIVE].label_text_color);
|
||||||
parse_hexstr("#000000", theme->window[SSD_INACTIVE].label_text_color);
|
parse_hexstr("#000000", theme->window[SSD_INACTIVE].label_text_color);
|
||||||
|
|
@ -581,6 +723,8 @@ theme_builtin(struct theme *theme)
|
||||||
theme->menu_max_width = 200;
|
theme->menu_max_width = 200;
|
||||||
theme->menu_border_width = INT_MIN;
|
theme->menu_border_width = INT_MIN;
|
||||||
theme->menu_border_color[0] = FLT_MIN;
|
theme->menu_border_color[0] = FLT_MIN;
|
||||||
|
theme->menu_border_type = BORDER_NONE;
|
||||||
|
theme->menu_bevel_width = 0;
|
||||||
|
|
||||||
theme->menu_items_padding_x = 7;
|
theme->menu_items_padding_x = 7;
|
||||||
theme->menu_items_padding_y = 4;
|
theme->menu_items_padding_y = 4;
|
||||||
|
|
@ -588,6 +732,12 @@ theme_builtin(struct theme *theme)
|
||||||
parse_hexstr("#000000", theme->menu_items_text_color);
|
parse_hexstr("#000000", theme->menu_items_text_color);
|
||||||
parse_hexstr("#e1dedb", theme->menu_items_active_bg_color);
|
parse_hexstr("#e1dedb", theme->menu_items_active_bg_color);
|
||||||
parse_hexstr("#000000", theme->menu_items_active_text_color);
|
parse_hexstr("#000000", theme->menu_items_active_text_color);
|
||||||
|
theme->menu_items_border_type = BORDER_NONE;
|
||||||
|
theme->menu_items_bevel_width = 0;
|
||||||
|
theme->menu_title_border_type = BORDER_NONE;
|
||||||
|
theme->menu_title_bevel_width = 0;
|
||||||
|
theme->menu_items_active_border_type = BORDER_NONE;
|
||||||
|
theme->menu_items_active_bevel_width = 0;
|
||||||
|
|
||||||
theme->menu_separator_line_thickness = 1;
|
theme->menu_separator_line_thickness = 1;
|
||||||
theme->menu_separator_padding_width = 6;
|
theme->menu_separator_padding_width = 6;
|
||||||
|
|
@ -633,6 +783,8 @@ theme_builtin(struct theme *theme)
|
||||||
theme->osd_border_width = INT_MIN;
|
theme->osd_border_width = INT_MIN;
|
||||||
theme->osd_border_color[0] = FLT_MIN;
|
theme->osd_border_color[0] = FLT_MIN;
|
||||||
theme->osd_label_text_color[0] = FLT_MIN;
|
theme->osd_label_text_color[0] = FLT_MIN;
|
||||||
|
theme->osd_border_type = BORDER_NONE;
|
||||||
|
theme->osd_border_bevel_width = 0;
|
||||||
|
|
||||||
if (wlr_renderer_is_pixman(server.renderer)) {
|
if (wlr_renderer_is_pixman(server.renderer)) {
|
||||||
/* Draw only outlined overlay by default to save CPU resource */
|
/* Draw only outlined overlay by default to save CPU resource */
|
||||||
|
|
@ -695,6 +847,7 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
theme->border_width = get_int_if_positive(
|
theme->border_width = get_int_if_positive(
|
||||||
value, "border.width");
|
value, "border.width");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match_glob(key, "window.titlebar.padding.width")) {
|
if (match_glob(key, "window.titlebar.padding.width")) {
|
||||||
theme->window_titlebar_padding_width = get_int_if_positive(
|
theme->window_titlebar_padding_width = get_int_if_positive(
|
||||||
value, "window.titlebar.padding.width");
|
value, "window.titlebar.padding.width");
|
||||||
|
|
@ -710,12 +863,45 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
wlr_log(WLR_INFO, "padding.height is no longer supported");
|
wlr_log(WLR_INFO, "padding.height is no longer supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.active.title.bg") && parse_border_type(value)) {
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.active.title.bg.width")) {
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.border_width =
|
||||||
|
get_int_if_positive(value, "window.active.title.bg.width");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.active.title.bg.exclusive")) {
|
||||||
|
set_bool(value, &theme->window[SSD_ACTIVE].title_bg.exclusive);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.active.title.bg.bevel-width")) {
|
||||||
|
theme->window[SSD_ACTIVE].title_bg.bevel_width =
|
||||||
|
get_int_if_positive(value, "window.active.title.bg.bevel-width");
|
||||||
|
}
|
||||||
if (match_glob(key, "window.active.border.color")) {
|
if (match_glob(key, "window.active.border.color")) {
|
||||||
parse_color(value, theme->window[SSD_ACTIVE].border_color);
|
parse_color(value, theme->window[SSD_ACTIVE].border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.active.border.type")) {
|
||||||
|
theme->window[SSD_ACTIVE].border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.active.border.bevel-width")) {
|
||||||
|
theme->window[SSD_ACTIVE].bevel_width =
|
||||||
|
get_int_if_positive(value, "window.active.border.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
if (match_glob(key, "window.inactive.border.color")) {
|
if (match_glob(key, "window.inactive.border.color")) {
|
||||||
parse_color(value, theme->window[SSD_INACTIVE].border_color);
|
parse_color(value, theme->window[SSD_INACTIVE].border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.inactive.border.bevel-width")) {
|
||||||
|
theme->window[SSD_INACTIVE].bevel_width =
|
||||||
|
get_int_if_positive(value, "window.inactive.border.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.inactive.border.type")) {
|
||||||
|
theme->window[SSD_INACTIVE].border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
/* border.color is obsolete, but handled for backward compatibility */
|
/* border.color is obsolete, but handled for backward compatibility */
|
||||||
if (match_glob(key, "border.color")) {
|
if (match_glob(key, "border.color")) {
|
||||||
parse_color(value, theme->window[SSD_ACTIVE].border_color);
|
parse_color(value, theme->window[SSD_ACTIVE].border_color);
|
||||||
|
|
@ -729,6 +915,22 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
if (match_glob(key, "window.active.title.bg")) {
|
if (match_glob(key, "window.active.title.bg")) {
|
||||||
theme->window[SSD_ACTIVE].title_bg.gradient = parse_gradient(value);
|
theme->window[SSD_ACTIVE].title_bg.gradient = parse_gradient(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.inactive.title.bg") && parse_border_type(value)) {
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.inactive.title.bg.width")) {
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.border_width =
|
||||||
|
get_int_if_positive(value, "window.inactive.title.bg.width");
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.inactive.title.bg.bevel-width")) {
|
||||||
|
theme->window[SSD_INACTIVE].title_bg.bevel_width =
|
||||||
|
get_int_if_positive(value, "window.inactive.title.bg.bevel-width");
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.inactive.title.bg.exclusive")) {
|
||||||
|
set_bool(value, &theme->window[SSD_INACTIVE].title_bg.exclusive);
|
||||||
|
}
|
||||||
|
|
||||||
if (match_glob(key, "window.inactive.title.bg")) {
|
if (match_glob(key, "window.inactive.title.bg")) {
|
||||||
theme->window[SSD_INACTIVE].title_bg.gradient = parse_gradient(value);
|
theme->window[SSD_INACTIVE].title_bg.gradient = parse_gradient(value);
|
||||||
}
|
}
|
||||||
|
|
@ -788,6 +990,46 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
value, "window.button.spacing");
|
value, "window.button.spacing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.inactive.button.bg") && parse_border_type(value)) {
|
||||||
|
theme->window[SSD_INACTIVE].button_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.inactive.button.bg.width")) {
|
||||||
|
theme->window[SSD_INACTIVE].button_border_width =
|
||||||
|
get_int_if_positive(value, "window.inactive.button.bg.width");
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.inactive.button.bg.bevel-width")) {
|
||||||
|
theme->window[SSD_INACTIVE].button_bevel_width =
|
||||||
|
get_int_if_positive(value, "window.inactive.button.bg.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.inactive.button.bg.border-color")) {
|
||||||
|
parse_color(value, theme->window[SSD_INACTIVE].button_border_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.inactive.button.bg.border-hover-color")) {
|
||||||
|
parse_color(value, theme->window[SSD_INACTIVE].button_hover_border_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.active.button.bg") && parse_border_type(value)) {
|
||||||
|
theme->window[SSD_ACTIVE].button_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.active.button.bg.width")) {
|
||||||
|
theme->window[SSD_ACTIVE].button_border_width =
|
||||||
|
get_int_if_positive(value, "window.active.button.bg.width");
|
||||||
|
}
|
||||||
|
if (match_glob(key, "window.inactive.button.bg.bevel-width")) {
|
||||||
|
theme->window[SSD_ACTIVE].button_bevel_width =
|
||||||
|
get_int_if_positive(value, "window.active.button.bg.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.active.button.bg.border-color")) {
|
||||||
|
parse_color(value, theme->window[SSD_ACTIVE].button_border_color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "window.active.button.bg.border-hover-color")) {
|
||||||
|
parse_color(value, theme->window[SSD_ACTIVE].button_hover_border_color);
|
||||||
|
}
|
||||||
|
|
||||||
/* botton hover overlay */
|
/* botton hover overlay */
|
||||||
if (match_glob(key, "window.button.hover.bg.color")) {
|
if (match_glob(key, "window.button.hover.bg.color")) {
|
||||||
parse_color(value, theme->window_button_hover_bg_color);
|
parse_color(value, theme->window_button_hover_bg_color);
|
||||||
|
|
@ -905,6 +1147,14 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
parse_color(value, theme->menu_border_color);
|
parse_color(value, theme->menu_border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "menu.bg")) {
|
||||||
|
theme->menu_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "menu.bg.bevel-width")) {
|
||||||
|
theme->menu_bevel_width =
|
||||||
|
get_int_if_positive(value, "menu.bg.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
if (match_glob(key, "menu.items.padding.x")) {
|
if (match_glob(key, "menu.items.padding.x")) {
|
||||||
theme->menu_items_padding_x = get_int_if_positive(
|
theme->menu_items_padding_x = get_int_if_positive(
|
||||||
value, "menu.items.padding.x");
|
value, "menu.items.padding.x");
|
||||||
|
|
@ -916,6 +1166,14 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
if (match_glob(key, "menu.items.bg.color")) {
|
if (match_glob(key, "menu.items.bg.color")) {
|
||||||
parse_color(value, theme->menu_items_bg_color);
|
parse_color(value, theme->menu_items_bg_color);
|
||||||
}
|
}
|
||||||
|
if (match_glob(key, "menu.items.bg")) {
|
||||||
|
theme->menu_items_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "menu.items.bg.bevel-width")) {
|
||||||
|
theme->menu_items_bevel_width =
|
||||||
|
get_int_if_positive(value, "menu.items.bg.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
if (match_glob(key, "menu.items.text.color")) {
|
if (match_glob(key, "menu.items.text.color")) {
|
||||||
parse_color(value, theme->menu_items_text_color);
|
parse_color(value, theme->menu_items_text_color);
|
||||||
}
|
}
|
||||||
|
|
@ -926,6 +1184,14 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
parse_color(value, theme->menu_items_active_text_color);
|
parse_color(value, theme->menu_items_active_text_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "menu.items.active.bg")) {
|
||||||
|
theme->menu_items_active_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "menu.items.active.bg.bevel-width")) {
|
||||||
|
theme->menu_items_active_bevel_width =
|
||||||
|
get_int_if_positive(value, "menu.items.active.bg.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
if (match_glob(key, "menu.separator.width")) {
|
if (match_glob(key, "menu.separator.width")) {
|
||||||
theme->menu_separator_line_thickness = get_int_if_positive(
|
theme->menu_separator_line_thickness = get_int_if_positive(
|
||||||
value, "menu.separator.width");
|
value, "menu.separator.width");
|
||||||
|
|
@ -952,6 +1218,14 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
parse_color(value, theme->menu_title_text_color);
|
parse_color(value, theme->menu_title_text_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "menu.title.bg")) {
|
||||||
|
theme->menu_title_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "menu.title.bg.bevel-width")) {
|
||||||
|
theme->menu_title_bevel_width =
|
||||||
|
get_int_if_positive(value, "menu.title.bg.bevel-width");
|
||||||
|
}
|
||||||
|
|
||||||
if (match_glob(key, "osd.bg.color")) {
|
if (match_glob(key, "osd.bg.color")) {
|
||||||
parse_color(value, theme->osd_bg_color);
|
parse_color(value, theme->osd_bg_color);
|
||||||
}
|
}
|
||||||
|
|
@ -962,6 +1236,13 @@ entry(struct theme *theme, const char *key, const char *value)
|
||||||
if (match_glob(key, "osd.border.color")) {
|
if (match_glob(key, "osd.border.color")) {
|
||||||
parse_color(value, theme->osd_border_color);
|
parse_color(value, theme->osd_border_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (match_glob(key, "osd.bg")) {
|
||||||
|
theme->osd_border_type = parse_border_type(value);
|
||||||
|
}
|
||||||
|
if (match_glob(key, "osd.bg.bevel-width")) {
|
||||||
|
theme->osd_border_bevel_width = get_int_if_positive(value, "osd.bg.bevel-width");
|
||||||
|
}
|
||||||
/* classic window switcher */
|
/* classic window switcher */
|
||||||
if (match_glob(key, "osd.window-switcher.style-classic.width")
|
if (match_glob(key, "osd.window-switcher.style-classic.width")
|
||||||
|| match_glob(key, "osd.window-switcher.width")) {
|
|| match_glob(key, "osd.window-switcher.width")) {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "common/scene-helpers.h"
|
#include "common/scene-helpers.h"
|
||||||
#include "config/rcxml.h"
|
#include "config/rcxml.h"
|
||||||
#include "input/keyboard.h"
|
#include "input/keyboard.h"
|
||||||
|
#include "common/borderset.h"
|
||||||
#include "labwc.h"
|
#include "labwc.h"
|
||||||
#include "output.h"
|
#include "output.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
|
@ -96,18 +97,73 @@ _osd_update(void)
|
||||||
|
|
||||||
cairo = cairo_create(buffer->surface);
|
cairo = cairo_create(buffer->surface);
|
||||||
|
|
||||||
|
int bw = theme->osd_border_width;
|
||||||
/* Background */
|
/* Background */
|
||||||
set_cairo_color(cairo, theme->osd_bg_color);
|
set_cairo_color(cairo, theme->osd_bg_color);
|
||||||
cairo_rectangle(cairo, 0, 0, width, height);
|
cairo_rectangle(cairo, bw, bw, width-bw*2, height-bw*2);
|
||||||
cairo_fill(cairo);
|
cairo_fill(cairo);
|
||||||
|
|
||||||
/* Border */
|
/* Border */
|
||||||
set_cairo_color(cairo, theme->osd_border_color);
|
if (theme->osd_border_type) {
|
||||||
struct wlr_fbox border_fbox = {
|
float r = theme->osd_border_color[0];
|
||||||
.width = width,
|
float g = theme->osd_border_color[1];
|
||||||
.height = height,
|
float b = theme->osd_border_color[2];
|
||||||
};
|
float a = theme->osd_border_color[3];
|
||||||
draw_cairo_border(cairo, border_fbox, theme->osd_border_width);
|
|
||||||
|
uint32_t colour32 = (uint32_t)(a*255) << 24 |
|
||||||
|
(uint32_t)(r*255) << 16 |
|
||||||
|
(uint32_t)(g*255) << 8 |
|
||||||
|
(uint32_t)(b*255);
|
||||||
|
struct borderset *renderedborders = get_borders(colour32, bw,
|
||||||
|
theme->osd_border_type, theme->osd_border_bevel_width);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->top->surface, 0, 0);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, bw, 0, width-bw*2, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->bottom->surface, 0, 0);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, bw, height-bw, width-bw*2, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->left->surface, 0, 0);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, 0, bw, bw, height-bw*2);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->right->surface, 0, 0);
|
||||||
|
cairo_pattern_set_extend(cairo_get_source(cairo), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle(cairo, width-bw, bw, bw, height-bw*2);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->tl->surface, 0, 0);
|
||||||
|
cairo_rectangle(cairo, 0, 0, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->tr->surface, width-bw, 0);
|
||||||
|
cairo_rectangle(cairo, width - bw, 0, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->bl->surface,
|
||||||
|
0, height - bw);
|
||||||
|
cairo_rectangle(cairo, 0, height - bw, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
cairo_set_source_surface(cairo, renderedborders->br->surface,
|
||||||
|
width - bw, height -bw);
|
||||||
|
cairo_rectangle(cairo, width - bw, height - bw, bw, bw);
|
||||||
|
cairo_fill(cairo);
|
||||||
|
|
||||||
|
set_cairo_color(cairo, theme->osd_border_color);
|
||||||
|
} else {
|
||||||
|
set_cairo_color(cairo, theme->osd_border_color);
|
||||||
|
struct wlr_fbox border_fbox = {
|
||||||
|
.width = width,
|
||||||
|
.height = height,
|
||||||
|
};
|
||||||
|
draw_cairo_border(cairo, border_fbox, theme->osd_border_width);
|
||||||
|
}
|
||||||
|
|
||||||
/* Boxes */
|
/* Boxes */
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue