2002-05-10 Seth Nickell <snickell@stanford.edu>
* .cvsignore: * Makefile.am: * gnome-window-properties.c: (wm_selection_changed), (wm_widget_clear), (wm_widget_new), (wm_widget_add_wm), (response_cb), (state_changed), (restart_label_update), (restart_dialog_raise), (restart_dialog_destroyed), (show_restart_dialog), (hide_restart_dialog), (update_session), (init_session), (update_gui), (init_callback), (restart_finalize), (restart_failure), (show_restart_info), (restart_finish), (restart_callback), (restart), (revert_callback), (cancel_callback), (apply_wm), (create_dialog), (main): * gnome-window-properties.glade: * window-capplet.png: * window-properties.desktop.in: * 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:
This commit is contained in:
parent
00c628d44b
commit
ad15ad16c9
10 changed files with 2118 additions and 0 deletions
10
capplets/windows/.cvsignore
Normal file
10
capplets/windows/.cvsignore
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Makefile
|
||||||
|
Makefile.in
|
||||||
|
.deps
|
||||||
|
.libs
|
||||||
|
*.o
|
||||||
|
*.lo
|
||||||
|
*.la
|
||||||
|
gnome-window-properties
|
||||||
|
window-properties.desktop
|
||||||
|
*.oaf
|
29
capplets/windows/ChangeLog
Normal file
29
capplets/windows/ChangeLog
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
2002-05-10 Seth Nickell <snickell@stanford.edu>
|
||||||
|
|
||||||
|
* .cvsignore:
|
||||||
|
* Makefile.am:
|
||||||
|
* gnome-window-properties.c: (wm_selection_changed),
|
||||||
|
(wm_widget_clear), (wm_widget_new), (wm_widget_add_wm),
|
||||||
|
(response_cb), (state_changed), (restart_label_update),
|
||||||
|
(restart_dialog_raise), (restart_dialog_destroyed),
|
||||||
|
(show_restart_dialog), (hide_restart_dialog), (update_session),
|
||||||
|
(init_session), (update_gui), (init_callback), (restart_finalize),
|
||||||
|
(restart_failure), (show_restart_info), (restart_finish),
|
||||||
|
(restart_callback), (restart), (revert_callback),
|
||||||
|
(cancel_callback), (apply_wm), (create_dialog), (main):
|
||||||
|
* gnome-window-properties.glade:
|
||||||
|
* window-capplet.png:
|
||||||
|
* window-properties.desktop.in:
|
||||||
|
* 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:
|
31
capplets/windows/Makefile.am
Normal file
31
capplets/windows/Makefile.am
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
bin_PROGRAMS = gnome-window-properties
|
||||||
|
|
||||||
|
gnome_window_properties_LDADD = $(GNOMECC_CAPPLETS_LIBS)
|
||||||
|
gnome_window_properties_SOURCES = \
|
||||||
|
gnome-window-properties.c \
|
||||||
|
wm-properties.h \
|
||||||
|
wm-exec.c \
|
||||||
|
wm-list.c
|
||||||
|
|
||||||
|
@INTLTOOL_DESKTOP_RULE@
|
||||||
|
|
||||||
|
pixmapdir = $(GNOMECC_PIXMAPS_DIR)
|
||||||
|
pixmap_DATA =
|
||||||
|
|
||||||
|
Gladedir = $(GNOMECC_GLADE_DIR)
|
||||||
|
Glade_DATA = gnome-window-properties.glade
|
||||||
|
|
||||||
|
iconsdir = $(GNOMECC_ICONS_DIR)
|
||||||
|
icons_DATA = window-capplet.png
|
||||||
|
|
||||||
|
desktop_iconsdir = $(datadir)/pixmaps
|
||||||
|
desktop_icons_DATA = window-capplet.png
|
||||||
|
|
||||||
|
desktopdir = $(GNOMECC_DESKTOP_DIR)
|
||||||
|
Desktop_in_files = window-properties.desktop.in
|
||||||
|
desktop_DATA = $(Desktop_in_files:.desktop.in=.desktop)
|
||||||
|
|
||||||
|
INCLUDES = $(GNOMECC_CAPPLETS_CFLAGS) $(DESKTOP_ITEM_CFLAGS)
|
||||||
|
CLEANFILES = $(GNOMECC_CAPPLETS_CLEANFILES)
|
||||||
|
EXTRA_DIST = $(Glade_DATA) $(icons_DATA) $(Desktop_in_files) $(pixmap_DATA)
|
||||||
|
|
797
capplets/windows/gnome-window-properties.c
Normal file
797
capplets/windows/gnome-window-properties.c
Normal file
|
@ -0,0 +1,797 @@
|
||||||
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
||||||
|
/* Copyright (C) 1998-1999 Redhat Software Inc.
|
||||||
|
* Code available under the Gnu GPL.
|
||||||
|
* Authors: Jonathan Blandford <jrb@redhat.com>
|
||||||
|
* Owen Taylor <otaylor@redhat.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <gconf/gconf-client.h>
|
||||||
|
#include <glade/glade.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "capplet-util.h"
|
||||||
|
#include "gconf-property-editor.h"
|
||||||
|
#include "wm-properties.h"
|
||||||
|
|
||||||
|
//#include "gnome-startup.h"
|
||||||
|
|
||||||
|
/* prototypes */
|
||||||
|
static void restart (gboolean force);
|
||||||
|
static void revert_callback (void);
|
||||||
|
static void cancel_callback (void);
|
||||||
|
|
||||||
|
/* structures */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GtkWidget *dialog;
|
||||||
|
GtkWidget *name_entry;
|
||||||
|
GtkWidget *exec_entry;
|
||||||
|
GtkWidget *config_entry;
|
||||||
|
GtkWidget *sm_toggle;
|
||||||
|
} WMDialog;
|
||||||
|
|
||||||
|
/* vars. */
|
||||||
|
static GtkWidget *capplet;
|
||||||
|
static GtkWidget *wm_widget;
|
||||||
|
static GtkWidget *apply_now_button;
|
||||||
|
|
||||||
|
static WindowManager *selected_wm = NULL;
|
||||||
|
|
||||||
|
static GtkWidget *restart_dialog = NULL;
|
||||||
|
static GtkWidget *restart_label = NULL;
|
||||||
|
guint restart_dialog_timeout;
|
||||||
|
gchar *restart_name = NULL;
|
||||||
|
|
||||||
|
/* Time until dialog times out */
|
||||||
|
gdouble restart_remaining_time;
|
||||||
|
gint restart_displayed_time;
|
||||||
|
|
||||||
|
GnomeClient *client = NULL;
|
||||||
|
gchar *argv0;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Current state
|
||||||
|
*/
|
||||||
|
StateType state = STATE_IDLE;
|
||||||
|
|
||||||
|
/* Set TRUE when we've exited the main loop, but restart_pending
|
||||||
|
*/
|
||||||
|
gboolean quit_pending = FALSE;
|
||||||
|
|
||||||
|
/* Set TRUE when we're waiting for the WM to restart
|
||||||
|
*/
|
||||||
|
gboolean restart_pending = FALSE;
|
||||||
|
|
||||||
|
/* Set TRUE while we are filling in the list
|
||||||
|
*/
|
||||||
|
gboolean in_fill = FALSE;
|
||||||
|
|
||||||
|
static gint cap_session_init = 0;
|
||||||
|
static struct poptOption cap_options[] = {
|
||||||
|
{"init-session-settings", '\0', POPT_ARG_NONE, &cap_session_init, 0,
|
||||||
|
N_("Initialize session settings"), NULL},
|
||||||
|
{NULL, '\0', 0, NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void state_changed (void);
|
||||||
|
static void update_session (void);
|
||||||
|
|
||||||
|
static GtkWidget *wm_menu;
|
||||||
|
static GtkWidget *option_menu;
|
||||||
|
static GList *wm_menu_window_managers;
|
||||||
|
|
||||||
|
static void
|
||||||
|
wm_selection_changed (GtkOptionMenu *option_menu, gpointer data)
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
WindowManager *wm;
|
||||||
|
|
||||||
|
index = gtk_option_menu_get_history (option_menu);
|
||||||
|
wm = (WindowManager *) g_list_nth (wm_menu_window_managers, index)->data;
|
||||||
|
|
||||||
|
if (!in_fill) {
|
||||||
|
if (wm != selected_wm) {
|
||||||
|
selected_wm = wm;
|
||||||
|
state_changed ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wm_widget_clear ()
|
||||||
|
{
|
||||||
|
wm_menu_window_managers = NULL;
|
||||||
|
|
||||||
|
wm_menu = gtk_menu_new ();
|
||||||
|
gtk_widget_show_all (wm_menu);
|
||||||
|
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), wm_menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkWidget *
|
||||||
|
wm_widget_new ()
|
||||||
|
{
|
||||||
|
option_menu = gtk_option_menu_new ();
|
||||||
|
g_signal_connect (G_OBJECT (option_menu), "changed",
|
||||||
|
wm_selection_changed, NULL);
|
||||||
|
|
||||||
|
wm_widget_clear ();
|
||||||
|
|
||||||
|
gtk_widget_show_all (option_menu);
|
||||||
|
return option_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wm_widget_add_wm (WindowManager *wm, const char *row_text)
|
||||||
|
{
|
||||||
|
GtkWidget *menu_item;
|
||||||
|
|
||||||
|
menu_item = gtk_menu_item_new_with_label (row_text);
|
||||||
|
gtk_widget_show_all (menu_item);
|
||||||
|
|
||||||
|
gtk_menu_shell_prepend (GTK_MENU_SHELL (wm_menu), menu_item);
|
||||||
|
wm_menu_window_managers = g_list_prepend (wm_menu_window_managers, wm);
|
||||||
|
|
||||||
|
if (wm == selected_wm)
|
||||||
|
gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
response_cb (GtkDialog *dialog, gint response_id, gpointer data)
|
||||||
|
{
|
||||||
|
switch (response_id)
|
||||||
|
{
|
||||||
|
case GTK_RESPONSE_NONE:
|
||||||
|
case GTK_RESPONSE_CLOSE:
|
||||||
|
gtk_main_quit ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
state_changed (void)
|
||||||
|
{
|
||||||
|
gtk_widget_set_sensitive (apply_now_button, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
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 {
|
||||||
|
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_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)
|
||||||
|
update_session();
|
||||||
|
else {
|
||||||
|
gnome_client_set_restart_style (client,
|
||||||
|
GNOME_RESTART_NEVER);
|
||||||
|
gnome_client_flush (client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_gui (void)
|
||||||
|
{
|
||||||
|
GList *tmp_list;
|
||||||
|
|
||||||
|
wm_widget_clear ();
|
||||||
|
|
||||||
|
in_fill = TRUE;
|
||||||
|
|
||||||
|
tmp_list = window_managers;
|
||||||
|
while (tmp_list) {
|
||||||
|
gchar *row_text;
|
||||||
|
WindowManager *wm;
|
||||||
|
|
||||||
|
wm = tmp_list->data;
|
||||||
|
|
||||||
|
if (wm->is_user && !wm->is_present) {
|
||||||
|
row_text = g_strconcat (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME),
|
||||||
|
_(" (Not found)"), NULL);
|
||||||
|
} else {
|
||||||
|
row_text = g_strdup (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
wm_widget_add_wm (wm, row_text);
|
||||||
|
|
||||||
|
g_free (row_text);
|
||||||
|
|
||||||
|
tmp_list = tmp_list->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
in_fill = FALSE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
apply_wm (GObject *object, gpointer data)
|
||||||
|
{
|
||||||
|
state = STATE_TRY;
|
||||||
|
restart(FALSE);
|
||||||
|
wm_list_set_current (selected_wm);
|
||||||
|
wm_list_save ();
|
||||||
|
update_session ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static GladeXML *
|
||||||
|
create_dialog (void)
|
||||||
|
{
|
||||||
|
GladeXML *dialog;
|
||||||
|
|
||||||
|
dialog = glade_xml_new (GNOMECC_DATA_DIR "/interfaces/gnome-window-properties.glade", "prefs_widget", NULL);
|
||||||
|
|
||||||
|
apply_now_button = WID ("apply_now_button");
|
||||||
|
gtk_widget_set_sensitive (apply_now_button, FALSE);
|
||||||
|
g_signal_connect (G_OBJECT (apply_now_button), "clicked", apply_wm, NULL);
|
||||||
|
|
||||||
|
wm_widget = wm_widget_new ();
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (WID ("wm_widget_box")), wm_widget, TRUE, TRUE, 0);
|
||||||
|
|
||||||
|
update_gui();
|
||||||
|
|
||||||
|
return dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
GladeXML *dialog;
|
||||||
|
GtkWidget *dialog_win;
|
||||||
|
|
||||||
|
bindtextdomain (PACKAGE, GNOMELOCALEDIR);
|
||||||
|
textdomain (PACKAGE);
|
||||||
|
|
||||||
|
argv0 = g_strdup (argv[0]);
|
||||||
|
gnome_program_init ("wm-properties", VERSION,
|
||||||
|
LIBGNOMEUI_MODULE, argc, argv,
|
||||||
|
GNOME_PARAM_POPT_TABLE, &cap_options,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Read in the list of window managers, and the current
|
||||||
|
* window manager
|
||||||
|
*/
|
||||||
|
wm_list_init();
|
||||||
|
selected_wm = wm_list_get_current();
|
||||||
|
|
||||||
|
if (!cap_session_init)
|
||||||
|
{
|
||||||
|
init_session();
|
||||||
|
dialog = create_dialog ();
|
||||||
|
|
||||||
|
dialog_win = gtk_dialog_new_with_buttons
|
||||||
|
(_("Window Preferences"), NULL, -1,
|
||||||
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
||||||
|
NULL);
|
||||||
|
g_signal_connect (G_OBJECT (dialog_win), "response", response_cb, NULL);
|
||||||
|
|
||||||
|
capplet = dialog_win;
|
||||||
|
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_win)->vbox), WID ("prefs_widget"), TRUE, TRUE, GNOME_PAD_SMALL);
|
||||||
|
gtk_widget_show_all (dialog_win);
|
||||||
|
|
||||||
|
gtk_main ();
|
||||||
|
|
||||||
|
if (restart_pending) {
|
||||||
|
quit_pending = TRUE;
|
||||||
|
gtk_main();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (selected_wm &&
|
||||||
|
!selected_wm->session_managed &&
|
||||||
|
!wm_is_running()) {
|
||||||
|
|
||||||
|
wm_restart (selected_wm, NULL, init_callback,
|
||||||
|
g_strdup (gnome_desktop_item_get_string (selected_wm->dentry, GNOME_DESKTOP_ITEM_NAME)));
|
||||||
|
gtk_main ();
|
||||||
|
}
|
||||||
|
|
||||||
|
init_session();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
275
capplets/windows/gnome-window-properties.glade
Normal file
275
capplets/windows/gnome-window-properties.glade
Normal file
|
@ -0,0 +1,275 @@
|
||||||
|
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||||
|
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||||
|
|
||||||
|
<glade-interface>
|
||||||
|
|
||||||
|
<widget class="GtkWindow" id="window1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="title" translatable="yes">Window Properties</property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||||
|
<property name="modal">False</property>
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="prefs_widget">
|
||||||
|
<property name="border_width">10</property>
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label" translatable="yes">Window Manager:</property>
|
||||||
|
<property name="use_underline">False</property>
|
||||||
|
<property name="use_markup">False</property>
|
||||||
|
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||||
|
<property name="wrap">False</property>
|
||||||
|
<property name="selectable">False</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="wm_widget_box">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<placeholder/>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="apply_now_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Apply Now</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHSeparator" id="hseparator1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">10</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">5</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="label_yalign">0.5</property>
|
||||||
|
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkImage" id="image1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0.5</property>
|
||||||
|
<property name="yalign">0.5</property>
|
||||||
|
<property name="xpad">0</property>
|
||||||
|
<property name="ypad">0</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="label_yalign">0.5</property>
|
||||||
|
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkOptionMenu" id="optionmenu2">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="history">-1</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="label_yalign">0.5</property>
|
||||||
|
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkOptionMenu" id="optionmenu3">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="history">-1</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkFrame" id="frame4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="label_xalign">0</property>
|
||||||
|
<property name="label_yalign">0.5</property>
|
||||||
|
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkOptionMenu" id="optionmenu4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="history">-1</property>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="vbox4">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
|
<child>
|
||||||
|
<widget class="GtkCheckButton" id="checkbutton1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Select windows when the mouse moves over them</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||||
|
<property name="active">False</property>
|
||||||
|
<property name="inconsistent">False</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
|
||||||
|
</glade-interface>
|
BIN
capplets/windows/window-capplet.png
Normal file
BIN
capplets/windows/window-capplet.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3 KiB |
8
capplets/windows/window-properties.desktop.in
Normal file
8
capplets/windows/window-properties.desktop.in
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
_Name=Mouse
|
||||||
|
_Comment=Window Properties
|
||||||
|
Exec=gnome2-window-properties
|
||||||
|
Icon=window-capplet.png
|
||||||
|
Terminal=0
|
||||||
|
Type=Application
|
||||||
|
Categories=Application;Settings;
|
331
capplets/windows/wm-exec.c
Normal file
331
capplets/windows/wm-exec.c
Normal 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;
|
||||||
|
}
|
574
capplets/windows/wm-list.c
Normal file
574
capplets/windows/wm-list.c
Normal file
|
@ -0,0 +1,574 @@
|
||||||
|
/* -*- 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 "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, gchar *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, gchar *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;
|
||||||
|
}
|
63
capplets/windows/wm-properties.h
Normal file
63
capplets/windows/wm-properties.h
Normal 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);
|
Loading…
Add table
Add a link
Reference in a new issue