Commit 604ff30f authored by Mikhail Zolotukhin's avatar Mikhail Zolotukhin

Use only GTK Module for managing window decorations CSS

Now we are no longer use gtk.css file inside ~/.config/gtk-3.0/ directory
for window decorations. To load decorations into GTK apps we now exclusively
use GTK module.

The module is a GTK-app addon, that loads the buttons on application startup,
then it reacts to changes of windows_decorations.css file in config directory
and loads and unloads it dynamically depending on its presence.

For example: file is present - it is loaded on the startup, file is deleted -
it is unloaded, file is created or changed - it is loaded, while the past
version of it is unloaded.

File presence is controlled by kde-gtk-config kded5 module.

BUG: 428322
BUG: 428120
BUG: 428842
parent 6e81458e
......@@ -37,3 +37,9 @@ install(
DESTINATION
${KCONF_UPDATE_INSTALL_DIR}
)
install(
PROGRAMS
remove_window_decorations_from_gtk_css.sh
DESTINATION
${LIB_INSTALL_DIR}/kconf_update_bin/
)
Version=5
Id=gtk_theme
Script=gtk_theme
Id=dont_use_gtk_css_for_window_decorations
Script=remove_window_decorations_from_gtk_css.sh,sh
#!/usr/bin/env sh
remove_window_decorations_import() {
if [ -z "$XDG_CONFIG_HOME" ]; then
GTK_CSS_PATH="$HOME/.config/gtk-3.0/gtk.css"
else
GTK_CSS_PATH="$XDG_CONFIG_HOME/gtk-3.0/gtk.css"
fi
sed -i "/@import 'window_decorations.css';/d" "$GTK_CSS_PATH"
}
remove_window_decorations_import
......@@ -107,13 +107,12 @@ void ConfigEditor::setCustomClientSideDecorations(const QStringList &windowDecor
{
saveWindowDecorationsToAssets(windowDecorationsButtonsImages);
addWindowDecorationsCssFile();
addImportStatementsToGtkCssUserFile();
addGtkModule(QStringLiteral("window-decorations-gtk-module"));
}
void ConfigEditor::disableCustomClientSideDecorations()
{
removeDecorationsImportStatementFromGtkCssUserFile();
removeWindowDecorationsCSS();
}
void ConfigEditor::setGtk3Colors(const QMap<QString, QColor> &colorsDefinitions)
......@@ -199,8 +198,7 @@ void ConfigEditor::addImportStatementsToGtkCssUserFile()
QByteArray gtkCssContents = gtkCss.readAll().trimmed();
static const QVector<QByteArray> importStatements {
QByteArrayLiteral("\n@import 'colors.css';"),
QByteArrayLiteral("\n@import 'window_decorations.css';"),
QByteArrayLiteral("\n@import 'colors.css';")
};
for (const auto &statement : importStatements) {
......@@ -215,22 +213,12 @@ void ConfigEditor::addImportStatementsToGtkCssUserFile()
}
}
void ConfigEditor::removeDecorationsImportStatementFromGtkCssUserFile()
void ConfigEditor::removeWindowDecorationsCSS()
{
QString gtkCssPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/gtk-3.0/gtk.css");
QFile gtkCss(gtkCssPath);
if (gtkCss.open(QIODevice::ReadWrite)) {
QByteArray gtkCssContents = gtkCss.readAll().trimmed();
using SP = QStandardPaths;
static const QByteArray importStatement = QByteArrayLiteral("\n@import 'window_decorations.css';");
gtkCssContents.replace(importStatement.trimmed(), QByteArray());
gtkCss.remove();
gtkCss.open(QIODevice::WriteOnly | QIODevice::Text);
gtkCss.write(gtkCssContents);
}
QFile windowsDecorationsCss(SP::writableLocation(SP::GenericConfigLocation) + QStringLiteral("/gtk-3.0/window_decorations.css"));
windowsDecorationsCss.remove();
}
void ConfigEditor::modifyColorsCssFile(const QMap<QString, QColor> &colorsDefinitions)
......
......@@ -44,7 +44,7 @@ namespace ConfigEditor
void addGtkModule(const QString &moduleName);
void addImportStatementsToGtkCssUserFile();
void removeDecorationsImportStatementFromGtkCssUserFile();
void removeWindowDecorationsCSS();
void modifyColorsCssFile(const QMap<QString, QColor> &colorsDefinitions);
void replaceValueInGtkrcContents(QString &gtkrcContents, const QString &paramName, const QVariant &paramValue);
......
......@@ -4,81 +4,68 @@
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include <gtk/gtk.h>
#include <glib.h>
#include <gio/gio.h>
#include <gdk/gdk.h>
#include <gio/gio.h>
#include <glib.h>
#include <gtk/gtk.h>
#define UNUSED(x) (void)(x)
gchar *window_decorations_css_path;
GFile *window_decorations_css_file;
gchar *gtk_css_path;
GFile *gtk_css_file;
gchar *assets_directory_path;
GFile *assets_directory;
GFileMonitor *window_decorations_css_monitor;
GFileMonitor *directory_monitor;
GFileMonitor *gtk_css_monitor;
GtkCssProvider *css_provider;
void reload_decorations();
void remove_css_provider_if_needed();
void manage_css_provider(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data);
void reload_css_provider();
void remove_css_provider();
__attribute__((visibility("default"))) void gtk_module_init(gint *argc, gchar ***argv[])
{
UNUSED(argc);
UNUSED(argv);
window_decorations_css_path = g_strconcat(g_get_user_config_dir(), "/gtk-3.0/window_decorations.css", NULL);
window_decorations_css_file = g_file_new_for_path(window_decorations_css_path);
gtk_css_path = g_strconcat(g_get_user_config_dir(), "/gtk-3.0/gtk.css", NULL);
gtk_css_file = g_file_new_for_path(gtk_css_path);
assets_directory_path = g_strconcat(g_get_user_config_dir(), "/gtk-3.0/assets/", NULL);
assets_directory = g_file_new_for_path(assets_directory_path);
window_decorations_css_monitor = g_file_monitor_file(window_decorations_css_file, G_FILE_MONITOR_NONE, NULL, NULL);
css_provider = NULL;
gtk_css_monitor = g_file_monitor_file(gtk_css_file, G_FILE_MONITOR_NONE, NULL, NULL);
directory_monitor = g_file_monitor_directory(assets_directory, G_FILE_MONITOR_NONE, NULL, NULL);
g_signal_connect(window_decorations_css_monitor, "changed", G_CALLBACK(manage_css_provider), NULL);
g_signal_connect(directory_monitor, "changed", G_CALLBACK(reload_decorations), NULL);
g_signal_connect(gtk_css_monitor, "changed", G_CALLBACK(remove_css_provider_if_needed), NULL);
reload_css_provider();
}
void reload_decorations()
void manage_css_provider(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data)
{
if (css_provider == NULL) {
css_provider = gtk_css_provider_new();
} else {
UNUSED(monitor);
UNUSED(file);
UNUSED(other_file);
UNUSED(user_data);
if (event_type == G_FILE_MONITOR_EVENT_CREATED || event_type == G_FILE_MONITOR_EVENT_CHANGED) {
reload_css_provider();
} else if (event_type == G_FILE_MONITOR_EVENT_DELETED) {
remove_css_provider();
css_provider = gtk_css_provider_new();
}
gtk_style_context_add_provider_for_screen(
gdk_screen_get_default(),
GTK_STYLE_PROVIDER (css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER + 1
);
gtk_css_provider_load_from_file(css_provider, window_decorations_css_file, NULL);
}
void remove_css_provider_if_needed()
void reload_css_provider()
{
gchar *gtk_css_contents;
gboolean success = g_file_load_contents(gtk_css_file, NULL, &gtk_css_contents, NULL, NULL, NULL);
if (success == FALSE) {
return;
printf("WINDOW DECORATIONS RELOADED\n");
if (css_provider != NULL) {
remove_css_provider();
}
// If custom decorations are disabled we must unload our custom CSS
if (g_strrstr(gtk_css_contents, "@import 'window_decorations.css';") == NULL) {
if (css_provider != NULL) {
remove_css_provider();
}
}
css_provider = gtk_css_provider_new();
g_free(gtk_css_contents);
gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER + 1);
if (g_file_query_exists(window_decorations_css_file, NULL)) {
gtk_css_provider_load_from_file(css_provider, window_decorations_css_file, NULL);
}
}
void remove_css_provider()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment