diff --git a/ChangeLog b/ChangeLog index 561800777..f5cb10d7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2002-08-19 Jody Goldberg + + * gnome-settings-daemon/gnome-settings-gtk1theme.c : new + file from owen to manage gtk1 themes. + 2002-08-15 Jody Goldberg * configure.in : set the version number to something sane diff --git a/capplets/common/theme-common.c b/capplets/common/theme-common.c index 76481e352..cda04d480 100644 --- a/capplets/common/theme-common.c +++ b/capplets/common/theme-common.c @@ -22,9 +22,9 @@ typedef struct _ThemeCallbackData GList *theme_list = NULL; GList *callbacks = NULL; -const gchar *suffix = "gtk-2.0"; +const gchar *gtk2_suffix = "gtk-2.0"; const gchar *key_suffix = "gtk-2.0-key"; - +const gchar *metacity_suffix = "metacity-1"; static ThemeInfo * find_theme_info_by_dir (const gchar *theme_dir) @@ -49,10 +49,11 @@ update_theme_dir (const gchar *theme_dir) gboolean changed = FALSE; gboolean has_gtk = FALSE; gboolean has_keybinding = FALSE; + gboolean has_metacity = FALSE; gchar *tmp; - tmp = g_build_filename (theme_dir, suffix, NULL); + tmp = g_build_filename (theme_dir, gtk2_suffix, NULL); if (g_file_test (tmp, G_FILE_TEST_IS_DIR)) { has_gtk = TRUE; @@ -66,33 +67,43 @@ update_theme_dir (const gchar *theme_dir) } g_free (tmp); + tmp = g_build_filename (theme_dir, metacity_suffix, NULL); + if (g_file_test (tmp, G_FILE_TEST_IS_DIR)) + { + has_metacity = TRUE; + } + g_free (tmp); + info = find_theme_info_by_dir (theme_dir); if (info) { - if (!has_gtk && ! has_keybinding) + if (!has_gtk && ! has_keybinding && ! has_metacity) { theme_list = g_list_remove (theme_list, info); theme_info_free (info); changed = TRUE; } else if ((info->has_keybinding != has_keybinding) || - (info->has_gtk != has_gtk)) + (info->has_gtk != has_gtk) || + (info->has_metacity != has_metacity)) { info->has_keybinding = has_keybinding; info->has_gtk = has_gtk; + info->has_metacity = has_metacity; changed = TRUE; } } else { - if (has_gtk || has_keybinding) + if (has_gtk || has_keybinding || has_metacity) { info = g_new0 (ThemeInfo, 1); info->path = g_strdup (theme_dir); info->name = g_strdup (strrchr (theme_dir, '/') + 1); info->has_gtk = has_gtk; info->has_keybinding = has_keybinding; + info->has_metacity = has_metacity; theme_list = g_list_prepend (theme_list, info); changed = TRUE; diff --git a/capplets/common/theme-common.h b/capplets/common/theme-common.h index 0ce52f165..2125fadb6 100644 --- a/capplets/common/theme-common.h +++ b/capplets/common/theme-common.h @@ -11,6 +11,7 @@ struct _ThemeInfo gchar *name; guint has_gtk : 1; guint has_keybinding : 1; + guint has_metacity : 1; guint user_writable : 1; }; diff --git a/capplets/keyboard/gnome-keyboard-properties.glade b/capplets/keyboard/gnome-keyboard-properties.glade index 075d1e399..a0b5b0fc5 100644 --- a/capplets/keyboard/gnome-keyboard-properties.glade +++ b/capplets/keyboard/gnome-keyboard-properties.glade @@ -229,7 +229,7 @@ 1 GTK_UPDATE_CONTINUOUS False - 500 50 1510 10 10 0 + 500 100 1510 10 10 0 1 diff --git a/gnome-settings-daemon/Makefile.am b/gnome-settings-daemon/Makefile.am index 4af1bed42..625cf14c0 100644 --- a/gnome-settings-daemon/Makefile.am +++ b/gnome-settings-daemon/Makefile.am @@ -1,7 +1,7 @@ INCLUDES=$(GNOME_SETTINGS_DAEMON_CFLAGS) -I$(top_srcdir)/libbackground -I$(top_srcdir) \ -DGNOMELOCALEDIR="\"$(datadir)/locale\"" \ - -DESD_SERVER="\"$(ESD_SERVER)\"" - + -DESD_SERVER="\"$(ESD_SERVER)\"" \ + -DDATADIR="\"$(datadir)\"" bin_PROGRAMS=gnome-settings-daemon gnome_settings_daemon_SOURCES = \ @@ -30,6 +30,8 @@ gnome_settings_daemon_SOURCES = \ gnome-settings-screensaver.c \ gnome-settings-default-editor.c \ gnome-settings-default-editor.h \ + gnome-settings-gtk1theme.c \ + gnome-settings-gtk1theme.h \ xsettings-common.c \ xsettings-manager.c \ xsettings-common.h \ diff --git a/gnome-settings-daemon/gnome-settings-daemon.c b/gnome-settings-daemon/gnome-settings-daemon.c index 947f74333..0fef31064 100644 --- a/gnome-settings-daemon/gnome-settings-daemon.c +++ b/gnome-settings-daemon/gnome-settings-daemon.c @@ -46,6 +46,7 @@ #include "gnome-settings-screensaver.h" #include "gnome-settings-default-editor.h" #include "gnome-settings-keybindings.h" +#include "gnome-settings-gtk1theme.h" #include "GNOME_SettingsDaemon.h" @@ -241,6 +242,7 @@ gnome_settings_daemon_new (void) gnome_settings_default_editor_init (client); gnome_settings_background_init (client); gnome_settings_keybindings_init (client); + gnome_settings_gtk1_theme_init (client); for (list = directories; list; list = list->next) { @@ -281,6 +283,7 @@ gnome_settings_daemon_new (void) gnome_settings_default_editor_load (client); gnome_settings_background_load (client); gnome_settings_keybindings_load (client); + gnome_settings_gtk1_theme_load (client); return G_OBJECT (daemon); } diff --git a/gnome-settings-daemon/gnome-settings-gtk1theme.c b/gnome-settings-daemon/gnome-settings-gtk1theme.c new file mode 100644 index 000000000..f4b05280e --- /dev/null +++ b/gnome-settings-daemon/gnome-settings-gtk1theme.c @@ -0,0 +1,220 @@ +/* -*- mode: c; style: linux -*- */ + +/* gnome-settings-gtk1theme.c + * + * Copyright © 2002 Red Hat, Inc. + * + * Written by Owen Taylor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "gnome-settings-daemon.h" +#include "gnome-settings-gtk1theme.h" + +#define GTK_THEME_KEY "/desktop/gnome/interface/gtk_theme" + +/* Given the theme filename, return the needed contents for the RC file + * in the user's home directory + */ +static char * +make_contents (const char *filename) +{ + GString *result = g_string_new (NULL); + + g_string_append (result, + "# Autowritten by gnome-settings-daemon. Do not edit\n" + "\n"); + if (filename) + g_string_append_printf (result, + "include \"%s\"\n" + "\n", + filename); + g_string_append_printf (result, + "include \"%s/.gtkrc.mine\"\n", + g_get_home_dir ()); + + return g_string_free (result, FALSE); +} + +/* Writes @contents to @rc_filename atomically (using rename); returns + * %TRUE on sucess + */ +static gboolean +write_contents (const char *rc_filename, + const char *contents) +{ + char *tmp_filename = g_strconcat (rc_filename, ".new", NULL); + GIOChannel *channel; + GError *err = NULL; + + channel = g_io_channel_new_file (tmp_filename, "w", &err); + if (!channel) { + g_warning ("Cannot open %s: %s", tmp_filename, err->message); + goto bail2; + } + + if (g_io_channel_write_chars (channel, contents, -1, NULL, &err) != G_IO_STATUS_NORMAL) { + g_warning ("Cannot open %s: %s", tmp_filename, err->message); + goto bail0; + } + + if (g_io_channel_flush (channel, &err) != G_IO_STATUS_NORMAL) { + g_warning ("Error flushing %s: %s", tmp_filename, err->message); + goto bail0; + } + + if (g_io_channel_shutdown (channel, TRUE, &err) != G_IO_STATUS_NORMAL) { + g_warning ("Error closing %s: %s", tmp_filename, err->message); + goto bail1; + } + + if (rename (tmp_filename, rc_filename) < 0) { + g_warning ("Cannot move %s to %s: %s", tmp_filename, rc_filename, g_strerror (errno)); + goto bail1; + + } + + g_free (tmp_filename); + + return TRUE; + + bail0: + g_io_channel_shutdown (channel, FALSE, NULL); + bail1: + unlink (tmp_filename); + bail2: + g_clear_error (&err); + g_free (tmp_filename); + + return FALSE; +} + +/* Send a client message telling GTK+-1.2 apps to reread their RC files + */ +static void +send_change_message (void) +{ + GdkEventClient sev; + int i; + + for(i = 0; i < 5; i++) + sev.data.l[i] = 0; + + sev.data_format = 32; + sev.message_type = gdk_atom_intern("_GTK_READ_RCFILES", FALSE); + + gdk_event_send_clientmessage_toall ((GdkEvent *) &sev); +} + +/* See if a theme called @theme exists in @base_dir. Takes ownership of @base_dir + */ +static char * +check_filename (char *base_dir, + const char *theme) +{ + char *theme_filename = g_build_filename (base_dir, theme, "gtk", "gtkrc", NULL); + + if (!g_file_test (theme_filename, G_FILE_TEST_EXISTS)) { + g_free (theme_filename); + theme_filename = NULL; + } + + g_free (base_dir); + + return theme_filename; +} + +static void +apply_settings (void) +{ + GConfClient *client = gconf_client_get_default (); + gchar *current_theme; + gchar *theme_filename; + gchar *rc_filename; + gchar *current_contents; + gint current_length; + gchar *new_contents; + GError *err = NULL; + + current_theme = gconf_client_get_string (client, GTK_THEME_KEY, NULL); + if (!current_theme) + current_theme = g_strdup ("Default"); + + /* Translate Default into Raleigh, since it's a better + * match than the default gtk1 theme. + */ + if (strcmp (current_theme, "Default") == 0) { + g_free (current_theme); + current_theme = g_strdup ("Raleigh"); + } + + /* Now look for a gtk1 theme with the name + */ + theme_filename = check_filename (g_build_filename (g_get_home_dir (),".themes", NULL), + current_theme); + + if (!theme_filename) { + theme_filename = check_filename (g_build_filename (DATADIR, "themes", NULL), + current_theme); + } + + /* If we don't find a match, use Raleigh + */ + if (!theme_filename) { + theme_filename = check_filename (g_build_filename (DATADIR, "themes", NULL), + "Raleigh"); + } + + rc_filename = g_build_filename (g_get_home_dir(), ".gtkrc-1.2-gnome2", NULL); + + if (!g_file_get_contents (rc_filename, ¤t_contents, ¤t_length, &err) && + !g_error_matches (err, G_FILE_ERROR, G_FILE_ERROR_NOENT)) { + g_warning ("Can't get contents of %s: %s", rc_filename, err->message); + g_clear_error (&err); + } + + new_contents = make_contents (theme_filename); + + if (!current_contents || + current_length != strlen (new_contents) || + memcmp (current_contents, new_contents, current_length) != 0) { + if (write_contents (rc_filename, new_contents)) + send_change_message (); + } + + g_object_unref (client); + g_free (new_contents); + g_free (current_contents); + g_free (rc_filename); +} + +void +gnome_settings_gtk1_theme_init (GConfClient *client) +{ + gnome_settings_daemon_register_callback (GTK_THEME_KEY, (KeyCallbackFunc) apply_settings); +} + +void +gnome_settings_gtk1_theme_load (GConfClient *client) +{ + apply_settings (); +} diff --git a/gnome-settings-daemon/gnome-settings-gtk1theme.h b/gnome-settings-daemon/gnome-settings-gtk1theme.h new file mode 100644 index 000000000..36cd2354c --- /dev/null +++ b/gnome-settings-daemon/gnome-settings-gtk1theme.h @@ -0,0 +1,34 @@ +/* -*- mode: c; style: linux -*- */ + +/* gnome-settings-keyboard.h + * + * Copyright © 2002 Red Hat, Inc. + * + * Written by Owen Taylor + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __GNOME_SETTINGS_GTK1THEME_H +#define __GNOME_SETTINGS_GTK1THEME_H + +#include +#include + +void gnome_settings_gtk1_theme_init (GConfClient *client); +void gnome_settings_gtk1_theme_load (GConfClient *client); + +#endif