The officially official Devuan Forum!

You are not logged in.

#1 2019-02-13 20:12:24

geki
Member
Registered: 2019-02-04
Posts: 104  

Change accent and highlight color of Qt5 Kvantum and Gtk 2/3 theme

Hi all,

I happened to find the Qt5 Kvantum theme engine looking to have VLC Qt5 frontend somewhat close to my MATE Gtk3 desktop. Having found out about Kvantum, I stumbled across Adapta Gtk theme[0] and its port to KDE[1]. Its Nokto variant is just great. And they fit perfectly - Qt5 and Gtk3 and you cannot tell. smile

Now, that theme has its blueish accent color. And I just prefer a violet color instead. The last days I put a script together to switch colors for Kvantum themes - quite easy as it is a plain config and svg with hex-rgb color values to replace - and for Gtk 2/3 themes. Gtk is not quite so easy. There are css and svg - again easy -  but there are png and gresource files - png and css container.

Luckily, there is imagemagick's convert and its documentation, gresource and glib-compile-resources to unpack gtk resource files, recolor all png and bundle things up again.

I wonder if this is anyhow useful to anyone but me. O well, whenever I got something I like to make it public. You never know when it may come handy to you?! So, here is the script and take the pieces with pride, if it hoses your system. Have fun! big_smile

#!/bin/bash

# Copyright (c) 2019, Hanno Meyer-Thurow
# All rights reserved.
#
# FreeBSD License (2-clause BSD License)
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# 
# The views and conclusions contained in the software and documentation are those
# of the authors and should not be interpreted as representing official policies,
# either expressed or implied, of the <project name> project.

# CONFIGURATION
#
# only basic error checking, so make sure all configuration are valid

# Kvantum theme is used as-is
theme_kvantum="AdaptaNokto"

# Gtk theme is used as variants
# (meaning an asterisk is appended)
theme_gtk="Adapta-Nokto"

# old rgb colors
color_old_accented="#4db6ac"
color_old_selected="#00bcd4"
color_old_altered="#05abc1"
color_old_background="#009688"

# new rgb colors
color_new_accented="#a146ff"
color_new_selected="#662477"
color_new_altered="#612453"
color_new_background="#880096"

# png recoloring
#
# - imagemagick modulate - percentage difference - base 100
#
# - modulate value order in reversed hsl colorspace
#
# - generated by http://www.fmwconcepts.com/imagemagick/colorconverter/index.php
#
# $ ~/colorconverter -c "#00bcd4" | grep hsl
# hsl(187,255,106)
# hsl(187,100%,41.5686%)
#
# $ ~/colorconverter -c "#662477" | grep hsl
# hsl(288,137,78)
# hsl(288,53.5485%,30.3929%)
#
# 30.3929 / 41.5686	= 73.115
# 53.5485 / 100		= 53.5485
# 288 / 187		= 154.0107
recolor_old_hsl="hsl(187,100%,41.5686%)"
recolor_mod_lsh="73.115,53.5485,154.0107"

# PARAMETERS
#
# set options

debug=""
find_follow_symlinks=""
gtk_theme_resource="gtk.gresource"
gnome_shell_theme_resource="gnome-shell-theme.gresource"
verbose=""

while [ ${#} -gt 0 ]
do
	case "${1}" in
	-d|--debug)
		debug="true"
		shift
		;;
	-l|--follow-symlinks)
		find_follow_symlinks="-L"
		shift
		;;
	-g|--gtk-theme-resource)
		gtk_theme_resource="${2}.gresource"
		shift
		shift
		;;
	-s|--gnome-shell-theme-resource)
		gnome_shell_theme_resource="${2}.gresource"
		shift
		shift
		;;
	-v|--verbose)
		verbose="true"
		shift
		;;
	*)
		echo "unknown parameter: ${1}"
		exit -1
		;;
	esac
done

# PROCESSING
#
# no change from here on

clr_old_acc_lc="$(echo ${color_old_accented} | tr '[:upper:]' '[:lower:]')"
clr_old_sel_lc="$(echo ${color_old_selected} | tr '[:upper:]' '[:lower:]')"
clr_old_alt_lc="$(echo ${color_old_altered} | tr '[:upper:]' '[:lower:]')"
clr_old_bkg_lc="$(echo ${color_old_background} | tr '[:upper:]' '[:lower:]')"

clr_old_acc_uc="$(echo ${color_old_accented} | tr '[:lower:]' '[:upper:]')"
clr_old_sel_uc="$(echo ${color_old_selected} | tr '[:lower:]' '[:upper:]')"
clr_old_alt_uc="$(echo ${color_old_altered} | tr '[:lower:]' '[:upper:]')"
clr_old_bkg_uc="$(echo ${color_old_background} | tr '[:lower:]' '[:upper:]')"

