1 /*
2 * SPDX-FileCopyrightText: 2020 Mikhail Zolotukhin <zomial@protonmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6
7 #include <gdk/gdk.h>
8 #include <gio/gio.h>
9 #include <glib.h>
10 #include <gtk/gtk.h>
11
12 #define UNUSED(x) (void)(x)
13
14 gchar *window_decorations_css_path;
15 GFile *window_decorations_css_file;
16
17 GFileMonitor *window_decorations_css_monitor;
18
19 GtkCssProvider *css_provider;
20
21 void manage_css_provider(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data);
22 void reload_css_provider();
23 void remove_css_provider();
24 int theme_is_breeze();
25 void theme_changed(GtkSettings *settings, GParamSpec *param_spec, void *user_data);
26
gtk_module_init(gint * argc,gchar *** argv[])27 __attribute__((visibility("default"))) void gtk_module_init(gint *argc, gchar ***argv[])
28 {
29 UNUSED(argc);
30 UNUSED(argv);
31
32 window_decorations_css_path = g_strconcat(g_get_user_config_dir(), "/gtk-3.0/window_decorations.css", NULL);
33 window_decorations_css_file = g_file_new_for_path(window_decorations_css_path);
34
35 window_decorations_css_monitor = g_file_monitor_file(window_decorations_css_file, G_FILE_MONITOR_NONE, NULL, NULL);
36
37 css_provider = NULL;
38
39 g_signal_connect(window_decorations_css_monitor, "changed", G_CALLBACK(manage_css_provider), NULL);
40 g_signal_connect(gtk_settings_get_default(), "notify::gtk-theme-name", G_CALLBACK(theme_changed), NULL);
41
42 reload_css_provider();
43 }
44
manage_css_provider(GFileMonitor * monitor,GFile * file,GFile * other_file,GFileMonitorEvent event_type,gpointer user_data)45 void manage_css_provider(GFileMonitor *monitor, GFile *file, GFile *other_file, GFileMonitorEvent event_type, gpointer user_data)
46 {
47 UNUSED(monitor);
48 UNUSED(file);
49 UNUSED(other_file);
50 UNUSED(user_data);
51
52 if (event_type == G_FILE_MONITOR_EVENT_CREATED || event_type == G_FILE_MONITOR_EVENT_CHANGED) {
53 reload_css_provider();
54 } else if (event_type == G_FILE_MONITOR_EVENT_DELETED) {
55 remove_css_provider();
56 }
57 }
58
reload_css_provider()59 void reload_css_provider()
60 {
61 remove_css_provider();
62
63 if (!theme_is_breeze()) {
64 return;
65 }
66
67 css_provider = gtk_css_provider_new();
68
69 gtk_style_context_add_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css_provider), GTK_STYLE_PROVIDER_PRIORITY_USER + 1);
70 if (g_file_query_exists(window_decorations_css_file, NULL)) {
71 gtk_css_provider_load_from_file(css_provider, window_decorations_css_file, NULL);
72 }
73 }
74
remove_css_provider()75 void remove_css_provider()
76 {
77 if (!css_provider) {
78 return;
79 }
80 gtk_style_context_remove_provider_for_screen(gdk_screen_get_default(), GTK_STYLE_PROVIDER(css_provider));
81 g_clear_object(&css_provider);
82 }
83
theme_is_breeze()84 int theme_is_breeze()
85 {
86 GtkSettings *settings = gtk_settings_get_default();
87 char *theme_name = NULL;
88 g_object_get(settings, "gtk-theme-name", &theme_name, NULL);
89 if (!theme_name) {
90 return 0;
91 }
92 int ret = !strcmp(theme_name, "Breeze");
93 g_free(theme_name);
94 return ret;
95 }
96
theme_changed(GtkSettings * settings,GParamSpec * param_spec,void * user_data)97 void theme_changed(GtkSettings *settings, GParamSpec *param_spec, void *user_data)
98 {
99 UNUSED(settings);
100 UNUSED(param_spec);
101 UNUSED(user_data);
102 reload_css_provider();
103 }
104