Height of boxes in workspace switcher in pixels. Setting to 0 disables
boxes. Default is 20.
-*snapping.overlay.region.fill* [yes|no]
+*snapping.overlay.region.bg.enabled* [yes|no]
Show a filled rectangle as an overlay when a window is snapped to a region.
- Otherwise, an outlined rectangle is shown instead.
- If software rendering is used, an outlined rectangle is always shown.
+ Default is yes for hardware-based renderers and no for software-based
+ renderers.
-*snapping.overlay.edge.fill* [yes|no]
+*snapping.overlay.edge.bg.enabled* [yes|no]
Show a filled rectangle as an overlay when a window is snapped to an edge.
- Otherwise, an outlined rectangle is shown instead.
- If software rendering is used, an outlined rectangle is always shown.
+ Default is yes for hardware-based renderer and no for software-based
+ renderers.
+
+*snapping.overlay.region.border.enabled* [yes|no]
+ Show an outlined rectangle as an overlay when a window is snapped to a
+ region. Default is no for hardware-based renderers and yes for software-based
+ renderers.
+
+*snapping.overlay.edge.border.enabled* [yes|no]
+ Show an outlined rectangle as an overlay when a window is snapped to an edge.
+ Default is no for hardware-based renderer and yes for software-based
+ renderers.
*snapping.overlay.region.bg.color*
Color of a filled rectangle shown as an overlay when a window is snapped to
osd.workspace-switcher.boxes.width: 20
osd.workspace-switcher.boxes.height: 20
-snapping.overlay.region.fill: yes
-snapping.overlay.edge.fill: yes
+# Default values for following options change depending on the rendering
+# backend. For software-based renderers, *.bg.enabled is "no" and
+# *.border.enabled is "yes" if not set. For hardware-based renderers,
+# *.bg.enabled is "yes" and *.border.enabled is "no" if not set.
+# Setting *.bg.enabled to "yes" for software-based renderer with translucent
+# background color may severely impact performance.
+#
+# snapping.overlay.region.bg.enabled:
+# snapping.overlay.edge.bg.enabled:
+# snapping.overlay.region.border.enabled:
+# snapping.overlay.edge.border.enabled:
+
snapping.overlay.region.bg.color: #8080b380
snapping.overlay.edge.bg.color: #8080b380
snapping.overlay.region.border.width: 1
#include "view.h"
struct overlay_rect {
- struct wlr_scene_node *node;
- bool fill;
- union {
- /* if fill is true */
- struct wlr_scene_rect *scene_rect;
- /* if fill is false */
- struct multi_rect *pixman_rect;
- };
+ struct wlr_scene_tree *tree;
+
+ bool bg_enabled;
+ struct wlr_scene_rect *bg_rect;
+
+ bool border_enabled;
+ struct multi_rect *border_rect;
};
struct overlay {
LAB_JUSTIFY_RIGHT,
};
+struct theme_snapping_overlay {
+ bool bg_enabled;
+ bool border_enabled;
+ float bg_color[4];
+ int border_width;
+ float border_color[3][4];
+};
+
struct theme {
int border_width;
int padding_height;
int osd_workspace_switcher_boxes_width;
int osd_workspace_switcher_boxes_height;
- bool snapping_overlay_region_fill;
- bool snapping_overlay_edge_fill;
-
- float snapping_overlay_region_bg_color[4];
- float snapping_overlay_edge_bg_color[4];
-
- int snapping_overlay_region_border_width;
- int snapping_overlay_edge_border_width;
- float snapping_overlay_region_border_color[3][4];
- float snapping_overlay_edge_border_color[3][4];
+ struct theme_snapping_overlay
+ snapping_overlay_region, snapping_overlay_edge;
/* textures */
struct lab_data_buffer *button_close_active_unpressed;
int osd_window_switcher_item_height;
};
+struct server;
+
/**
* theme_init - read openbox theme and generate button textures
* @theme: theme data
+ * @server: server
* @theme_name: theme-name in <theme-dir>/<theme-name>/openbox-3/themerc
* Note <theme-dir> is obtained in theme-dir.c
*/
-void theme_init(struct theme *theme, const char *theme_name);
+void theme_init(struct theme *theme, struct server *server, const char *theme_name);
/**
* theme_finish - free button textures
if (node == &server->seat.drag.icons->node) {
return "seat->drag.icons";
}
- if (server->seat.overlay.region_rect.node
- && node == server->seat.overlay.region_rect.node) {
+ if (server->seat.overlay.region_rect.tree
+ && node == &server->seat.overlay.region_rect.tree->node) {
/* Created on-demand */
return "seat->overlay.region_rect";
}
- if (server->seat.overlay.edge_rect.node
- && node == server->seat.overlay.edge_rect.node) {
+ if (server->seat.overlay.edge_rect.tree
+ && node == &server->seat.overlay.edge_rect.tree->node) {
/* Created on-demand */
return "seat->overlay.edge_rect";
}
}
printf("%.*s %*c %4d %4d [%p]\n", max_width - 1, type, padding, ' ', x, y, node);
+ struct multi_rect *osd_preview_outline =
+ server->osd_state.preview_outline;
+ struct multi_rect *region_snapping_overlay_outline =
+ server->seat.overlay.region_rect.border_rect;
+ struct multi_rect *edge_snapping_overlay_outline =
+ server->seat.overlay.edge_rect.border_rect;
if ((IGNORE_MENU && node == &server->menu_tree->node)
|| (IGNORE_SSD && last_view
&& ssd_debug_is_root_node(last_view->ssd, node))
- || (IGNORE_OSD_PREVIEW_OUTLINE && server->osd_state.preview_outline
- && node == &server->osd_state.preview_outline->tree->node)
- || (IGNORE_SNAPPING_PREVIEW_OUTLINE && server->seat.overlay.region_rect.node
- && !server->seat.overlay.region_rect.fill
- && node == server->seat.overlay.region_rect.node)
- || (IGNORE_SNAPPING_PREVIEW_OUTLINE && server->seat.overlay.edge_rect.node
- && !server->seat.overlay.edge_rect.fill
- && node == server->seat.overlay.edge_rect.node)) {
+ || (IGNORE_OSD_PREVIEW_OUTLINE && osd_preview_outline
+ && node == &osd_preview_outline->tree->node)
+ || (IGNORE_SNAPPING_PREVIEW_OUTLINE
+ && region_snapping_overlay_outline
+ && node == ®ion_snapping_overlay_outline->tree->node)
+ || (IGNORE_SNAPPING_PREVIEW_OUTLINE
+ && edge_snapping_overlay_outline
+ && node == &edge_snapping_overlay_outline->tree->node)) {
printf("%*c%s\n", pos + 4 + INDENT_SIZE, ' ', "<skipping children>");
return;
}
server_start(&server);
struct theme theme = { 0 };
- theme_init(&theme, rc.theme_name);
+ theme_init(&theme, &server, rc.theme_name);
rc.theme = &theme;
server.theme = &theme;
// SPDX-License-Identifier: GPL-2.0-only
#include <assert.h>
-#include <wlr/render/pixman.h>
#include "labwc.h"
#include "overlay.h"
#include "view.h"
+#include "theme.h"
static void
-create_overlay_rect(struct seat *seat, struct overlay_rect *rect, int fill,
- float bg_color[4], int border_width, float border_colors[3][4])
+create_overlay_rect(struct seat *seat, struct overlay_rect *rect,
+ struct theme_snapping_overlay *theme)
{
struct server *server = seat->server;
- rect->fill = fill;
- /* For pixman renderer, always render outlines to save CPU resource */
- if (wlr_renderer_is_pixman(server->renderer)) {
- rect->fill = false;
- }
+ rect->bg_enabled = theme->bg_enabled;
+ rect->border_enabled = theme->border_enabled;
+ rect->tree = wlr_scene_tree_create(&server->scene->tree);
- if (rect->fill) {
+ if (rect->bg_enabled) {
/* Create a filled rectangle */
- rect->scene_rect = wlr_scene_rect_create(&server->scene->tree,
- 0, 0, bg_color);
- rect->node = &rect->scene_rect->node;
- } else {
+ rect->bg_rect = wlr_scene_rect_create(
+ rect->tree, 0, 0, theme->bg_color);
+ }
+
+ if (rect->border_enabled) {
/* Create outlines */
float *colors[3] = {
- border_colors[0],
- border_colors[1],
- border_colors[2],
+ theme->border_color[0],
+ theme->border_color[1],
+ theme->border_color[2],
};
- rect->pixman_rect = multi_rect_create(&server->scene->tree,
- colors, border_width);
- rect->node = &rect->pixman_rect->tree->node;
+ rect->border_rect = multi_rect_create(
+ rect->tree, colors, theme->border_width);
}
- wlr_scene_node_set_enabled(rect->node, false);
+ wlr_scene_node_set_enabled(&rect->tree->node, false);
}
void overlay_reconfigure(struct seat *seat)
{
- if (seat->overlay.region_rect.node) {
- wlr_scene_node_destroy(seat->overlay.region_rect.node);
+ if (seat->overlay.region_rect.tree) {
+ wlr_scene_node_destroy(&seat->overlay.region_rect.tree->node);
}
- if (seat->overlay.edge_rect.node) {
- wlr_scene_node_destroy(seat->overlay.edge_rect.node);
+ if (seat->overlay.edge_rect.tree) {
+ wlr_scene_node_destroy(&seat->overlay.edge_rect.tree->node);
}
struct theme *theme = seat->server->theme;
create_overlay_rect(seat, &seat->overlay.region_rect,
- theme->snapping_overlay_region_fill,
- theme->snapping_overlay_region_bg_color,
- theme->snapping_overlay_region_border_width,
- theme->snapping_overlay_region_border_color);
+ &theme->snapping_overlay_region);
create_overlay_rect(seat, &seat->overlay.edge_rect,
- theme->snapping_overlay_edge_fill,
- theme->snapping_overlay_edge_bg_color,
- theme->snapping_overlay_edge_border_width,
- theme->snapping_overlay_edge_border_color);
+ &theme->snapping_overlay_edge);
}
static void
struct server *server = seat->server;
struct view *view = server->grabbed_view;
assert(view);
- struct wlr_scene_node *node = rect->node;
- if (!node) {
+ if (!rect->tree) {
overlay_reconfigure(seat);
- node = rect->node;
- assert(node);
+ assert(rect->tree);
}
- if (rect->fill) {
- wlr_scene_rect_set_size(rect->scene_rect, box->width, box->height);
- } else {
- multi_rect_set_size(rect->pixman_rect, box->width, box->height);
+ if (rect->bg_enabled) {
+ wlr_scene_rect_set_size(rect->bg_rect, box->width, box->height);
+ }
+ if (rect->border_enabled) {
+ multi_rect_set_size(rect->border_rect, box->width, box->height);
}
+ struct wlr_scene_node *node = &rect->tree->node;
wlr_scene_node_reparent(node, view->scene_tree->node.parent);
wlr_scene_node_place_below(node, &view->scene_tree->node);
wlr_scene_node_set_position(node, box->x, box->y);
static void
inactivate_overlay(struct overlay *overlay)
{
- if (overlay->region_rect.node) {
+ if (overlay->region_rect.tree) {
wlr_scene_node_set_enabled(
- overlay->region_rect.node, false);
+ &overlay->region_rect.tree->node, false);
}
- if (overlay->edge_rect.node) {
+ if (overlay->edge_rect.tree) {
wlr_scene_node_set_enabled(
- overlay->edge_rect.node, false);
+ &overlay->edge_rect.tree->node, false);
}
overlay->active.region = NULL;
overlay->active.edge = VIEW_EDGE_INVALID;
* Reparent the rectangle nodes to server's scene-tree so they don't
* get destroyed on view destruction
*/
- if (overlay->region_rect.node) {
- wlr_scene_node_reparent(overlay->region_rect.node,
+ if (overlay->region_rect.tree) {
+ wlr_scene_node_reparent(&overlay->region_rect.tree->node,
&server->scene->tree);
}
- if (overlay->edge_rect.node) {
- wlr_scene_node_reparent(overlay->edge_rect.node,
+ if (overlay->edge_rect.tree) {
+ wlr_scene_node_reparent(&overlay->edge_rect.tree->node,
&server->scene->tree);
}
}
rcxml_finish();
rcxml_read(rc.config_file);
theme_finish(server->theme);
- theme_init(server->theme, rc.theme_name);
+ theme_init(server->theme, server, rc.theme_name);
struct view *view;
wl_list_for_each(view, &server->views, link) {
#include <string.h>
#include <wlr/util/box.h>
#include <wlr/util/log.h>
+#include <wlr/render/pixman.h>
#include <strings.h>
#include "common/macros.h"
#include "common/dir.h"
#include "common/string-helpers.h"
#include "config/rcxml.h"
#include "button/button-png.h"
+#include "labwc.h"
#if HAVE_RSVG
#include "button/button-svg.h"
* theme_builtin() applies a theme that is similar to vanilla GTK
*/
static void
-theme_builtin(struct theme *theme)
+theme_builtin(struct theme *theme, struct server *server)
{
theme->border_width = 1;
theme->padding_height = 3;
theme->osd_border_color[0] = FLT_MIN;
theme->osd_label_text_color[0] = FLT_MIN;
- theme->snapping_overlay_region_fill = true;
- theme->snapping_overlay_edge_fill = true;
+ if (wlr_renderer_is_pixman(server->renderer)) {
+ /* Draw only outlined overlay by default to save CPU resource */
+ theme->snapping_overlay_region.bg_enabled = false;
+ theme->snapping_overlay_edge.bg_enabled = false;
+ theme->snapping_overlay_region.border_enabled = true;
+ theme->snapping_overlay_edge.border_enabled = true;
+ } else {
+ theme->snapping_overlay_region.bg_enabled = true;
+ theme->snapping_overlay_edge.bg_enabled = true;
+ theme->snapping_overlay_region.border_enabled = false;
+ theme->snapping_overlay_edge.border_enabled = false;
+ }
- parse_hexstr("#8080b380", theme->snapping_overlay_region_bg_color);
- parse_hexstr("#8080b380", theme->snapping_overlay_edge_bg_color);
+ parse_hexstr("#8080b380", theme->snapping_overlay_region.bg_color);
+ parse_hexstr("#8080b380", theme->snapping_overlay_edge.bg_color);
/* inherit settings in post_processing() if not set elsewhere */
- theme->snapping_overlay_region_border_width = INT_MIN;
- theme->snapping_overlay_edge_border_width = INT_MIN;
- memset(theme->snapping_overlay_region_border_color, 0,
- sizeof(theme->snapping_overlay_region_border_color));
- theme->snapping_overlay_region_border_color[0][0] = FLT_MIN;
- memset(theme->snapping_overlay_edge_border_color, 0,
- sizeof(theme->snapping_overlay_edge_border_color));
- theme->snapping_overlay_edge_border_color[0][0] = FLT_MIN;
+ theme->snapping_overlay_region.border_width = INT_MIN;
+ theme->snapping_overlay_edge.border_width = INT_MIN;
+ memset(theme->snapping_overlay_region.border_color, 0,
+ sizeof(theme->snapping_overlay_region.border_color));
+ theme->snapping_overlay_region.border_color[0][0] = FLT_MIN;
+ memset(theme->snapping_overlay_edge.border_color, 0,
+ sizeof(theme->snapping_overlay_edge.border_color));
+ theme->snapping_overlay_edge.border_color[0][0] = FLT_MIN;
}
static void
if (match_glob(key, "osd.label.text.color")) {
parse_hexstr(value, theme->osd_label_text_color);
}
- if (match_glob(key, "snapping.overlay.region.fill")) {
- theme->snapping_overlay_region_fill = parse_bool(value, true);
+ if (match_glob(key, "snapping.overlay.region.bg.enabled")) {
+ set_bool(value, &theme->snapping_overlay_region.bg_enabled);
+ }
+ if (match_glob(key, "snapping.overlay.edge.bg.enabled")) {
+ set_bool(value, &theme->snapping_overlay_edge.bg_enabled);
+ }
+ if (match_glob(key, "snapping.overlay.region.border.enabled")) {
+ set_bool(value, &theme->snapping_overlay_region.border_enabled);
}
- if (match_glob(key, "snapping.overlay.edge.fill")) {
- theme->snapping_overlay_edge_fill = parse_bool(value, true);
+ if (match_glob(key, "snapping.overlay.edge.border.enabled")) {
+ set_bool(value, &theme->snapping_overlay_edge.border_enabled);
}
if (match_glob(key, "snapping.overlay.region.bg.color")) {
- parse_hexstr(value, theme->snapping_overlay_region_bg_color);
+ parse_hexstr(value, theme->snapping_overlay_region.bg_color);
}
if (match_glob(key, "snapping.overlay.edge.bg.color")) {
- parse_hexstr(value, theme->snapping_overlay_edge_bg_color);
+ parse_hexstr(value, theme->snapping_overlay_edge.bg_color);
}
if (match_glob(key, "snapping.overlay.region.border.width")) {
- theme->snapping_overlay_region_border_width = atoi(value);
+ theme->snapping_overlay_region.border_width = atoi(value);
}
if (match_glob(key, "snapping.overlay.edge.border.width")) {
- theme->snapping_overlay_edge_border_width = atoi(value);
+ theme->snapping_overlay_edge.border_width = atoi(value);
}
if (match_glob(key, "snapping.overlay.region.border.color")) {
- parse_hexstrs(value, theme->snapping_overlay_region_border_color);
+ parse_hexstrs(value, theme->snapping_overlay_region.border_color);
}
if (match_glob(key, "snapping.overlay.edge.border.color")) {
- parse_hexstrs(value, theme->snapping_overlay_edge_border_color);
+ parse_hexstrs(value, theme->snapping_overlay_edge.border_color);
}
}
theme->osd_window_switcher_preview_border_color);
}
- if (theme->snapping_overlay_region_border_width == INT_MIN) {
- theme->snapping_overlay_region_border_width =
+ if (theme->snapping_overlay_region.border_width == INT_MIN) {
+ theme->snapping_overlay_region.border_width =
theme->osd_border_width;
}
- if (theme->snapping_overlay_edge_border_width == INT_MIN) {
- theme->snapping_overlay_edge_border_width =
+ if (theme->snapping_overlay_edge.border_width == INT_MIN) {
+ theme->snapping_overlay_edge.border_width =
theme->osd_border_width;
}
- if (theme->snapping_overlay_region_border_color[0][0] == FLT_MIN) {
+ if (theme->snapping_overlay_region.border_color[0][0] == FLT_MIN) {
fill_colors_with_osd_theme(theme,
- theme->snapping_overlay_region_border_color);
+ theme->snapping_overlay_region.border_color);
}
- if (theme->snapping_overlay_edge_border_color[0][0] == FLT_MIN) {
+ if (theme->snapping_overlay_edge.border_color[0][0] == FLT_MIN) {
fill_colors_with_osd_theme(theme,
- theme->snapping_overlay_edge_border_color);
+ theme->snapping_overlay_edge.border_color);
}
}
void
-theme_init(struct theme *theme, const char *theme_name)
+theme_init(struct theme *theme, struct server *server, const char *theme_name)
{
/*
* Set some default values. This is particularly important on
* reconfigure as not all themes set all options
*/
- theme_builtin(theme);
+ theme_builtin(theme, server);
/* Read <data-dir>/share/themes/$theme_name/openbox-3/themerc */
struct wl_list paths;