Use default Gtk theme directory for shell theme + launch apps with the theme configured by the shell

This commit is contained in:
DL 2025-06-17 12:18:47 +02:00
parent 12014a121d
commit 2775e497f5
6 changed files with 65 additions and 68 deletions

View File

@ -7,7 +7,7 @@ Wayland shell for diyac wayland compositor
## Theme ## Theme
Default theme can be set using the envar `DIYA_DEFAULT_THEME`, this will cause the shell searching for CSS file theme in Default theme can be set using the envar `DIYA_DEFAULT_THEME`, this will cause the shell searching for CSS file theme in
`/home/$USER/.config/diya/themes/`: `/home/$USER/.themes/<name>/gtk-4.0/gtk.css`:
* diya-shell: will looking for file: `dev.iohub.diya.session-shell.css` * diya-shell: will looking for file: `dev.iohub.diya.session-shell.css`
* diya-login-shell: will looking for file: `dev.iohub.diya.login-shell.css` * diya-login-shell: will looking for file: `dev.iohub.diya.login-shell.css`

View File

@ -5,8 +5,8 @@
#include "files-monior.h" #include "files-monior.h"
#include "input.h" #include "input.h"
#define diya_shell_config_css_file(priv) (g_strconcat(g_get_user_config_dir(), "/diya/themes/", priv->theme ? priv->theme : "default", "/", priv->name, ".css", NULL)) #define diya_shell_config_theme(priv) (g_strconcat(g_get_home_dir(), "/.themes/", priv->theme ? priv->theme : "default", "/gtk-4.0/gtk.css", NULL))
#define diya_shell_config_theme_dir(priv) (g_strconcat(g_get_home_dir(), "/.themes/", priv->theme ? priv->theme : "default", "/gtk-4.0", NULL))
enum enum
{ {
NO_PROP, NO_PROP,
@ -76,59 +76,36 @@ static void diya_shell_dispose(GObject *object)
static void diya_shell_reload_theme(DiyaShell *shell) static void diya_shell_reload_theme(DiyaShell *shell)
{ {
GError *err = NULL;
GBytes *bytes = NULL;
gchar *css_string = NULL;
DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); DiyaShellPrivate *priv = diya_shell_get_instance_private(shell);
gchar *css_file = diya_shell_config_css_file(priv);
g_debug("diya_shell_reload: Looking for css file: %s", css_file);
g_file_get_contents(css_file, &css_string, NULL, &err);
g_free(css_file);
if (err != NULL)
{
g_warning("diya_shell_reload: Unable to load CSS from file: %s", err->message);
g_error_free(err);
err = NULL;
g_debug("diya_shell_reload: Fallback to default theme");
css_file = g_strconcat("/dev/iohub/diya/shell/", priv->name, ".css", NULL);
bytes = g_resources_lookup_data(css_file, 0, &err);
free(css_file);
if (err != NULL)
{
g_critical("diya_shell_reload: Unable to load CSS from resource: %s", err->message);
g_error_free(err);
css_string = NULL;
}
else
{
css_string = (gchar *)g_bytes_get_data(bytes, NULL);
}
}
if (css_string)
{
if (priv->css_provider)
{
gtk_style_context_remove_provider_for_display(gdk_display_get_default(), GTK_STYLE_PROVIDER(priv->css_provider));
g_object_unref(priv->css_provider);
priv->css_provider = NULL;
}
g_debug("diya_shell_reload: Applying stylesheet:\n %s", css_string); if (priv->css_provider)
priv->css_provider = gtk_css_provider_new(); {
gtk_css_provider_load_from_string(priv->css_provider, css_string); gtk_style_context_remove_provider_for_display(gdk_display_get_default(), GTK_STYLE_PROVIDER(priv->css_provider));
gtk_style_context_add_provider_for_display( g_object_unref(priv->css_provider);
priv->css_provider = NULL;
}
priv->css_provider = gtk_css_provider_new();
gchar *css_file = diya_shell_config_theme(priv);
g_debug("diya_shell_reload_theme: Looking for css file: %s", css_file);
if (g_file_test(css_file, G_FILE_TEST_EXISTS))
{
GFile* file = g_file_new_for_path(css_file);
gtk_css_provider_load_from_file(priv->css_provider, file);
g_object_unref(file);
}
else
{
g_warning("diya_shell_reload_theme: Unable to load CSS from file: %s. Fallback to default theme", css_file);
gchar* css_resource = g_strconcat("/dev/iohub/diya/shell/", priv->name, ".css", NULL);
gtk_css_provider_load_from_resource(priv->css_provider, css_resource);
g_free(css_resource);
}
g_free(css_file);
gtk_style_context_add_provider_for_display(
gdk_display_get_default(), gdk_display_get_default(),
GTK_STYLE_PROVIDER(priv->css_provider), GTK_STYLE_PROVIDER(priv->css_provider),
GTK_STYLE_PROVIDER_PRIORITY_USER); GTK_STYLE_PROVIDER_PRIORITY_USER);
if (!bytes)
{
free(css_string);
}
}
if (bytes)
{
g_bytes_unref(bytes);
}
} }
void diya_shell_reload(DiyaShell *self) void diya_shell_reload(DiyaShell *self)
@ -183,9 +160,9 @@ static void on_gtk_app_startup(GtkApplication *app, void *data)
priv->theme = g_strdup(default_theme); priv->theme = g_strdup(default_theme);
} }
gchar *css_file = diya_shell_config_css_file(priv); gchar *dir = diya_shell_config_theme_dir(priv);
diya_shell_watch_file(shell, css_file, G_CALLBACK(on_diya_shell_theme_file_changed), (gpointer)shell); diya_shell_watch_file(shell, dir, G_CALLBACK(on_diya_shell_theme_file_changed), (gpointer)shell);
g_free(css_file); g_free(dir);
diya_shell_reload(shell); diya_shell_reload(shell);
if (class->startup_handle) if (class->startup_handle)
@ -442,16 +419,16 @@ int diya_shell_run(DiyaShell *shell, int argc, char **argv)
DiyaShellPrivate *priv = diya_shell_get_instance_private(shell); DiyaShellPrivate *priv = diya_shell_get_instance_private(shell);
assert(GTK_IS_APPLICATION(priv->app)); assert(GTK_IS_APPLICATION(priv->app));
GtkApplication *app = priv->app; GtkApplication *app = priv->app;
/**
* create shell config dir if not exists /*
*/
// theme dir // theme dir
gchar *path = g_strconcat(g_get_user_config_dir(), "/diya/themes/", NULL); gchar *path = g_strconcat(g_get_user_config_dir(), "/diya/themes/", NULL);
g_mkdir_with_parents((const gchar *)path, 0755); g_mkdir_with_parents((const gchar *)path, 0755);
g_free(path); g_free(path);
*/
// keymap dir // keymap dir
path = g_strconcat(g_get_user_config_dir(), "/diya/xkb/", NULL); gchar* path = g_strconcat(g_get_user_config_dir(), "/diya/xkb/", NULL);
g_mkdir_with_parents((const gchar *)path, 0755); g_mkdir_with_parents((const gchar *)path, 0755);
g_free(path); g_free(path);
@ -529,4 +506,23 @@ void diya_shell_unwatch_file(DiyaShell *self, const gchar *file)
{ {
diya_files_monitor_unwatch(priv->files_watchdog, file); diya_files_monitor_unwatch(priv->files_watchdog, file);
} }
}
void diya_shell_launch(DiyaShell* self, GAppInfo* app)
{
GError* error = NULL;
DiyaShellPrivate *priv = diya_shell_get_instance_private(self);
GAppLaunchContext* context = g_app_launch_context_new();
if(priv->theme)
{
g_app_launch_context_setenv(context, "GTK_THEME", priv->theme);
}
g_app_info_launch(app, NULL, context, &error);
g_object_unref (context);
if(error)
{
g_critical("Unable to launch application: %s", error->message);
g_error_free(error);
return;
}
} }

