You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
560 lines
14 KiB
560 lines
14 KiB
/*
|
|
* Copyright © 2005 Novell, Inc.
|
|
*
|
|
* Permission to use, copy, modify, distribute, and sell this software
|
|
* and its documentation for any purpose is hereby granted without
|
|
* fee, provided that the above copyright notice appear in all copies
|
|
* and that both that copyright notice and this permission notice
|
|
* appear in supporting documentation, and that the name of
|
|
* Novell, Inc. not be used in advertising or publicity pertaining to
|
|
* distribution of the software without specific, written prior permission.
|
|
* Novell, Inc. makes no representations about the suitability of this
|
|
* software for any purpose. It is provided "as is" without express or
|
|
* implied warranty.
|
|
*
|
|
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
|
|
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
|
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Author: David Reveman <davidr@novell.com>
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <sys/types.h>
|
|
#include <dirent.h>
|
|
#include <string.h>
|
|
#include <gconf/gconf-client.h>
|
|
#include <glib/gi18n.h>
|
|
|
|
#include "compiz-window-manager.h"
|
|
|
|
#define COMPIZ_CLICK_TO_FOCUS_KEY \
|
|
"/apps/compiz/general/allscreens/options/click_to_focus"
|
|
|
|
#define COMPIZ_AUTORAISE_KEY \
|
|
"/apps/compiz/general/allscreens/options/autoraise"
|
|
|
|
#define COMPIZ_AUTORAISE_DELAY_KEY \
|
|
"/apps/compiz/general/allscreens/options/autoraise_delay"
|
|
|
|
#define COMPIZ_MOUSE_MOVE_KEY \
|
|
"/apps/compiz/plugins/move/allscreens/options/initiate_button"
|
|
|
|
#define GCONF_DIR "/apps/metacity/general"
|
|
|
|
#define COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY \
|
|
GCONF_DIR "/action_double_click_titlebar"
|
|
|
|
#define COMPIZ_USE_SYSTEM_FONT_KEY \
|
|
GCONF_DIR "/titlebar_uses_system_font"
|
|
|
|
#define COMPIZ_TITLEBAR_FONT_KEY \
|
|
GCONF_DIR "/titlebar_font"
|
|
|
|
#define COMPIZ_THEME_KEY \
|
|
GCONF_DIR "/theme"
|
|
|
|
enum {
|
|
DOUBLE_CLICK_NONE,
|
|
DOUBLE_CLICK_SHADE,
|
|
DOUBLE_CLICK_MAXIMIZE,
|
|
DOUBLE_CLICK_MAXIMIZE_HORIZONTALLY,
|
|
DOUBLE_CLICK_MAXIMIZE_VERTICALLY,
|
|
DOUBLE_CLICK_MINIMIZE,
|
|
DOUBLE_CLICK_RAISE,
|
|
DOUBLE_CLICK_LOWER,
|
|
DOUBLE_CLICK_MENU
|
|
};
|
|
|
|
static const struct {
|
|
unsigned int action;
|
|
const char *value;
|
|
} double_click_actions [] = {
|
|
{ DOUBLE_CLICK_NONE, "none" },
|
|
{ DOUBLE_CLICK_SHADE, "toggle_shade" },
|
|
{ DOUBLE_CLICK_MAXIMIZE, "toggle_maximize" },
|
|
{ DOUBLE_CLICK_MAXIMIZE_HORIZONTALLY, "toggle_maximize_horizontally" },
|
|
{ DOUBLE_CLICK_MAXIMIZE_VERTICALLY, "toggle_maximize_vertically" },
|
|
{ DOUBLE_CLICK_MINIMIZE, "minimize" },
|
|
{ DOUBLE_CLICK_RAISE, "raise" },
|
|
{ DOUBLE_CLICK_LOWER, "lower" },
|
|
{ DOUBLE_CLICK_MENU, "menu" }
|
|
};
|
|
|
|
static GnomeWindowManagerClass *parent_class;
|
|
|
|
struct _CompizWindowManagerPrivate {
|
|
GConfClient *gconf;
|
|
gchar *font;
|
|
gchar *theme;
|
|
gchar *mouse_modifier;
|
|
};
|
|
|
|
static void
|
|
value_changed (GConfClient *client,
|
|
const gchar *key,
|
|
GConfValue *value,
|
|
void *data)
|
|
{
|
|
CompizWindowManager *wm;
|
|
|
|
wm = COMPIZ_WINDOW_MANAGER (data);
|
|
|
|
gnome_window_manager_settings_changed (GNOME_WINDOW_MANAGER (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 ("Compiz window manager module wasn't compiled with the "
|
|
"current version of gnome-control-center");
|
|
return NULL;
|
|
}
|
|
|
|
wm = g_object_new (compiz_window_manager_get_type (), NULL);
|
|
|
|
return wm;
|
|
}
|
|
|
|
static void
|
|
compiz_change_settings (GnomeWindowManager *wm,
|
|
const GnomeWMSettings *settings)
|
|
{
|
|
CompizWindowManager *cwm;
|
|
|
|
cwm = COMPIZ_WINDOW_MANAGER (wm);
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_FONT)
|
|
gconf_client_set_string (cwm->p->gconf,
|
|
COMPIZ_TITLEBAR_FONT_KEY,
|
|
settings->font, NULL);
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_MOUSE_FOCUS)
|
|
gconf_client_set_bool (cwm->p->gconf,
|
|
COMPIZ_CLICK_TO_FOCUS_KEY,
|
|
settings->focus_follows_mouse == FALSE,
|
|
NULL);
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_AUTORAISE)
|
|
gconf_client_set_bool (cwm->p->gconf,
|
|
COMPIZ_AUTORAISE_KEY,
|
|
settings->autoraise, NULL);
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_AUTORAISE_DELAY)
|
|
gconf_client_set_int (cwm->p->gconf,
|
|
COMPIZ_AUTORAISE_DELAY_KEY,
|
|
settings->autoraise_delay, NULL);
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER)
|
|
{
|
|
char *value;
|
|
|
|
value = g_strdup_printf ("<%s>Button1", settings->mouse_move_modifier);
|
|
gconf_client_set_string (cwm->p->gconf,
|
|
COMPIZ_MOUSE_MOVE_KEY,
|
|
value, NULL);
|
|
g_free (value);
|
|
}
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_THEME)
|
|
gconf_client_set_string (cwm->p->gconf,
|
|
COMPIZ_THEME_KEY,
|
|
settings->theme, NULL);
|
|
|
|
if (settings->flags & GNOME_WM_SETTING_DOUBLE_CLICK_ACTION)
|
|
{
|
|
const char *action = NULL;
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (double_click_actions); i++)
|
|
{
|
|
if (settings->double_click_action ==
|
|
double_click_actions[i].action)
|
|
{
|
|
action = double_click_actions[i].value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (action)
|
|
gconf_client_set_string (cwm->p->gconf,
|
|
COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY,
|
|
action, NULL);
|
|
}
|
|
}
|
|
|
|
static void
|
|
compiz_get_settings (GnomeWindowManager *wm,
|
|
GnomeWMSettings *settings)
|
|
{
|
|
CompizWindowManager *cwm;
|
|
int to_get;
|
|
|
|
cwm = COMPIZ_WINDOW_MANAGER (wm);
|
|
|
|
to_get = settings->flags;
|
|
settings->flags = 0;
|
|
|
|
if (to_get & GNOME_WM_SETTING_FONT)
|
|
{
|
|
char *str;
|
|
|
|
str = gconf_client_get_string (cwm->p->gconf,
|
|
COMPIZ_TITLEBAR_FONT_KEY,
|
|
NULL);
|
|
|
|
if (!str)
|
|
str = g_strdup ("Sans Bold 12");
|
|
|
|
if (cwm->p->font)
|
|
g_free (cwm->p->font);
|
|
|
|
cwm->p->font = str;
|
|
|
|
settings->font = cwm->p->font;
|
|
|
|
settings->flags |= GNOME_WM_SETTING_FONT;
|
|
}
|
|
|
|
if (to_get & GNOME_WM_SETTING_MOUSE_FOCUS)
|
|
{
|
|
settings->focus_follows_mouse =
|
|
gconf_client_get_bool (cwm->p->gconf,
|
|
COMPIZ_CLICK_TO_FOCUS_KEY, NULL) == FALSE;
|
|
|
|
settings->flags |= GNOME_WM_SETTING_MOUSE_FOCUS;
|
|
}
|
|
|
|
if (to_get & GNOME_WM_SETTING_AUTORAISE)
|
|
{
|
|
settings->autoraise = gconf_client_get_bool (cwm->p->gconf,
|
|
COMPIZ_AUTORAISE_KEY,
|
|
NULL);
|
|
|
|
settings->flags |= GNOME_WM_SETTING_AUTORAISE;
|
|
}
|
|
|
|
if (to_get & GNOME_WM_SETTING_AUTORAISE_DELAY)
|
|
{
|
|
settings->autoraise_delay =
|
|
gconf_client_get_int (cwm->p->gconf,
|
|
COMPIZ_AUTORAISE_DELAY_KEY,
|
|
NULL);
|
|
|
|
settings->flags |= GNOME_WM_SETTING_AUTORAISE_DELAY;
|
|
}
|
|
|
|
if (to_get & GNOME_WM_SETTING_MOUSE_MOVE_MODIFIER)
|
|
{
|
|
const char *new;
|
|
char *str;
|
|
|
|
str = gconf_client_get_string (cwm->p->gconf,
|
|
COMPIZ_MOUSE_MOVE_KEY,
|
|
NULL);
|
|
|
|
if (str == NULL)
|
|
str = g_strdup ("<Super>");
|
|
|
|
if (strncmp (str, "<Super>", 7) == 0)
|
|
new = "Super";
|
|
else if (strncmp (str, "<Alt>", 5) == 0)
|
|
new = "Alt";
|
|
else if (strncmp (str, "<Meta>", 6) == 0)
|
|
new = "Meta";
|
|
else if (strncmp (str, "<Hyper>", 7) == 0)
|
|
new = "Hyper";
|
|
else if (strncmp (str, "<Control>", 9) == 0)
|
|
new = "Control";
|
|
else
|
|
new = NULL;
|
|
|
|
if (cwm->p->mouse_modifier)
|
|
g_free (cwm->p->mouse_modifier);
|
|
|
|
cwm->p->mouse_modifier = g_strdup (new ? new : "");
|
|
|
|
g_free (str);
|
|
|
|
settings->mouse_move_modifier = cwm->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 (cwm->p->gconf,
|
|
COMPIZ_THEME_KEY,
|
|
NULL);
|
|
|
|
if (str == NULL)
|
|
str = g_strdup ("Atlanta");
|
|
|
|
g_free (cwm->p->theme);
|
|
cwm->p->theme = str;
|
|
settings->theme = cwm->p->theme;
|
|
|
|
settings->flags |= GNOME_WM_SETTING_THEME;
|
|
}
|
|
|
|
if (to_get & GNOME_WM_SETTING_DOUBLE_CLICK_ACTION)
|
|
{
|
|
char *str;
|
|
|
|
settings->double_click_action = DOUBLE_CLICK_MAXIMIZE;
|
|
|
|
str = gconf_client_get_string (cwm->p->gconf,
|
|
COMPIZ_DOUBLE_CLICK_TITLEBAR_KEY,
|
|
NULL);
|
|
|
|
if (str)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (double_click_actions); i++)
|
|
{
|
|
if (strcmp (str, double_click_actions[i].value) == 0)
|
|
{
|
|
settings->double_click_action =
|
|
double_click_actions[i].action;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
settings->flags |= GNOME_WM_SETTING_DOUBLE_CLICK_ACTION;
|
|
}
|
|
}
|
|
|
|
static int
|
|
compiz_get_settings_mask (GnomeWindowManager *wm)
|
|
{
|
|
return GNOME_WM_SETTING_MASK;
|
|
}
|
|
|
|
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; entry = readdir (theme_dir))
|
|
{
|
|
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 && !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 (theme_file_path);
|
|
}
|
|
|
|
closedir (theme_dir);
|
|
|
|
return current_list;
|
|
}
|
|
|
|
static GList *
|
|
compiz_get_theme_list (GnomeWindowManager *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, METACITY_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 *
|
|
compiz_get_user_theme_folder (GnomeWindowManager *wm)
|
|
{
|
|
return g_build_filename (g_get_home_dir (), ".themes", NULL);
|
|
}
|
|
|
|
static void
|
|
compiz_get_double_click_actions (GnomeWindowManager *wm,
|
|
const GnomeWMDoubleClickAction **actions_p,
|
|
int *n_actions_p)
|
|
{
|
|
static gboolean initialized = FALSE;
|
|
static GnomeWMDoubleClickAction actions[] = {
|
|
{ DOUBLE_CLICK_NONE, N_("None") },
|
|
{ DOUBLE_CLICK_SHADE, N_("Shade") },
|
|
{ DOUBLE_CLICK_MAXIMIZE, N_("Maximize") },
|
|
{ DOUBLE_CLICK_MAXIMIZE_HORIZONTALLY, N_("Maximize Horizontally") },
|
|
{ DOUBLE_CLICK_MAXIMIZE_HORIZONTALLY, N_("Maximize Vertically") },
|
|
{ DOUBLE_CLICK_MINIMIZE, N_("Minimize") },
|
|
{ DOUBLE_CLICK_RAISE, N_("Raise") },
|
|
{ DOUBLE_CLICK_LOWER, N_("Lower") },
|
|
{ DOUBLE_CLICK_MENU, N_("Window Menu") }
|
|
};
|
|
|
|
if (!initialized)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < G_N_ELEMENTS (actions); i++)
|
|
actions[i].human_readable_name = _(actions[i].human_readable_name);
|
|
|
|
initialized = TRUE;
|
|
}
|
|
|
|
*actions_p = actions;
|
|
*n_actions_p = (int) G_N_ELEMENTS (actions);
|
|
}
|
|
|
|
static void
|
|
compiz_window_manager_init (CompizWindowManager *cwm,
|
|
CompizWindowManagerClass *class)
|
|
{
|
|
cwm->p = g_new0 (CompizWindowManagerPrivate, 1);
|
|
cwm->p->gconf = gconf_client_get_default ();
|
|
cwm->p->mouse_modifier = NULL;
|
|
cwm->p->font = NULL;
|
|
cwm->p->theme = NULL;
|
|
|
|
gconf_client_add_dir (cwm->p->gconf,
|
|
"/apps/compiz",
|
|
GCONF_CLIENT_PRELOAD_ONELEVEL,
|
|
NULL);
|
|
|
|
gconf_client_add_dir (cwm->p->gconf,
|
|
GCONF_DIR,
|
|
GCONF_CLIENT_PRELOAD_ONELEVEL,
|
|
NULL);
|
|
|
|
|
|
g_signal_connect (G_OBJECT (cwm->p->gconf),
|
|
"value_changed",
|
|
G_CALLBACK (value_changed),
|
|
cwm);
|
|
}
|
|
|
|
static void
|
|
compiz_window_manager_finalize (GObject *object)
|
|
{
|
|
CompizWindowManager *cwm;
|
|
|
|
g_return_if_fail (object != NULL);
|
|
g_return_if_fail (IS_COMPIZ_WINDOW_MANAGER (object));
|
|
|
|
cwm = COMPIZ_WINDOW_MANAGER (object);
|
|
|
|
g_signal_handlers_disconnect_by_func (G_OBJECT (cwm->p->gconf),
|
|
G_CALLBACK (value_changed),
|
|
cwm);
|
|
|
|
if (cwm->p->mouse_modifier)
|
|
g_free (cwm->p->mouse_modifier);
|
|
|
|
if (cwm->p->font)
|
|
g_free (cwm->p->font);
|
|
|
|
if (cwm->p->theme)
|
|
g_free (cwm->p->theme);
|
|
|
|
g_object_unref (G_OBJECT (cwm->p->gconf));
|
|
g_free (cwm->p);
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
compiz_window_manager_class_init (CompizWindowManagerClass *class)
|
|
{
|
|
GObjectClass *object_class;
|
|
GnomeWindowManagerClass *wm_class;
|
|
|
|
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
textdomain (GETTEXT_PACKAGE);
|
|
|
|
object_class = G_OBJECT_CLASS (class);
|
|
wm_class = GNOME_WINDOW_MANAGER_CLASS (class);
|
|
|
|
object_class->finalize = compiz_window_manager_finalize;
|
|
|
|
wm_class->change_settings = compiz_change_settings;
|
|
wm_class->get_settings = compiz_get_settings;
|
|
wm_class->get_settings_mask = compiz_get_settings_mask;
|
|
wm_class->get_user_theme_folder = compiz_get_user_theme_folder;
|
|
wm_class->get_theme_list = compiz_get_theme_list;
|
|
wm_class->get_double_click_actions = compiz_get_double_click_actions;
|
|
|
|
parent_class = g_type_class_peek_parent (class);
|
|
}
|
|
|
|
GType
|
|
compiz_window_manager_get_type (void)
|
|
{
|
|
static GType compiz_window_manager_type = 0;
|
|
|
|
if (!compiz_window_manager_type)
|
|
{
|
|
static GTypeInfo compiz_window_manager_info = {
|
|
sizeof (CompizWindowManagerClass),
|
|
NULL,
|
|
NULL,
|
|
(GClassInitFunc) compiz_window_manager_class_init,
|
|
NULL,
|
|
NULL,
|
|
sizeof (CompizWindowManager),
|
|
0,
|
|
(GInstanceInitFunc) compiz_window_manager_init,
|
|
NULL
|
|
};
|
|
|
|
compiz_window_manager_type =
|
|
g_type_register_static (gnome_window_manager_get_type (),
|
|
"CompizWindowManager",
|
|
&compiz_window_manager_info, 0);
|
|
}
|
|
|
|
return compiz_window_manager_type;
|
|
}
|