File indexing completed on 2024-04-14 15:33:00

0001 /*
0002  * SPDX-FileCopyrightText: 2020 Mikhail Zolotukhin <zomial@protonmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #include <gdk/gdk.h>
0008 #include <gio/gio.h>
0009 #include <glib.h>
0010 #include <gtk/gtk.h>
0011 
0012 #define UNUSED(x) (void)(x)
0013 
0014 gchar *window_decorations_css_path;
0015 GFile *window_decorations_css_file;
0016 
0017 GFileMonitor *window_decorations_css_monitor;
0018 
0019 GtkCssProvider *css_provider;
0020 
0021 void manage_css_provider(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data);
0022 void reload_css_provider();
0023 void remove_css_provider();
0024 int theme_is_breeze();
0025 void theme_changed(GtkSettings *settings, GParamSpec *param_spec, void *user_data);
0026 
0027 __attribute__((visibility("default"))) void gtk_module_init(gint *argc, gchar ***argv[])
0028 {
0029     UNUSED(argc);
0030     UNUSED(argv);
0031 
0032     window_decorations_css_path = g_strconcat(g_get_user_config_dir(), "/gtk-3.0/window_decorations.css", NULL);
0033     window_decorations_css_file = g_file_new_for_path(window_decorations_css_path);
0034 
0035     window_decorations_css_monitor = g_file_monitor_file(window_decorations_css_file, G_FILE_MONITOR_NONE, NULL, NULL);
0036 
0037     css_provider = NULL;
0038 
0039     g_signal_connect(window_decorations_css_monitor, "changed", G_CALLBACK(manage_css_provider), NULL);
0040     g_signal_connect(gtk_settings_get_default(), "notify::gtk-theme-name", G_CALLBACK(theme_changed), NULL);
0041 
0042     reload_css_provider();
0043 }
0044 
0045 void manage_css_provider(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data)
0046 {
0047     UNUSED(monitor);
0048     UNUSED(file);
0049     UNUSED(other_file);
0050     UNUSED(user_data);
0051 
0052     if (event_type == G_FILE_MONITOR_EVENT_CREATED || event_type == G_FILE_MONITOR_EVENT_CHANGED) {
0053         reload_css_provider();
0054     } else if (event_type == G_FILE_MONITOR_EVENT_DELETED) {
0055         remove_css_provider();
0056     }
0057 }
0058 
0059 void reload_css_provider()
0060 {
0061     remove_css_provider();
0062 
0063     if (!theme_is_breeze()) {
0064         return;
0065     }
0066 
0067     css_provider = gtk_css_provider_new();
0068 
0069     gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER + 1);
0070     if (g_file_query_exists(window_decorations_css_file, NULL)) {
0071         gtk_css_provider_load_from_file(css_provider, window_decorations_css_file, NULL);
0072     }
0073 }
0074 
0075 void remove_css_provider()
0076 {
0077     if (!css_provider) {
0078         return;
0079     }
0080     gtk_style_context_remove_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css_provider));
0081     g_clear_object(&css_provider);
0082 }
0083 
0084 int theme_is_breeze()
0085 {
0086     GtkSettings *settings = gtk_settings_get_default();
0087     char *theme_name = NULL;
0088     g_object_get(settings, "gtk-theme-name", &theme_name, NULL);
0089     if (!theme_name) {
0090         return 0;
0091     }
0092     int ret = !strcmp(theme_name, "Breeze");
0093     g_free(theme_name);
0094     return ret;
0095 }
0096 
0097 void theme_changed(GtkSettings *settings, GParamSpec *param_spec, void *user_data)
0098 {
0099     UNUSED(settings);
0100     UNUSED(param_spec);
0101     UNUSED(user_data);
0102     reload_css_provider();
0103 }