diff --git a/capplets/theme-switcher/ChangeLog b/capplets/theme-switcher/ChangeLog index 1ca1059d5..021561d51 100644 --- a/capplets/theme-switcher/ChangeLog +++ b/capplets/theme-switcher/ChangeLog @@ -1,3 +1,8 @@ +2002-10-26 Havoc Pennington + + * theme-switcher.c (window_read_themes): adapt to gnome-wm-manager + API changes + 2002-10-21 Jody Goldberg * Release 2.1.1 diff --git a/capplets/theme-switcher/theme-switcher.c b/capplets/theme-switcher/theme-switcher.c index ef06d2c90..6cd593e29 100644 --- a/capplets/theme-switcher/theme-switcher.c +++ b/capplets/theme-switcher/theme-switcher.c @@ -271,10 +271,13 @@ window_read_themes (GladeXML *dialog) gboolean current_theme_found = FALSE; GtkTreeRowReference *row_ref = NULL; GnomeWindowManager *wm; + GdkScreen *screen; client = gconf_client_get_default (); - wm = gnome_wm_manager_get_current (); + screen = gdk_display_get_default_screen (gdk_display_get_default ()); + + wm = gnome_wm_manager_get_current (screen); if (wm != NULL) { window_theme_list = gnome_window_manager_get_theme_list (wm); g_object_unref (G_OBJECT (wm)); @@ -479,7 +482,7 @@ window_show_manage_themes (GtkWidget *button, gpointer data) GnomeVFSURI *uri; GnomeWindowManager *wm; - wm = gnome_wm_manager_get_current (); + wm = gnome_wm_manager_get_current (gtk_widget_get_screen (button)); path = gnome_window_manager_get_user_theme_folder (wm); g_object_unref (G_OBJECT (wm)); @@ -824,7 +827,7 @@ main (int argc, char *argv[]) activate_settings_daemon (); dialog = create_dialog (); - gnome_wm_manager_init (WID ("theme_dialog")); + gnome_wm_manager_init (); setup_dialog (dialog); gtk_main (); diff --git a/capplets/windows/ChangeLog b/capplets/windows/ChangeLog index 9ddcee2db..5b6d8ad05 100644 --- a/capplets/windows/ChangeLog +++ b/capplets/windows/ChangeLog @@ -1,3 +1,12 @@ +2002-10-26 Havoc Pennington + + * gnome-window-properties.c: rewrite + + * Makefile.am (bin_PROGRAMS): remove metacity module, move to + libwindow-settings + (gnome_window_properties_LDADD): properly link to .la file for + libgnome-window-settings, not the installed copy + 2002-10-21 Seth Nickell * gnome-window-properties.c: (setup_appearance_option_menu): diff --git a/capplets/windows/Makefile.am b/capplets/windows/Makefile.am index 92370e78d..7cb506f2a 100644 --- a/capplets/windows/Makefile.am +++ b/capplets/windows/Makefile.am @@ -1,34 +1,18 @@ bin_PROGRAMS = gnome-window-properties gnome_window_properties_LDADD = $(GNOMECC_CAPPLETS_LIBS) \ - -L$(top_builddir)/libwindow-settings/ -lgnome-window-settings + $(top_builddir)/libwindow-settings/libgnome-window-settings.la gnome_window_properties_SOURCES = \ gnome-window-properties.c - -wms_flags = -export_dynamic -avoid-version -wmsdir = $(libdir)/window-manager-settings/ - -wms_LTLIBRARIES = \ - libmetacity.la - -libmetacity_la_SOURCES = \ - metacity-window-manager.c \ - metacity-window-manager.h - - -libmetacity_la_LDFLAGS = $(wms_flags) -#libmetacity_la_LIBADD = $(top_builddir)/libwindow-settings/libwindow-settings.la - - @INTLTOOL_DESKTOP_RULE@ pixmapdir = $(GNOMECC_PIXMAPS_DIR) pixmap_DATA = -Gladedir = $(GNOMECC_GLADE_DIR) -Glade_DATA = gnome-window-properties.glade +gladedir = $(GNOMECC_GLADE_DIR) +glade_DATA = gnome-window-properties.glade iconsdir = $(GNOMECC_ICONS_DIR) icons_DATA = window-capplet.png @@ -43,7 +27,9 @@ desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop) INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS) \ -I $(top_srcdir)/libwindow-settings \ -DGNOME_WINDOW_MANAGER_MODULE_PATH=\""$(libdir)/window-manager-settings"\" \ - -DMETACITY_THEME_DIR=\""$(datadir)/metacity/themes"\" -CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) -EXTRA_DIST = $(Glade_DATA) $(icons_DATA) $(Desktop_in_files) $(pixmap_DATA) + -DGLADEDIR=\""$(gladedir)"\" \ + -DPIXMAPDIR=\""$(pixmapdir)"\" + +CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES) +EXTRA_DIST = $(glade_DATA) $(icons_DATA) $(Desktop_in_files) $(pixmap_DATA) diff --git a/capplets/windows/gnome-window-properties.c b/capplets/windows/gnome-window-properties.c index 21ea022d7..7d70aee83 100644 --- a/capplets/windows/gnome-window-properties.c +++ b/capplets/windows/gnome-window-properties.c @@ -2,8 +2,10 @@ /* gnome-window-properties.c * Copyright (C) 2002 Seth Nickell + * Copyright (C) 2002 Red Hat, Inc. * * Written by: Seth Nickell + * Havoc Pennington * * 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 @@ -22,11 +24,9 @@ */ #ifdef HAVE_CONFIG_H -# include +#include #endif -#include - #include #include #include @@ -34,273 +34,595 @@ #include "capplet-util.h" #include "gconf-property-editor.h" - -#define THEME_KEY "/desktop/gnome/applications/window_manager/theme" -#define TITLEBAR_FONT_KEY "/desktop/gnome/applications/window_manager/titlebar_font" -#define FOCUS_FOLLOWS_MOUSE_KEY "/desktop/gnome/applications/window_manager/focus_follows_mouse" - -static GtkWidget *wm_widget; -static GtkWidget *apply_now_button; -static GtkWidget *properties_box; -static GtkWidget *wm_menu; -static GtkWidget *option_menu; -static GList *wm_menu_window_managers; - -static GtkWidget *appearance_option_menu; -static GList *theme_list; - -static GnomeWindowManager *selected_wm; - -static gboolean in_fill; +typedef struct +{ + int number; + char *name; + const char *value; /* machine-readable name for storing config */ +} MouseClickModifier; static GConfClient *gconf_client; +static GladeXML *dialog; +static GnomeWindowManager *current_wm; /* may be NULL */ +static GtkWidget *dialog_win; +static GtkWidget *focus_mode_checkbutton; +static GtkWidget *autoraise_checkbutton; +static GtkWidget *autoraise_delay_spinbutton; +static GtkWidget *autoraise_delay_hbox; +static GtkWidget *double_click_titlebar_optionmenu; +static GtkWidget *double_click_titlebar_hbox; +static GtkWidget *alt_click_optionmenu; -static void setup_appearance_option_menu (GtkWidget *appearance_option_menu, GnomeWindowManager *wm); +static GnomeWMSettings settings; +static const GnomeWMDoubleClickAction *double_click_actions = NULL; +static int n_double_click_actions = 0; + +static MouseClickModifier *mouse_modifiers = NULL; +static int n_mouse_modifiers = 0; + +static void reload_mouse_modifiers (void); static void -set_wm_change_pending (gboolean pending) +mouse_focus_toggled_callback (GtkWidget *button, + void *data) { - gtk_widget_set_sensitive (apply_now_button, pending); - gtk_widget_set_sensitive (properties_box, !pending); + GnomeWMSettings new_settings; + + new_settings.flags = GNOME_WM_SETTING_MOUSE_FOCUS; + new_settings.focus_follows_mouse = + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + + if (current_wm != NULL && new_settings.focus_follows_mouse != settings.focus_follows_mouse) + gnome_window_manager_change_settings (current_wm, &new_settings); } static void -wm_selection_changed (GtkOptionMenu *option_menu, gpointer data) +autoraise_toggled_callback (GtkWidget *button, + void *data) { - int index; - GnomeWindowManager *wm; + GnomeWMSettings new_settings; - index = gtk_option_menu_get_history (option_menu); - wm = (GnomeWindowManager *) g_list_nth (wm_menu_window_managers, index)->data; + new_settings.flags = GNOME_WM_SETTING_AUTORAISE; + new_settings.autoraise = + gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); + + if (current_wm != NULL && new_settings.autoraise != settings.autoraise) + gnome_window_manager_change_settings (current_wm, &new_settings); - if (!in_fill) { - if (!gnome_wm_manager_same_wm (wm, selected_wm)) { - selected_wm = wm; - set_wm_change_pending (TRUE); - } - } } static void -wm_widget_clear () +autoraise_delay_value_changed_callback (GtkWidget *spinbutton, + void *data) { - wm_menu_window_managers = NULL; + GnomeWMSettings new_settings; - wm_menu = gtk_menu_new (); - gtk_widget_show_all (wm_menu); - gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), wm_menu); -} + new_settings.flags = GNOME_WM_SETTING_AUTORAISE_DELAY; + new_settings.autoraise_delay = + gtk_spin_button_get_value (GTK_SPIN_BUTTON (spinbutton)) * 100; -GtkWidget * -wm_widget_new () -{ - option_menu = gtk_option_menu_new (); - g_signal_connect (G_OBJECT (option_menu), "changed", - (GCallback)wm_selection_changed, NULL); - - wm_widget_clear (); - - gtk_widget_show_all (option_menu); - return option_menu; + if (current_wm != NULL && new_settings.autoraise_delay != settings.autoraise_delay) + gnome_window_manager_change_settings (current_wm, &new_settings); } static void -wm_widget_add_wm (GnomeWindowManager *wm) +double_click_titlebar_changed_callback (GtkWidget *optionmenu, + void *data) { - GtkWidget *menu_item; - const char *row_text; + GnomeWMSettings new_settings; + + new_settings.flags = GNOME_WM_SETTING_DOUBLE_CLICK_ACTION; + new_settings.double_click_action = + gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu)); - row_text = gnome_window_manager_get_name (wm); - - menu_item = gtk_menu_item_new_with_label (row_text); - gtk_widget_show_all (menu_item); - - gtk_menu_shell_prepend (GTK_MENU_SHELL (wm_menu), menu_item); - wm_menu_window_managers = g_list_append (wm_menu_window_managers, wm); - - /* If this is supposed to be the selected window manager, do so */ - if (gnome_wm_manager_same_wm (wm, selected_wm)) - gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), g_list_length (wm_menu_window_managers) - 1); + if (current_wm != NULL && new_settings.double_click_action != settings.double_click_action) + gnome_window_manager_change_settings (current_wm, &new_settings); } static void -response_cb (GtkDialog *dialog, gint response_id, gpointer data) +alt_click_modifier_changed_callback (GtkWidget *optionmenu, + void *data) { - switch (response_id) - { - case GTK_RESPONSE_NONE: - case GTK_RESPONSE_CLOSE: - gtk_main_quit (); - break; - } + GnomeWMSettings new_settings; + int history; + + new_settings.flags = GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER; + history = gtk_option_menu_get_history (GTK_OPTION_MENU (optionmenu)); + + if (history >= n_mouse_modifiers) /* paranoia */ + return; + + new_settings.mouse_move_modifier = mouse_modifiers[history].value; + + if (current_wm != NULL && + strcmp (new_settings.mouse_move_modifier, + settings.mouse_move_modifier) != 0) + gnome_window_manager_change_settings (current_wm, &new_settings); } static void -update_gui (void) +update_sensitivity (void) { - GList *tmp_list; - GnomeWindowManager *wm; + gtk_widget_set_sensitive (autoraise_checkbutton, + settings.focus_follows_mouse); + + gtk_widget_set_sensitive (autoraise_delay_hbox, + settings.focus_follows_mouse && settings.autoraise); - wm_widget_clear (); + gtk_widget_set_sensitive (double_click_titlebar_optionmenu, + n_double_click_actions > 1); - in_fill = TRUE; + /* disable the whole dialog while no WM is running, or + * a WM we don't understand is running. We should probably do + * something better. I don't want to just launch the config tool + * as we would on startup though, because then you'd get weirdness + * in the gap time between old and new WM. + */ + gtk_widget_set_sensitive (dialog_win, current_wm != NULL); +} - tmp_list = gnome_wm_manager_get_list (); +static void +init_settings_struct (GnomeWMSettings *settings) +{ + /* Init fields that weren't initialized */ + if ((settings->flags & GNOME_WM_SETTING_MOUSE_FOCUS) == 0) + settings->focus_follows_mouse = FALSE; + + if ((settings->flags & GNOME_WM_SETTING_AUTORAISE) == 0) + settings->autoraise = FALSE; + + if ((settings->flags & GNOME_WM_SETTING_AUTORAISE_DELAY) == 0) + settings->autoraise_delay = 1000; + + if ((settings->flags & GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER) == 0) + settings->mouse_move_modifier = "Super"; - printf ("got a list of %d wms\n", g_list_length (tmp_list)); + if ((settings->flags & GNOME_WM_SETTING_DOUBLE_CLICK_ACTION) == 0) + settings->double_click_action = 0; +} - for (tmp_list = gnome_wm_manager_get_list (); tmp_list != NULL; tmp_list = tmp_list->next) { - wm = tmp_list->data; - if (wm != NULL) wm_widget_add_wm (wm); +static void +set_alt_click_optionmenu_value (const GnomeWMSettings *settings) +{ + int i; + + i = 0; + while (i < n_mouse_modifiers) { + if (strcmp (mouse_modifiers[i].value, + settings->mouse_move_modifier) == 0) + break; + ++i; } - in_fill = FALSE; - + if (i < n_mouse_modifiers) + gtk_option_menu_set_history (GTK_OPTION_MENU (alt_click_optionmenu), + i); } static void -apply_wm (GObject *object, gpointer data) +rebuild_double_click_actions_menu (void) { - gnome_wm_manager_set_current (selected_wm); - setup_appearance_option_menu (appearance_option_menu, selected_wm); - set_wm_change_pending (FALSE); -} - -static GladeXML * -create_dialog (void) -{ - GladeXML *dialog; + int i; + GtkWidget *menu; - dialog = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/gnome-window-properties.glade", "prefs_widget", NULL); - - apply_now_button = WID ("apply_now_button"); - g_signal_connect (G_OBJECT (apply_now_button), "clicked", (GCallback)apply_wm, NULL); - - properties_box = WID ("properties_box"); - - set_wm_change_pending (FALSE); - - wm_widget = wm_widget_new (); - - gtk_box_pack_start (GTK_BOX (WID ("wm_widget_box")), wm_widget, TRUE, TRUE, 0); - - return dialog; -} - -static void -setup_appearance_option_menu (GtkWidget *appearance_option_menu, GnomeWindowManager *wm) -{ - GtkWidget *menu, *menu_item; - GList *themes, *node; - const char *theme_name; - char *current_theme_name; - int index = 0; - menu = gtk_menu_new (); - gtk_widget_show_all (menu); - gtk_option_menu_set_menu (GTK_OPTION_MENU (appearance_option_menu), menu); + i = 0; + while (i < n_double_click_actions) { + GtkWidget *mi; + + mi = gtk_menu_item_new_with_label (double_click_actions[i].human_readable_name); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + mi); + + gtk_widget_show (mi); + + ++i; + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (double_click_titlebar_optionmenu), + menu); +} - themes = gnome_window_manager_get_theme_list (wm); +static void +reload_settings (void) +{ + GnomeWMSettings new_settings; - current_theme_name = gconf_client_get_string (gconf_client, THEME_KEY, NULL); + g_assert (n_mouse_modifiers > 0); + + if (current_wm != NULL) { + new_settings.flags = GNOME_WM_SETTING_MOUSE_FOCUS | + GNOME_WM_SETTING_AUTORAISE | + GNOME_WM_SETTING_AUTORAISE_DELAY | + GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER | + GNOME_WM_SETTING_DOUBLE_CLICK_ACTION; - for (node = themes; node != NULL; node = node->next) { - theme_name = (char *)node->data; - - menu_item = gtk_menu_item_new_with_label (theme_name); - gtk_widget_show_all (menu_item); - - gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item); - - if ((current_theme_name != NULL) && (theme_name != NULL) && (strcmp (theme_name, current_theme_name) == 0)) - gtk_option_menu_set_history (GTK_OPTION_MENU (appearance_option_menu), index); - - index++; + /* this will clear any flags that don't get filled in */ + gnome_window_manager_get_settings (current_wm, &new_settings); + } else { + new_settings.flags = 0; } - g_free (current_theme_name); - - theme_list = themes; -} - -static void -appearance_changed (GtkOptionMenu *option_menu, gpointer data) -{ - int index; - const char *theme_name; - - index = gtk_option_menu_get_history (option_menu); - theme_name = (const char *) g_list_nth (theme_list, index)->data; - - printf ("Setting theme to %s\n", theme_name); + init_settings_struct (&new_settings); - gconf_client_set_string (gconf_client, THEME_KEY, theme_name, NULL); + if (new_settings.focus_follows_mouse != settings.focus_follows_mouse) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (focus_mode_checkbutton), + new_settings.focus_follows_mouse); + + if (new_settings.autoraise != settings.autoraise) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (autoraise_checkbutton), + new_settings.autoraise); + + if (new_settings.autoraise_delay != settings.autoraise_delay) + gtk_spin_button_set_value (GTK_SPIN_BUTTON (autoraise_delay_spinbutton), + new_settings.autoraise_delay / 100); + + if (n_double_click_actions > 0 && + new_settings.double_click_action != settings.double_click_action) { + gtk_option_menu_set_history (GTK_OPTION_MENU (double_click_titlebar_optionmenu), + new_settings.double_click_action); + } + + + if (settings.mouse_move_modifier == NULL || + strcmp (settings.mouse_move_modifier, + new_settings.mouse_move_modifier) != 0) { + set_alt_click_optionmenu_value (&new_settings); + } + + settings = new_settings; + + update_sensitivity (); } static void -setup_dialog (GladeXML *dialog) -{ - GObject *peditor; - - update_gui (); - - peditor = gconf_peditor_new_font (NULL, TITLEBAR_FONT_KEY, - WID ("titlebar_font"), - PEDITOR_FONT_COMBINED, NULL); - - peditor = gconf_peditor_new_boolean (NULL, FOCUS_FOLLOWS_MOUSE_KEY, - WID ("focus_follows_mouse"), - NULL); - - appearance_option_menu = WID ("window_border_appearance"); - setup_appearance_option_menu (appearance_option_menu, selected_wm); - g_signal_connect (G_OBJECT (appearance_option_menu), "changed", - (GCallback)appearance_changed, NULL); - gtk_widget_show_all (appearance_option_menu); +wm_settings_changed_callback (GnomeWindowManager *wm, + void *data) +{ + reload_settings (); } +static void +update_wm (GdkScreen *screen, + gboolean load_settings) +{ + g_assert (n_mouse_modifiers > 0); + + if (current_wm != NULL) { + g_signal_handlers_disconnect_by_func (G_OBJECT (current_wm), + G_CALLBACK (wm_settings_changed_callback), + NULL); + current_wm = NULL; + double_click_actions = NULL; + n_double_click_actions = 0; + } + current_wm = gnome_wm_manager_get_current (screen); + + if (current_wm != NULL) { + g_signal_connect (G_OBJECT (current_wm), "settings_changed", + G_CALLBACK (wm_settings_changed_callback), NULL); + + gnome_window_manager_get_double_click_actions (current_wm, + &double_click_actions, + &n_double_click_actions); + + } + + rebuild_double_click_actions_menu (); + if (load_settings) + reload_settings (); +} + +static void +wm_changed_callback (GdkScreen *screen, + void *data) +{ + update_wm (screen, TRUE); +} + +static void +response_cb (GtkWidget *dialog_win, + int response_id, + void *data) +{ + + if (response_id == GTK_RESPONSE_HELP) { + + } else { + gtk_widget_destroy (dialog_win); + } +} + +static void +try_spawn_config_tool (GdkScreen *screen) +{ + GError *error; + + error = NULL; + gnome_wm_manager_spawn_config_tool_for_current (screen, &error); + + if (error != NULL) { + GtkWidget *no_tool_dialog; + char *str; + char *escaped; + + escaped = g_markup_escape_text (error->message, -1); + + str = g_strdup_printf (_("Cannot start the preferences application for your window manager\n\n%s"), + escaped); + g_free (escaped); + + no_tool_dialog = + gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + " "); + gtk_window_set_title (GTK_WINDOW (no_tool_dialog), ""); + gtk_window_set_resizable (GTK_WINDOW (no_tool_dialog), FALSE); + + gtk_label_set_markup (GTK_LABEL (GTK_MESSAGE_DIALOG (no_tool_dialog)->label), + str); + + g_free (str); + + gtk_dialog_run (GTK_DIALOG (no_tool_dialog)); + + gtk_widget_destroy (no_tool_dialog); + g_error_free (error); + + exit (1); + } + + /* exit, let the config tool handle it */ + exit (0); +} int main (int argc, char **argv) { - GladeXML *dialog; - GtkWidget *dialog_win; - + GdkScreen *screen; + GtkSizeGroup *size_group; + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); - gnome_program_init ("wm-properties", VERSION, + gnome_program_init ("gnome-window-properties", VERSION, LIBGNOMEUI_MODULE, argc, argv, - GNOME_PARAM_POPT_TABLE, NULL); gconf_client = gconf_client_get_default (); - - dialog_win = gtk_dialog_new_with_buttons - (_("Window Preferences"), NULL, -1, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - g_signal_connect (G_OBJECT (dialog_win), "response", (GCallback)response_cb, NULL); - gnome_wm_manager_init (dialog_win); - selected_wm = gnome_wm_manager_get_current (); + gnome_wm_manager_init (); - dialog = create_dialog (); - setup_dialog (dialog); + screen = gdk_display_get_default_screen (gdk_display_get_default ()); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_win)->vbox), WID ("prefs_widget"), TRUE, TRUE, GNOME_PAD_SMALL); - gtk_widget_show_all (dialog_win); + current_wm = gnome_wm_manager_get_current (screen); + + if (current_wm == NULL) { + try_spawn_config_tool (screen); + return 0; + } + + dialog = glade_xml_new (GLADEDIR "/gnome-window-properties.glade", + "main-dialog", GETTEXT_PACKAGE); + + if (dialog == NULL) { + g_warning ("Missing glade file for gnome-window-properties"); + exit (1); + } + + dialog_win = WID ("main-dialog"); + focus_mode_checkbutton = WID ("focus-mode-checkbutton"); + autoraise_checkbutton = WID ("autoraise-checkbutton"); + autoraise_delay_spinbutton = WID ("autoraise-delay-spinbutton"); + autoraise_delay_hbox = WID ("autoraise-delay-hbox"); + double_click_titlebar_optionmenu = WID ("double-click-titlebar-optionmenu"); + double_click_titlebar_hbox = WID ("double-click-titlebar-hbox"); + alt_click_optionmenu = WID ("alt-click-optionmenu"); + + gtk_spin_button_set_range (GTK_SPIN_BUTTON (autoraise_delay_spinbutton), + 0, 100); + + gtk_spin_button_set_increments (GTK_SPIN_BUTTON (autoraise_delay_spinbutton), + 1, 5); + + size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + gtk_size_group_add_widget (size_group, double_click_titlebar_optionmenu); + gtk_size_group_add_widget (size_group, alt_click_optionmenu); + g_object_unref (G_OBJECT (size_group)); + + settings.flags = 0; + init_settings_struct (&settings); + + reload_mouse_modifiers (); + update_wm (screen, FALSE); + + set_alt_click_optionmenu_value (&settings); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (autoraise_delay_spinbutton), + settings.autoraise_delay / 100); + gtk_option_menu_set_history (GTK_OPTION_MENU (double_click_titlebar_optionmenu), + settings.double_click_action); + + reload_settings (); /* must come before below signal connections */ + + g_signal_connect (G_OBJECT (dialog_win), "response", + G_CALLBACK (response_cb), NULL); + + g_signal_connect (G_OBJECT (dialog_win), "destroy", + G_CALLBACK (gtk_main_quit), NULL); + + + g_signal_connect (G_OBJECT (focus_mode_checkbutton), "toggled", + G_CALLBACK (mouse_focus_toggled_callback), NULL); + + g_signal_connect (G_OBJECT (autoraise_checkbutton), "toggled", + G_CALLBACK (autoraise_toggled_callback), NULL); + + g_signal_connect (G_OBJECT (autoraise_delay_spinbutton), "value_changed", + G_CALLBACK (autoraise_delay_value_changed_callback), NULL); + + g_signal_connect (G_OBJECT (double_click_titlebar_optionmenu), "changed", + G_CALLBACK (double_click_titlebar_changed_callback), NULL); + + g_signal_connect (G_OBJECT (alt_click_optionmenu), "changed", + G_CALLBACK (alt_click_modifier_changed_callback), NULL); + + g_signal_connect (G_OBJECT (screen), "window_manager_changed", + G_CALLBACK (wm_changed_callback), NULL); + + gtk_widget_show (dialog_win); gtk_main (); - - /* FIXME: we need to handle this through the library somehow - if (restart_pending) { - quit_pending = TRUE; - gtk_main(); - } - */ return 0; } + +#include +#include +#include +static void +reload_mouse_modifiers (void) +{ + XModifierKeymap *modmap; + KeySym *keymap; + int keysyms_per_keycode; + int map_size; + int i; + gboolean have_meta; + gboolean have_hyper; + gboolean have_super; + int min_keycode, max_keycode; + + XDisplayKeycodes (gdk_display, + &min_keycode, + &max_keycode); + + keymap = XGetKeyboardMapping (gdk_display, + min_keycode, + max_keycode - min_keycode, + &keysyms_per_keycode); + + modmap = XGetModifierMapping (gdk_display); + + have_super = FALSE; + have_meta = FALSE; + have_hyper = FALSE; + + /* there are 8 modifiers, and the first 3 are shift, shift lock, + * and control + */ + map_size = 8 * modmap->max_keypermod; + i = 3 * modmap->max_keypermod; + while (i < map_size) { + /* get the key code at this point in the map, + * see if its keysym is one we're interested in + */ + int keycode = modmap->modifiermap[i]; + + if (keycode >= min_keycode && + keycode <= max_keycode) { + int j = 0; + KeySym *syms = keymap + (keycode - min_keycode) * keysyms_per_keycode; + + while (j < keysyms_per_keycode) { + if (syms[j] == XK_Super_L || + syms[j] == XK_Super_R) + have_super = TRUE; + else if (syms[j] == XK_Hyper_L || + syms[j] == XK_Hyper_R) + have_hyper = TRUE; + else if ((syms[j] == XK_Meta_L || + syms[j] == XK_Meta_R) && + (1 << ( i / modmap->max_keypermod)) != Mod1Mask) + have_meta = TRUE; + ++j; + } + } + + ++i; + } + + XFreeModifiermap (modmap); + XFree (keymap); + + i = 0; + while (i < n_mouse_modifiers) { + g_free (mouse_modifiers[i].name); + ++i; + } + g_free (mouse_modifiers); + mouse_modifiers = NULL; + + + n_mouse_modifiers = 2; /* control, alt */ + if (have_super) + ++n_mouse_modifiers; + if (have_hyper) + ++n_mouse_modifiers; + if (have_meta) + ++n_mouse_modifiers; + + g_free (mouse_modifiers); + + mouse_modifiers = g_new0 (MouseClickModifier, n_mouse_modifiers); + + i = 0; + + mouse_modifiers[i].number = i; + mouse_modifiers[i].name = g_strdup (_("Control")); + mouse_modifiers[i].value = "Control"; + ++i; + + mouse_modifiers[i].number = i; + mouse_modifiers[i].name = g_strdup (_("Alt")); + mouse_modifiers[i].value = "Alt"; + ++i; + + if (have_hyper) { + mouse_modifiers[i].number = i; + mouse_modifiers[i].name = g_strdup (_("Hyper")); + mouse_modifiers[i].value = "Hyper"; + ++i; + } + + if (have_super) { + mouse_modifiers[i].number = i; + mouse_modifiers[i].name = g_strdup (_("Super")); + mouse_modifiers[i].value = "Super"; + ++i; + } + + if (have_meta) { + mouse_modifiers[i].number = i; + mouse_modifiers[i].name = g_strdup (_("Meta")); + mouse_modifiers[i].value = "Meta"; + ++i; + } + + g_assert (i == n_mouse_modifiers); + + /* Build modifier option menu */ + { + GtkWidget *menu; + + menu = gtk_menu_new (); + i = 0; + while (i < n_mouse_modifiers) { + GtkWidget *mi; + + mi = gtk_menu_item_new_with_label (mouse_modifiers[i].name); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), + mi); + + gtk_widget_show (mi); + + ++i; + } + + gtk_option_menu_set_menu (GTK_OPTION_MENU (alt_click_optionmenu), + menu); + } +} diff --git a/capplets/windows/gnome-window-properties.glade b/capplets/windows/gnome-window-properties.glade index 780f5c78d..6cf80b7d2 100644 --- a/capplets/windows/gnome-window-properties.glade +++ b/capplets/windows/gnome-window-properties.glade @@ -2,165 +2,131 @@ - - - True + + 6 Window Preferences GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False - True + False False + False - - - 5 + + True False - 5 + 0 - - + + True - False - 9 + GTK_BUTTONBOX_END - + + True + True + True + gtk-help + True + GTK_RELIEF_NORMAL + -11 + + + + + + True + True + True + gtk-close + True + GTK_RELIEF_NORMAL + -7 + + + + + 0 + False + True + GTK_PACK_END + + + + + + True + 12 + 14 + True + 0 + 0 + + + + True + True + _Select windows when the mouse moves over them + True + GTK_RELIEF_NORMAL + False + False + True + + + 0 + 14 + 0 + 2 + fill + + + + + + + True + True + _Raise selected windows after a short time + True + GTK_RELIEF_NORMAL + False + False + True + + + 1 + 14 + 2 + 4 + fill + + + + + + True False - 3 + 6 - + True - Window Manager: - False + _Double-click window titles to: + True False GTK_JUSTIFY_LEFT False False - 0.5 + 0 0.5 0 0 - - - 0 - False - False - - - - - - True - False - 0 - - - - - - - 0 - True - True - - - - - 0 - True - True - - - - - - True - True - Apply Now - True - GTK_RELIEF_NORMAL - - - 0 - False - False - - - - - 0 - False - True - - - - - - True - - - 0 - False - True - - - - - - True - False - 9 - - - - True - False - 3 - - - - True - False - 0 - - - - True - Window Border Appearance - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - True - -1 - - - 0 - False - False - - + double-click-titlebar-optionmenu 0 @@ -170,92 +136,171 @@ - - True - False - 0 - - - - True - Titlebar Font - False - False - GTK_JUSTIFY_LEFT - False - False - 0 - 0.5 - 0 - 0 - - - 0 - False - False - - - - - - True - True - GNOME_FONT_PICKER_MODE_FONT_INFO - True - True - 14 - - - 0 - False - False - - - - - 0 - True - True - - - - - 0 - False - True - - - - - - True - False - 0 - - - + True True - Select windows when the mouse moves over them - True - GTK_RELIEF_NORMAL - False - False - True + -1 + + + + + + + + 0 False - False + True - 0 - False - False + 0 + 14 + 7 + 9 + fill + + + + True + False + 6 + + + + True + To _move windows, click while holding down: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + alt-click-optionmenu + + + 0 + True + True + + + + + + True + True + -1 + + + + + + + + + + + 0 + False + True + + + + + 0 + 14 + 10 + 12 + fill + + + + + + True + False + 6 + + + + True + _Tenths of a second before raising the window: + True + False + GTK_JUSTIFY_LEFT + False + False + 0 + 0.5 + 0 + 0 + autoraise-delay-spinbutton + + + 0 + True + True + + + + + + True + True + 1 + 0 + False + GTK_UPDATE_ALWAYS + False + False + 1 0 100 1 10 10 + + + + + + 0 + False + True + + + + + 2 + 14 + 4 + 6 + fill + + + + + 0 + True + True + + + + + + 10 + True + 0.5 + 0.5 + 0 + 1 + + + + 0 diff --git a/capplets/windows/metacity-window-manager.c b/capplets/windows/metacity-window-manager.c deleted file mode 100644 index 48b7b1a10..000000000 --- a/capplets/windows/metacity-window-manager.c +++ /dev/null @@ -1,197 +0,0 @@ -#include -#include -#include -#include -#include - -#include "metacity-window-manager.h" - -#define METACITY_THEME_KEY "/apps/metacity/general/theme" -#define METACITY_FONT_KEY "/apps/metacity/general/titlebar_font" -#define METACITY_FOCUS_KEY "/apps/metacity/general/focus_mode" -#define METACITY_USE_SYSTEM_FONT_KEY "/apps/metacity/titlebar_uses_system_font" - -static GnomeWindowManagerClass *parent_class; - -struct _MetacityWindowManagerPrivate { - int padding; -}; - -/* this function is called when the shared lib is loaded */ -GObject * -window_manager_new (void) -{ - GObject *wm; - - wm = g_object_new (metacity_window_manager_get_type (), NULL); - - return wm; -} - -static void -metacity_set_theme (GnomeWindowManager *wm, const char *theme_name) -{ - gconf_client_set_string (gconf_client_get_default (), - METACITY_THEME_KEY, - theme_name, NULL); -} - -static GList * -add_themes_from_dir (GList *current_list, const char *path) -{ - DIR *theme_dir; - struct dirent *entry; - char *theme_file_path; - GList *node; - gboolean found = FALSE; - - if (!(g_file_test (path, G_FILE_TEST_EXISTS) && g_file_test (path, G_FILE_TEST_IS_DIR))) { - return current_list; - } - - theme_dir = opendir (path); - - for (entry = readdir (theme_dir); entry != NULL; entry = readdir (theme_dir)) { - theme_file_path = g_build_filename (path, entry->d_name, "metacity-theme-1.xml", NULL); - - if (g_file_test (theme_file_path, G_FILE_TEST_EXISTS)) { - - for (node = current_list; (node != NULL) && (!found); node = node->next) { - found = (strcmp (node->data, entry->d_name) == 0); - } - - if (!found) { - current_list = g_list_prepend (current_list, g_strdup (entry->d_name)); - } - } - - /*g_free (entry);*/ - g_free (theme_file_path); - } - - closedir (theme_dir); - - return current_list; -} - -static GList * -metacity_get_theme_list (GnomeWindowManager *wm) -{ - GList *themes = NULL; - char *home_dir_themes; - - home_dir_themes = g_build_filename (g_get_home_dir (), ".metacity/themes", NULL); - - themes = add_themes_from_dir (themes, METACITY_THEME_DIR); - themes = add_themes_from_dir (themes, "/usr/share/metacity/themes"); - themes = add_themes_from_dir (themes, home_dir_themes); - - g_free (home_dir_themes); - - return themes; -} - -static void -metacity_set_font (GnomeWindowManager *wm, const char *font) -{ - GConfClient *client; - - client = gconf_client_get_default (); - - gconf_client_set_bool (client, METACITY_USE_SYSTEM_FONT_KEY, FALSE, NULL); - gconf_client_set_string (client, METACITY_FONT_KEY, font, NULL); -} - -static void -metacity_set_focus_follows_mouse (GnomeWindowManager *wm, gboolean focus_follows_mouse) -{ - const char *focus_mode; - - if (focus_follows_mouse) { - focus_mode = "sloppy"; - } else { - focus_mode = "click"; - } - - gconf_client_set_string (gconf_client_get_default (), - METACITY_FOCUS_KEY, - focus_mode, NULL); -} - -static char * -metacity_get_user_theme_folder (GnomeWindowManager *wm) -{ - return g_build_filename (g_get_home_dir (), ".metacity/themes", NULL); -} - -static void -metacity_window_manager_init (MetacityWindowManager *metacity_window_manager, MetacityWindowManagerClass *class) -{ - metacity_window_manager->p = g_new0 (MetacityWindowManagerPrivate, 1); -} - -static void -metacity_window_manager_finalize (GObject *object) -{ - MetacityWindowManager *metacity_window_manager; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_METACITY_WINDOW_MANAGER (object)); - - metacity_window_manager = METACITY_WINDOW_MANAGER (object); - - g_free (metacity_window_manager->p); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - - -static void -metacity_window_manager_class_init (MetacityWindowManagerClass *class) -{ - GObjectClass *object_class; - GnomeWindowManagerClass *wm_class; - - object_class = G_OBJECT_CLASS (class); - wm_class = GNOME_WINDOW_MANAGER_CLASS (class); - - object_class->finalize = metacity_window_manager_finalize; - - wm_class->set_theme = metacity_set_theme; - wm_class->get_theme_list = metacity_get_theme_list; - wm_class->set_font = metacity_set_font; - wm_class->set_focus_follows_mouse = metacity_set_focus_follows_mouse; - wm_class->get_user_theme_folder = metacity_get_user_theme_folder; - - parent_class = g_type_class_peek_parent (class); -} - -GType -metacity_window_manager_get_type (void) -{ - static GType metacity_window_manager_type = 0; - - if (!metacity_window_manager_type) { - static GTypeInfo metacity_window_manager_info = { - sizeof (MetacityWindowManagerClass), - NULL, /* GBaseInitFunc */ - NULL, /* GBaseFinalizeFunc */ - (GClassInitFunc) metacity_window_manager_class_init, - NULL, /* GClassFinalizeFunc */ - NULL, /* user-supplied data */ - sizeof (MetacityWindowManager), - 0, /* n_preallocs */ - (GInstanceInitFunc) metacity_window_manager_init, - NULL - }; - - metacity_window_manager_type = - g_type_register_static (gnome_window_manager_get_type (), - "MetacityWindowManager", - &metacity_window_manager_info, 0); - } - - return metacity_window_manager_type; -} - - diff --git a/gnome-settings-daemon/ChangeLog b/gnome-settings-daemon/ChangeLog index 861776219..9399136c4 100644 --- a/gnome-settings-daemon/ChangeLog +++ b/gnome-settings-daemon/ChangeLog @@ -1,3 +1,9 @@ +2002-10-26 Havoc Pennington + + * gnome-settings-wm.c, gnome-settings-wm.h: blow this away + + * gnome-settings-daemon.c: don't init WM stuff + Sun Oct 27 09:00:46 2002 Jonathan Blandford * gnome-settings-xsettings.c: add Gtk/CanChangeAccels to xsettings diff --git a/gnome-settings-daemon/Makefile.am b/gnome-settings-daemon/Makefile.am index 625cf14c0..e7cf73cea 100644 --- a/gnome-settings-daemon/Makefile.am +++ b/gnome-settings-daemon/Makefile.am @@ -18,8 +18,6 @@ gnome_settings_daemon_SOURCES = \ gnome-settings-background.c \ gnome-settings-xsettings.c \ gnome-settings-xsettings.h \ - gnome-settings-wm.c \ - gnome-settings-wm.h \ gnome-settings-locate-pointer.c \ gnome-settings-locate-pointer.h \ gnome-settings-sound.c \ diff --git a/gnome-settings-daemon/gnome-settings-daemon.c b/gnome-settings-daemon/gnome-settings-daemon.c index 0fef31064..d3c3fe9a0 100644 --- a/gnome-settings-daemon/gnome-settings-daemon.c +++ b/gnome-settings-daemon/gnome-settings-daemon.c @@ -41,7 +41,6 @@ #include "gnome-settings-keyboard.h" #include "gnome-settings-background.h" #include "gnome-settings-sound.h" -#include "gnome-settings-wm.h" #include "gnome-settings-accessibility-keyboard.h" #include "gnome-settings-screensaver.h" #include "gnome-settings-default-editor.h" @@ -236,7 +235,6 @@ gnome_settings_daemon_new (void) gnome_settings_mouse_init (client); gnome_settings_keyboard_init (client); gnome_settings_sound_init (client); - gnome_settings_wm_init (client); gnome_settings_accessibility_keyboard_init (client); gnome_settings_screensaver_init (client); gnome_settings_default_editor_init (client); @@ -277,7 +275,6 @@ gnome_settings_daemon_new (void) gnome_settings_mouse_load (client); gnome_settings_keyboard_load (client); gnome_settings_sound_load (client); - gnome_settings_wm_load (client); gnome_settings_accessibility_keyboard_load (client); gnome_settings_screensaver_load (client); gnome_settings_default_editor_load (client); diff --git a/gnome-settings-daemon/gnome-settings-wm.c b/gnome-settings-daemon/gnome-settings-wm.c deleted file mode 100644 index 7bc6f8a6c..000000000 --- a/gnome-settings-daemon/gnome-settings-wm.c +++ /dev/null @@ -1,122 +0,0 @@ -#include - -#include "gnome-settings-daemon.h" -#include "gnome-settings-wm.h" -#include -#include - -#include - -static void -set_number_of_workspaces (int workspaces) -{ - XEvent xev; - - xev.xclient.type = ClientMessage; - xev.xclient.serial = 0; - xev.xclient.window = GDK_ROOT_WINDOW (); - xev.xclient.send_event = True; - xev.xclient.display = gdk_display; - xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_NUMBER_OF_DESKTOPS"); - xev.xclient.format = 32; - xev.xclient.data.l[0] = workspaces; - - XSendEvent (gdk_display, - gdk_x11_get_default_root_xwindow (), - False, - SubstructureRedirectMask | SubstructureNotifyMask, - &xev); -} - -static void -set_workspace_names (GSList *values) -{ - GConfValue *value; - GSList *list; - - /* First delete the properties */ - XDeleteProperty (gdk_display, - gdk_x11_get_default_root_xwindow (), - gdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES")); - - for (list = values; list; list = list->next) { - unsigned char *str; - value = list->data; - - str = (unsigned char *)gconf_value_get_string (value); - - if (!g_utf8_validate (str, -1, NULL)) { - continue; - } - - XChangeProperty (gdk_display, - gdk_x11_get_default_root_xwindow (), - gdk_x11_get_xatom_by_name ("_NET_DESKTOP_NAMES"), - gdk_x11_get_xatom_by_name ("UTF8_STRING"), - 8, - PropModeAppend, - str, - strlen (str) + 1); - } -} - -static void -wm_callback (GConfEntry *entry) -{ - GnomeWindowManager *wm; - - if (!strcmp (entry->key, "/desktop/gnome/applications/window_manager/number_of_workspaces")) { - if (entry->value->type == GCONF_VALUE_INT) - set_number_of_workspaces (gconf_value_get_int (entry->value)); - } - else if (!strcmp (entry->key, "/desktop/gnome/applications/window_manager/workspace_names")) { - if (entry->value->type == GCONF_VALUE_LIST && - gconf_value_get_list_type (entry->value) == GCONF_VALUE_STRING) - set_workspace_names (gconf_value_get_list (entry->value)); - } - else if (!strcmp (entry->key, "/desktop/gnome/applications/window_manager/theme")) { - wm = gnome_wm_manager_get_current (); - if (wm != NULL) { - gnome_window_manager_set_theme (wm, gconf_value_get_string (entry->value)); - } - } - else if (!strcmp (entry->key, "/desktop/gnome/applications/window_manager/titlebar_font")) { - wm = gnome_wm_manager_get_current (); - gnome_window_manager_set_font (wm, gconf_value_get_string (entry->value)); - } - else if (!strcmp (entry->key, "/desktop/gnome/applications/window_manager/focus_follows_mouse")) { - wm = gnome_wm_manager_get_current (); - gnome_window_manager_set_focus_follows_mouse (wm, gconf_value_get_bool (entry->value)); - } -} - -void -gnome_settings_wm_init (GConfClient *client) -{ - gnome_wm_manager_init (NULL); - gnome_settings_daemon_register_callback ("/desktop/gnome/applications/window_manager", wm_callback); -} - -void -gnome_settings_wm_load (GConfClient *client) -{ - GConfValue *value; - GSList * workspace_list, *li; - int n; - - n = gconf_client_get_int (client, "/desktop/gnome/applications/window_manager/number_of_workspaces", NULL); - set_number_of_workspaces (n >= 1 ? n : 1); - - value = gconf_client_get (client, "/desktop/gnome/applications/window_manager/workspace_names", NULL); - if (value != NULL && - gconf_value_get_list_type (value) == GCONF_VALUE_STRING) { - workspace_list = gconf_value_get_list (value); - set_workspace_names (workspace_list); - for (li = workspace_list; li != NULL; li = li->next) { - g_free (li->data); - li->data = NULL; - } - g_slist_free (workspace_list); - } -} - diff --git a/gnome-settings-daemon/gnome-settings-wm.h b/gnome-settings-daemon/gnome-settings-wm.h deleted file mode 100644 index 2ae1e7788..000000000 --- a/gnome-settings-daemon/gnome-settings-wm.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- mode: c; style: linux -*- */ - -/* gnome-settings-sound.h - * - * Copyright (C) 2002 Anders Carlsson - * - * 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. - * - * Author: Anders Carlsson - */ - -#ifndef __GNOME_SETTINGS_WM_H__ -#define __GNOME_SETTINGS_WM_H__ - -#include - -void gnome_settings_wm_init (GConfClient *client); -void gnome_settings_wm_load (GConfClient *client); - -#endif /* __GNOME_SETTINGS_WM_H__ */ diff --git a/libwindow-settings/ChangeLog b/libwindow-settings/ChangeLog index 30b3cc817..8071f9ddb 100644 --- a/libwindow-settings/ChangeLog +++ b/libwindow-settings/ChangeLog @@ -1,3 +1,22 @@ +2002-10-26 Havoc Pennington + + * gnome-window-manager.c: handle NULL fields in the class struct; + and replace the individual setters with get/set for a big + struct with flags indicating which fields we care about, + a la a graphics context. Add settings_changed signal. + (gnome_window_manager_get_type): change object name to + GnomeWindowManager not GWindowManager + + * gnome-window-manager.h (struct _GnomeWindowManagerClass): add + padding to the class struct + + * Makefile.am: move metacity module here from capplets/windows/ + (libgnome_window_settings_la_SOURCES): don't build the code to + switch window managers, it was bitrotted and broken anyway, and + isn't in the UI right now. Keep the code in EXTRA_DIST in case + someone wants to recover it. Move some relevant bits to + gnome-wm-manager.c + 2002-10-21 Jody Goldberg * Release 2.1.1 diff --git a/libwindow-settings/Makefile.am b/libwindow-settings/Makefile.am index b82d32728..69ff56a8e 100644 --- a/libwindow-settings/Makefile.am +++ b/libwindow-settings/Makefile.am @@ -1,10 +1,13 @@ +WM_MODULE_DIR=$(libdir)/window-manager-settings + INCLUDES = \ -DGNOMELOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DGNOME_ICONDIR=\""${prefix}/share/pixmaps"\" \ -DG_LOG_DOMAIN=\"capplet-common\" \ - -DGNOME_WINDOW_MANAGER_MODULE_PATH=\""$(libdir)/window-manager-settings"\" \ + -DGNOME_WINDOW_MANAGER_MODULE_PATH=\""$(WM_MODULE_DIR)"\" \ -I$(top_srcdir)/ \ - @CAPPLET_CFLAGS@ + @CAPPLET_CFLAGS@ \ + -DMETACITY_THEME_DIR=\""$(datadir)/metacity/themes"\" lib_LTLIBRARIES = libgnome-window-settings.la @@ -16,10 +19,7 @@ libgnome_window_settings_la_SOURCES = \ gnome-window-manager.c \ gnome-window-manager.h \ gnome-wm-manager.c \ - gnome-wm-manager.h \ - wm-exec.c \ - wm-list.c \ - wm-properties.h + gnome-wm-manager.h libgnome_window_settingsincludedir = $(includedir)/gnome-window-settings-2.0 @@ -32,4 +32,20 @@ pkgconfig_DATA = gnome-window-settings-2.0.pc EXTRA_DIST = \ gnome-window-settings-2.0.pc.in \ - ChangeLog \ No newline at end of file + ChangeLog \ + wm-exec.c \ + wm-list.c \ + wm-properties.h + +wms_flags = -export_dynamic -avoid-version +wmsdir = $(WM_MODULE_DIR) + +wms_LTLIBRARIES = \ + libmetacity.la + +libmetacity_la_SOURCES = \ + metacity-window-manager.c \ + metacity-window-manager.h + +libmetacity_la_LDFLAGS = $(wms_flags) +#libmetacity_la_LIBADD = $(top_builddir)/libwindow-settings/libwindow-settings.la diff --git a/libwindow-settings/gnome-window-manager.c b/libwindow-settings/gnome-window-manager.c index 7a8b1eaf7..dbf346743 100644 --- a/libwindow-settings/gnome-window-manager.c +++ b/libwindow-settings/gnome-window-manager.c @@ -1,3 +1,28 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* gnome-window-manager.h + * Copyright (C) 2002 Seth Nickell + * Copyright (C) 2002 Red Hat, Inc. + * + * Written by: Seth Nickell , + * Havoc Pennington + * + * 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 "gnome-window-manager.h" #include @@ -5,92 +30,119 @@ static GObjectClass *parent_class; struct _GnomeWindowManagerPrivate { - char *window_manager_name; - GnomeDesktopItem *ditem; + char *window_manager_name; + GnomeDesktopItem *ditem; }; GObject * -gnome_window_manager_new (GnomeDesktopItem *item) +gnome_window_manager_new (GnomeDesktopItem *it) { - const char *settings_lib; - char *module_name; - GnomeWindowManagerNewFunc wm_new_func = NULL; - GObject *wm; - GModule *module; - gboolean success; + const char *settings_lib; + char *module_name; + GnomeWindowManagerNewFunc wm_new_func = NULL; + GObject *wm; + GModule *module; + gboolean success; - settings_lib = gnome_desktop_item_get_string (item, "X-GnomeWMSettingsLibrary"); + settings_lib = gnome_desktop_item_get_string (it, "X-GNOME-WMSettingsModule"); - module_name = g_module_build_path (GNOME_WINDOW_MANAGER_MODULE_PATH, - settings_lib); + module_name = g_module_build_path (GNOME_WINDOW_MANAGER_MODULE_PATH, + settings_lib); - module = g_module_open (module_name, G_MODULE_BIND_LAZY); - if (module == NULL) { - g_warning ("Couldn't load window manager settings module `%s' (%s)", module_name, g_module_error ()); - return NULL; - } + module = g_module_open (module_name, G_MODULE_BIND_LAZY); + if (module == NULL) { + g_warning ("Couldn't load window manager settings module `%s' (%s)", module_name, g_module_error ()); + return NULL; + } - success = g_module_symbol (module, "window_manager_new", - (gpointer *) &wm_new_func); + success = g_module_symbol (module, "window_manager_new", + (gpointer *) &wm_new_func); - if ((!success) || wm_new_func == NULL) { - g_warning ("Couldn't load window manager settings module `%s`, couldn't find symbol \'window_manager_new\'", module_name); - return NULL; - } + if ((!success) || wm_new_func == NULL) { + g_warning ("Couldn't load window manager settings module `%s`, couldn't find symbol \'window_manager_new\'", module_name); + return NULL; + } - wm = (wm_new_func) (); + wm = (* wm_new_func) (GNOME_WINDOW_MANAGER_INTERFACE_VERSION); - (GNOME_WINDOW_MANAGER (wm))->p->window_manager_name = g_strdup (gnome_desktop_item_get_string (item, GNOME_DESKTOP_ITEM_NAME)); - (GNOME_WINDOW_MANAGER (wm))->p->ditem = gnome_desktop_item_ref (item); + if (wm == NULL) + return NULL; + + (GNOME_WINDOW_MANAGER (wm))->p->window_manager_name = g_strdup (gnome_desktop_item_get_string (it, GNOME_DESKTOP_ITEM_NAME)); + (GNOME_WINDOW_MANAGER (wm))->p->ditem = gnome_desktop_item_ref (it); - return (wm); + return wm; } const char * gnome_window_manager_get_name (GnomeWindowManager *wm) { - return wm->p->window_manager_name; + return wm->p->window_manager_name; } GnomeDesktopItem * gnome_window_manager_get_ditem (GnomeWindowManager *wm) { - return gnome_desktop_item_ref (wm->p->ditem); -} - -void -gnome_window_manager_set_theme (GnomeWindowManager *wm, const char *theme_name) -{ - GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); - klass->set_theme (wm, theme_name); + return gnome_desktop_item_ref (wm->p->ditem); } GList * gnome_window_manager_get_theme_list (GnomeWindowManager *wm) { - GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); - return klass->get_theme_list (wm); -} - -void -gnome_window_manager_set_font (GnomeWindowManager *wm, const char *font) -{ - GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); - klass->set_font (wm, font); -} - -void -gnome_window_manager_set_focus_follows_mouse (GnomeWindowManager *wm, gboolean focus_follows_mouse) -{ - GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); - klass->set_focus_follows_mouse (wm, focus_follows_mouse); + GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); + if (klass->get_theme_list) + return klass->get_theme_list (wm); + else + return NULL; } char * gnome_window_manager_get_user_theme_folder (GnomeWindowManager *wm) { - GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); - return klass->get_user_theme_folder (wm); + GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); + if (klass->get_user_theme_folder) + return klass->get_user_theme_folder (wm); + else + return NULL; +} + +void +gnome_window_manager_get_double_click_actions (GnomeWindowManager *wm, + const GnomeWMDoubleClickAction **actions, + int *n_actions) +{ + GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); + + *actions = NULL; + *n_actions = 0; + + if (klass->get_double_click_actions) + return klass->get_double_click_actions (wm, actions, n_actions); +} + +void +gnome_window_manager_change_settings (GnomeWindowManager *wm, + const GnomeWMSettings *settings) +{ + GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); + + (* klass->change_settings) (wm, settings); +} + +void +gnome_window_manager_get_settings (GnomeWindowManager *wm, + GnomeWMSettings *settings) +{ + GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm); + int mask; + + mask = (* klass->get_settings_mask) (wm); + settings->flags &= mask; /* avoid back compat issues by not returning + * fields to the caller that the WM module + * doesn't know about + */ + + (* klass->get_settings) (wm, settings); } static void @@ -114,6 +166,12 @@ gnome_window_manager_finalize (GObject *object) parent_class->finalize (object); } +enum { + SETTINGS_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; static void gnome_window_manager_class_init (GnomeWindowManagerClass *class) @@ -125,16 +183,21 @@ gnome_window_manager_class_init (GnomeWindowManagerClass *class) wm_class = GNOME_WINDOW_MANAGER_CLASS (class); object_class->finalize = gnome_window_manager_finalize; - - wm_class->set_theme = NULL; - wm_class->get_theme_list = NULL; - wm_class->set_font = NULL; - wm_class->set_focus_follows_mouse = NULL; - wm_class->get_user_theme_folder = NULL; - + parent_class = g_type_class_peek_parent (class); + + + signals[SETTINGS_CHANGED] = + g_signal_new ("settings_changed", + G_OBJECT_CLASS_TYPE (class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (GnomeWindowManagerClass, settings_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } + GType gnome_window_manager_get_type (void) { @@ -156,11 +219,16 @@ gnome_window_manager_get_type (void) gnome_window_manager_type = g_type_register_static (G_TYPE_OBJECT, - "GWindowManager", - &gnome_window_manager_info, 0); + "GnomeWindowManager", + &gnome_window_manager_info, 0); } return gnome_window_manager_type; } +void +gnome_window_manager_settings_changed (GnomeWindowManager *wm) +{ + g_signal_emit (wm, signals[SETTINGS_CHANGED], 0); +} diff --git a/libwindow-settings/gnome-window-manager.h b/libwindow-settings/gnome-window-manager.h index f8a5842f6..7c7d482d1 100644 --- a/libwindow-settings/gnome-window-manager.h +++ b/libwindow-settings/gnome-window-manager.h @@ -1,3 +1,28 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* gnome-window-manager.h + * Copyright (C) 2002 Seth Nickell + * Copyright (C) 2002 Red Hat, Inc. + * + * Written by: Seth Nickell , + * Havoc Pennington + * + * 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_WINDOW_MANAGER_H #define GNOME_WINDOW_MANAGER_H @@ -5,7 +30,55 @@ #include -typedef GObject * (* GnomeWindowManagerNewFunc) (void); +/* Increment if backward-incompatible changes are made, so we get a clean + * error. In principle the libtool versioning handles this, but + * in combination with dlopen I don't quite trust that. + */ +#define GNOME_WINDOW_MANAGER_INTERFACE_VERSION 1 + +typedef GObject * (* GnomeWindowManagerNewFunc) (int expected_interface_version); + +typedef enum +{ + GNOME_WM_SETTING_FONT = 1 << 0, + GNOME_WM_SETTING_MOUSE_FOCUS = 1 << 1, + GNOME_WM_SETTING_AUTORAISE = 1 << 2, + GNOME_WM_SETTING_AUTORAISE_DELAY = 1 << 3, + GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER = 1 << 4, + GNOME_WM_SETTING_THEME = 1 << 5, + GNOME_WM_SETTING_DOUBLE_CLICK_ACTION = 1 << 6, + GNOME_WM_SETTING_MASK = + GNOME_WM_SETTING_FONT | + GNOME_WM_SETTING_MOUSE_FOCUS | + GNOME_WM_SETTING_AUTORAISE | + GNOME_WM_SETTING_AUTORAISE_DELAY | + GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER | + GNOME_WM_SETTING_THEME | + GNOME_WM_SETTING_DOUBLE_CLICK_ACTION +} GnomeWMSettingsFlags; + +typedef struct +{ + int number; + const char *human_readable_name; +} GnomeWMDoubleClickAction; + +typedef struct +{ + GnomeWMSettingsFlags flags; /* this allows us to expand the struct + * while remaining binary compatible + */ + const char *font; + int autoraise_delay; + /* One of the strings "Alt", "Control", "Super", "Hyper", "Meta" */ + const char *mouse_move_modifier; + const char *theme; + int double_click_action; + + guint focus_follows_mouse : 1; + guint autoraise : 1; + +} GnomeWMSettings; G_BEGIN_DECLS @@ -21,34 +94,67 @@ typedef struct _GnomeWindowManagerPrivate GnomeWindowManagerPrivate; struct _GnomeWindowManager { - GObject parent; - - GnomeWindowManagerPrivate *p; + GObject parent; + + GnomeWindowManagerPrivate *p; }; struct _GnomeWindowManagerClass { - GObjectClass klass; + GObjectClass klass; - void (*set_theme) (GnomeWindowManager *wm, const char *theme_name); - GList * (*get_theme_list) (GnomeWindowManager *wm); - void (*set_font) (GnomeWindowManager *wm, const char *font); - void (*set_focus_follows_mouse) (GnomeWindowManager *wm, gboolean focus_follows_mouse); - char * (*get_user_theme_folder) (GnomeWindowManager *wm); + void (* settings_changed) (GnomeWindowManager *wm); + + void (* change_settings) (GnomeWindowManager *wm, + const GnomeWMSettings *settings); + void (* get_settings) (GnomeWindowManager *wm, + GnomeWMSettings *settings); + + GList * (* get_theme_list) (GnomeWindowManager *wm); + char * (* get_user_theme_folder) (GnomeWindowManager *wm); + + int (* get_settings_mask) (GnomeWindowManager *wm); + + void (* get_double_click_actions) (GnomeWindowManager *wm, + const GnomeWMDoubleClickAction **actions, + int *n_actions); + + void (* padding_func_1) (GnomeWindowManager *wm); + void (* padding_func_2) (GnomeWindowManager *wm); + void (* padding_func_3) (GnomeWindowManager *wm); + void (* padding_func_4) (GnomeWindowManager *wm); + void (* padding_func_5) (GnomeWindowManager *wm); + void (* padding_func_6) (GnomeWindowManager *wm); + void (* padding_func_7) (GnomeWindowManager *wm); + void (* padding_func_8) (GnomeWindowManager *wm); + void (* padding_func_9) (GnomeWindowManager *wm); + void (* padding_func_10) (GnomeWindowManager *wm); }; +GObject * gnome_window_manager_new (GnomeDesktopItem *item); +GType gnome_window_manager_get_type (void); +const char * gnome_window_manager_get_name (GnomeWindowManager *wm); +GnomeDesktopItem *gnome_window_manager_get_ditem (GnomeWindowManager *wm); -GObject * gnome_window_manager_new (GnomeDesktopItem *item); -GType gnome_window_manager_get_type (void); - -const char * gnome_window_manager_get_name (GnomeWindowManager *wm); -GnomeDesktopItem *gnome_window_manager_get_ditem (GnomeWindowManager *wm); -void gnome_window_manager_set_theme (GnomeWindowManager *wm, const char *theme_name); /* GList of char *'s */ -GList * gnome_window_manager_get_theme_list (GnomeWindowManager *wm); -void gnome_window_manager_set_font (GnomeWindowManager *wm, const char *font); -void gnome_window_manager_set_focus_follows_mouse (GnomeWindowManager *wm, gboolean focus_follows_mouse); -char * gnome_window_manager_get_user_theme_folder (GnomeWindowManager *wm); +GList * gnome_window_manager_get_theme_list (GnomeWindowManager *wm); +char * gnome_window_manager_get_user_theme_folder (GnomeWindowManager *wm); + +/* only uses fields with their flags set */ +void gnome_window_manager_change_settings (GnomeWindowManager *wm, + const GnomeWMSettings *settings); +/* only gets fields with their flags set (and if it fails to get a field, + * it unsets that flag, so flags should be checked on return) + */ +void gnome_window_manager_get_settings (GnomeWindowManager *wm, + GnomeWMSettings *settings); + +void gnome_window_manager_settings_changed (GnomeWindowManager *wm); + +void gnome_window_manager_get_double_click_actions (GnomeWindowManager *wm, + const GnomeWMDoubleClickAction **actions, + int *n_actions); + G_END_DECLS diff --git a/libwindow-settings/gnome-wm-manager.c b/libwindow-settings/gnome-wm-manager.c index 0db82124f..22094c271 100644 --- a/libwindow-settings/gnome-wm-manager.c +++ b/libwindow-settings/gnome-wm-manager.c @@ -1,631 +1,324 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* gnome-wm-manager.c + * Copyright (C) 2002 Seth Nickell + * Copyright (C) 1998, 2002 Red Hat, Inc. + * + * Written by: Seth Nickell , + * Havoc Pennington + * Owen Taylor , + * Bradford Hovinen + * + * 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 "gnome-wm-manager.h" -#include "wm-properties.h" -#include -#include -#include +#include +#include +#include +#include +#include -/* prototypes */ -static void restart (gboolean force); -static void revert_callback (void); -static void cancel_callback (void); -static void update_session (void); +#include +#include +#include -static WindowManager *selected_wm = NULL; +typedef struct { + GnomeDesktopItem *ditem; + char *name; /* human readable, localized */ + char *identify_name; /* name we expect to be set on the screen */ + char *exec; + char *config_exec; + char *config_tryexec; + char *module; + gboolean session_managed : 1; + gboolean is_user : 1; + gboolean is_present : 1; + gboolean is_config_present : 1; + GnomeWindowManager *gnome_wm; +} AvailableWindowManager; -/* Enumeration describing the current state of the capplet. - * in any other state than idle, all controls are !sensitive. - */ -typedef enum { - STATE_IDLE, - STATE_TRY, - STATE_REVERT, - STATE_OK, - STATE_CANCEL, - STATE_TRY_REVERT, /* Currently trying, revert afterwards */ - STATE_TRY_CANCEL /* Currently trying, cancel afterwards */ -} StateType; +static gboolean done_scan = FALSE; +static GList *available_wms; -/* Current state - */ -static StateType state = STATE_IDLE; - -/* Set TRUE when we've exited the main loop, but restart_pending - */ -static gboolean quit_pending = FALSE; - -/* Set TRUE when we're waiting for the WM to restart - */ -static gboolean restart_pending = FALSE; - -static GtkWidget *capplet; - -void -gnome_wm_manager_init (GtkWidget *some_window) +static void +wm_free (AvailableWindowManager *wm) { - wm_list_init(); - selected_wm = wm_list_get_current(); + g_free (wm->name); + g_free (wm->exec); + g_free (wm->config_exec); + g_free (wm->config_tryexec); + g_free (wm->module); + g_free (wm->identify_name); + + g_free (wm); } -GList * -gnome_wm_manager_get_list (void) +static GList * +list_desktop_files_in_dir (gchar *directory) { - GList *wm_ditem; - GList *wms = NULL; - GnomeDesktopItem *ditem; + DIR *dir; + struct dirent *child; + GList *result = NULL; + gchar *suffix; - for (wm_ditem = window_managers; wm_ditem != NULL; wm_ditem = wm_ditem->next) { - ditem = ((WindowManager *)wm_ditem->data)->dentry; - wms = g_list_prepend (wms, gnome_window_manager_new (ditem)); - } - - return wms; + dir = opendir (directory); + if (dir == NULL) + return NULL; + + while ((child = readdir (dir)) != NULL) { + /* Ignore files without .desktop suffix, and ignore + * .desktop files with no prefix + */ + suffix = child->d_name + strlen (child->d_name) - 8; + /* strlen(".desktop") == 8 */ + + if (suffix <= child->d_name || + strcmp (suffix, ".desktop") != 0) + continue; + + result = g_list_prepend (result, + g_concat_dir_and_file (directory, + child->d_name)); + } + closedir (dir); + + return result; +} + +static gint +wm_compare (gconstpointer a, gconstpointer b) +{ + const AvailableWindowManager *wm_a = (const AvailableWindowManager *)a; + const AvailableWindowManager *wm_b = (const AvailableWindowManager *)b; + + /* mmm, sloooow */ + + return g_utf8_collate (gnome_desktop_item_get_string (wm_a->ditem, GNOME_DESKTOP_ITEM_NAME), + gnome_desktop_item_get_string (wm_b->ditem, GNOME_DESKTOP_ITEM_NAME)); +} + +static AvailableWindowManager* +wm_load (const char *desktop_file, + gboolean is_user) +{ + gchar *path; + AvailableWindowManager *wm; + + wm = g_new0 (AvailableWindowManager, 1); + + wm->ditem = gnome_desktop_item_new_from_file (desktop_file, + GNOME_DESKTOP_ITEM_TYPE_APPLICATION, + NULL); + + if (wm->ditem == NULL) { + g_free (wm); + return NULL; + } + + gnome_desktop_item_set_entry_type (wm->ditem, GNOME_DESKTOP_ITEM_TYPE_APPLICATION); + + wm->exec = g_strdup (gnome_desktop_item_get_string (wm->ditem, + GNOME_DESKTOP_ITEM_EXEC)); + + wm->name = g_strdup (gnome_desktop_item_get_string (wm->ditem, + GNOME_DESKTOP_ITEM_NAME)); + + wm->config_exec = g_strdup (gnome_desktop_item_get_string (wm->ditem, + "ConfigExec")); + wm->config_tryexec = g_strdup (gnome_desktop_item_get_string (wm->ditem, + "ConfigTryExec")); + wm->session_managed = gnome_desktop_item_get_boolean (wm->ditem, + "SessionManaged"); + + wm->module = g_strdup (gnome_desktop_item_get_string (wm->ditem, + "X-GNOME-WMSettingsModule")); + + wm->identify_name = g_strdup (gnome_desktop_item_get_string (wm->ditem, + "X-GNOME-WMName")); + + wm->is_user = is_user; + + if (gnome_desktop_item_get_string (wm->ditem, GNOME_DESKTOP_ITEM_EXEC)) { + const char *tryexec; + + tryexec = gnome_desktop_item_get_string (wm->ditem, GNOME_DESKTOP_ITEM_TRY_EXEC); + + if (tryexec) { + path = g_find_program_in_path (tryexec); + wm->is_present = (path != NULL); + if (path) + g_free (path); + } else + wm->is_present = TRUE; + } else + wm->is_present = FALSE; + + if (wm->config_exec) { + if (wm->config_tryexec) { + path = g_find_program_in_path (wm->config_tryexec); + wm->is_config_present = (path != NULL); + if (path) + g_free (path); + } else { + path = g_find_program_in_path (wm->config_exec); + wm->is_config_present = (path != NULL); + if (path) + g_free (path); + } + } else + wm->is_config_present = FALSE; + + if (wm->name && wm->exec && + (wm->is_user || wm->is_present)) + return wm; + else { + wm_free (wm); + return NULL; + } +} + +static void +scan_wm_directory (gchar *directory, gboolean is_user) +{ + GList *tmp_list; + GList *files; + + files = list_desktop_files_in_dir (directory); + + tmp_list = files; + while (tmp_list) { + AvailableWindowManager *wm; + + wm = wm_load (tmp_list->data, is_user); + + if (wm != NULL) + available_wms = g_list_prepend (available_wms, wm); + + tmp_list = tmp_list->next; + } + + g_list_foreach (files, (GFunc) g_free, NULL); + g_list_free (files); } void -gnome_wm_manager_set_current (GnomeWindowManager *wm) +gnome_wm_manager_init (void) { - /* this line is bogus */ - /*selected_wm = gnome_window_manager_get_ditem (wm);*/ + char *tempdir; + + if (done_scan) + return; + + done_scan = TRUE; + + tempdir = gnome_unconditional_datadir_file ("gnome/wm-properties/"); + scan_wm_directory (tempdir, FALSE); + g_free (tempdir); + + tempdir = gnome_util_home_file("wm-properties/"); + scan_wm_directory (tempdir, TRUE); + g_free (tempdir); + + available_wms = g_list_sort (available_wms, + wm_compare); } -GnomeWindowManager * -gnome_wm_manager_get_current (void) +static AvailableWindowManager* +get_current_wm (GdkScreen *screen) { - WindowManager *current_wm = wm_list_get_current(); - if (current_wm == NULL) - return NULL; - return GNOME_WINDOW_MANAGER (gnome_window_manager_new (current_wm->dentry)); + AvailableWindowManager *current_wm; + const char *name; + GList *tmp_list; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + name = gdk_x11_screen_get_window_manager_name (screen); + + current_wm = NULL; + + tmp_list = available_wms; + while (tmp_list != NULL) { + AvailableWindowManager *wm = tmp_list->data; + + if (wm->identify_name && + strcmp (wm->identify_name, name) == 0) { + current_wm = wm; + break; + } + tmp_list = tmp_list->next; + } + + if (current_wm == NULL) { + /* Try with localized name, sort of crackrock + * back compat hack + */ + + tmp_list = available_wms; + while (tmp_list != NULL) { + AvailableWindowManager *wm = tmp_list->data; + + if (strcmp (wm->name, name) == 0) { + current_wm = wm; + break; + } + tmp_list = tmp_list->next; + } + } + + return current_wm; } -void gnome_wm_manager_change_wm_to_settings (void) +GnomeWindowManager* +gnome_wm_manager_get_current (GdkScreen *screen) { - state = STATE_TRY; - restart(FALSE); - wm_list_set_current (selected_wm); - wm_list_save (); - update_session (); + AvailableWindowManager *wm; + + wm = get_current_wm (screen); + + if (wm != NULL && wm->module != NULL) + /* may still return NULL here */ + return (GnomeWindowManager*) gnome_window_manager_new (wm->ditem); + else + return NULL; } gboolean -gnome_wm_manager_same_wm (GnomeWindowManager *wm1, GnomeWindowManager *wm2) +gnome_wm_manager_spawn_config_tool_for_current (GdkScreen *screen, + GError **error) { - GnomeDesktopItem *item1, *item2; - const char *location1, *location2; - gboolean same; + AvailableWindowManager *wm; - item1 = gnome_window_manager_get_ditem (wm1); - item2 = gnome_window_manager_get_ditem (wm2); - - location1 = gnome_desktop_item_get_location (item1); - location2 = gnome_desktop_item_get_location (item2); - - same = (strcmp (location1, location2) == 0); - - gnome_desktop_item_unref (item1); - gnome_desktop_item_unref (item2); - - return same; -} - -static GtkWidget *restart_dialog = NULL; -static GtkWidget *restart_label = NULL; -static guint restart_dialog_timeout; -static gchar *restart_name = NULL; - -/* Time until dialog times out */ -static gdouble restart_remaining_time; -static gint restart_displayed_time; - -static GnomeClient *client = NULL; - -/* The possible transitions between states are described below. - * - - * operation | try revert ok cancel finish - * ===========+================================================= - * IDLE | TRY REVERT OK CANCEL - * TRY | TRY_REVERT OK TRY_CANCEL IDLE - * REVERT | CANCEL CANCEL IDLE - * OK | (quit) - * CANCEL | (quit) - * TRY_REVERT | TRY_CANCEL TRY_CANCEL REVERT - * TRY_CANCEL | CANCEL - * - * When a restart fails, there are three cases - * - * (1) The failure was because the current window manager didn't - * die. We inform the user of the situation, and then - * abort the operation. - * - * (2) The window manager didn't start, and we don't have a - * a fallback. We pop up a error dialog, tell the user - * to start a new window manager, and abort the operation. - * - * (3) The window manager didn't start, and we previously had a - * window manager runnning. We pop up a warning dialog, - * then try to go back to the old window manager. - * - * operation | (1) (2) (3) - * ===========+================================================= - * IDLE | - * TRY | IDLE IDLE TRY - * REVERT | IDLE IDLE REVERT - * OK | (quit) (quit) OK - * CANCEL | (quit) (quit) CANCEL - * TRY_REVERT | REVERT REVERT REVERT - * TRY_CANCEL | CANCEL CANCEL CANCEL - */ - - - -static void -restart_label_update (void) -{ - gchar *tmp; - - if ((gint)restart_remaining_time != restart_displayed_time) { - restart_displayed_time = restart_remaining_time; - - tmp = g_strdup_printf (_("Starting %s\n" - "(%d seconds left before operation times out)"), - restart_name, - restart_displayed_time); - gtk_label_set_text (GTK_LABEL (restart_label), tmp); - g_free (tmp); - } -} - -static gboolean -restart_dialog_raise (gpointer data) -{ - if (restart_dialog && GTK_WIDGET_REALIZED (restart_dialog)) { - restart_remaining_time -= 0.25; - restart_label_update(); - gdk_window_raise (restart_dialog->window); - } - return TRUE; -} - -static void -restart_dialog_destroyed (GtkWidget *widget) -{ - if (restart_dialog_timeout) { - gtk_timeout_remove (restart_dialog_timeout); - restart_dialog_timeout = 0; - } - - restart_dialog = NULL; -} - -static void -show_restart_dialog (gchar *name) -{ - GtkWidget *hbox; - GtkWidget *frame; - GtkWidget *pixmap; - gchar *tmp; + wm = get_current_wm (screen); - if (!restart_dialog) { - restart_dialog = gtk_window_new (GTK_WINDOW_POPUP); - gtk_window_set_position (GTK_WINDOW (restart_dialog), - GTK_WIN_POS_CENTER); - - gtk_signal_connect (GTK_OBJECT (restart_dialog), "destroy", - GTK_SIGNAL_FUNC (restart_dialog_destroyed), - &restart_dialog); - frame = gtk_frame_new (NULL); - gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT); - gtk_container_add (GTK_CONTAINER (restart_dialog), frame); - - hbox = gtk_hbox_new (FALSE, GNOME_PAD); - gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD); - gtk_container_add (GTK_CONTAINER (frame), hbox); - - tmp = gnome_unconditional_pixmap_file("gnome-info.png"); - if (tmp) { - pixmap = gnome_pixmap_new_from_file(tmp); - g_free(tmp); - gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, FALSE, 0); - } - - restart_label = gtk_label_new (""); - gtk_box_pack_start (GTK_BOX (hbox), restart_label, FALSE, FALSE, GNOME_PAD); - } - - if (!restart_dialog_timeout) { - restart_dialog_timeout = gtk_timeout_add (250, restart_dialog_raise, NULL); - } - - restart_remaining_time = 10.0; - restart_displayed_time = -1; - if (restart_name) - g_free (restart_name); - - restart_name = g_strdup (name); - restart_label_update (); - - gtk_widget_show_all (restart_dialog); -} - -static void -hide_restart_dialog (void) -{ - if (restart_dialog) - gtk_widget_destroy (restart_dialog); -} - -static void -init_session (void) -{ - GnomeClientFlags flags; - gint token; - - return; - - client = gnome_master_client (); - flags = gnome_client_get_flags (client); - - if (flags & GNOME_CLIENT_IS_CONNECTED) { - /*token = gnome_startup_acquire_token("GNOME_WM_PROPERTIES", - gnome_client_get_id(client));*/ - - if (token) - printf ("broken\n"); - /*update_session();*/ - else { - gnome_client_set_restart_style (client, - GNOME_RESTART_NEVER); - gnome_client_flush (client); - } - } -} - -static void -update_session (void) -{ - WindowManager *current_wm = wm_list_get_current(); - //gchar *session_args[3]; - - if (!current_wm) - return; - - if (current_wm->session_managed) { - gnome_client_set_restart_style (client, - GNOME_RESTART_NEVER); - + if (wm != NULL && wm->config_exec != NULL) { + return g_spawn_command_line_async (wm->config_exec, + error); } else { - g_warning ("We don't properly handle non-session managed Window Managers right now"); - } - //else { - // session_args[0] = argv0; - // session_args[1] = "--init-session-settings"; - // session_args[2] = NULL; - // /* We use a priority of 15 so that we start after - // * session-managed WM's (priority 10), for safety. - /// */ - // gnome_client_set_priority (client, 15); - // gnome_client_set_restart_style (client, - // GNOME_RESTART_ANYWAY); - // gnome_client_set_restart_command (client, 2, - // session_args); -//} - - gnome_client_flush (client); -} - -static void -init_callback (WMResult result, gpointer data) -{ - switch (result) { - case WM_SUCCESS: - break; - case WM_ALREADY_RUNNING: - g_warning (_("wm-properties-capplet: Unable to initialize window manager.\n" - "\tAnother window manager is already running and could not be killed\n")); - break; - case WM_CANT_START: - g_warning (_("wm-properties-capplet: Unable to initialize window manager.\n" - "\t'%s' didn't start\n"), (gchar *)data); - break; - } - - g_free (data); - gtk_main_quit (); -} - -static void -restart_finalize () -{ - wm_list_set_current (selected_wm); - hide_restart_dialog(); - - switch (state) { - case STATE_TRY: - case STATE_REVERT: - gtk_widget_set_sensitive (capplet, TRUE); - //update_gui(); - state = STATE_IDLE; - break; + const char *name; - case STATE_OK: - case STATE_CANCEL: - if (quit_pending) - gtk_main_quit(); - break; - default: - g_warning ("Finalize in state %d!!!\n", state); - return; - } + name = gdk_x11_screen_get_window_manager_name (screen); - restart_pending = FALSE; -} - -static void -restart_failure (WMResult reason) -{ - GtkWidget *msgbox; - WindowManager *current_wm; - gchar *msg = NULL; - gboolean modal = FALSE; - - current_wm = wm_list_get_current (); - - /* Did the previous window manager not die? - */ - if (reason == WM_ALREADY_RUNNING) { - msg = g_strdup (_("Previous window manager did not die\n")); - - switch (state) { - case STATE_TRY: - case STATE_REVERT: - case STATE_OK: - case STATE_CANCEL: - selected_wm = current_wm; - restart_finalize (); - break; - - case STATE_TRY_REVERT: - revert_callback (); - break; - - case STATE_TRY_CANCEL: - cancel_callback (); - break; - - default: - g_warning ("Failure in state %d!!!\n", state); - return; - } - } - /* Is there something reasonable to try to fall back to? - */ - else if (current_wm != selected_wm) { - - switch (state) { - case STATE_TRY: - case STATE_REVERT: - case STATE_OK: - case STATE_CANCEL: - msg = g_strdup_printf (_("Could not start '%s'.\n" - "Falling back to previous window manager '%s'\n"), - selected_wm?gnome_desktop_item_get_string (selected_wm->dentry, GNOME_DESKTOP_ITEM_NAME):"Unknown", - current_wm?gnome_desktop_item_get_string (current_wm->dentry, GNOME_DESKTOP_ITEM_NAME):"Unknown"); - selected_wm = current_wm; - restart(TRUE); - break; - - case STATE_TRY_REVERT: - revert_callback (); - break; - - case STATE_TRY_CANCEL: - cancel_callback (); - break; - - default: - g_warning ("Failure in state %d!!!\n", state); - return; - } - - /* Give up */ - } else { - - switch (state) { - case STATE_OK: - case STATE_CANCEL: - modal = TRUE; /* prevent an immediate exit */ - /* Fall through */ - case STATE_TRY: - case STATE_REVERT: - msg = g_strdup (_("Could not start fallback window manager.\n" - "Please run a window manager manually. You can\n" - "do this by selecting \"Run Program\" in the\n" - "foot menu\n")); - - restart_finalize(); - break; - - case STATE_TRY_REVERT: - revert_callback (); - break; - - case STATE_TRY_CANCEL: - cancel_callback (); - break; - - default: - g_warning ("Failure in state %d!!!\n", state); - return; - } - } - - if (msg) { - msgbox = gnome_message_box_new (msg, - GNOME_MESSAGE_BOX_ERROR, - _("OK"), NULL); - if (modal) - gnome_dialog_run (GNOME_DIALOG (msgbox)); - else - gtk_widget_show (msgbox); - g_free (msg); + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + _("Window manager \"%s\" has not registered a configuration tool\n"), + name); + return FALSE; } } - -static void -show_restart_info (void) -{ - gchar *save_session; - - save_session = gnome_is_program_in_path ("save-session"); - - if (save_session != NULL) { - system (save_session); - } - - g_free (save_session); -} - -static void -restart_finish (void) -{ - switch (state) { - case STATE_TRY: - case STATE_REVERT: - case STATE_OK: - case STATE_CANCEL: - hide_restart_dialog(); - show_restart_info (); - restart_finalize(); - break; - - case STATE_TRY_REVERT: - revert_callback (); - break; - - case STATE_TRY_CANCEL: - cancel_callback (); - break; - - default: - g_warning ("Finished in state %d!!!\n", state); - return; - } -} - -static void -restart_callback (WMResult result, gpointer data) -{ - if (result == WM_SUCCESS) - restart_finish (); - else - restart_failure (result); -} - -static void -restart (gboolean force) -{ - WindowManager *current_wm = wm_list_get_current(), *mywm; - static gboolean last_try_was_twm = FALSE; - GnomeDesktopItem *twm_dentry = gnome_desktop_item_new (); - WindowManager twm_fallback = {twm_dentry, "twm", "twm", 0, 0, 1, 0}; - - gnome_desktop_item_set_entry_type (twm_dentry, GNOME_DESKTOP_ITEM_TYPE_APPLICATION); - gnome_desktop_item_set_string (twm_dentry, - GNOME_DESKTOP_ITEM_NAME, "twm"); - gnome_desktop_item_set_string (twm_dentry, - GNOME_DESKTOP_ITEM_COMMENT, "twm"); - gnome_desktop_item_set_string (twm_dentry, - GNOME_DESKTOP_ITEM_EXEC, "twm"); - - if(selected_wm) { - last_try_was_twm = FALSE; - mywm = selected_wm; - } else if(!last_try_was_twm) { - last_try_was_twm = TRUE; - mywm = (WindowManager*)&twm_fallback; - } else { - restart_finalize(); - gnome_desktop_item_unref (twm_dentry); - return; - } - - if (force || current_wm != mywm) { - show_restart_dialog (g_strdup (gnome_desktop_item_get_string (mywm->dentry, GNOME_DESKTOP_ITEM_NAME))); - if (state != STATE_OK && state != STATE_CANCEL) - gtk_widget_set_sensitive (capplet, FALSE); - restart_pending = TRUE; - wm_restart (mywm, - capplet->window, - restart_callback, - NULL); - } else { - restart_finalize (); - } - - gnome_desktop_item_unref (twm_dentry); -} - -static void -revert_callback (void) -{ - StateType old_state = state; - - switch (state) { - case STATE_IDLE: - case STATE_TRY_REVERT: - wm_list_revert(); - selected_wm = wm_list_get_revert(); - state = STATE_REVERT; - - restart (old_state == STATE_TRY_REVERT); - /*update_gui();*/ - - break; - - case STATE_TRY: - state = STATE_TRY_REVERT; - break; - - default: - g_warning ("revert callback in state %d!!!\n", state); - return; - } -} - -static void -cancel_callback (void) -{ - StateType old_state = state; - - switch (state) { - case STATE_IDLE: - case STATE_TRY_CANCEL: - wm_list_revert(); - selected_wm = wm_list_get_revert(); - state = STATE_CANCEL; - - restart (old_state == STATE_TRY_CANCEL); - - break; - - case STATE_TRY: - state = STATE_TRY_CANCEL; - break; - - case STATE_REVERT: - state = STATE_CANCEL; - break; - - case STATE_TRY_REVERT: - state = STATE_TRY_CANCEL; - break; - - default: - g_warning ("ok callback in state %d!!!\n", state); - return; - } -} - - diff --git a/libwindow-settings/gnome-wm-manager.h b/libwindow-settings/gnome-wm-manager.h index 0bc008ded..55f279168 100644 --- a/libwindow-settings/gnome-wm-manager.h +++ b/libwindow-settings/gnome-wm-manager.h @@ -5,21 +5,12 @@ #include "gnome-window-manager.h" -void gnome_wm_manager_init (GtkWidget *some_window); +void gnome_wm_manager_init (void); -/* returns a GList of available window managers */ -GList * gnome_wm_manager_get_list (void); +/* gets the currently active window manager */ +GnomeWindowManager *gnome_wm_manager_get_current (GdkScreen *screen); -/* sets the currently active window manager in GConf */ -void gnome_wm_manager_set_current (GnomeWindowManager *wm); - -/* gets the currently active window manager from GConf */ -GnomeWindowManager *gnome_wm_manager_get_current (void); - -/* change to the wm specified in GConf */ -void gnome_wm_manager_change_wm_to_settings (void); - -/* return TRUE if wm1 and wm2 refer to the same window manager */ -gboolean gnome_wm_manager_same_wm (GnomeWindowManager *wm1, GnomeWindowManager *wm2); +gboolean gnome_wm_manager_spawn_config_tool_for_current (GdkScreen *screen, + GError **error); #endif diff --git a/libwindow-settings/metacity-window-manager.c b/libwindow-settings/metacity-window-manager.c new file mode 100644 index 000000000..891e82dbe --- /dev/null +++ b/libwindow-settings/metacity-window-manager.c @@ -0,0 +1,491 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ + +/* metacity-window-manager.c + * Copyright (C) 2002 Seth Nickell + * Copyright (C) 2002 Red Hat, Inc. + * + * Written by: Seth Nickell , + * Havoc Pennington + * + * 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 +#include + +#include "metacity-window-manager.h" + +#define METACITY_THEME_KEY "/apps/metacity/general/theme" +#define METACITY_FONT_KEY "/apps/metacity/general/titlebar_font" +#define METACITY_FOCUS_KEY "/apps/metacity/general/focus_mode" +#define METACITY_USE_SYSTEM_FONT_KEY "/apps/metacity/general/titlebar_uses_system_font" +#define METACITY_AUTORAISE_KEY "/apps/metacity/general/auto_raise" +#define METACITY_AUTORAISE_DELAY_KEY "/apps/metacity/general/auto_raise_delay" +#define METACITY_MOUSE_MODIFIER_KEY "/apps/metacity/general/mouse_button_modifier" +#define METACITY_DOUBLE_CLICK_TITLEBAR_KEY "/apps/metacity/general/action_double_click_titlebar" + +enum +{ + DOUBLE_CLICK_MAXIMIZE, + DOUBLE_CLICK_SHADE +}; + +static GnomeWindowManagerClass *parent_class; + +struct _MetacityWindowManagerPrivate { + GConfClient *gconf; + char *font; + char *theme; + char *mouse_modifier; +}; + +static void +value_changed (GConfClient *client, + const gchar *key, + GConfValue *value, + void *data) +{ + MetacityWindowManager *meta_wm; + + meta_wm = METACITY_WINDOW_MANAGER (data); + + gnome_window_manager_settings_changed (GNOME_WINDOW_MANAGER (meta_wm)); +} + +/* this function is called when the shared lib is loaded */ +GObject * +window_manager_new (int expected_interface_version) +{ + GObject *wm; + + if (expected_interface_version != GNOME_WINDOW_MANAGER_INTERFACE_VERSION) { + g_warning ("Metacity window manager module wasn't compiled with the current version of gnome-control-center"); + return NULL; + } + + wm = g_object_new (metacity_window_manager_get_type (), NULL); + + return wm; +} + +static GList * +add_themes_from_dir (GList *current_list, const char *path) +{ + DIR *theme_dir; + struct dirent *entry; + char *theme_file_path; + GList *node; + gboolean found = FALSE; + + if (!(g_file_test (path, G_FILE_TEST_EXISTS) && g_file_test (path, G_FILE_TEST_IS_DIR))) { + return current_list; + } + + theme_dir = opendir (path); + + for (entry = readdir (theme_dir); entry != NULL; entry = readdir (theme_dir)) { + theme_file_path = g_build_filename (path, entry->d_name, "metacity-theme-1.xml", NULL); + + if (g_file_test (theme_file_path, G_FILE_TEST_EXISTS)) { + + for (node = current_list; (node != NULL) && (!found); node = node->next) { + found = (strcmp (node->data, entry->d_name) == 0); + } + + if (!found) { + current_list = g_list_prepend (current_list, g_strdup (entry->d_name)); + } + } + + /*g_free (entry);*/ + g_free (theme_file_path); + } + + closedir (theme_dir); + + return current_list; +} + +static GList * +metacity_get_theme_list (GnomeWindowManager *wm) +{ + GList *themes = NULL; + char *home_dir_themes; + + home_dir_themes = g_build_filename (g_get_home_dir (), ".metacity/themes", NULL); + + themes = add_themes_from_dir (themes, METACITY_THEME_DIR); + themes = add_themes_from_dir (themes, "/usr/share/metacity/themes"); + themes = add_themes_from_dir (themes, home_dir_themes); + + g_free (home_dir_themes); + + return themes; +} + +static char * +metacity_get_user_theme_folder (GnomeWindowManager *wm) +{ + return g_build_filename (g_get_home_dir (), ".themes", NULL); +} + +static void +metacity_change_settings (GnomeWindowManager *wm, + const GnomeWMSettings *settings) +{ + MetacityWindowManager *meta_wm; + + meta_wm = METACITY_WINDOW_MANAGER (wm); + + if (settings->flags & GNOME_WM_SETTING_MOUSE_FOCUS) + gconf_client_set_string (meta_wm->p->gconf, + METACITY_FOCUS_KEY, + settings->focus_follows_mouse ? + "sloppy" : "click", NULL); + + if (settings->flags & GNOME_WM_SETTING_AUTORAISE) + gconf_client_set_bool (meta_wm->p->gconf, + METACITY_AUTORAISE_KEY, + settings->autoraise, NULL); + + if (settings->flags & GNOME_WM_SETTING_AUTORAISE_DELAY) + gconf_client_set_int (meta_wm->p->gconf, + METACITY_AUTORAISE_DELAY_KEY, + settings->autoraise_delay, NULL); + + if (settings->flags & GNOME_WM_SETTING_FONT) { + gconf_client_set_string (meta_wm->p->gconf, + METACITY_FONT_KEY, + settings->font, NULL); + } + + if (settings->flags & GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER) { + char *value; + + value = g_strdup_printf ("<%s>", settings->mouse_move_modifier); + gconf_client_set_string (meta_wm->p->gconf, + METACITY_MOUSE_MODIFIER_KEY, + value, NULL); + g_free (value); + } + + if (settings->flags & GNOME_WM_SETTING_THEME) { + gconf_client_set_string (meta_wm->p->gconf, + METACITY_THEME_KEY, + settings->theme, NULL); + } + + if (settings->flags & GNOME_WM_SETTING_DOUBLE_CLICK_ACTION) { + const char *action; + + action = NULL; + + switch (settings->double_click_action) { + case DOUBLE_CLICK_SHADE: + action = "toggle_shade"; + break; + case DOUBLE_CLICK_MAXIMIZE: + action = "toggle_maximize"; + break; + } + + if (action != NULL) { + gconf_client_set_string (meta_wm->p->gconf, + METACITY_DOUBLE_CLICK_TITLEBAR_KEY, + action, NULL); + } + } +} + +static void +metacity_get_settings (GnomeWindowManager *wm, + GnomeWMSettings *settings) +{ + int to_get; + MetacityWindowManager *meta_wm; + + meta_wm = METACITY_WINDOW_MANAGER (wm); + + to_get = settings->flags; + settings->flags = 0; + + if (to_get & GNOME_WM_SETTING_MOUSE_FOCUS) { + char *str; + + str = gconf_client_get_string (meta_wm->p->gconf, + METACITY_FOCUS_KEY, NULL); + settings->focus_follows_mouse = FALSE; + if (str && (strcmp (str, "sloppy") == 0 || + strcmp (str, "mouse") == 0)) + settings->focus_follows_mouse = TRUE; + + g_free (str); + + settings->flags |= GNOME_WM_SETTING_MOUSE_FOCUS; + } + + if (to_get & GNOME_WM_SETTING_AUTORAISE) { + settings->autoraise = gconf_client_get_bool (meta_wm->p->gconf, + METACITY_AUTORAISE_KEY, + NULL); + settings->flags |= GNOME_WM_SETTING_AUTORAISE; + } + + if (to_get & GNOME_WM_SETTING_AUTORAISE_DELAY) { + settings->autoraise_delay = + gconf_client_get_int (meta_wm->p->gconf, + METACITY_AUTORAISE_DELAY_KEY, + NULL); + settings->flags |= GNOME_WM_SETTING_AUTORAISE_DELAY; + } + + if (to_get & GNOME_WM_SETTING_FONT) { + char *str; + + str = gconf_client_get_string (meta_wm->p->gconf, + METACITY_FONT_KEY, + NULL); + + if (str == NULL) + str = g_strdup ("Sans Bold 12"); + + if (meta_wm->p->font && + strcmp (meta_wm->p->font, str) == 0) { + g_free (str); + } else { + g_free (meta_wm->p->font); + meta_wm->p->font = str; + } + + settings->font = meta_wm->p->font; + + settings->flags |= GNOME_WM_SETTING_FONT; + } + + if (to_get & GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER) { + char *str; + const char *new; + + str = gconf_client_get_string (meta_wm->p->gconf, + METACITY_MOUSE_MODIFIER_KEY, + NULL); + + if (str == NULL) + str = g_strdup (""); + + if (strcmp (str, "") == 0) + new = "Super"; + else if (strcmp (str, "") == 0) + new = "Alt"; + else if (strcmp (str, "") == 0) + new = "Meta"; + else if (strcmp (str, "") == 0) + new = "Hyper"; + else if (strcmp (str, "") == 0) + new = "Control"; + else + new = NULL; + + if (new && meta_wm->p->mouse_modifier && + strcmp (new, meta_wm->p->mouse_modifier) == 0) { + /* unchanged */; + } else { + g_free (meta_wm->p->mouse_modifier); + meta_wm->p->mouse_modifier = g_strdup (new); + } + + g_free (str); + + settings->mouse_move_modifier = meta_wm->p->mouse_modifier; + + settings->flags |= GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER; + } + + if (to_get & GNOME_WM_SETTING_THEME) { + char *str; + + str = gconf_client_get_string (meta_wm->p->gconf, + METACITY_THEME_KEY, + NULL); + + if (str == NULL) + str = g_strdup ("Atlanta"); + + if (meta_wm->p->theme && + strcmp (meta_wm->p->theme, str) == 0) { + g_free (str); + } else { + g_free (meta_wm->p->theme); + meta_wm->p->font = str; + } + + settings->theme = meta_wm->p->theme; + + settings->flags |= GNOME_WM_SETTING_THEME; + } + + if (to_get & GNOME_WM_SETTING_DOUBLE_CLICK_ACTION) { + char *str; + + str = gconf_client_get_string (meta_wm->p->gconf, + METACITY_DOUBLE_CLICK_TITLEBAR_KEY, + NULL); + + if (str == NULL) + str = g_strdup ("toggle_shade"); + + if (strcmp (str, "toggle_shade") == 0) + settings->double_click_action = DOUBLE_CLICK_SHADE; + else if (strcmp (str, "toggle_maximize") == 0) + settings->double_click_action = DOUBLE_CLICK_MAXIMIZE; + else + settings->double_click_action = DOUBLE_CLICK_SHADE; + + g_free (str); + + settings->flags |= GNOME_WM_SETTING_DOUBLE_CLICK_ACTION; + } +} + +static int +metacity_get_settings_mask (GnomeWindowManager *wm) +{ + return GNOME_WM_SETTING_MASK; +} + +static void +metacity_get_double_click_actions (GnomeWindowManager *wm, + const GnomeWMDoubleClickAction **actions_p, + int *n_actions_p) +{ + static GnomeWMDoubleClickAction actions[] = { + { DOUBLE_CLICK_MAXIMIZE, N_("Maximize") }, + { DOUBLE_CLICK_SHADE, N_("Roll up") } + }; + static gboolean initialized = FALSE; + + if (!initialized) { + int i; + + initialized = TRUE; + i = 0; + while (i < (int) G_N_ELEMENTS (actions)) { + g_assert (actions[i].number == i); + actions[i].human_readable_name = _(actions[i].human_readable_name); + + ++i; + } + } + + *actions_p = actions; + *n_actions_p = (int) G_N_ELEMENTS (actions); +} + +static void +metacity_window_manager_init (MetacityWindowManager *metacity_window_manager, + MetacityWindowManagerClass *class) +{ + metacity_window_manager->p = g_new0 (MetacityWindowManagerPrivate, 1); + metacity_window_manager->p->gconf = gconf_client_get_default (); + metacity_window_manager->p->font = NULL; + metacity_window_manager->p->theme = NULL; + metacity_window_manager->p->mouse_modifier = NULL; + + gconf_client_add_dir (metacity_window_manager->p->gconf, + "/apps/metacity/general", + GCONF_CLIENT_PRELOAD_ONELEVEL, + NULL); + + g_signal_connect (G_OBJECT (metacity_window_manager->p->gconf), + "value_changed", + G_CALLBACK (value_changed), metacity_window_manager); +} + +static void +metacity_window_manager_finalize (GObject *object) +{ + MetacityWindowManager *metacity_window_manager; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_METACITY_WINDOW_MANAGER (object)); + + metacity_window_manager = METACITY_WINDOW_MANAGER (object); + + g_signal_handlers_disconnect_by_func (G_OBJECT (metacity_window_manager->p->gconf), + G_CALLBACK (value_changed), + metacity_window_manager); + + g_object_unref (G_OBJECT (metacity_window_manager->p->gconf)); + g_free (metacity_window_manager->p); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + +static void +metacity_window_manager_class_init (MetacityWindowManagerClass *class) +{ + GObjectClass *object_class; + GnomeWindowManagerClass *wm_class; + + object_class = G_OBJECT_CLASS (class); + wm_class = GNOME_WINDOW_MANAGER_CLASS (class); + + object_class->finalize = metacity_window_manager_finalize; + + wm_class->change_settings = metacity_change_settings; + wm_class->get_settings = metacity_get_settings; + wm_class->get_settings_mask = metacity_get_settings_mask; + wm_class->get_user_theme_folder = metacity_get_user_theme_folder; + wm_class->get_theme_list = metacity_get_theme_list; + wm_class->get_double_click_actions = metacity_get_double_click_actions; + + parent_class = g_type_class_peek_parent (class); +} + +GType +metacity_window_manager_get_type (void) +{ + static GType metacity_window_manager_type = 0; + + if (!metacity_window_manager_type) { + static GTypeInfo metacity_window_manager_info = { + sizeof (MetacityWindowManagerClass), + NULL, /* GBaseInitFunc */ + NULL, /* GBaseFinalizeFunc */ + (GClassInitFunc) metacity_window_manager_class_init, + NULL, /* GClassFinalizeFunc */ + NULL, /* user-supplied data */ + sizeof (MetacityWindowManager), + 0, /* n_preallocs */ + (GInstanceInitFunc) metacity_window_manager_init, + NULL + }; + + metacity_window_manager_type = + g_type_register_static (gnome_window_manager_get_type (), + "MetacityWindowManager", + &metacity_window_manager_info, 0); + } + + return metacity_window_manager_type; +} + + diff --git a/capplets/windows/metacity-window-manager.h b/libwindow-settings/metacity-window-manager.h similarity index 100% rename from capplets/windows/metacity-window-manager.h rename to libwindow-settings/metacity-window-manager.h