clr_new_acc_lc="$(echo ${color_new_accented} | tr '[:upper:]' '[:lower:]')"
clr_new_sel_lc="$(echo ${color_new_selected} | tr '[:upper:]' '[:lower:]')"
clr_new_alt_lc="$(echo ${color_new_altered} | tr '[:upper:]' '[:lower:]')"
clr_new_bkg_lc="$(echo ${color_new_background} | tr '[:upper:]' '[:lower:]')"

clr_new_acc_uc="$(echo ${color_new_accented} | tr '[:lower:]' '[:upper:]')"
clr_new_sel_uc="$(echo ${color_new_selected} | tr '[:lower:]' '[:upper:]')"
clr_new_alt_uc="$(echo ${color_new_altered} | tr '[:lower:]' '[:upper:]')"
clr_new_bkg_uc="$(echo ${color_new_background} | tr '[:lower:]' '[:upper:]')"

clr_old_acc_rgb="$(printf "%d, %d, %d" \
	0x${clr_old_acc_uc:1:2} 0x${clr_old_acc_uc:3:2} 0x${clr_old_acc_uc:5:2})"
clr_old_sel_rgb="$(printf "%d, %d, %d" \
	0x${clr_old_sel_uc:1:2} 0x${clr_old_sel_uc:3:2} 0x${clr_old_sel_uc:5:2})"
clr_old_alt_rgb="$(printf "%d, %d, %d" \
	0x${clr_old_alt_uc:1:2} 0x${clr_old_alt_uc:3:2} 0x${clr_old_alt_uc:5:2})"
clr_old_bkg_rgb="$(printf "%d, %d, %d" \
	0x${clr_old_bkg_uc:1:2} 0x${clr_old_bkg_uc:3:2} 0x${clr_old_bkg_uc:5:2})"

clr_new_acc_rgb="$(printf "%d, %d, %d" \
	0x${clr_new_acc_uc:1:2} 0x${clr_new_acc_uc:3:2} 0x${clr_new_acc_uc:5:2})"
clr_new_sel_rgb="$(printf "%d, %d, %d" \
	0x${clr_new_sel_uc:1:2} 0x${clr_new_sel_uc:3:2} 0x${clr_new_sel_uc:5:2})"
clr_new_alt_rgb="$(printf "%d, %d, %d" \
	0x${clr_new_alt_uc:1:2} 0x${clr_new_alt_uc:3:2} 0x${clr_new_alt_uc:5:2})"
clr_new_bkg_rgb="$(printf "%d, %d, %d" \
	0x${clr_new_bkg_uc:1:2} 0x${clr_new_bkg_uc:3:2} 0x${clr_new_bkg_uc:5:2})"

if [ "${debug}" = "true" ]
then
	echo "parameter debug: ${debug}"
	echo "parameter verbose: ${verbose}"
	echo
	echo "parameter gtk theme resource: ${gtk_theme_resource}"
	echo "parameter gnome shell theme resource: ${gnome_shell_theme_resource}"
	echo "parameter find follow symlinks: ${find_follow_symlinks}"
	echo
	echo "clr_old_acc_lc=${clr_old_acc_lc}"
	echo "clr_old_sel_lc=${clr_old_sel_lc}"
	echo "clr_old_alt_lc=${clr_old_alt_lc}"
	echo "clr_old_bkg_lc=${clr_old_bkg_lc}"
	echo
	echo "clr_old_acc_uc=${clr_old_acc_uc}"
	echo "clr_old_sel_uc=${clr_old_sel_uc}"
	echo "clr_old_alt_uc=${clr_old_alt_uc}"
	echo "clr_old_bkg_uc=${clr_old_bkg_uc}"
	echo
	echo "clr_new_acc_lc=${clr_new_acc_lc}"
	echo "clr_new_sel_lc=${clr_new_sel_lc}"
	echo "clr_new_alt_lc=${clr_new_alt_lc}"
	echo "clr_new_bkg_lc=${clr_new_bkg_lc}"
	echo
	echo "clr_new_acc_uc=${clr_new_acc_uc}"
	echo "clr_new_sel_uc=${clr_new_sel_uc}"
	echo "clr_new_alt_uc=${clr_new_alt_uc}"
	echo "clr_new_bkg_uc=${clr_new_bkg_uc}"
	echo
	echo "clr_old_acc_rgb=${clr_old_acc_rgb}"
	echo "clr_old_sel_rgb=${clr_old_sel_rgb}"
	echo "clr_old_alt_rgb=${clr_old_alt_rgb}"
	echo "clr_old_bkg_rgb=${clr_old_bkg_rgb}"
	echo
	echo "clr_new_acc_rgb=${clr_new_acc_rgb}"
	echo "clr_new_sel_rgb=${clr_new_sel_rgb}"
	echo "clr_new_alt_rgb=${clr_new_alt_rgb}"
	echo "clr_new_bkg_rgb=${clr_new_bkg_rgb}"

	exit 0
fi

pushd /usr/share/Kvantum || exit 1
[ "${verbose}" = "true" ] && echo " * replacing colors in ${theme_kvantum}"

sed -i "s:${clr_old_acc_lc}:${clr_new_acc_lc}:g" "${theme_kvantum}"/*.*
sed -i "s:${clr_old_sel_lc}:${clr_new_sel_lc}:g" "${theme_kvantum}"/*.*
popd

pushd /usr/share/themes || exit 1
# extract data from resource blobs
for g in $(find "${theme_gtk}"* -type f -name "${gtk_theme_resource}")
do
	gtk_dir="${g%/*}"

	pushd "${gtk_dir}" || continue
	res_css="$(gresource list ${gtk_theme_resource} | grep css | head -n1)"
	res_prefix="${res_css%/*}"
	res_dir="${res_prefix##*/}"

	if [ "${res_dir}" = "" ]
	then
		echo " * failed with css:${res_css} - prefix:${res_prefix} - dir:<empty>"

		popd
		continue
	fi

	[ "${verbose}" = "true" ] && echo " * resource path: ${gtk_dir}"

	mkdir -vp "${res_dir}"/assets

	for r in $(gresource list ${gtk_theme_resource})
	do
		[ "${verbose}" = "true" ] && echo "extract: ${r}"

		gresource extract ${gtk_theme_resource} ${r} \
			> "${res_dir}"/"${r##*${res_dir}/}"
	done
	popd
done

for g in $(find "${theme_gtk}"* -type f -name "${gnome_shell_theme_resource}")
do
	gtk_dir="${g%/*}"

	pushd "${gtk_dir}" || continue
	res_prefix="/org/gnome/shell/theme/"

	[ "${verbose}" = "true" ] && echo " * resource path: ${gtk_dir}"

	mkdir -vp assets icons

	for r in $(gresource list ${gnome_shell_theme_resource})
	do
		[ "${verbose}" = "true" ] && echo "extract: ${r}"

		gresource extract ${gnome_shell_theme_resource} ${r} \
			> "${r/"${res_prefix}"}"
	done
	popd
done

# recolor css/svg/xml/rc
[ "${verbose}" = "true" ] && echo " * replacing colors in ${theme_gtk}*"

for f in css svg rc xml
do
	find ${find_follow_symlinks} "${theme_gtk}"* -type f \
		-name '*.'${f} -exec sed \
		-e "s:${clr_old_acc_uc}:${clr_new_acc_uc}:g" \
		-e "s:${clr_old_sel_uc}:${clr_new_sel_uc}:g" \
		-e "s:${clr_old_alt_uc}:${clr_new_alt_uc}:g" \
		-e "s:${clr_old_bkg_uc}:${clr_new_bkg_uc}:g" \
		-e "s:(${clr_old_acc_rgb}:(${clr_new_acc_rgb}:g" \
		-e "s:(${clr_old_sel_rgb}:(${clr_new_sel_rgb}:g" \
		-e "s:(${clr_old_alt_rgb}:(${clr_new_alt_rgb}:g" \
		-e "s:(${clr_old_bkg_rgb}:(${clr_new_bkg_rgb}:g" \
		-i {} +
done

# recolor png
for f in $(find ${find_follow_symlinks} "${theme_gtk}"* -type f -name '*.png')
do
	file="${f/\.png}"
	f_mask="${file}-mask.png"
	f_out="${file}-out.png"

	[ "${verbose}" = "true" ] && echo "recoloring: ${f}"

	convert "${f}" -colorspace HSL -channel Hue,Saturation -separate +channel \
		-background none -fuzz 10% -transparent "${recolor_old_hsl}" \
		-composite -negate "${f_mask}"
	convert "${f}" -mask "${f_mask}" -modulate ${recolor_mod_lsh} \
		+mask "${f_out}"

	mv "${f_out}" "${f}"
	rm -f "${f_mask}"
done

