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.
|
||||
|
||||
# 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
|
||||
|
|
|
|||
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
|
||||
#define LABWC_LAB_SCENE_RECT_H
|
||||
#include <wayland-server-core.h>
|
||||
#include "common/borderset.h"
|
||||
|
||||
struct wlr_scene_tree;
|
||||
|
||||
|
|
@ -12,6 +13,8 @@ struct lab_scene_rect_options {
|
|||
float *bg_color; /* can be NULL */
|
||||
int width;
|
||||
int height;
|
||||
enum border_type border_type;
|
||||
int bevel_width;
|
||||
};
|
||||
|
||||
struct lab_scene_rect {
|
||||
|
|
|
|||
|
|
@ -65,4 +65,15 @@
|
|||
#define LAB_WLR_VERSION_AT_LEAST(major, minor, 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 */
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ struct ssd {
|
|||
struct scaled_font_buffer *title;
|
||||
struct wl_list buttons_left; /* ssd_button.link */
|
||||
struct wl_list buttons_right; /* ssd_button.link */
|
||||
struct bufferset *textured_borders;
|
||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||
} titlebar;
|
||||
|
||||
|
|
@ -115,6 +116,7 @@ struct ssd {
|
|||
struct ssd_border_subtree {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||
struct bufferset *textured_borders;
|
||||
} subtrees[2]; /* indexed by enum ssd_active_state */
|
||||
} border;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <cairo.h>
|
||||
#include <stdbool.h>
|
||||
#include "common/node-type.h"
|
||||
#include "common/borderset.h"
|
||||
|
||||
struct lab_img;
|
||||
|
||||
|
|
@ -56,6 +57,10 @@ struct theme_background {
|
|||
float color_split_to[4];
|
||||
float color_to[4];
|
||||
float color_to_split_to[4];
|
||||
enum border_type border_type;
|
||||
int border_width;
|
||||
int bevel_width;
|
||||
bool exclusive;
|
||||
};
|
||||
|
||||
struct theme {
|
||||
|
|
@ -92,10 +97,17 @@ struct theme {
|
|||
|
||||
/* TODO: add toggled/hover/pressed/disabled colors for buttons */
|
||||
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 toggled_keybinds_color[4];
|
||||
float label_text_color[4];
|
||||
enum border_type border_type;
|
||||
int bevel_width;
|
||||
|
||||
/* window drop-shadows */
|
||||
int shadow_size;
|
||||
|
|
@ -142,6 +154,8 @@ struct theme {
|
|||
int menu_max_width;
|
||||
int menu_border_width;
|
||||
float menu_border_color[4];
|
||||
enum border_type menu_border_type;
|
||||
int menu_bevel_width;
|
||||
|
||||
int menu_items_padding_x;
|
||||
int menu_items_padding_y;
|
||||
|
|
@ -149,6 +163,12 @@ struct theme {
|
|||
float menu_items_text_color[4];
|
||||
float menu_items_active_bg_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_padding_width;
|
||||
|
|
@ -164,6 +184,8 @@ struct theme {
|
|||
float osd_bg_color[4];
|
||||
float osd_border_color[4];
|
||||
float osd_label_text_color[4];
|
||||
enum border_type osd_border_type;
|
||||
int osd_border_bevel_width;
|
||||
|
||||
struct window_switcher_classic_theme {
|
||||
int width;
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ struct view {
|
|||
int width, height;
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_rect *border;
|
||||
struct bufferset *textured_borders;
|
||||
struct wlr_scene_rect *background;
|
||||
struct scaled_font_buffer *text;
|
||||
} 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 "common/mem.h"
|
||||
#include "common/scene-helpers.h"
|
||||
#include "common/macros.h"
|
||||
#include "common/borderset.h"
|
||||
#include "theme.h"
|
||||
#include "buffer.h"
|
||||
|
||||
struct border_scene {
|
||||
struct wlr_scene_tree *tree;
|
||||
struct wlr_scene_rect *top, *bottom, *left, *right;
|
||||
struct bufferset *textured_borders;
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
@ -37,10 +42,29 @@ lab_scene_rect_create(struct wlr_scene_tree *parent,
|
|||
struct border_scene *border = &rect->borders[i];
|
||||
float *color = opts->border_colors[i];
|
||||
border->tree = lab_wlr_scene_tree_create(rect->tree);
|
||||
|
||||
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->bottom = 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;
|
||||
|
|
@ -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->left, 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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
labwc_sources += files(
|
||||
'borderset.c',
|
||||
'box.c',
|
||||
'buf.c',
|
||||
'dir.c',
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@ update_preview_outlines(struct view *view)
|
|||
},
|
||||
.nr_borders = 3,
|
||||
.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);
|
||||
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,
|
||||
.width = w,
|
||||
.height = h,
|
||||
.border_type = theme->osd_border_type,
|
||||
.bevel_width = theme->osd_border_bevel_width
|
||||
};
|
||||
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,
|
||||
.width = w - 2 * padding,
|
||||
.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(
|
||||
item->active_tree, &highlight_opts);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,9 @@
|
|||
#include <wlr/types/wlr_scene.h>
|
||||
#include "common/lab-scene-rect.h"
|
||||
#include "common/scene-helpers.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "labwc.h"
|
||||
#include "theme.h"
|
||||
#include "cycle.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,
|
||||
float *border_color, float *bg_color)
|
||||
{
|
||||
struct theme *theme = rc.theme;
|
||||
|
||||
if (nr_visible_rows >= nr_rows) {
|
||||
/* OSD doesn't have so many windows to scroll through */
|
||||
return;
|
||||
|
|
@ -35,6 +39,8 @@ cycle_osd_scroll_init(struct cycle_osd_output *osd_output, struct wlr_box bar_ar
|
|||
.bg_color = bg_color,
|
||||
.width = bar_area.width,
|
||||
.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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
|
|||
.bg_color = switcher_theme->item_active_bg_color,
|
||||
.width = switcher_theme->item_width,
|
||||
.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);
|
||||
|
||||
|
|
@ -286,6 +288,8 @@ cycle_osd_thumbnail_init(struct cycle_osd_output *osd_output)
|
|||
.bg_color = theme->osd_bg_color,
|
||||
.width = items_width + 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 =
|
||||
lab_scene_rect_create(osd_output->tree, &bg_opts);
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include "theme.h"
|
||||
#include "translate.h"
|
||||
#include "menu/menu.h"
|
||||
#include "common/borderset.h"
|
||||
|
||||
/*
|
||||
* Globals
|
||||
|
|
@ -40,6 +41,8 @@ static const struct option long_options[] = {
|
|||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
struct borderset *border_cache;
|
||||
|
||||
static const char labwc_usage[] =
|
||||
"Usage: labwc [options...]\n"
|
||||
" -c, --config <file> Specify config file (with path)\n"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@
|
|||
#include "translate.h"
|
||||
#include "view.h"
|
||||
#include "workspaces.h"
|
||||
#include "common/borderset.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#define PIPEMENU_MAX_BUF_SIZE 1048576 /* 1 MiB */
|
||||
#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 *
|
||||
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 theme *theme = rc.theme;
|
||||
struct bufferset *bufferset = NULL;
|
||||
|
||||
/* Tree to hold background and label buffers */
|
||||
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 */
|
||||
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 */
|
||||
bool show_app_icon = !strcmp(item->parent->id, "client-list-combined-menu")
|
||||
&& 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;
|
||||
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) {
|
||||
return tree;
|
||||
}
|
||||
|
|
@ -252,10 +290,10 @@ item_create_scene(struct menuitem *menuitem, int *item_y)
|
|||
/* Create scenes for unselected/selected states */
|
||||
menuitem->normal_tree = item_create_scene_for_state(menuitem,
|
||||
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,
|
||||
theme->menu_items_active_text_color,
|
||||
theme->menu_items_active_bg_color);
|
||||
theme->menu_items_active_bg_color, 1);
|
||||
/* Hide selected state */
|
||||
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);
|
||||
struct menu *menu = menuitem->parent;
|
||||
struct theme *theme = rc.theme;
|
||||
struct bufferset *bufferset = NULL;
|
||||
|
||||
float *bg_color = theme->menu_title_bg_color;
|
||||
float *text_color = theme->menu_title_text_color;
|
||||
|
||||
|
|
@ -357,6 +397,23 @@ title_create_scene(struct menuitem *menuitem, int *item_y)
|
|||
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 */
|
||||
lab_wlr_scene_rect_create(menuitem->normal_tree,
|
||||
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;
|
||||
wlr_scene_node_set_position(&title_font_buffer->scene_buffer->node,
|
||||
title_x, title_y);
|
||||
|
||||
if (bufferset && rc.theme->menu_title_border_type) {
|
||||
renderBufferset(bufferset, bg_width, theme->menu_item_height, 0);
|
||||
}
|
||||
error:
|
||||
wlr_scene_node_set_position(&menuitem->tree->node,
|
||||
theme->menu_border_width, *item_y);
|
||||
|
|
@ -457,6 +518,8 @@ menu_create_scene(struct menu *menu)
|
|||
.border_width = theme->menu_border_width,
|
||||
.width = menu->size.width,
|
||||
.height = menu->size.height,
|
||||
.border_type = theme->menu_border_type,
|
||||
.bevel_width = theme->menu_bevel_width
|
||||
};
|
||||
struct lab_scene_rect *bg_rect =
|
||||
lab_scene_rect_create(menu->scene_tree, &opts);
|
||||
|
|
|
|||
|
|
@ -73,6 +73,7 @@
|
|||
#include "view.h"
|
||||
#include "workspaces.h"
|
||||
#include "xwayland.h"
|
||||
#include "common/borderset.h"
|
||||
|
||||
#define LAB_EXT_DATA_CONTROL_VERSION 1
|
||||
#define LAB_EXT_FOREIGN_TOPLEVEL_LIST_VERSION 1
|
||||
|
|
@ -89,6 +90,9 @@ reload_config_and_theme(void)
|
|||
|
||||
scaled_buffer_invalidate_sharing();
|
||||
rcxml_finish();
|
||||
clearborder_cache(border_cache);
|
||||
border_cache = NULL;
|
||||
|
||||
rcxml_read(rc.config_file);
|
||||
theme_finish(rc.theme);
|
||||
theme_init(rc.theme, rc.theme_name);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
#include "ssd.h"
|
||||
#include "theme.h"
|
||||
#include "view.h"
|
||||
#include "common/borderset.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#define PADDING rc.theme->osd_window_switcher_classic.padding
|
||||
|
||||
|
|
@ -36,6 +38,23 @@ resize_indicator_reconfigure_view(struct resize_indicator *indicator)
|
|||
/* Colors */
|
||||
wlr_scene_rect_set_color(indicator->border, theme->osd_border_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
|
||||
|
|
@ -50,6 +69,7 @@ resize_indicator_init(struct view *view)
|
|||
indicator->tree, 0, 0, rc.theme->osd_border_color);
|
||||
indicator->background = lab_wlr_scene_rect_create(
|
||||
indicator->tree, 0, 0, rc.theme->osd_bg_color);
|
||||
|
||||
indicator->text = scaled_font_buffer_create(indicator->tree);
|
||||
|
||||
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) {
|
||||
struct resize_indicator *indicator = &view->resize_indicator;
|
||||
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) {
|
||||
continue;
|
||||
|
|
@ -117,6 +139,11 @@ resize_indicator_set_size(struct resize_indicator *indicator, int width)
|
|||
wlr_scene_rect_set_size(indicator->background,
|
||||
indicator->width - 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
|
||||
|
|
|
|||
|
|
@ -2,13 +2,16 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include "buffer.h"
|
||||
#include "common/macros.h"
|
||||
#include "common/mem.h"
|
||||
#include "common/scene-helpers.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "ssd.h"
|
||||
#include "ssd-internal.h"
|
||||
#include "theme.h"
|
||||
#include "view.h"
|
||||
#include "common/borderset.h"
|
||||
|
||||
void
|
||||
ssd_border_create(struct ssd *ssd)
|
||||
|
|
@ -18,6 +21,7 @@ ssd_border_create(struct ssd *ssd)
|
|||
|
||||
struct view *view = ssd->view;
|
||||
struct theme *theme = rc.theme;
|
||||
int bw = theme->border_width;
|
||||
int width = view->current.width;
|
||||
int height = view_effective_height(view, /* use_pending */ false);
|
||||
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;
|
||||
wlr_scene_node_set_enabled(&parent->node, active);
|
||||
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,
|
||||
theme->border_width, height, color);
|
||||
wlr_scene_node_set_position(&subtree->left->node, 0, 0);
|
||||
subtree->left = lab_wlr_scene_rect_create(parent, 1, 1, color);
|
||||
subtree->right = lab_wlr_scene_rect_create(parent, 1, 1, color);
|
||||
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,
|
||||
theme->border_width, height, color);
|
||||
wlr_scene_node_set_position(&subtree->right->node,
|
||||
theme->border_width + width, 0);
|
||||
/* From Pull request 3382 */
|
||||
float r = color[0];
|
||||
float g = color[1];
|
||||
float b = color[2];
|
||||
float a = color[3];
|
||||
|
||||
subtree->bottom = lab_wlr_scene_rect_create(parent,
|
||||
full_width, theme->border_width, color);
|
||||
wlr_scene_node_set_position(&subtree->bottom->node,
|
||||
0, height);
|
||||
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->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,
|
||||
MAX(width - 2 * corner_width, 0), theme->border_width, color);
|
||||
wlr_scene_node_set_position(&subtree->top->node,
|
||||
theme->border_width + corner_width,
|
||||
-(ssd->titlebar.height + theme->border_width));
|
||||
wlr_scene_node_set_position(&subtree->left->node, 0, 0);
|
||||
wlr_scene_node_set_position(&subtree->right->node,
|
||||
theme->border_width + width, 0);
|
||||
wlr_scene_node_set_position(&subtree->bottom->node,
|
||||
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) {
|
||||
|
|
@ -132,26 +158,28 @@ ssd_border_update(struct ssd *ssd)
|
|||
enum ssd_active_state active;
|
||||
FOR_EACH_ACTIVE_STATE(active) {
|
||||
struct ssd_border_subtree *subtree = &ssd->border.subtrees[active];
|
||||
|
||||
wlr_scene_rect_set_size(subtree->left,
|
||||
theme->border_width, side_height);
|
||||
wlr_scene_node_set_position(&subtree->left->node,
|
||||
0, side_y);
|
||||
|
||||
wlr_scene_rect_set_size(subtree->right,
|
||||
theme->border_width, side_height);
|
||||
wlr_scene_node_set_position(&subtree->right->node,
|
||||
theme->border_width + width, side_y);
|
||||
|
||||
wlr_scene_rect_set_size(subtree->bottom,
|
||||
full_width, theme->border_width);
|
||||
wlr_scene_node_set_position(&subtree->bottom->node,
|
||||
0, height);
|
||||
|
||||
wlr_scene_rect_set_size(subtree->top,
|
||||
top_width, theme->border_width);
|
||||
wlr_scene_node_set_position(&subtree->top->node,
|
||||
top_x, -(ssd->titlebar.height + theme->border_width));
|
||||
if (theme->window[active].border_type) {
|
||||
renderBufferset(subtree->textured_borders, full_width,
|
||||
side_height+(ssd->titlebar.height + 2*theme->border_width),
|
||||
-ssd->titlebar.height-theme->border_width);
|
||||
} else {
|
||||
wlr_scene_rect_set_size(subtree->left,
|
||||
theme->border_width, side_height);
|
||||
wlr_scene_node_set_position(&subtree->left->node,
|
||||
0, side_y);
|
||||
wlr_scene_rect_set_size(subtree->right,
|
||||
theme->border_width, side_height);
|
||||
wlr_scene_node_set_position(&subtree->right->node,
|
||||
theme->border_width + width, side_y);
|
||||
wlr_scene_rect_set_size(subtree->bottom,
|
||||
full_width, theme->border_width);
|
||||
wlr_scene_node_set_position(&subtree->bottom->node,
|
||||
0, height);
|
||||
wlr_scene_rect_set_size(subtree->top,
|
||||
top_width, 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 "theme.h"
|
||||
#include "view.h"
|
||||
#include "common/borderset.h"
|
||||
|
||||
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);
|
||||
|
|
@ -36,6 +37,7 @@ ssd_titlebar_create(struct ssd *ssd)
|
|||
LAB_NODE_TITLEBAR, view, /*data*/ NULL);
|
||||
|
||||
enum ssd_active_state active;
|
||||
bool should_force_update = FALSE;
|
||||
FOR_EACH_ACTIVE_STATE(active) {
|
||||
struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[active];
|
||||
subtree->tree = lab_wlr_scene_tree_create(ssd->titlebar.tree);
|
||||
|
|
@ -52,6 +54,30 @@ ssd_titlebar_create(struct ssd *ssd)
|
|||
|
||||
/* Background */
|
||||
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
|
||||
* becomes translucent when bilinear filtering is used.
|
||||
|
|
@ -73,9 +99,17 @@ ssd_titlebar_create(struct ssd *ssd)
|
|||
width - corner_width, -rc.theme->border_width);
|
||||
|
||||
/* Title */
|
||||
subtree->title = scaled_font_buffer_create_for_titlebar(
|
||||
subtree->tree, theme->titlebar_height,
|
||||
theme->window[active].titlebar_pattern);
|
||||
if (theme->window[active].title_bg.border_type) {
|
||||
// Use a blank background pattern so it doesn't overlay
|
||||
// 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);
|
||||
node_descriptor_create(&subtree->title->scene_buffer->node,
|
||||
LAB_NODE_TITLE, view, /*data*/ NULL);
|
||||
|
|
@ -122,7 +156,10 @@ ssd_titlebar_create(struct ssd *ssd)
|
|||
if (squared) {
|
||||
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) {
|
||||
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) {
|
||||
set_alt_button_icon(ssd, LAB_NODE_BUTTON_OMNIPRESENT, true);
|
||||
}
|
||||
|
||||
if (should_force_update) {
|
||||
ssd_titlebar_update(ssd);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -280,7 +321,10 @@ ssd_titlebar_update(struct ssd *ssd)
|
|||
|
||||
if (ssd->state.was_maximized != maximized
|
||||
|| 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) {
|
||||
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 */
|
||||
int y = (theme->titlebar_height - theme->window_button_height) / 2;
|
||||
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;
|
||||
FOR_EACH_ACTIVE_STATE(active) {
|
||||
|
|
@ -318,10 +366,14 @@ ssd_titlebar_update(struct ssd *ssd)
|
|||
|
||||
x = theme->window_titlebar_padding_width;
|
||||
struct ssd_button *button;
|
||||
int button_count = 0;
|
||||
|
||||
wl_list_for_each(button, &subtree->buttons_left, link) {
|
||||
wlr_scene_node_set_position(button->node, x, y);
|
||||
x += theme->window_button_width + theme->window_button_spacing;
|
||||
button_count++;
|
||||
}
|
||||
int exclusive_x = x;
|
||||
|
||||
x = width - corner_width;
|
||||
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) {
|
||||
x -= theme->window_button_width + theme->window_button_spacing;
|
||||
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);
|
||||
}
|
||||
|
||||
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 */
|
||||
static void
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
* rounded variants.
|
||||
|
|
@ -450,6 +548,28 @@ parse_hexstrs(const char *hexes, float colors[3][4])
|
|||
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
|
||||
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_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_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_INACTIVE].label_text_color);
|
||||
|
|
@ -581,6 +723,8 @@ theme_builtin(struct theme *theme)
|
|||
theme->menu_max_width = 200;
|
||||
theme->menu_border_width = INT_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_y = 4;
|
||||
|
|
@ -588,6 +732,12 @@ theme_builtin(struct theme *theme)
|
|||
parse_hexstr("#000000", theme->menu_items_text_color);
|
||||
parse_hexstr("#e1dedb", theme->menu_items_active_bg_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_padding_width = 6;
|
||||
|
|
@ -633,6 +783,8 @@ theme_builtin(struct theme *theme)
|
|||
theme->osd_border_width = INT_MIN;
|
||||
theme->osd_border_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)) {
|
||||
/* 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(
|
||||
value, "border.width");
|
||||
}
|
||||
|
||||
if (match_glob(key, "window.titlebar.padding.width")) {
|
||||
theme->window_titlebar_padding_width = get_int_if_positive(
|
||||
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");
|
||||
}
|
||||
|
||||
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")) {
|
||||
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")) {
|
||||
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 */
|
||||
if (match_glob(key, "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")) {
|
||||
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")) {
|
||||
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");
|
||||
}
|
||||
|
||||
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 */
|
||||
if (match_glob(key, "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);
|
||||
}
|
||||
|
||||
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")) {
|
||||
theme->menu_items_padding_x = get_int_if_positive(
|
||||
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")) {
|
||||
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")) {
|
||||
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);
|
||||
}
|
||||
|
||||
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")) {
|
||||
theme->menu_separator_line_thickness = get_int_if_positive(
|
||||
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);
|
||||
}
|
||||
|
||||
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")) {
|
||||
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")) {
|
||||
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 */
|
||||
if (match_glob(key, "osd.window-switcher.style-classic.width")
|
||||
|| match_glob(key, "osd.window-switcher.width")) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "common/scene-helpers.h"
|
||||
#include "config/rcxml.h"
|
||||
#include "input/keyboard.h"
|
||||
#include "common/borderset.h"
|
||||
#include "labwc.h"
|
||||
#include "output.h"
|
||||
#include "theme.h"
|
||||
|
|
@ -96,18 +97,73 @@ _osd_update(void)
|
|||
|
||||
cairo = cairo_create(buffer->surface);
|
||||
|
||||
int bw = theme->osd_border_width;
|
||||
/* Background */
|
||||
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);
|
||||
|
||||
/* Border */
|
||||
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);
|
||||
if (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];
|
||||
|
||||
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 */
|
||||
uint16_t x;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue