From 18b53479e9f7d0a679c43c934856462df45b8bde Mon Sep 17 00:00:00 2001 From: jasperro <42558625+jasperro@users.noreply.github.com> Date: Wed, 7 Oct 2020 13:10:30 +0200 Subject: [PATCH] Add gtk3 reload in reload.py from wpg This requires a theme like deviantfero's FlatColor to change gtk3 color theme on reload. See https://github.com/deviantfero/wpgtk-templates/tree/master/FlatColor. Add the base files to the user template folder. Use the -g command line parameter to use this function. --- pywal/__main__.py | 6 ++++ pywal/reload.py | 82 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/pywal/__main__.py b/pywal/__main__.py index 91ead11..cad9777 100644 --- a/pywal/__main__.py +++ b/pywal/__main__.py @@ -112,6 +112,9 @@ def get_args(): arg.add_argument("-e", action="store_true", help="Skip reloading gtk/xrdb/i3/sway/polybar") + arg.add_argument("-g", action="store_true", + help="Reload the gtk3 theme") + return arg @@ -216,6 +219,9 @@ def parse_args(parser): if not args.e: reload.gtk() + + if args.g: + reload.gtk3() def main(): diff --git a/pywal/reload.py b/pywal/reload.py index 24106c7..df64f75 100644 --- a/pywal/reload.py +++ b/pywal/reload.py @@ -6,7 +6,7 @@ import os import shutil import subprocess -from .settings import CACHE_DIR, MODULE_DIR, OS +from .settings import CACHE_DIR, XDG_CONF_DIR, MODULE_DIR, OS from . import util @@ -30,7 +30,7 @@ def xrdb(xrdb_files=None): def gtk(): - """Reload GTK theme on the fly.""" + """Reload GTK2 theme on the fly.""" # Here we call a Python 2 script to reload the GTK themes. # This is done because the Python 3 GTK/Gdk libraries don't # provide a way of doing this. @@ -40,6 +40,84 @@ def gtk(): else: logging.warning("GTK2 reload support requires Python 2.") + +def gtk3(): + """Reload GTK3 theme on the fly, requires a theme that enables styling via gtk.css""" + settings_ini = os.path.join(XDG_CONF_DIR, "gtk-3.0", "settings.ini") + + # Multiple backends available to set, xfsettings for xfce, + # then gsd-settings in gnome, gsettings for everything else + refresh_gsettings = ( + "gsettings set org.gnome.desktop.interface " + "gtk-theme '' && sleep 0.1 && gsettings set " + "org.gnome.desktop.interface gtk-theme '{}'" + ) + + refresh_xfsettings = ( + "xfconf-query -c xsettings -p /Net/ThemeName -s" + " '' && sleep 0.1 && xfconf-query -c xsettings -p" + " /Net/ThemeName -s '{}'" + ) + + if shutil.which("gsettings"): + cmd = ["gsettings", "get", "org.gnome.desktop.interface", "gtk-theme"] + gsettings_theme = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL + ).communicate()[0].decode().strip("' \n") + + xfsettings_theme = None + if shutil.which("xfconf-query"): + cmd = ["xfconf-query", "-c", "xsettings", "-p", "/Net/ThemeName"] + xfsettings_theme = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL + ).communicate()[0].decode().strip("' \n") + + if util.get_pid("gsd-settings") and gsettings_theme: + subprocess.Popen(refresh_gsettings.format(gsettings_theme), shell=True) + logging.info("Reloaded %s theme via gsd-settings" % gsettings_theme) + + elif util.get_pid("xfsettingsd") and xfsettings_theme: + subprocess.Popen(refresh_xfsettings, shell=True) + logging.info("reloaded %s theme via xfsettingsd" % xfsettings_theme) + + # no settings daemon is running. + # So GTK is getting theme info from gtkrc file + # using xsettingd to set the same theme (parsing it from gtkrc) + elif shutil.which("xsettingsd") and os.path.isfile(settings_ini): + gtkrc = configparser.ConfigParser() + gtkrc.read(settings_ini) + + if gtkrc["Settings"]: + theme = gtkrc["Settings"].get("gtk-theme-name", "FlatColor") + fd, path = tempfile.mkstemp() + + try: + with os.fdopen(fd, "w+") as tmp: + tmp.write('Net/ThemeName "' + theme + '"\n') + tmp.close() + util.silent_call([ + "timeout", "0.2s", "xsettingsd", "-c", path + ]) + logging.info( + "reloaded %s from settings.ini using xsettingsd" + % theme + ) + finally: + os.remove(path) + + # The system has no known settings daemon installed, + # but dconf gtk-theme exists, just refreshing its theme + # Because user might be using unknown settings daemon + elif shutil.which("gsettings") and gsettings_theme: + subprocess.Popen(refresh_gsettings.format(gsettings_theme), shell=True) + logging.warning( + "No settings daemon found, just refreshing %s theme from gsettings" + % gsettings_theme + ) def i3():