adapt to gnome-wm-manager API changes

2002-10-26  Havoc Pennington  <hp@pobox.com>

	* theme-switcher.c (window_read_themes): adapt to gnome-wm-manager
	API changes

2002-10-26  Havoc Pennington  <hp@pobox.com>

	* 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-26  Havoc Pennington  <hp@pobox.com>

	* 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
This commit is contained in:
Havoc Pennington 2002-10-29 06:19:52 +00:00 committed by Havoc Pennington
parent 69fcadbe29
commit 692b9dde4f
20 changed files with 1892 additions and 1489 deletions

View file

@ -1,3 +1,22 @@
2002-10-26 Havoc Pennington <hp@pobox.com>
* 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 <jody@gnome.org>
* Release 2.1.1

View file

@ -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
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

View file

@ -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 <snickell@stanford.edu>,
* Havoc Pennington <hp@redhat.com>
*
* 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 <gmodule.h>
@ -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);
}

View file

@ -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 <snickell@stanford.edu>,
* Havoc Pennington <hp@redhat.com>
*
* 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 <libgnome/gnome-desktop-item.h>
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

View file

@ -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 <snickell@stanford.edu>,
* Havoc Pennington <hp@redhat.com>
* Owen Taylor <otaylor@redhat.com>,
* Bradford Hovinen <hovinen@helixcode.com>
*
* 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 <config.h>
#include "gnome-wm-manager.h"
#include "wm-properties.h"
#include <gtk/gtk.h>
#include <libgnomeui/gnome-client.h>
#include <gnome.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <libgnome/gnome-util.h>
#include <libgnome/gnome-i18n.h>
/* prototypes */
static void restart (gboolean force);
static void revert_callback (void);
static void cancel_callback (void);
static void update_session (void);
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
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;
}
}

View file

@ -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

View file

@ -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 <snickell@stanford.edu>,
* Havoc Pennington <hp@redhat.com>
*
* 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 <config.h>
#include <sys/types.h>
#include <dirent.h>
#include <string.h>
#include <gconf/gconf-client.h>
#include <libgnome/gnome-i18n.h>
#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 ("<Super>");
if (strcmp (str, "<Super>") == 0)
new = "Super";
else if (strcmp (str, "<Alt>") == 0)
new = "Alt";
else if (strcmp (str, "<Meta>") == 0)
new = "Meta";
else if (strcmp (str, "<Hyper>") == 0)
new = "Hyper";
else if (strcmp (str, "<Control>") == 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;
}

View file

@ -0,0 +1,29 @@
#ifndef METACITY_WINDOW_MANAGER_H
#define METACITY_WINDOW_MANAGER_H
#include <glib-object.h>
#include "gnome-window-manager.h"
#define METACITY_WINDOW_MANAGER(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, metacity_window_manager_get_type (), MetacityWindowManager)
#define METACITY_WINDOW_MANAGER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, metacity_window_manager_get_type (), MetacityWindowManagerClass)
#define IS_METACITY_WINDOW_MANAGER(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, metacity_window_manager_get_type ())
typedef struct _MetacityWindowManager MetacityWindowManager;
typedef struct _MetacityWindowManagerClass MetacityWindowManagerClass;
typedef struct _MetacityWindowManagerPrivate MetacityWindowManagerPrivate;
struct _MetacityWindowManager
{
GnomeWindowManager parent;
MetacityWindowManagerPrivate *p;
};
struct _MetacityWindowManagerClass
{
GnomeWindowManagerClass klass;
};
GType metacity_window_manager_get_type (void);
#endif