# rebuild data into resource blobs
for g in $(find "${theme_gtk}"* -type f -name "${gtk_theme_resource}")
do
	gtk_dir="${g%/*}"

	pushd "${gtk_dir}" || continue
	res_css="$(gresource list ${gtk_theme_resource} | grep css | head -n1)"
	res_prefix="${res_css%/*}"
	res_dir="${res_prefix##*/}"

	if [ ! -d "${res_dir}" ]
	then
		echo " * failed with css:${res_css} - prefix:${res_prefix} - dir:${res_dir}"

		popd
		continue
	fi

	[ "${verbose}" = "true" ] && echo " * resource path: ${gtk_dir}"

	pushd "${res_dir}"
	echo "<?xml version="1.0" encoding="UTF-8"?>" > ${gtk_theme_resource}.xml
	echo "<gresources>" >> ${gtk_theme_resource}.xml
	echo "  <gresource prefix=\"${res_prefix}\">" >> ${gtk_theme_resource}.xml
	for f in $(find * -type f | sort -u | grep -v \.xml)
	do
		echo "    <file>${f}</file>" >> ${gtk_theme_resource}.xml
	done
	echo "  </gresource>" >> ${gtk_theme_resource}.xml
	echo "</gresources>" >> ${gtk_theme_resource}.xml
	popd

	[ "${verbose}" = "true" ] && echo "compile: ${res_dir}/${gtk_theme_resource}"

	glib-compile-resources --target="${res_dir}"/${gtk_theme_resource} \
		--sourcedir="${res_dir}" "${res_dir}"/${gtk_theme_resource}.xml

	if [ ${?} -eq 0 ]
	then
		mv -v "${res_dir}"/${gtk_theme_resource} ${gtk_theme_resource}
	else
		echo " * resource not regenerated in ${gtk_dir}"
	fi

	rm -rf "${res_dir}"
	popd
done

for g in $(find "${theme_gtk}"* -type f -name "${gnome_shell_theme_resource}")
do
	gtk_dir="${g%/*}"

	pushd "${gtk_dir}" || continue
	res_prefix="/org/gnome/shell/theme/"

	[ "${verbose}" = "true" ] && echo " * resource path: ${gtk_dir}"

	echo "<?xml version="1.0" encoding="UTF-8"?>" > ${gnome_shell_theme_resource}.xml
	echo "<gresources>" >> ${gnome_shell_theme_resource}.xml
	echo "  <gresource prefix=\"${res_prefix}\">" >> ${gnome_shell_theme_resource}.xml
	for r in $(gresource list ${gnome_shell_theme_resource})
	do
		echo "    <file>${r/"${res_prefix}"}</file>" >> ${gnome_shell_theme_resource}.xml
	done
	echo "  </gresource>" >> ${gnome_shell_theme_resource}.xml
	echo "</gresources>" >> ${gnome_shell_theme_resource}.xml

	[ "${verbose}" = "true" ] && echo "compile: new_${gnome_shell_theme_resource}"

	glib-compile-resources --target="new_${gnome_shell_theme_resource}" \
		--sourcedir=. ${gnome_shell_theme_resource}.xml

	if [ ${?} -eq 0 ]
	then
		mv -v "new_${gnome_shell_theme_resource}" ${gnome_shell_theme_resource}
	else
		echo " * resource not regenerated in ${gtk_dir}"
	fi

	rm -f ${gnome_shell_theme_resource}.xml
	popd
done
popd

unset theme_kvantum theme_gtk \
	color_old_accented color_old_selected color_old_altered \
	color_old_background color_new_accented color_new_selected \
	color_new_altered color_new_background \
	clr_old_acc_lc clr_old_sel_lc clr_old_alt_lc clr_old_bkg_lc \
	clr_old_acc_uc clr_old_sel_uc clr_old_alt_uc clr_old_bkg_uc \
	clr_old_acc_rgb clr_old_sel_rgb clr_old_alt_rgb clr_old_bkg_rgb \
	clr_new_acc_lc clr_new_sel_lc clr_new_alt_lc clr_new_bkg_lc \
	clr_new_acc_uc clr_new_sel_uc clr_new_alt_uc clr_new_bkg_uc \
	clr_new_acc_rgb clr_new_sel_rgb clr_new_alt_rgb clr_new_bkg_rgb \
	recolor_old_hsl recolor_mod_lsh f file f_mask f_out \
	res_css res_prefix res_dir g gtk_dir \
	debug find_follow_symlinks gtk_theme_resource \
	gnome_shell_theme_resource verbose

exit 0

[0] https://github.com/adapta-project/adapt … /README.md
[1] https://github.com/PapirusDevelopmentTe … /README.md

Last edited by geki (2019-03-08 22:47:38)

Offline

#2 2019-02-17 20:31:01

geki
Member
Registered: 2019-02-04
Posts: 104  

Re: Change accent and highlight color of Qt5 Kvantum and Gtk 2/3 theme

Finally made the first stable version on 20190217.

revision 4 20190308
- check for unknown parameter and abort

revision 3 20190217
- add background color to be changed
- stable version 1

revision 2 20190216
- repackage gnome shell theme resource bundles
- add parameters: debug, verbose, find follow symlinks, alternate gtk theme resource name and alternate gnome shell theme resource name
- properly recolor gtk css svg rc and xml files

revision 1 20190215
- rename colors: accent -> selected; hilight -> accented
- scan rc files next to svg and css

Last edited by geki (2019-03-08 22:50:52)

Offline

Board footer