View File

@ -51,6 +51,7 @@ DiyaVirtualKeyboard* diya_shell_get_virtual_keyboard(DiyaShell* shell, const gch
void diya_shell_monitor_input(DiyaShell* shell); void diya_shell_monitor_input(DiyaShell* shell);
gboolean diya_shell_watch_file(DiyaShell* shell, const gchar* file, GCallback callback, gpointer userdata); gboolean diya_shell_watch_file(DiyaShell* shell, const gchar* file, GCallback callback, gpointer userdata);
void diya_shell_unwatch_file(DiyaShell* shell, const gchar* file); void diya_shell_unwatch_file(DiyaShell* shell, const gchar* file);
void diya_shell_launch(DiyaShell* shell, GAppInfo* app);
int diya_shell_run(DiyaShell* shell, int argc, char **argv); int diya_shell_run(DiyaShell* shell, int argc, char **argv);
#endif #endif

View File

@ -97,4 +97,10 @@ DiyaShellWindow* diya_shell_window_new(GType window_type, gpointer data)
class->setup(self); class->setup(self);
} }
return self; return self;
}
gpointer diya_shell_window_get_shell(DiyaShellWindow* self)
{
DiyaShellWindowPrivate* priv = diya_shell_window_get_instance_private(self);
return priv->shell;
} }

View File

@ -12,7 +12,7 @@ struct _DiyaShellWindowClass
GtkApplicationWindowClass parent_class; GtkApplicationWindowClass parent_class;
void (*setup)(DiyaShellWindow* self); void (*setup)(DiyaShellWindow* self);
}; };
gpointer diya_shell_window_get_shell(DiyaShellWindow* self);
DiyaShellWindow* diya_shell_window_new(GType window_type, gpointer shell); DiyaShellWindow* diya_shell_window_new(GType window_type, gpointer shell);
#endif #endif

View File

@ -113,22 +113,16 @@ static void diya_dashboard_launch(GtkButton* btn, DiyaDashboardWidget* self)
g_debug("Clicked %d %d", DIYA_IS_DASHBOARD_WIDGET(self), GTK_IS_BUTTON(btn)); g_debug("Clicked %d %d", DIYA_IS_DASHBOARD_WIDGET(self), GTK_IS_BUTTON(btn));
GError* error = NULL; GError* error = NULL;
GAppInfo* app = g_app_info_create_from_commandline("htop", "Foot", G_APP_INFO_CREATE_NEEDS_TERMINAL, &error); GAppInfo* app = g_app_info_create_from_commandline("gtk4example", "Gtk Example", G_APP_INFO_CREATE_NONE, &error);
if(error) if(error)
{ {
g_critical("Unable to create app info: %s", error->message); g_critical("Unable to create app info: %s", error->message);
g_error_free(error); g_error_free(error);
return; return;
} }
error = NULL; diya_shell_launch(diya_shell_window_get_shell(DIYA_SHELL_WINDOW(self)), app);
g_app_info_launch(app, NULL, NULL, &error);
if(error)
{
g_critical("Unable to launch application: %s", error->message);
g_error_free(error);
return;
}
g_object_set(self, DIYA_PROP_DASHBOARD_ACTIVE, false, NULL); g_object_set(self, DIYA_PROP_DASHBOARD_ACTIVE, false, NULL);
} }
static void diya_dashboard_widget_class_init(DiyaDashboardWidgetClass* class) static void diya_dashboard_widget_class_init(DiyaDashboardWidgetClass* class)