mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
Support png buttons
In the theme directory add close-{active,inactive}.png instead of
close.xbm - and similarly for iconify, menu and max.
This commit is contained in:
parent
eca98a9b6e
commit
a6a03daae3
7 changed files with 138 additions and 11 deletions
|
|
@ -18,7 +18,8 @@ searched for in the following order:
|
||||||
Choosing a theme is done by editing the <name> key in the <theme> section of
|
Choosing a theme is done by editing the <name> key in the <theme> section of
|
||||||
the rc.xml configuration file (labwc-config(5)).
|
the rc.xml configuration file (labwc-config(5)).
|
||||||
|
|
||||||
A theme consists of a themerc file and optionally some xbm icons.
|
A theme consists of a themerc file and optionally some titlebar icons (referred
|
||||||
|
to as buttons).
|
||||||
|
|
||||||
Theme settings specified in themerc can be overridden by creating a
|
Theme settings specified in themerc can be overridden by creating a
|
||||||
'themerc-override' file in the configuration directory, which is normally
|
'themerc-override' file in the configuration directory, which is normally
|
||||||
|
|
@ -175,19 +176,26 @@ elements are not listed here, but are supported.
|
||||||
|
|
||||||
# BUTTONS
|
# BUTTONS
|
||||||
|
|
||||||
The images used for the titlebar buttons are 1-bit xbm (X Bitmaps). These are
|
The images used for the titlebar icons are referred to as buttons.
|
||||||
masks where 0=clear and 1=colored. The xbm image files are placed in the same
|
|
||||||
directory within your theme as the themerc file. Here are all the possible xbm
|
The image formats listed below are supported. They are listed in order of
|
||||||
files looked for:
|
precedence, where the first format in the list is searched for first.
|
||||||
|
|
||||||
|
- png
|
||||||
|
- xbm
|
||||||
|
|
||||||
|
By default, buttons are 1-bit xbm (X Bitmaps). These are masks where 0=clear and
|
||||||
|
1=colored. The xbm image files are placed in the same directory as the themerc
|
||||||
|
file within a particular theme. The following xbm buttons are supported:
|
||||||
|
|
||||||
- max.xbm
|
- max.xbm
|
||||||
- iconify.xbm
|
- iconify.xbm
|
||||||
- close.xbm
|
- close.xbm
|
||||||
- menu.xbm
|
- menu.xbm
|
||||||
|
|
||||||
More will be supported later.
|
One advantage of xbm buttons over other formats is that they change color based
|
||||||
|
on the theme. Other formats use the suffices "-active" and "-inactive" to align
|
||||||
Note: menu.xbm is not part of openbox-3.6 spec
|
with the respective titlebar colors. For example: "close-active.png"
|
||||||
|
|
||||||
# DEFINITIONS
|
# DEFINITIONS
|
||||||
|
|
||||||
|
|
|
||||||
9
include/button-png.h
Normal file
9
include/button-png.h
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#ifndef LABWC_BUTTON_PNG_H
|
||||||
|
#define LABWC_BUTTON_PNG_H
|
||||||
|
|
||||||
|
struct lab_data_buffer;
|
||||||
|
|
||||||
|
void png_load(const char *filename, struct lab_data_buffer **buffer);
|
||||||
|
|
||||||
|
#endif /* LABWC_BUTTON_PNG_H */
|
||||||
|
|
@ -69,6 +69,7 @@ cairo = dependency('cairo')
|
||||||
pangocairo = dependency('pangocairo')
|
pangocairo = dependency('pangocairo')
|
||||||
input = dependency('libinput', version: '>=1.14')
|
input = dependency('libinput', version: '>=1.14')
|
||||||
math = cc.find_library('m')
|
math = cc.find_library('m')
|
||||||
|
png = dependency('libpng')
|
||||||
|
|
||||||
if get_option('xwayland').enabled() and not wlroots_has_xwayland
|
if get_option('xwayland').enabled() and not wlroots_has_xwayland
|
||||||
error('no wlroots Xwayland support')
|
error('no wlroots Xwayland support')
|
||||||
|
|
@ -103,6 +104,7 @@ labwc_deps = [
|
||||||
pangocairo,
|
pangocairo,
|
||||||
input,
|
input,
|
||||||
math,
|
math,
|
||||||
|
png,
|
||||||
]
|
]
|
||||||
|
|
||||||
subdir('include')
|
subdir('include')
|
||||||
|
|
|
||||||
91
src/button-png.c
Normal file
91
src/button-png.c
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (C) Johan Malm 2023
|
||||||
|
*/
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <png.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "button-png.h"
|
||||||
|
#include "common/dir.h"
|
||||||
|
#include "labwc.h"
|
||||||
|
#include "theme.h"
|
||||||
|
|
||||||
|
/* Share with session.c:isfile() */
|
||||||
|
static bool
|
||||||
|
file_exists(const char *path)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return (!stat(path, &st));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Share with xbm.c:xbm_path() */
|
||||||
|
static char *
|
||||||
|
button_path(const char *filename)
|
||||||
|
{
|
||||||
|
static char buffer[4096] = { 0 };
|
||||||
|
snprintf(buffer, sizeof(buffer), "%s/%s", theme_dir(rc.theme_name), filename);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cairo_image_surface_create_from_png() does not gracefully handle non-png
|
||||||
|
* files, so we verify the header before trying to read the rest of the file.
|
||||||
|
*/
|
||||||
|
#define PNG_BYTES_TO_CHECK (4)
|
||||||
|
static bool
|
||||||
|
ispng(const char *filename)
|
||||||
|
{
|
||||||
|
unsigned char header[PNG_BYTES_TO_CHECK];
|
||||||
|
FILE *fp = fopen(filename, "rb");
|
||||||
|
if (!fp) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fread(header, 1, PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK) {
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (png_sig_cmp(header, (png_size_t)0, PNG_BYTES_TO_CHECK)) {
|
||||||
|
wlr_log(WLR_ERROR, "file '%s' is not a recognised png file", filename);
|
||||||
|
fclose(fp);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef PNG_BYTES_TO_CHECK
|
||||||
|
|
||||||
|
void
|
||||||
|
png_load(const char *filename, struct lab_data_buffer **buffer)
|
||||||
|
{
|
||||||
|
if (*buffer) {
|
||||||
|
wlr_buffer_drop(&(*buffer)->base);
|
||||||
|
*buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *path = button_path(filename);
|
||||||
|
if (!file_exists(path) || !ispng(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_t *image = cairo_image_surface_create_from_png(path);
|
||||||
|
if (cairo_surface_status(image)) {
|
||||||
|
wlr_log(WLR_ERROR, "error reading png button '%s'", path);
|
||||||
|
cairo_surface_destroy(image);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cairo_surface_flush(image);
|
||||||
|
|
||||||
|
double w = cairo_image_surface_get_width(image);
|
||||||
|
double h = cairo_image_surface_get_height(image);
|
||||||
|
*buffer = buffer_create_cairo((int)w, (int)h, 1.0, true);
|
||||||
|
cairo_t *cairo = (*buffer)->cairo;
|
||||||
|
cairo_set_source_surface(cairo, image, 0, 0);
|
||||||
|
cairo_paint_with_alpha(cairo, 1.0);
|
||||||
|
}
|
||||||
|
|
@ -15,6 +15,7 @@ labwc_sources = files(
|
||||||
'node.c',
|
'node.c',
|
||||||
'osd.c',
|
'osd.c',
|
||||||
'output.c',
|
'output.c',
|
||||||
|
'button-png.c',
|
||||||
'regions.c',
|
'regions.c',
|
||||||
'resistance.c',
|
'resistance.c',
|
||||||
'seat.c',
|
'seat.c',
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ ssd_titlebar_create(struct ssd *ssd)
|
||||||
corner_top_right = &theme->corner_top_right_inactive_normal->base;
|
corner_top_right = &theme->corner_top_right_inactive_normal->base;
|
||||||
menu_button_unpressed = &theme->button_menu_inactive_unpressed->base;
|
menu_button_unpressed = &theme->button_menu_inactive_unpressed->base;
|
||||||
iconify_button_unpressed = &theme->button_iconify_inactive_unpressed->base;
|
iconify_button_unpressed = &theme->button_iconify_inactive_unpressed->base;
|
||||||
maximize_button_unpressed = &theme->button_maximize_inactive_unpressed->base;
|
maximize_button_unpressed =
|
||||||
|
&theme->button_maximize_inactive_unpressed->base;
|
||||||
close_button_unpressed = &theme->button_close_inactive_unpressed->base;
|
close_button_unpressed = &theme->button_close_inactive_unpressed->base;
|
||||||
wlr_scene_node_set_enabled(&parent->node, false);
|
wlr_scene_node_set_enabled(&parent->node, false);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/theme.c
19
src/theme.c
|
|
@ -24,6 +24,7 @@
|
||||||
#include "common/match.h"
|
#include "common/match.h"
|
||||||
#include "common/string-helpers.h"
|
#include "common/string-helpers.h"
|
||||||
#include "config/rcxml.h"
|
#include "config/rcxml.h"
|
||||||
|
#include "button-png.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "xbm/xbm.h"
|
#include "xbm/xbm.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
@ -95,9 +96,23 @@ load_buttons(struct theme *theme)
|
||||||
char filename[4096] = {0};
|
char filename[4096] = {0};
|
||||||
for (size_t i = 0; i < sizeof(buttons) / sizeof(buttons[0]); ++i) {
|
for (size_t i = 0; i < sizeof(buttons) / sizeof(buttons[0]); ++i) {
|
||||||
struct button *b = &buttons[i];
|
struct button *b = &buttons[i];
|
||||||
|
|
||||||
|
/* Try png icon first */
|
||||||
|
snprintf(filename, sizeof(filename), "%s-active.png", b->name);
|
||||||
|
png_load(filename, b->active.buffer);
|
||||||
|
snprintf(filename, sizeof(filename), "%s-inactive.png", b->name);
|
||||||
|
png_load(filename, b->inactive.buffer);
|
||||||
|
|
||||||
|
/* If there were no png buttons, use xbm */
|
||||||
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
|
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
|
||||||
xbm_load_button(filename, b->active.buffer, b->fallback_button, b->active.rgba);
|
if (!*b->active.buffer) {
|
||||||
xbm_load_button(filename, b->inactive.buffer, b->fallback_button, b->inactive.rgba);
|
xbm_load_button(filename, b->active.buffer,
|
||||||
|
b->fallback_button, b->active.rgba);
|
||||||
|
}
|
||||||
|
if (!*b->inactive.buffer) {
|
||||||
|
xbm_load_button(filename, b->inactive.buffer,
|
||||||
|
b->fallback_button, b->inactive.rgba);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue