mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
Support svg buttons
In the theme directory add close-{active,inactive}.svg instead of
close.xbm - and similarly for iconify, menu and max.
This commit is contained in:
parent
a386133068
commit
c62df26c2a
10 changed files with 137 additions and 5 deletions
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
|
|
@ -67,7 +67,7 @@ jobs:
|
||||||
pacman-key --init
|
pacman-key --init
|
||||||
pacman -Syu --noconfirm
|
pacman -Syu --noconfirm
|
||||||
pacman -S --noconfirm git meson clang wlroots libdrm libinput \
|
pacman -S --noconfirm git meson clang wlroots libdrm libinput \
|
||||||
wayland-protocols cairo pango libxml2 xorg-xwayland
|
wayland-protocols cairo pango libxml2 xorg-xwayland librsvg
|
||||||
|
|
||||||
- name: Install Debian Testing dependencies
|
- name: Install Debian Testing dependencies
|
||||||
if: matrix.name == 'Debian'
|
if: matrix.name == 'Debian'
|
||||||
|
|
@ -77,7 +77,8 @@ jobs:
|
||||||
apt-get upgrade -y
|
apt-get upgrade -y
|
||||||
apt-get install -y git clang \
|
apt-get install -y git clang \
|
||||||
hwdata \
|
hwdata \
|
||||||
libxml2-dev libcairo2-dev libpango1.0-dev
|
libxml2-dev libcairo2-dev libpango1.0-dev \
|
||||||
|
librsvg2-dev
|
||||||
apt-get build-dep -y wlroots
|
apt-get build-dep -y wlroots
|
||||||
|
|
||||||
- name: Install FreeBSD dependencies
|
- name: Install FreeBSD dependencies
|
||||||
|
|
@ -108,6 +109,7 @@ jobs:
|
||||||
xcb-util-cursor-devel xcb-util-devel xcb-util-image-devel \
|
xcb-util-cursor-devel xcb-util-devel xcb-util-image-devel \
|
||||||
xcb-util-keysyms-devel xcb-util-xrm-devel xorg-server-xwayland \
|
xcb-util-keysyms-devel xcb-util-xrm-devel xorg-server-xwayland \
|
||||||
hwids \
|
hwids \
|
||||||
|
librsvg-devel \
|
||||||
libglib-devel cairo-devel pango-devel
|
libglib-devel cairo-devel pango-devel
|
||||||
|
|
||||||
- name: Build with gcc
|
- name: Build with gcc
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,7 @@ Run-time dependencies include:
|
||||||
|
|
||||||
- wlroots, wayland, libinput, xkbcommon
|
- wlroots, wayland, libinput, xkbcommon
|
||||||
- libxml2, cairo, pango, glib-2.0
|
- libxml2, cairo, pango, glib-2.0
|
||||||
|
- libpng, librsvg-2.0
|
||||||
- xwayland, xcb (optional)
|
- xwayland, xcb (optional)
|
||||||
|
|
||||||
Build dependencies include:
|
Build dependencies include:
|
||||||
|
|
|
||||||
|
|
@ -182,6 +182,7 @@ The image formats listed below are supported. They are listed in order of
|
||||||
precedence, where the first format in the list is searched for first.
|
precedence, where the first format in the list is searched for first.
|
||||||
|
|
||||||
- png
|
- png
|
||||||
|
- svg
|
||||||
- xbm
|
- xbm
|
||||||
|
|
||||||
By default, buttons are 1-bit xbm (X Bitmaps). These are masks where 0=clear and
|
By default, buttons are 1-bit xbm (X Bitmaps). These are masks where 0=clear and
|
||||||
|
|
|
||||||
10
include/button/button-svg.h
Normal file
10
include/button/button-svg.h
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
#ifndef LABWC_BUTTON_SVG_H
|
||||||
|
#define LABWC_BUTTON_SVG_H
|
||||||
|
|
||||||
|
struct lab_data_buffer;
|
||||||
|
|
||||||
|
void button_svg_load(const char *button_name, struct lab_data_buffer **buffer,
|
||||||
|
int size);
|
||||||
|
|
||||||
|
#endif /* LABWC_BUTTON_SVG_H */
|
||||||
|
|
@ -70,6 +70,7 @@ 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')
|
png = dependency('libpng')
|
||||||
|
svg = dependency('librsvg-2.0', version: '>=2.46', required: false)
|
||||||
|
|
||||||
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')
|
||||||
|
|
@ -78,6 +79,8 @@ have_xwayland = xcb.found() and wlroots_has_xwayland
|
||||||
conf_data = configuration_data()
|
conf_data = configuration_data()
|
||||||
conf_data.set10('HAVE_XWAYLAND', have_xwayland)
|
conf_data.set10('HAVE_XWAYLAND', have_xwayland)
|
||||||
|
|
||||||
|
conf_data.set10('HAVE_RSVG', svg.found())
|
||||||
|
|
||||||
msgfmt = find_program('msgfmt', required: get_option('nls'))
|
msgfmt = find_program('msgfmt', required: get_option('nls'))
|
||||||
if msgfmt.found()
|
if msgfmt.found()
|
||||||
source_root = meson.current_source_dir()
|
source_root = meson.current_source_dir()
|
||||||
|
|
@ -106,6 +109,11 @@ labwc_deps = [
|
||||||
math,
|
math,
|
||||||
png,
|
png,
|
||||||
]
|
]
|
||||||
|
if svg.found()
|
||||||
|
labwc_deps += [
|
||||||
|
svg,
|
||||||
|
]
|
||||||
|
endif
|
||||||
|
|
||||||
subdir('include')
|
subdir('include')
|
||||||
subdir('src')
|
subdir('src')
|
||||||
|
|
|
||||||
3
scripts/checkpatch.pl
vendored
3
scripts/checkpatch.pl
vendored
|
|
@ -5653,7 +5653,7 @@ sub process {
|
||||||
#Ignore Page<foo> variants
|
#Ignore Page<foo> variants
|
||||||
$var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
|
$var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
|
||||||
|
|
||||||
#Ignore some pango and libxml2 CamelCase variants
|
#labwc-custom check to ignore some pango/libxml2/etc CamelCase variants
|
||||||
$var !~ /^(?:PangoLayout|PangoFontDescription)/ &&
|
$var !~ /^(?:PangoLayout|PangoFontDescription)/ &&
|
||||||
$var !~ /^(?:PangoTabArray|PangoRectangle)/ &&
|
$var !~ /^(?:PangoTabArray|PangoRectangle)/ &&
|
||||||
$var !~ /^(?:PangoWeight|_PangoFontDescription)/ &&
|
$var !~ /^(?:PangoWeight|_PangoFontDescription)/ &&
|
||||||
|
|
@ -5664,6 +5664,7 @@ sub process {
|
||||||
$var !~ /^(?:xmlParseMemory)/ &&
|
$var !~ /^(?:xmlParseMemory)/ &&
|
||||||
$var !~ /^(?:xmlFree)/ &&
|
$var !~ /^(?:xmlFree)/ &&
|
||||||
$var !~ /^(?:GString|GError)/ &&
|
$var !~ /^(?:GString|GError)/ &&
|
||||||
|
$var !~ /^(?:RsvgRectangle|RsvgHandle)/ &&
|
||||||
$var !~ /^(?:XKB_KEY_XF86Switch_VT_1)/ &&
|
$var !~ /^(?:XKB_KEY_XF86Switch_VT_1)/ &&
|
||||||
|
|
||||||
#Ignore SI style variants like nS, mV and dB
|
#Ignore SI style variants like nS, mV and dB
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ png_load(const char *button_name, struct lab_data_buffer **buffer)
|
||||||
|
|
||||||
char path[4096] = { 0 };
|
char path[4096] = { 0 };
|
||||||
button_filename(button_name, path, sizeof(path));
|
button_filename(button_name, path, sizeof(path));
|
||||||
if (!file_exists(path) || !ispng(path)) {
|
if (!ispng(path)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
71
src/button/button-svg.c
Normal file
71
src/button/button-svg.c
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (C) Johan Malm 2023
|
||||||
|
*/
|
||||||
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <librsvg/rsvg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wlr/util/log.h>
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "button/button-svg.h"
|
||||||
|
#include "button/common.h"
|
||||||
|
#include "common/file-helpers.h"
|
||||||
|
#include "labwc.h"
|
||||||
|
#include "theme.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
button_svg_load(const char *button_name, struct lab_data_buffer **buffer,
|
||||||
|
int size)
|
||||||
|
{
|
||||||
|
if (*buffer) {
|
||||||
|
wlr_buffer_drop(&(*buffer)->base);
|
||||||
|
*buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char filename[4096] = { 0 };
|
||||||
|
button_filename(button_name, filename, sizeof(filename));
|
||||||
|
|
||||||
|
GError *err = NULL;
|
||||||
|
RsvgRectangle viewport = { .width = size, .height = size };
|
||||||
|
RsvgHandle *svg = rsvg_handle_new_from_file(filename, &err);
|
||||||
|
if (err) {
|
||||||
|
wlr_log(WLR_DEBUG, "error reading svg %s-%s\n", filename, err->message);
|
||||||
|
g_error_free(err);
|
||||||
|
/*
|
||||||
|
* rsvg_handle_new_from_file() returns NULL if an error occurs,
|
||||||
|
* so there is no need to free svg here.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_surface_t *image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size, size);
|
||||||
|
cairo_t *cr = cairo_create(image);
|
||||||
|
|
||||||
|
rsvg_handle_render_document(svg, cr, &viewport, &err);
|
||||||
|
if (err) {
|
||||||
|
wlr_log(WLR_ERROR, "error rendering svg %s-%s\n", filename, err->message);
|
||||||
|
g_error_free(err);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cairo_surface_status(image)) {
|
||||||
|
wlr_log(WLR_ERROR, "error reading svg button '%s'", filename);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
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, /* free_on_destroy */ true);
|
||||||
|
cairo_t *cairo = (*buffer)->cairo;
|
||||||
|
cairo_set_source_surface(cairo, image, 0, 0);
|
||||||
|
cairo_paint_with_alpha(cairo, 1.0);
|
||||||
|
|
||||||
|
error:
|
||||||
|
cairo_destroy(cr);
|
||||||
|
cairo_surface_destroy(image);
|
||||||
|
g_object_unref(svg);
|
||||||
|
}
|
||||||
|
|
@ -3,3 +3,10 @@ labwc_sources += files(
|
||||||
'button-xbm.c',
|
'button-xbm.c',
|
||||||
'common.c',
|
'common.c',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if svg.found()
|
||||||
|
labwc_sources += files(
|
||||||
|
'button-svg.c',
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
|
||||||
33
src/theme.c
33
src/theme.c
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
|
#include "config.h"
|
||||||
#include <cairo.h>
|
#include <cairo.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
|
@ -25,6 +26,11 @@
|
||||||
#include "common/string-helpers.h"
|
#include "common/string-helpers.h"
|
||||||
#include "config/rcxml.h"
|
#include "config/rcxml.h"
|
||||||
#include "button/button-png.h"
|
#include "button/button-png.h"
|
||||||
|
|
||||||
|
#if HAVE_RSVG
|
||||||
|
#include "button/button-svg.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "button/button-xbm.h"
|
#include "button/button-xbm.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
|
|
@ -39,6 +45,15 @@ struct button {
|
||||||
} active, inactive;
|
} active, inactive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
drop(struct lab_data_buffer **buffer)
|
||||||
|
{
|
||||||
|
if (*buffer) {
|
||||||
|
wlr_buffer_drop(&(*buffer)->base);
|
||||||
|
*buffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_buttons(struct theme *theme)
|
load_buttons(struct theme *theme)
|
||||||
{
|
{
|
||||||
|
|
@ -97,13 +112,29 @@ load_buttons(struct theme *theme)
|
||||||
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];
|
||||||
|
|
||||||
|
drop(b->active.buffer);
|
||||||
|
drop(b->inactive.buffer);
|
||||||
|
|
||||||
/* Try png icon first */
|
/* Try png icon first */
|
||||||
snprintf(filename, sizeof(filename), "%s-active.png", b->name);
|
snprintf(filename, sizeof(filename), "%s-active.png", b->name);
|
||||||
png_load(filename, b->active.buffer);
|
png_load(filename, b->active.buffer);
|
||||||
snprintf(filename, sizeof(filename), "%s-inactive.png", b->name);
|
snprintf(filename, sizeof(filename), "%s-inactive.png", b->name);
|
||||||
png_load(filename, b->inactive.buffer);
|
png_load(filename, b->inactive.buffer);
|
||||||
|
|
||||||
/* If there were no png buttons, use xbm */
|
#if HAVE_RSVG
|
||||||
|
/* Then try svg icon */
|
||||||
|
int size = theme->title_height - 2 * theme->padding_height;
|
||||||
|
if (!*b->active.buffer) {
|
||||||
|
snprintf(filename, sizeof(filename), "%s-active.svg", b->name);
|
||||||
|
button_svg_load(filename, b->active.buffer, size);
|
||||||
|
}
|
||||||
|
if (!*b->inactive.buffer) {
|
||||||
|
snprintf(filename, sizeof(filename), "%s-inactive.svg", b->name);
|
||||||
|
button_svg_load(filename, b->inactive.buffer, size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* If there were no png/svg buttons, use xbm */
|
||||||
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
|
snprintf(filename, sizeof(filename), "%s.xbm", b->name);
|
||||||
if (!*b->active.buffer) {
|
if (!*b->active.buffer) {
|
||||||
button_xbm_load(filename, b->active.buffer,
|
button_xbm_load(filename, b->active.buffer,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue