Update to deal with the .pc file that gets generated.

2002-06-02  Seth Nickell  <snickell@stanford.edu>

	* .cvsignore:

	Update to deal with the .pc file that gets generated.

	* Makefile.am:

	Build a real library, not just a non-installed. This is to get around
	problems dealing with GObject inheritance and static memory problems. We
	have a run time loaded object deriving from the library, so it has to link it in. But then
	the problem that occurs is that both the run-time loaded library and the
	program that calls it statically link the .la in. Then they have different
	memory spaces, and type registration goes to pot. Open to suggestions if there's
	a way of doing this without making an installed library.

	* gnome-window-manager.c: (gnome_window_manager_new),
	(gnome_window_manager_get_name), (gnome_window_manager_set_theme),
	(gnome_window_manager_get_theme_list),
	(gnome_window_manager_set_font),
	(gnome_window_manager_get_focus_follows_mouse),
	(gnome_window_manager_set_focus_follows_mouse),
	(gnome_window_manager_init), (gnome_window_manager_finalize),
	(gnome_window_manager_class_init), (gnome_window_manager_get_type):
	* gnome-window-manager.h:

	Lots of formatting fixes, change some of the boilerplate.

	* gnome-window-settings-2.0.pc.in:

	Since we're installing a library, go the whole way. Its good to make this
	easy to depend on for external window managers anyway, now that I think
	of it.

	* gnome-wm-manager.c: (gnome_wm_manager_init),
	(gnome_wm_manager_get_list), (gnome_wm_manager_set_current),
	(gnome_wm_manager_get_current),
	(gnome_wm_manager_change_wm_to_settings), (restart_label_update),
	(restart_dialog_raise), (restart_dialog_destroyed),
	(show_restart_dialog), (hide_restart_dialog), (init_session),
	(update_session), (init_callback), (restart_finalize),
	(restart_failure), (show_restart_info), (restart_finish),
	(restart_callback), (restart), (revert_callback),
	(cancel_callback):
	* gnome-wm-manager.h:

	Add code for doing the window manager switch to the library,
	snitched out of wm-properties. Its probably a little broken right now.

	* wm-exec.c: (wm_is_running), (find_gnome_wm_window),
	(find_wm_window_from_client), (window_has_wm_state),
	(descendent_has_wm_state), (find_wm_window_from_hunt),
	(find_wm_window), (start_timeout), (start_do), (kill_timeout),
	(wm_restart), (wm_guess_current):
	* wm-list.c: (is_blank), (wm_compare), (wm_free),
	(wm_check_present), (wm_copy), (wm_list_find), (wm_list_find_exec),
	(wm_list_find_files), (wm_list_read_dir), (wm_list_init),
	(wm_list_save), (wm_list_revert), (wm_list_add), (wm_list_delete),
	(wm_list_set_current), (wm_list_get_current), (wm_list_get_revert),
	(wm_read_from_xml), (wm_list_read_from_xml), (wm_write_to_xml),
	(wm_list_write_to_xml), (xml_read_bool), (xml_write_bool):
	* wm-properties.h:

	Take wm-switching code out of the capplet, move it here.

	(Jacob, I did a make dist and build the resulting tarball, hope things
	 don't break for you this time ... )
This commit is contained in:
Seth Nickell 2002-06-03 00:33:59 +00:00 committed by Seth Nickell
parent 0a5695f294
commit aa217d6cd7
11 changed files with 1860 additions and 32 deletions

View file

@ -9,3 +9,4 @@ gnome-window-properties
window-properties.desktop
*.oaf
*.gladep
gnome-window-settings-2.0.pc

View file

@ -1,3 +1,71 @@
2002-06-02 Seth Nickell <snickell@stanford.edu>
* .cvsignore:
Update to deal with the .pc file that gets generated.
* Makefile.am:
Build a real library, not just a non-installed. This is to get around
problems dealing with GObject inheritance and static memory problems. We
have a run time loaded object deriving from the library, so it has to link it in. But then
the problem that occurs is that both the run-time loaded library and the
program that calls it statically link the .la in. Then they have different
memory spaces, and type registration goes to pot. Open to suggestions if there's
a way of doing this without making an installed library.
* gnome-window-manager.c: (gnome_window_manager_new),
(gnome_window_manager_get_name), (gnome_window_manager_set_theme),
(gnome_window_manager_get_theme_list),
(gnome_window_manager_set_font),
(gnome_window_manager_get_focus_follows_mouse),
(gnome_window_manager_set_focus_follows_mouse),
(gnome_window_manager_init), (gnome_window_manager_finalize),
(gnome_window_manager_class_init), (gnome_window_manager_get_type):
* gnome-window-manager.h:
Lots of formatting fixes, change some of the boilerplate.
* gnome-window-settings-2.0.pc.in:
Since we're installing a library, go the whole way. Its good to make this
easy to depend on for external window managers anyway, now that I think
of it.
* gnome-wm-manager.c: (gnome_wm_manager_init),
(gnome_wm_manager_get_list), (gnome_wm_manager_set_current),
(gnome_wm_manager_get_current),
(gnome_wm_manager_change_wm_to_settings), (restart_label_update),
(restart_dialog_raise), (restart_dialog_destroyed),
(show_restart_dialog), (hide_restart_dialog), (init_session),
(update_session), (init_callback), (restart_finalize),
(restart_failure), (show_restart_info), (restart_finish),
(restart_callback), (restart), (revert_callback),
(cancel_callback):
* gnome-wm-manager.h:
Add code for doing the window manager switch to the library,
snitched out of wm-properties. Its probably a little broken right now.
* wm-exec.c: (wm_is_running), (find_gnome_wm_window),
(find_wm_window_from_client), (window_has_wm_state),
(descendent_has_wm_state), (find_wm_window_from_hunt),
(find_wm_window), (start_timeout), (start_do), (kill_timeout),
(wm_restart), (wm_guess_current):
* wm-list.c: (is_blank), (wm_compare), (wm_free),
(wm_check_present), (wm_copy), (wm_list_find), (wm_list_find_exec),
(wm_list_find_files), (wm_list_read_dir), (wm_list_init),
(wm_list_save), (wm_list_revert), (wm_list_add), (wm_list_delete),
(wm_list_set_current), (wm_list_get_current), (wm_list_get_revert),
(wm_read_from_xml), (wm_list_read_from_xml), (wm_write_to_xml),
(wm_list_write_to_xml), (xml_read_bool), (xml_write_bool):
* wm-properties.h:
Take wm-switching code out of the capplet, move it here.
(Jacob, I did a make dist and build the resulting tarball, hope things
don't break for you this time ... )
2002-05-15 jacob berkman <jacob@ximian.com>
* Makefile.am: don't link against libs, like libbackground does

View file

@ -1,5 +1,3 @@
EXTRA_DIST = ChangeLog
INCLUDES = \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
-DGNOME_ICONDIR=\""${prefix}/share/pixmaps"\" \
@ -8,8 +6,30 @@ INCLUDES = \
-I$(top_srcdir)/ \
@CAPPLET_CFLAGS@
noinst_LTLIBRARIES = libwindow-settings.la
lib_LTLIBRARIES = libgnome-window-settings.la
libwindow_settings_la_SOURCES = \
libgnome_window_settings_la_LDFLAGS = \
-export_dynamic \
-version-info 1:0:0
libgnome_window_settings_la_SOURCES = \
gnome-window-manager.c \
gnome-window-manager.h
gnome-window-manager.h \
gnome-wm-manager.c \
gnome-wm-manager.h \
wm-exec.c \
wm-list.c \
wm-properties.h
libgnome_window_settingsincludedir = $(includedir)/gnome-window-settings-2.0
libgnome_window_settingsinclude_HEADERS = \
gnome-window-manager.h \
gnome-wm-manager.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = gnome-window-settings-2.0.pc
EXTRA_DIST = \
gnome-window-settings-2.0.pc.in \
ChangeLog

View file

@ -2,6 +2,13 @@
#include <gmodule.h>
static GObjectClass *parent_class;
struct _GnomeWindowManagerPrivate {
char *window_manager_name;
GnomeDesktopItem *ditem;
};
GObject *
gnome_window_manager_new (GnomeDesktopItem *item)
{
@ -23,7 +30,7 @@ gnome_window_manager_new (GnomeDesktopItem *item)
return NULL;
}
success = g_module_symbol (module, "window_manager_new",
success = g_module_symbol (module, "metacity_window_manager_get_type",
(gpointer *) &wm_new_func);
if ((!success) || wm_new_func == NULL) {
@ -31,7 +38,126 @@ gnome_window_manager_new (GnomeDesktopItem *item)
return NULL;
}
wm = (wm_new_func) ();
wm = g_object_new ((wm_new_func) (), NULL);
(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);
return (wm);
}
const char *
gnome_window_manager_get_name (GnomeWindowManager *wm)
{
return wm->p->window_manager_name;
}
void
gnome_window_manager_set_theme (GnomeWindowManager *wm, const char *theme_name)
{
GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm);
klass->set_theme (theme_name);
}
GList *
gnome_window_manager_get_theme_list (GnomeWindowManager *wm)
{
GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm);
return klass->get_theme_list ();
}
void
gnome_window_manager_set_font (GnomeWindowManager *wm, const char *font)
{
GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm);
klass->set_font (font);
}
gboolean
gnome_window_manager_get_focus_follows_mouse (GnomeWindowManager *wm)
{
GnomeWindowManagerClass *klass = GNOME_WINDOW_MANAGER_GET_CLASS (wm);
return klass->get_focus_follows_mouse ();
}
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 (focus_follows_mouse);
}
static void
gnome_window_manager_init (GnomeWindowManager *gnome_window_manager, GnomeWindowManagerClass *class)
{
gnome_window_manager->p = g_new0 (GnomeWindowManagerPrivate, 1);
}
static void
gnome_window_manager_finalize (GObject *object)
{
GnomeWindowManager *gnome_window_manager;
g_return_if_fail (object != NULL);
g_return_if_fail (IS_GNOME_WINDOW_MANAGER (object));
gnome_window_manager = GNOME_WINDOW_MANAGER (object);
g_free (gnome_window_manager->p);
parent_class->finalize (object);
}
static void
gnome_window_manager_class_init (GnomeWindowManagerClass *class)
{
GObjectClass *object_class;
GnomeWindowManagerClass *wm_class;
object_class = G_OBJECT_CLASS (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->get_focus_follows_mouse = NULL;
wm_class->set_focus_follows_mouse = NULL;
parent_class = g_type_class_peek_parent (class);
}
GType
gnome_window_manager_get_type (void)
{
static GType gnome_window_manager_type = 0;
printf ("getting called...\n");
if (!gnome_window_manager_type) {
static GTypeInfo gnome_window_manager_info = {
sizeof (GnomeWindowManagerClass),
NULL, /* GBaseInitFunc */
NULL, /* GBaseFinalizeFunc */
(GClassInitFunc) gnome_window_manager_class_init,
NULL, /* GClassFinalizeFunc */
NULL, /* user-supplied data */
sizeof (GnomeWindowManager),
0, /* n_preallocs */
(GInstanceInitFunc) gnome_window_manager_init,
NULL
};
gnome_window_manager_type =
g_type_register_static (G_TYPE_OBJECT,
"GWindowManager",
&gnome_window_manager_info, 0);
}
printf ("done\n");
return gnome_window_manager_type;
}

View file

@ -1,7 +1,6 @@
#ifndef GNOME_WINDOW_MANAGER_H
#define GNOME_WINDOW_MANAGER_H
#include <glib/gerror.h>
#include <glib-object.h>
#include <libgnome/gnome-desktop-item.h>
@ -10,43 +9,45 @@ typedef GObject * (* GnomeWindowManagerNewFunc) (void);
G_BEGIN_DECLS
#define GNOME_WINDOW_MANAGER_TYPE (gnome_window_manager_get_type ())
#define GNOME_WINDOW_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_WINDOW_MANAGER_TYPE, GnomeWindowManager))
#define GNOME_WINDOW_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_WINDOW_MANAGER_TYPE, GnomeWindowManagerClass))
#define IS_GNOME_WINDOW_MANAGER(obj) (GTK_TYPE_CHECK_INSTANCE_TYPE ((obj), GNOME_WINDOW_MANAGER_TYPE))
#define IS_GNOME_WINDOW_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNOME_WINDOW_MANAGER_TYPE))
#define GNOME_WINDOW_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNOME_WINDOW_MANAGER_TYPE, GnomeWindowManagerClass))
#define GNOME_WINDOW_MANAGER_ERROR gnome_window_manager_error_quark ()
#define GNOME_WINDOW_MANAGER(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, gnome_window_manager_get_type (), GnomeWindowManager)
#define GNOME_WINDOW_MANAGER_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, gnome_window_manager_get_type (), GnomeWindowManagerClass)
#define IS_GNOME_WINDOW_MANAGER(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, gnome_window_manager_get_type ())
#define GNOME_WINDOW_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), gnome_window_manager_get_type, GnomeWindowManagerClass))
typedef struct _GnomeWindowManager GnomeWindowManager;
typedef struct _GnomeWindowManagerClass GnomeWindowManagerClass;
typedef struct _GnomeWindowManagerPrivate GnomeWindowManagerPrivate;
struct _GnomeWindowManager
{
GObject parent_instance;
GObject parent;
GnomeWindowManagerPrivate *p;
};
struct _GnomeWindowManagerClass
{
GObjectClass parent_class;
GObjectClass klass;
void (*set_theme) (const char *theme_name);
GList * (*get_theme_list) (void);
void (*set_font) (const char *font);
gboolean (*get_focus_follows_mouse) (void);
void (*set_focus_follows_mouse) (gboolean focus_follows_mouse);
};
GObject *gnome_window_manager_new (GnomeDesktopItem *item);
GObject * gnome_window_manager_new (GnomeDesktopItem *item);
GType gnome_window_manager_get_type (void);
void gnome_window_manager_set_theme (const char *theme_name);
GList * gnome_window_manager_get_theme_list (void);
void gnome_window_manager_set_font (const char *font);
gboolean gnome_window_manager_get_focus_follows_mouse (void);
void gnome_window_manager_set_focus_follows_mouse (gboolean focus_follows_mouse);
const char * gnome_window_manager_get_name (GnomeWindowManager *wm);
void gnome_window_manager_set_theme (GnomeWindowManager *wm, const char *theme_name);
GList * gnome_window_manager_get_theme_list (GnomeWindowManager *wm);
void gnome_window_manager_set_font (GnomeWindowManager *wm, const char *font);
gboolean gnome_window_manager_get_focus_follows_mouse (GnomeWindowManager *wm);
void gnome_window_manager_set_focus_follows_mouse (GnomeWindowManager *wm, gboolean focus_follows_mouse);
G_END_DECLS

View file

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: gnome-window-settings-2.0
Description: Utility library for getting window manager settings
Requires: gtk+-2.0 libgnomeui-2.0
Version: @VERSION@
Libs: -L${libdir} -lwindow-settings
Cflags: -I${includedir}/gnome-window-settings-2.0

View file

@ -0,0 +1,608 @@
#include "gnome-wm-manager.h"
#include "wm-properties.h"
#include <gtk/gtk.h>
#include <libgnomeui/gnome-client.h>
#include <gnome.h>
/* prototypes */
static void restart (gboolean force);
static void revert_callback (void);
static void cancel_callback (void);
static void update_session (void);
static WindowManager *selected_wm = NULL;
/* 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;
/* 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)
{
wm_list_init();
selected_wm = wm_list_get_current();
}
GList *
gnome_wm_manager_get_list (void)
{
GList *wm_ditem;
GList *wms = NULL;
GnomeDesktopItem *ditem;
printf ("Total number of wms is %d\n", g_list_length (window_managers));
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;
}
void
gnome_wm_manager_set_current (GnomeWindowManager *wm)
{
/*selected_wm = wm->ditem;*/
}
GnomeWindowManager *
gnome_wm_manager_get_current (void)
{
return gnome_window_manager_new (wm_list_get_current()->dentry);
}
void gnome_wm_manager_change_wm_to_settings (void)
{
state = STATE_TRY;
restart(FALSE);
wm_list_set_current (selected_wm);
wm_list_save ();
update_session ();
}
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;
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);
} 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;
case STATE_OK:
case STATE_CANCEL:
if (quit_pending)
gtk_main_quit();
break;
default:
g_warning ("Finalize in state %d!!!\n", state);
return;
}
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);
}
}
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

@ -0,0 +1,22 @@
#ifndef GNOME_WINDOW_MANAGER_LIST_H
#define GNOME_WINDOW_MANAGER_LIST_H
#include <gtk/gtk.h>
#include "gnome-window-manager.h"
void gnome_wm_manager_init (GtkWidget *some_window);
/* returns a GList of available window managers */
GList * gnome_wm_manager_get_list (void);
/* 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);
#endif

View file

@ -0,0 +1,331 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/* Copyright (C) 1998 Redhat Software Inc.
* Code available under the Gnu GPL.
* Authors: Owen Taylor <otaylor@redhat.com>
*/
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
#include <libgnome/libgnome.h>
#include "wm-properties.h"
typedef struct _RestartInfo RestartInfo;
struct _RestartInfo {
GnomeDesktopItem *dentry;
gint retries;
WMResultFunc callback;
gpointer data;
};
gboolean
wm_is_running (void)
{
gboolean result;
guint old_mask;
XWindowAttributes attrs;
gdk_error_trap_push ();
XGetWindowAttributes (GDK_DISPLAY(), GDK_ROOT_WINDOW(), &attrs);
XSelectInput (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
SubstructureRedirectMask);
XSync (GDK_DISPLAY(), False);
if (gdk_error_trap_pop () == 0) {
result = FALSE;
XSelectInput (GDK_DISPLAY(), GDK_ROOT_WINDOW(),
attrs.your_event_mask);
} else
result = TRUE;
return result;
}
/* Cut and paste from gnome-libs/gnome_win_hints_wm_exists, except that we
* return the xid instead of a window
*/
static Window
find_gnome_wm_window(void)
{
Atom r_type;
int r_format;
unsigned long count;
unsigned long bytes_remain;
unsigned char *prop, *prop2;
GdkAtom cardinal_atom = gdk_atom_intern ("CARDINAL", FALSE);
gdk_error_trap_push ();
if (XGetWindowProperty(GDK_DISPLAY(), GDK_ROOT_WINDOW(),
gdk_x11_atom_to_xatom (gdk_atom_intern ("_WIN_SUPPORTING_WM_CHECK", FALSE)),
0, 1, False, gdk_x11_atom_to_xatom (cardinal_atom),
&r_type, &r_format,
&count, &bytes_remain, &prop) == Success && prop)
{
if (r_type == gdk_x11_atom_to_xatom (cardinal_atom) && r_format == 32 && count == 1)
{
Window n = *(long *)prop;
if (XGetWindowProperty(GDK_DISPLAY(), n,
gdk_x11_atom_to_xatom (gdk_atom_intern ("_WIN_SUPPORTING_WM_CHECK", FALSE)),
0, 1, False, gdk_x11_atom_to_xatom (cardinal_atom),
&r_type, &r_format, &count, &bytes_remain,
&prop2) == Success && prop)
{
if (r_type == gdk_x11_atom_to_xatom (cardinal_atom) && r_format == 32 && count == 1)
{
XFree(prop);
XFree(prop2);
gdk_error_trap_pop ();
return n;
}
XFree(prop2);
}
}
XFree(prop);
}
gdk_error_trap_pop ();
return None;
}
static Window
find_wm_window_from_client (GdkWindow *client)
{
Window window, frame, parent, root;
Window *children;
unsigned int nchildren;
gboolean needs_pop = TRUE;
if (!client)
return None;
frame = None;
window = GDK_WINDOW_XWINDOW (client);
gdk_error_trap_push ();
while (XQueryTree (GDK_DISPLAY(), window,
&root, &parent, &children, &nchildren))
{
if (gdk_error_trap_pop != 0)
{
needs_pop = FALSE;
break;
}
gdk_error_trap_push ();
if (children)
XFree(children);
if (window == root)
break;
if (root == parent) {
frame = window;
break;
}
window = parent;
}
if (needs_pop)
gdk_error_trap_pop ();
return frame;
}
static gboolean
window_has_wm_state (Window window)
{
Atom r_type;
int r_format;
unsigned long count;
unsigned long bytes_remain;
unsigned char *prop;
if (XGetWindowProperty(GDK_DISPLAY(), window,
gdk_x11_atom_to_xatom (gdk_atom_intern ("WM_STATE", FALSE)),
0, 0, False, AnyPropertyType,
&r_type, &r_format,
&count, &bytes_remain, &prop) == Success) {
if (r_type != None) {
XFree(prop);
return TRUE;
}
}
return FALSE;
}
static gboolean
descendent_has_wm_state (Window window)
{
gboolean result = FALSE;
Window parent, root;
Window *children;
unsigned int nchildren;
gint i;
if (!XQueryTree (GDK_DISPLAY(), window,
&root, &parent, &children, &nchildren))
return FALSE;
for (i=0; i<nchildren; i++) {
if (window_has_wm_state (children[i]) ||
descendent_has_wm_state (children[i])) {
result = TRUE;
break;
}
}
if (children)
XFree (children);
return result;
}
/* This function tries to find a window manager frame by
* hunting all the children of the root window
*/
static Window
find_wm_window_from_hunt (void)
{
Window parent, root, frame;
Window *children;
unsigned int nchildren;
gint i;
frame = None;
gdk_error_trap_push ();
XQueryTree (GDK_DISPLAY(), GDK_ROOT_WINDOW (),
&root, &parent, &children, &nchildren);
/* We are looking for a window that doesn't have WIN_STATE
* set on it, but does have a child with WIN_STATE set
*/
for (i=0; i<nchildren; i++) {
if (!window_has_wm_state (children[i]) &&
descendent_has_wm_state (children[i])) {
frame = children[i];
break;
}
}
if (children)
XFree (children);
gdk_error_trap_pop ();
return frame;
}
static Window
find_wm_window (GdkWindow *client)
{
Window wm_window = None;
/* First, try to find a GNOME compliant WM */
wm_window = find_gnome_wm_window();
if (!wm_window) {
wm_window = find_wm_window_from_client (client);
}
if (!wm_window) {
wm_window = find_wm_window_from_hunt ();
}
return wm_window;
}
static gboolean
start_timeout (gpointer data)
{
RestartInfo *info = data;
if (wm_is_running ()) {
info->callback(WM_SUCCESS, info->data);
gnome_desktop_item_unref (info->dentry);
g_free (info);
return FALSE;
} else {
info->retries--;
if (info->retries > 0)
return TRUE;
else {
info->callback(WM_CANT_START, info->data);
gnome_desktop_item_unref (info->dentry);
g_free (info);
return FALSE;
}
}
}
static void
start_do (RestartInfo *info)
{
gnome_desktop_item_launch (info->dentry, 0, 0, NULL);
info->retries = 10;
gtk_timeout_add (1000, start_timeout, info);
}
static gboolean
kill_timeout (gpointer data)
{
RestartInfo *info = data;
if (!wm_is_running ()) {
start_do (info);
return FALSE;
} else {
info->retries--;
if (info->retries > 0)
return TRUE;
else {
info->callback(WM_ALREADY_RUNNING, info->data);
gnome_desktop_item_unref (info->dentry);
g_free (info);
return FALSE;
}
}
}
void
wm_restart (WindowManager *new,
GdkWindow *client,
WMResultFunc callback,
gpointer data)
{
Window wm_window;
RestartInfo *info;
g_return_if_fail (new->is_present);
info = g_new (RestartInfo, 1);
info->dentry = gnome_desktop_item_copy (new->dentry);
info->callback = callback;
info->data = data;
info->retries = 10;
if (wm_is_running ()) {
wm_window = find_wm_window (client);
if (!wm_window) {
(*callback) (WM_ALREADY_RUNNING, data);
gnome_desktop_item_unref (info->dentry);
g_free (info);
} else {
XKillClient (GDK_DISPLAY(), wm_window);
gtk_timeout_add (1000, kill_timeout, info);
}
} else {
start_do (info);
}
}
WindowManager *
wm_guess_current (void)
{
return NULL;
}

View file

@ -0,0 +1,577 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/* Copyright (C) 1998 Redhat Software Inc.
* Code available under the Gnu GPL.
* Authors: Owen Taylor <otaylor@redhat.com>,
* Bradford Hovinen <hovinen@helixcode.com>
*/
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
#include <libgnome/libgnome.h>
#include <gconf/gconf-client.h>
#include <string.h>
#include "wm-properties.h"
#define CONFIG_PREFIX "/desktop/gnome/applications/window_manager"
/* Current list of window managers */
GList *window_managers = NULL;
/* List on startup */
static GList *window_managers_save = NULL;
/* Current window manager */
static WindowManager *current_wm = NULL;
/* Window manager on startup */
static WindowManager *current_wm_save = NULL;
static gboolean xml_read_bool (xmlNodePtr node);
static xmlNodePtr xml_write_bool (gchar *name,
gboolean value);
gboolean
is_blank (gchar *str)
{
while (*str) {
if (!isspace(*str))
return FALSE;
str++;
}
return TRUE;
}
static gint
wm_compare (gconstpointer a, gconstpointer b)
{
const WindowManager *wm_a = (const WindowManager *)a;
const WindowManager *wm_b = (const WindowManager *)b;
return g_strcasecmp (gnome_desktop_item_get_string (wm_a->dentry, GNOME_DESKTOP_ITEM_NAME), gnome_desktop_item_get_string (wm_b->dentry, GNOME_DESKTOP_ITEM_NAME));
}
static void
wm_free (WindowManager *wm)
{
gnome_desktop_item_unref (wm->dentry);
g_free (wm->config_exec);
g_free (wm->config_tryexec);;
g_free (wm);
}
void
wm_check_present (WindowManager *wm)
{
gchar *path;
if (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC)) {
if (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_TRY_EXEC)) {
path = gnome_is_program_in_path (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_TRY_EXEC));
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 = gnome_is_program_in_path (wm->config_tryexec);
wm->is_config_present = (path != NULL);
if (path)
g_free (path);
} else {
path = gnome_is_program_in_path (wm->config_exec);
wm->is_config_present = (path != NULL);
if (path)
g_free (path);
}
} else
wm->is_config_present = FALSE;
}
static WindowManager *
wm_copy (WindowManager *wm)
{
WindowManager *result = g_new (WindowManager, 1);
result->dentry = gnome_desktop_item_copy (wm->dentry);
result->config_exec = g_strdup (wm->config_exec);
result->config_tryexec = g_strdup (wm->config_tryexec);
result->session_managed = wm->session_managed;
result->is_user = wm->is_user;
result->is_present = wm->is_present;
result->is_config_present = wm->is_config_present;
return result;
}
static WindowManager *
wm_list_find (GList *list, const char *name)
{
GList *tmp_list = list;
while (tmp_list) {
WindowManager *wm = tmp_list->data;
if (strcmp (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC), name) == 0)
return wm;
tmp_list = tmp_list->next;
}
return NULL;
}
static WindowManager *
wm_list_find_exec (GList *list, const char *name)
{
GList *tmp_list = list;
while (tmp_list) {
WindowManager *wm = tmp_list->data;
if (!gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC))
continue;
if (strcmp (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC), name) == 0)
return wm;
tmp_list = tmp_list->next;
}
return NULL;
}
static GList *
wm_list_find_files (gchar *directory)
{
DIR *dir;
struct dirent *child;
GList *result = NULL;
gchar *suffix;
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 void
wm_list_read_dir (gchar *directory, gboolean is_user)
{
WindowManager *wm;
GList *tmp_list;
GList *files;
gchar *prefix;
files = wm_list_find_files (directory);
tmp_list = files;
while (tmp_list) {
wm = g_new (WindowManager, 1);
wm->dentry = gnome_desktop_item_new_from_file (tmp_list->data, GNOME_DESKTOP_ITEM_TYPE_APPLICATION, NULL);
gnome_desktop_item_set_entry_type (wm->dentry, GNOME_DESKTOP_ITEM_TYPE_APPLICATION);
if (!wm->dentry) {
g_free (wm);
tmp_list = tmp_list->next;
continue;
}
prefix = g_strconcat ("=", gnome_desktop_item_get_location (wm->dentry), "=/Window Manager/", NULL);
gnome_config_push_prefix (prefix);
g_free (prefix);
wm->config_exec = gnome_config_get_string ("ConfigExec");
wm->config_tryexec = gnome_config_get_string ("ConfigTryExec");
wm->session_managed = gnome_config_get_bool ("SessionManaged=0");
wm->is_user = is_user;
if (wm->config_exec && is_blank (wm->config_exec)) {
g_free (wm->config_exec);
wm->config_exec = NULL;
}
if (wm->config_tryexec && is_blank (wm->config_tryexec)) {
g_free (wm->config_tryexec);
wm->config_tryexec = NULL;
}
gnome_config_pop_prefix ();
wm_check_present (wm);
if (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME) && gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC) &&
(wm->is_user || wm->is_present)) {
window_managers =
g_list_insert_sorted (window_managers,
wm,
wm_compare);
window_managers_save =
g_list_insert_sorted (window_managers_save,
wm_copy (wm),
wm_compare);
} else {
wm_free (wm);
}
tmp_list = tmp_list->next;
}
g_list_free (files);
}
void
wm_list_init (void)
{
gchar *tempdir;
gchar *name;
GConfClient *client;
tempdir = gnome_unconditional_datadir_file ("gnome/wm-properties/");
wm_list_read_dir (tempdir, FALSE);
g_free (tempdir);
tempdir = gnome_util_home_file("wm-properties/");
wm_list_read_dir (tempdir, TRUE);
g_free (tempdir);
client = gconf_client_get_default ();
name = gconf_client_get_string (client, CONFIG_PREFIX "/current", NULL);
if (name) {
current_wm = wm_list_find (window_managers, name);
g_free (name);
}
if (!current_wm) {
name = gconf_client_get_string (client, CONFIG_PREFIX "/default", NULL);
if (name) {
current_wm = wm_list_find_exec (window_managers, name);
g_free (name);
}
}
if (!current_wm) {
gchar *wmfile, *prefix;
wmfile = gnome_unconditional_datadir_file ("default.wm");
prefix = g_strconcat ("=", wmfile, "=/Default/WM", NULL);
name = gnome_config_get_string (prefix);
g_free (wmfile);
g_free (prefix);
if (name) {
current_wm = wm_list_find_exec (window_managers, name);
g_free (name);
}
}
if (!current_wm && window_managers)
current_wm = window_managers->data;
if(current_wm)
current_wm_save = wm_list_find (window_managers_save, gnome_desktop_item_get_string (current_wm->dentry, GNOME_DESKTOP_ITEM_NAME));
g_object_unref (G_OBJECT (client));
}
void
wm_list_save (void)
{
GList *old_files;
GList *tmp_list;
gchar *tempdir;
gchar *prefix;
WindowManager *wm;
/* Clean out the current contents of .gnome/wm-desktops
*/
tempdir = gnome_util_home_file("wm-properties/");
old_files = wm_list_find_files (tempdir);
g_free (tempdir);
tmp_list = old_files;
while (tmp_list) {
prefix = g_strconcat ("=", tmp_list->data, "=", NULL);
gnome_config_clean_file (prefix);
gnome_config_sync_file (prefix);
g_free (prefix);
tmp_list = tmp_list->next;
}
g_list_free (old_files);
/* Save the user's desktops
*/
tmp_list = window_managers;
while (tmp_list) {
wm = tmp_list->data;
if (wm->is_user) {
gnome_desktop_item_save (wm->dentry, NULL, TRUE, NULL);
prefix = g_strconcat ("=", gnome_desktop_item_get_location (wm->dentry), "=/Window Manager/", NULL);
gnome_config_push_prefix (prefix);
g_free (prefix);
if (wm->config_exec)
gnome_config_set_string ("ConfigExec", wm->config_exec);
if (wm->config_tryexec)
gnome_config_set_string ("ConfigTryExec", wm->config_tryexec);
gnome_config_set_bool ("SessionManaged=0", wm->session_managed);
gnome_config_pop_prefix ();
}
tmp_list = tmp_list->next;
}
/* Save the current window manager
*/
if(current_wm)
{
GConfClient *client = gconf_client_get_default ();
gconf_client_set_string (client, CONFIG_PREFIX "/current",
gnome_desktop_item_get_string (current_wm->dentry, GNOME_DESKTOP_ITEM_EXEC),
NULL);
g_object_unref (G_OBJECT (client));
}
gnome_config_sync ();
}
void
wm_list_revert (void)
{
GList *tmp_list;
gchar *old_name = NULL;
if(current_wm)
old_name = g_strdup (gnome_desktop_item_get_string (current_wm->dentry, GNOME_DESKTOP_ITEM_NAME));
g_list_foreach (window_managers, (GFunc)wm_free, NULL);
g_list_free (window_managers);
window_managers = NULL;
tmp_list = window_managers_save;
while (tmp_list) {
window_managers = g_list_prepend (window_managers,
wm_copy (tmp_list->data));
tmp_list = tmp_list->next;
}
window_managers = g_list_reverse (window_managers);
current_wm = wm_list_find (window_managers, old_name);
g_free (old_name);
}
void
wm_list_add (WindowManager *wm)
{
g_return_if_fail (wm != NULL);
window_managers = g_list_insert_sorted (window_managers, wm,
wm_compare);
}
void
wm_list_delete (WindowManager *wm)
{
GList *node;
g_return_if_fail (wm != NULL);
g_return_if_fail (wm != current_wm);
node = g_list_find (window_managers, wm);
g_return_if_fail (node != NULL);
window_managers = g_list_remove_link (window_managers, node);
g_list_free_1 (node);
wm_free (wm);
}
void
wm_list_set_current (WindowManager *wm)
{
current_wm = wm;
}
WindowManager *
wm_list_get_current (void)
{
return current_wm;
}
WindowManager *
wm_list_get_revert (void)
{
if(current_wm_save)
return wm_list_find (window_managers, gnome_desktop_item_get_string (current_wm_save->dentry, GNOME_DESKTOP_ITEM_NAME));
else
return NULL;
}
static WindowManager *
wm_read_from_xml (xmlNodePtr wm_node)
{
xmlNodePtr node;
WindowManager *wm;
gboolean is_current = FALSE;
if (strcmp (wm_node->name, "window-manager")) return NULL;
wm = g_new0 (WindowManager, 1);
wm->dentry = gnome_desktop_item_new_from_file
(xmlGetProp (wm_node, "desktop-entry"),
GNOME_DESKTOP_ITEM_TYPE_APPLICATION, NULL);
gnome_desktop_item_set_entry_type (wm->dentry, GNOME_DESKTOP_ITEM_TYPE_APPLICATION);
for (node = wm_node->children; node; node = node->next) {
if (!strcmp (node->name, "config-exec"))
wm->config_exec = xmlNodeGetContent (node);
else if (!strcmp (node->name, "config-tryexec"))
wm->config_tryexec = xmlNodeGetContent (node);
else if (!strcmp (node->name, "session-managed"))
wm->session_managed = xml_read_bool (node);
else if (!strcmp (node->name, "is-user"))
wm->is_user = xml_read_bool (node);
else if (!strcmp (node->name, "is-current"))
is_current = xml_read_bool (node); /* FIXME: sanity check */
}
wm_check_present (wm);
if (wm->dentry == NULL ||
(wm->config_exec != NULL && is_blank (wm->config_exec)) ||
gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME) == NULL || gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC) == NULL ||
!(wm->is_user || wm->is_present))
{
g_free (wm);
return NULL;
}
if (is_current) current_wm = wm;
return wm;
}
void
wm_list_read_from_xml (xmlDocPtr doc)
{
xmlNodePtr root_node, node;
WindowManager *wm;
root_node = xmlDocGetRootElement (doc);
if (strcmp (root_node->name, "wm-prefs")) return;
for (node = root_node; node; node = node->next) {
if (!strcmp (node->name, "window-manager")) {
wm = wm_read_from_xml (node);
if (wm) window_managers =
g_list_insert_sorted
(window_managers, wm, wm_compare);
}
}
}
static xmlNodePtr
wm_write_to_xml (WindowManager *wm)
{
xmlNodePtr node;
node = xmlNewNode (NULL, "window-manager");
xmlNewProp (node, "desktop-entry", gnome_desktop_item_get_location (wm->dentry));
if (wm->config_exec != NULL)
xmlNewChild (node, NULL, "config-exec", wm->config_exec);
xmlAddChild (node, xml_write_bool ("session-managed",
wm->session_managed));
xmlAddChild (node, xml_write_bool ("is-user", wm->is_user));
xmlAddChild (node, xml_write_bool ("is-current", wm == current_wm));
return node;
}
xmlDocPtr
wm_list_write_to_xml (void)
{
xmlDocPtr doc;
xmlNodePtr root_node, node;
GList *wm_node;
doc = xmlNewDoc ("1.0");
root_node = xmlNewDocNode (doc, NULL, "wm-prefs", NULL);
for (wm_node = window_managers; wm_node; wm_node = wm_node->next) {
node = wm_write_to_xml ((WindowManager *) wm_node->data);
if (node) xmlAddChild (root_node, node);
}
xmlDocSetRootElement (doc, root_node);
return doc;
}
/* Read a boolean value from a node */
static gboolean
xml_read_bool (xmlNodePtr node)
{
char *text;
text = xmlNodeGetContent (node);
if (!g_strcasecmp (text, "true"))
return TRUE;
else
return FALSE;
}
/* Write out a boolean value in a node */
static xmlNodePtr
xml_write_bool (gchar *name, gboolean value)
{
xmlNodePtr node;
g_return_val_if_fail (name != NULL, NULL);
node = xmlNewNode (NULL, name);
if (value)
xmlNodeSetContent (node, "true");
else
xmlNodeSetContent (node, "false");
return node;
}

View file

@ -0,0 +1,63 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/* Copyright (C) 1998 Redhat Software Inc.
* Code available under the Gnu GPL.
* Authors: Owen Taylor <otaylor@redhat.com>,
* Bradford Hovinen <hovinen@helixcode.com>
*/
#include <gdk/gdk.h>
#include <libgnome/libgnome.h>
#include <libgnome/gnome-desktop-item.h>
#include <libxml/tree.h>
typedef struct _WindowManager WindowManager;
struct _WindowManager {
GnomeDesktopItem *dentry;
gchar *config_exec;
gchar *config_tryexec;
gboolean session_managed : 1;
gboolean is_user : 1;
gboolean is_present : 1;
gboolean is_config_present : 1;
};
/* Utility functions */
gboolean is_blank (gchar *str);
/* Fill in the is_present and is_config_present fields */
void wm_check_present (WindowManager *wm);
/* Management of window manager list */
void wm_list_init (void);
void wm_list_save (void);
void wm_list_revert (void);
void wm_list_add (WindowManager *window_manager);
void wm_list_delete (WindowManager *window_manager);
void wm_list_set_current (WindowManager *window_manager);
WindowManager *wm_list_get_current (void);
WindowManager *wm_list_get_revert (void);
void wm_list_read_from_xml (xmlDocPtr doc);
xmlDocPtr wm_list_write_to_xml (void);
extern GList *window_managers;
/* Management of current window manager */
typedef enum {
WM_SUCCESS,
WM_ALREADY_RUNNING,
WM_CANT_START
} WMResult;
typedef void (*WMResultFunc) (WMResult result, gpointer data);
void wm_restart (WindowManager *new,
GdkWindow *client,
WMResultFunc callback,
gpointer data);
gboolean wm_is_running (void);
WindowManager *wm_guess_current (void);