/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ /* marco-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., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include #include #include #include #include #include #include "marco-window-manager.h" #define MARCO_SCHEMA "org.mate.Marco.general" #define MARCO_THEME_KEY "theme" #define MARCO_FONT_KEY "titlebar-font" #define MARCO_FOCUS_KEY "focus-mode" #define MARCO_USE_SYSTEM_FONT_KEY "titlebar-uses-system-font" #define MARCO_AUTORAISE_KEY "auto-raise" #define MARCO_AUTORAISE_DELAY_KEY "auto-raise-delay" #define MARCO_MOUSE_MODIFIER_KEY "mouse-button-modifier" #define MARCO_DOUBLE_CLICK_TITLEBAR_KEY "action-double-click-titlebar" #define MARCO_COMPOSITING_MANAGER_KEY "compositing-manager" #define MARCO_COMPOSITING_FAST_ALT_TAB_KEY "compositing-fast-alt-tab" /* keep following enums in sync with marco */ enum { ACTION_TITLEBAR_TOGGLE_SHADE, ACTION_TITLEBAR_TOGGLE_MAXIMIZE, ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY, ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY, ACTION_TITLEBAR_MINIMIZE, ACTION_TITLEBAR_NONE, ACTION_TITLEBAR_LOWER, ACTION_TITLEBAR_MENU }; enum { FOCUS_MODE_CLICK, FOCUS_MODE_SLOPPY, FOCUS_MODE_MOUSE }; static MateWindowManagerClass *parent_class; struct _MarcoWindowManagerPrivate { GSettings *settings; char *font; char *theme; char *mouse_modifier; }; static void value_changed (GSettings *settings, gchar *key, void *data) { MarcoWindowManager *meta_wm; meta_wm = MARCO_WINDOW_MANAGER (data); mate_window_manager_settings_changed (MATE_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 != MATE_WINDOW_MANAGER_INTERFACE_VERSION) { g_warning ("Marco window manager module wasn't compiled with the current version of mate-control-center"); return NULL; } wm = g_object_new (marco_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); /* If this is NULL, then we couldn't open ~/.themes. The test above * only checks existence, not wether we can really read it.*/ if (theme_dir == NULL) return current_list; for (entry = readdir (theme_dir); entry != NULL; entry = readdir (theme_dir)) { theme_file_path = g_build_filename (path, entry->d_name, "metacity-1/metacity-theme-2.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)); } } else { g_free (theme_file_path); theme_file_path = g_build_filename (path, entry->d_name, "metacity-1/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)); } } } found = FALSE; /*g_free (entry);*/ g_free (theme_file_path); } closedir (theme_dir); return current_list; } static GList * marco_get_theme_list (MateWindowManager *wm) { GList *themes = NULL; char *home_dir_themes; home_dir_themes = g_build_filename (g_get_home_dir (), ".themes", NULL); themes = add_themes_from_dir (themes, MARCO_THEME_DIR); themes = add_themes_from_dir (themes, "/usr/share/themes"); themes = add_themes_from_dir (themes, home_dir_themes); g_free (home_dir_themes); return themes; } static char * marco_get_user_theme_folder (MateWindowManager *wm) { return g_build_filename (g_get_home_dir (), ".themes", NULL); } static void marco_change_settings (MateWindowManager *wm, const MateWMSettings *settings) { MarcoWindowManager *meta_wm; meta_wm = MARCO_WINDOW_MANAGER (wm); if (settings->flags & MATE_WM_SETTING_COMPOSITING_MANAGER) g_settings_set_boolean (meta_wm->p->settings, MARCO_COMPOSITING_MANAGER_KEY, settings->compositing_manager); if (settings->flags & MATE_WM_SETTING_COMPOSITING_ALTTAB) g_settings_set_boolean (meta_wm->p->settings, MARCO_COMPOSITING_FAST_ALT_TAB_KEY, settings->compositing_fast_alt_tab); if (settings->flags & MATE_WM_SETTING_MOUSE_FOCUS) g_settings_set_enum (meta_wm->p->settings, MARCO_FOCUS_KEY, settings->focus_follows_mouse ? FOCUS_MODE_SLOPPY : FOCUS_MODE_CLICK); if (settings->flags & MATE_WM_SETTING_AUTORAISE) g_settings_set_boolean (meta_wm->p->settings, MARCO_AUTORAISE_KEY, settings->autoraise); if (settings->flags & MATE_WM_SETTING_AUTORAISE_DELAY) g_settings_set_int (meta_wm->p->settings, MARCO_AUTORAISE_DELAY_KEY, settings->autoraise_delay); if (settings->flags & MATE_WM_SETTING_FONT) { g_settings_set_string (meta_wm->p->settings, MARCO_FONT_KEY, settings->font); } if (settings->flags & MATE_WM_SETTING_MOUSE_MOVE_MODIFIER) { char *value; value = g_strdup_printf ("<%s>", settings->mouse_move_modifier); g_settings_set_string (meta_wm->p->settings, MARCO_MOUSE_MODIFIER_KEY, value); g_free (value); } if (settings->flags & MATE_WM_SETTING_THEME) { g_settings_set_string (meta_wm->p->settings, MARCO_THEME_KEY, settings->theme); } if (settings->flags & MATE_WM_SETTING_DOUBLE_CLICK_ACTION) { g_settings_set_enum (meta_wm->p->settings, MARCO_DOUBLE_CLICK_TITLEBAR_KEY, settings->double_click_action); } } static void marco_get_settings (MateWindowManager *wm, MateWMSettings *settings) { int to_get; MarcoWindowManager *meta_wm; meta_wm = MARCO_WINDOW_MANAGER (wm); to_get = settings->flags; settings->flags = 0; if (to_get & MATE_WM_SETTING_COMPOSITING_MANAGER) { settings->compositing_manager = g_settings_get_boolean (meta_wm->p->settings, MARCO_COMPOSITING_MANAGER_KEY); settings->flags |= MATE_WM_SETTING_COMPOSITING_MANAGER; } if (to_get & MATE_WM_SETTING_COMPOSITING_ALTTAB) { settings->compositing_fast_alt_tab = g_settings_get_boolean (meta_wm->p->settings, MARCO_COMPOSITING_FAST_ALT_TAB_KEY); settings->flags |= MATE_WM_SETTING_COMPOSITING_ALTTAB; } if (to_get & MATE_WM_SETTING_MOUSE_FOCUS) { gint marco_focus_value; marco_focus_value = g_settings_get_enum (meta_wm->p->settings, MARCO_FOCUS_KEY); settings->focus_follows_mouse = FALSE; if (marco_focus_value == FOCUS_MODE_SLOPPY || marco_focus_value == FOCUS_MODE_MOUSE) settings->focus_follows_mouse = TRUE; settings->flags |= MATE_WM_SETTING_MOUSE_FOCUS; } if (to_get & MATE_WM_SETTING_AUTORAISE) { settings->autoraise = g_settings_get_boolean (meta_wm->p->settings, MARCO_AUTORAISE_KEY); settings->flags |= MATE_WM_SETTING_AUTORAISE; } if (to_get & MATE_WM_SETTING_AUTORAISE_DELAY) { settings->autoraise_delay = g_settings_get_int (meta_wm->p->settings, MARCO_AUTORAISE_DELAY_KEY); settings->flags |= MATE_WM_SETTING_AUTORAISE_DELAY; } if (to_get & MATE_WM_SETTING_FONT) { char *str; str = g_settings_get_string (meta_wm->p->settings, MARCO_FONT_KEY); 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 |= MATE_WM_SETTING_FONT; } if (to_get & MATE_WM_SETTING_MOUSE_MOVE_MODIFIER) { char *str; const char *new; str = g_settings_get_string (meta_wm->p->settings, MARCO_MOUSE_MODIFIER_KEY); 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 |= MATE_WM_SETTING_MOUSE_MOVE_MODIFIER; } if (to_get & MATE_WM_SETTING_THEME) { char *str; str = g_settings_get_string (meta_wm->p->settings, MARCO_THEME_KEY); if (str == NULL) str = g_strdup ("Spidey"); g_free (meta_wm->p->theme); meta_wm->p->theme = str; settings->theme = meta_wm->p->theme; settings->flags |= MATE_WM_SETTING_THEME; } if (to_get & MATE_WM_SETTING_DOUBLE_CLICK_ACTION) { settings->double_click_action = g_settings_get_enum (meta_wm->p->settings, MARCO_DOUBLE_CLICK_TITLEBAR_KEY); settings->flags |= MATE_WM_SETTING_DOUBLE_CLICK_ACTION; } } static int marco_get_settings_mask (MateWindowManager *wm) { return MATE_WM_SETTING_MASK; } static void marco_get_double_click_actions (MateWindowManager *wm, const MateWMDoubleClickAction **actions_p, int *n_actions_p) { static MateWMDoubleClickAction actions[] = { { ACTION_TITLEBAR_TOGGLE_SHADE, N_("Roll up") }, { ACTION_TITLEBAR_TOGGLE_MAXIMIZE, N_("Maximize") }, { ACTION_TITLEBAR_TOGGLE_MAXIMIZE_HORIZONTALLY, N_("Maximize Horizontally") }, { ACTION_TITLEBAR_TOGGLE_MAXIMIZE_VERTICALLY, N_("Maximize Vertically") }, { ACTION_TITLEBAR_MINIMIZE, N_("Minimize") }, { ACTION_TITLEBAR_NONE, N_("None") } }; static gboolean initialized = FALSE; if (!initialized) { int i; initialized = TRUE; i = 0; for (i = 0; i < G_N_ELEMENTS (actions); i++) { actions[i].human_readable_name = _(actions[i].human_readable_name); } } *actions_p = actions; *n_actions_p = (int) G_N_ELEMENTS (actions); } static void marco_window_manager_init (MarcoWindowManager *marco_window_manager, MarcoWindowManagerClass *class) { marco_window_manager->p = g_new0 (MarcoWindowManagerPrivate, 1); marco_window_manager->p->settings = g_settings_new (MARCO_SCHEMA); marco_window_manager->p->font = NULL; marco_window_manager->p->theme = NULL; marco_window_manager->p->mouse_modifier = NULL; g_signal_connect (marco_window_manager->p->settings, "changed", G_CALLBACK (value_changed), marco_window_manager); } static void marco_window_manager_finalize (GObject *object) { MarcoWindowManager *marco_window_manager; g_return_if_fail (object != NULL); g_return_if_fail (IS_MARCO_WINDOW_MANAGER (object)); marco_window_manager = MARCO_WINDOW_MANAGER (object); g_object_unref (marco_window_manager->p->settings); g_free (marco_window_manager->p); G_OBJECT_CLASS (parent_class)->finalize (object); } static void marco_window_manager_class_init (MarcoWindowManagerClass *class) { GObjectClass *object_class; MateWindowManagerClass *wm_class; object_class = G_OBJECT_CLASS (class); wm_class = MATE_WINDOW_MANAGER_CLASS (class); object_class->finalize = marco_window_manager_finalize; wm_class->change_settings = marco_change_settings; wm_class->get_settings = marco_get_settings; wm_class->get_settings_mask = marco_get_settings_mask; wm_class->get_user_theme_folder = marco_get_user_theme_folder; wm_class->get_theme_list = marco_get_theme_list; wm_class->get_double_click_actions = marco_get_double_click_actions; parent_class = g_type_class_peek_parent (class); } GType marco_window_manager_get_type (void) { static GType marco_window_manager_type = 0; if (!marco_window_manager_type) { static GTypeInfo marco_window_manager_info = { sizeof (MarcoWindowManagerClass), NULL, /* GBaseInitFunc */ NULL, /* GBaseFinalizeFunc */ (GClassInitFunc) marco_window_manager_class_init, NULL, /* GClassFinalizeFunc */ NULL, /* user-supplied data */ sizeof (MarcoWindowManager), 0, /* n_preallocs */ (GInstanceInitFunc) marco_window_manager_init, NULL }; marco_window_manager_type = g_type_register_static (mate_window_manager_get_type (), "MarcoWindowManager", &marco_window_manager_info, 0); } return marco_window_manager_type; }