gnome-control-center/capplets/wm-properties/wm-properties-capplet.c
Richard Hestilow 5146b73151 Port to GConf, away from libcapplet.
2001-12-08  Richard Hestilow  <hestilow@ximian.com>

	* Port to GConf, away from libcapplet.
2001-12-09 03:26:21 +00:00

1260 lines
39 KiB
C

/* -*- 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 <ctype.h>
#include <libxml/parser.h>
#include "wm-properties.h"
#include "gnome.h"
#ifdef HAVE_XIMIAN_ARCHIVER
# include <ximian-archiver/archive.h>
# include <ximian-archiver/location.h>
#endif /* HAVE_XIMIAN_ARCHIVER */
#include "gnome-startup.h"
/* prototypes */
static void restart (gboolean force);
static void try_callback (void);
static void help_callback (void);
static void ok_callback (void);
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 *delete_button;
static GtkWidget *edit_button;
static GtkWidget *config_button;
static GtkWidget *clist;
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}
};
#ifdef HAVE_XIMIAN_ARCHIVER
static void
store_archive_data (void)
{
Archive *archive;
Location *location;
xmlDocPtr xml_doc;
archive = ARCHIVE (archive_load (FALSE));
location = archive_get_current_location (archive);
xml_doc = wm_list_write_to_xml ();
location_store_xml (location, "wm-properties-capplet",
xml_doc, STORE_MASK_PREVIOUS);
xmlFreeDoc (xml_doc);
archive_close (archive);
}
#endif /* HAVE_XIMIAN_ARCHIVER */
static void
response_cb (GtkDialog *dialog, gint response_id, gpointer data)
{
int old_state = state;
switch (response_id)
{
case GTK_RESPONSE_NONE:
case GTK_RESPONSE_CLOSE:
gtk_main_quit ();
break;
case GTK_RESPONSE_APPLY:
state = STATE_TRY;
restart(FALSE);
wm_list_set_current (selected_wm);
wm_list_save ();
update_session ();
break;
}
}
static void
state_changed (void)
{
gtk_dialog_set_response_sensitive (GTK_DIALOG (capplet), GTK_RESPONSE_APPLY,
TRUE);
}
static GtkWidget *
left_aligned_button (gchar *label)
{
GtkWidget *button = gtk_button_new_with_label (label);
gtk_misc_set_alignment (GTK_MISC (GTK_BIN (button)->child),
0.0, 0.5);
gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child),
GNOME_PAD_SMALL, 0);
return button;
}
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;
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;
WindowManager *current_wm = wm_list_get_current();
gint new_row;
gchar *tmpstr;
gtk_clist_clear (GTK_CLIST (clist));
in_fill = TRUE;
tmp_list = window_managers;
while (tmp_list) {
gchar *row_text;
WindowManager *wm;
wm = tmp_list->data;
if (wm == current_wm) {
row_text = g_strdup_printf (_("%s (Current)"),
gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME));
tmpstr = g_strdup_printf (_("Run Configuration Tool for %s"),
gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME));
gtk_label_set_text (GTK_LABEL (GTK_BIN (config_button)->child),
tmpstr);
gtk_widget_set_sensitive (config_button,
wm->is_config_present);
g_free (tmpstr);
} else 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));
}
new_row = gtk_clist_append (GTK_CLIST (clist), &row_text);
gtk_clist_set_row_data (GTK_CLIST (clist), new_row, wm);
if (wm == selected_wm)
gtk_clist_select_row (GTK_CLIST (clist), new_row, 0);
g_free (row_text);
tmp_list = tmp_list->next;
}
in_fill = FALSE;
if(selected_wm) {
gtk_widget_set_sensitive (edit_button, selected_wm->is_user);
gtk_widget_set_sensitive (delete_button, selected_wm->is_user);
} else {
gtk_widget_set_sensitive (edit_button, FALSE);
gtk_widget_set_sensitive (delete_button, FALSE);
}
if (current_wm)
gtk_widget_show(config_button);
else
gtk_widget_hide(config_button);
}
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;
GtkWidget *dialog;
save_session = gnome_is_program_in_path ("save-session");
if (save_session) {
dialog = gnome_message_box_new (
_("Your current window manager has been changed. In order for\n"
"this change to be saved, you will need to save your current\n"
"session. You can do so immediately by selecting the \"Save session\n"
"now\" below, or you can save your session later. This can be\n"
"done either selecting \"Save Current Session\" under \"Settings\"\n"
"in the main menu, or by turning on \"Save Current Setup\" when\n"
"you log out.\n"),
GNOME_MESSAGE_BOX_INFO, _("Save Session Later"), _("Save Session Now"), NULL);
} else {
dialog = gnome_message_box_new (
_("Your current window manager has been changed. In order for\n"
"this change to be saved, you will need to save your current\n"
"session. This can be done by either selecting \"Save Current Session\"\n"
"under \"Settings\" in the main menu, or by turning on\n"
"\"Save Current Setup\" when you log out.\n"),
GNOME_MESSAGE_BOX_INFO, GNOME_STOCK_BUTTON_CLOSE, NULL);
}
if ((gnome_dialog_run_and_close (GNOME_DIALOG (dialog)) == 1) && save_session) {
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
destroy_callback (GtkWidget *widget, void *data)
{
}
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 (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
try_callback (void)
{
if (state != STATE_IDLE) {
g_warning ("try_callback in state %d!!!\n", state);
return;
}
state = STATE_TRY;
restart(FALSE);
}
static void
help_callback (void)
{
gchar *tmp;
gnome_help_display_with_doc_id (gnome_program_get (), "users-guide", "gccdesktop.html", "#GCCWM", NULL);
}
static void
ok_callback (void)
{
switch (state) {
case STATE_IDLE:
state = STATE_OK;
restart(FALSE);
break;
case STATE_TRY:
state = STATE_OK;
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;
}
wm_list_save ();
#ifdef HAVE_XIMIAN_ARCHIVER
store_archive_data ();
#endif /* HAVE_XIMIAN_ARCHIVER */
}
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 WMDialog *
create_dialog (gchar *title)
{
GtkWidget *label;
GtkWidget *alignment;
GtkWidget *table;
WMDialog *dialog;
dialog = g_new (WMDialog, 1);
dialog->dialog = gnome_dialog_new (_("Add New Window Manager"),
_("OK"), _("Cancel"), NULL);
gnome_dialog_set_default (GNOME_DIALOG (dialog->dialog), 0);
gnome_dialog_close_hides (GNOME_DIALOG (dialog->dialog), TRUE);
table = gtk_table_new (4, 2, FALSE);
gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
gtk_container_add (GTK_CONTAINER (GNOME_DIALOG (dialog->dialog)->vbox),
table);
label = gtk_label_new (_("Name:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label,
0, 1, 0, 1,
GTK_FILL, 0,
0, 0);
dialog->name_entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), dialog->name_entry,
1, 2, 0, 1,
GTK_FILL | GTK_EXPAND, 0,
0, 0);
label = gtk_label_new (_("Command:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label,
0, 1, 1, 2,
GTK_FILL, 0,
0, 0);
dialog->exec_entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), dialog->exec_entry,
1, 2, 1, 2,
GTK_FILL | GTK_EXPAND, 0,
0, 0);
label = gtk_label_new (_("Configuration Command:"));
gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
gtk_table_attach (GTK_TABLE (table), label,
0, 1, 2, 3,
GTK_FILL, 0,
0, 0);
dialog->config_entry = gtk_entry_new ();
gtk_table_attach (GTK_TABLE (table), dialog->config_entry,
1, 2, 2, 3,
GTK_FILL | GTK_EXPAND, 0,
0, 0);
alignment = gtk_alignment_new (0.0, 0.5, 0.0, 0.0);
gtk_table_attach (GTK_TABLE (table), alignment,
0, 2, 3, 4,
GTK_FILL | GTK_EXPAND, 0,
0, 0);
dialog->sm_toggle = gtk_check_button_new_with_label (_("Window manager is session managed"));
gtk_container_add (GTK_CONTAINER (alignment), dialog->sm_toggle);
gtk_window_set_default_size (GTK_WINDOW (dialog->dialog), 400, -1);
gtk_window_set_policy (GTK_WINDOW (dialog->dialog), FALSE, TRUE, FALSE);
gtk_widget_show_all (dialog->dialog);
return dialog;
}
static gchar *
extract_entry (GtkWidget *widget)
{
gchar *tmp;
g_return_val_if_fail (GTK_IS_ENTRY (widget), NULL);
tmp = gtk_entry_get_text (GTK_ENTRY (widget));
if (is_blank (tmp))
return NULL;
else
return g_strdup (tmp);
}
static gchar *
make_filename (gchar *name)
{
gchar *tempname = g_strconcat (name, ".desktop", NULL);
gchar *tempdir = gnome_util_home_file("wm-properties/");
gchar *tmp = tempname;
gchar *result;
while (*tmp) {
if (isspace (*tmp) || (*tmp == '/'))
*tmp = '_';
tmp++;
}
result = g_concat_dir_and_file (tempdir, tempname);
g_free (tempname);
g_free (tempdir);
return result;
}
static gboolean
check_dialog (WMDialog *dialog)
{
GtkWidget *msgbox;
if (is_blank (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry)))) {
msgbox = gnome_message_box_new (_("Name cannot be empty"),
GNOME_MESSAGE_BOX_ERROR,
_("OK"), NULL);
gnome_dialog_run (GNOME_DIALOG (msgbox));
return FALSE;
}
if (is_blank (gtk_entry_get_text (GTK_ENTRY (dialog->exec_entry)))) {
msgbox = gnome_message_box_new (_("Command cannot be empty"),
GNOME_MESSAGE_BOX_ERROR,
_("OK"), NULL);
gnome_dialog_run (GNOME_DIALOG (msgbox));
return FALSE;
}
return TRUE;
}
static void
get_dialog_contents (WMDialog *dialog, WindowManager *wm)
{
gchar *tmp;
tmp = extract_entry (dialog->name_entry);
gnome_desktop_item_set_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME,
tmp);
g_free (tmp);
tmp = extract_entry (dialog->exec_entry);
gnome_desktop_item_set_string (wm->dentry, GNOME_DESKTOP_ITEM_EXEC,
tmp);
g_free (tmp);
if (wm->config_exec)
g_free (wm->config_exec);
wm->config_exec = extract_entry (dialog->config_entry);
tmp = make_filename (gnome_desktop_item_get_string (wm->dentry, GNOME_DESKTOP_ITEM_NAME));
gnome_desktop_item_set_location (wm->dentry, tmp);
g_free (tmp);
wm->session_managed = !!GTK_TOGGLE_BUTTON (dialog->sm_toggle)->active;
wm_check_present (wm);
}
static void
edit_dialog (void)
{
WMDialog *dialog;
gchar *tmp;
gint result;
if(!selected_wm)
return;
dialog = create_dialog (_("Edit Window Manager"));
if (gnome_desktop_item_get_string (selected_wm->dentry, GNOME_DESKTOP_ITEM_NAME))
gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), gnome_desktop_item_get_string (selected_wm->dentry, GNOME_DESKTOP_ITEM_NAME));
if (gnome_desktop_item_get_string (selected_wm->dentry, GNOME_DESKTOP_ITEM_EXEC))
gtk_entry_set_text (GTK_ENTRY (dialog->exec_entry), gnome_desktop_item_get_string (selected_wm->dentry, GNOME_DESKTOP_ITEM_EXEC));
if (selected_wm->config_exec)
gtk_entry_set_text (GTK_ENTRY (dialog->config_entry), selected_wm->config_exec);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->sm_toggle),
selected_wm->session_managed);
if (!selected_wm->is_user) {
gtk_widget_set_sensitive (dialog->name_entry, FALSE);
gtk_widget_set_sensitive (dialog->exec_entry, FALSE);
gtk_widget_set_sensitive (dialog->config_entry, FALSE);
gtk_widget_set_sensitive (dialog->sm_toggle, FALSE);
}
do {
gtk_widget_show (dialog->dialog);
result = gnome_dialog_run (GNOME_DIALOG (dialog->dialog));
} while (result == 0 && !check_dialog (dialog));
if (selected_wm->is_user && (result == 0)) {
get_dialog_contents (dialog, selected_wm);
update_gui();
state_changed ();
}
gtk_widget_destroy (dialog->dialog);
g_free (dialog);
}
static void
add_dialog (void)
{
WMDialog *dialog = create_dialog (_("Edit Window Manager"));
WindowManager *wm;
gint result;
do {
result = gnome_dialog_run (GNOME_DIALOG (dialog->dialog));
} while (result == 0 && !check_dialog (dialog));
if (result == 0) {
wm = g_new0 (WindowManager, 1);
wm->dentry = gnome_desktop_item_new ();
gnome_desktop_item_set_entry_type (wm->dentry, GNOME_DESKTOP_ITEM_TYPE_APPLICATION);
get_dialog_contents (dialog, wm);
wm->is_user = TRUE;
wm_list_add (wm);
selected_wm = wm;
update_gui();
state_changed ();
}
gtk_widget_destroy (dialog->dialog);
g_free (dialog);
}
static void
select_row (GtkCList *the_clist,
gint row,
gint column,
GdkEvent *event,
gpointer data)
{
WindowManager *wm;
if (!in_fill) {
wm = gtk_clist_get_row_data (GTK_CLIST (clist), row);
gtk_widget_set_sensitive (edit_button, wm->is_user);
gtk_widget_set_sensitive (delete_button, wm->is_user);
if (wm != selected_wm) {
selected_wm = wm;
state_changed ();
}
}
}
static void
delete (void)
{
WindowManager *current_wm = wm_list_get_current();
GtkWidget *msgbox;
if (current_wm == selected_wm) {
msgbox = gnome_message_box_new (
_("You cannot delete the current Window Manager"),
GNOME_MESSAGE_BOX_ERROR, _("OK"), NULL);
gnome_dialog_run (GNOME_DIALOG (msgbox));
return;
}
wm_list_delete (selected_wm);
selected_wm = current_wm;
update_gui();
state_changed ();
}
static void
run_config (GtkWidget *w)
{
WindowManager *current_wm = wm_list_get_current();
if (current_wm
&& current_wm->is_config_present
&& current_wm->config_exec != NULL) {
gchar *argv[4];
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = current_wm->config_exec;
argv[3] = NULL;
gnome_execute_async (NULL, 4, argv);
}
}
static void
wm_setup (void)
{
GtkWidget *hbox, *vbox, *bottom;
GtkWidget *util_vbox;
GtkWidget *add_button;
GtkWidget *scrolled_window;
GtkWidget *label;
capplet = gtk_dialog_new_with_buttons (_("Window Manager Selector"),
NULL,
-1,
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
NULL);
gtk_dialog_set_response_sensitive (GTK_DIALOG (capplet), GTK_RESPONSE_APPLY, FALSE);
gtk_widget_set_usize (capplet, 360, 200);
vbox = gtk_vbox_new (FALSE, 0);
label = gtk_label_new (_("Window Manager Selector"));
gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 10);
hbox = gtk_hbox_new (FALSE, GNOME_PAD);
gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD_SMALL);
bottom = gtk_hbox_new (FALSE, GNOME_PAD_SMALL);
gtk_container_set_border_width (GTK_CONTAINER (bottom), GNOME_PAD_SMALL);
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
clist = gtk_clist_new (1);
gtk_clist_column_titles_hide (GTK_CLIST (clist));
gtk_clist_set_column_auto_resize (GTK_CLIST (clist), 0, TRUE);
gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_BROWSE);
gtk_signal_connect (GTK_OBJECT (clist), "select_row",
GTK_SIGNAL_FUNC (select_row), NULL);
gtk_container_add (GTK_CONTAINER (scrolled_window), clist);
gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0);
util_vbox = gtk_vbox_new (FALSE, GNOME_PAD_SMALL);
gtk_box_pack_start (GTK_BOX (hbox), util_vbox, FALSE, FALSE, 0);
add_button = left_aligned_button (_("Add..."));
gtk_signal_connect (GTK_OBJECT (add_button), "clicked",
GTK_SIGNAL_FUNC (add_dialog), NULL);
gtk_box_pack_start (GTK_BOX (util_vbox), add_button, FALSE, FALSE, 0);
edit_button = left_aligned_button (_("Edit..."));
gtk_signal_connect (GTK_OBJECT (edit_button), "clicked",
GTK_SIGNAL_FUNC (edit_dialog), NULL);
gtk_box_pack_start (GTK_BOX (util_vbox), edit_button, FALSE, FALSE, 0);
delete_button = left_aligned_button (_("Delete"));
gtk_signal_connect (GTK_OBJECT (delete_button), "clicked",
GTK_SIGNAL_FUNC (delete), NULL);
gtk_box_pack_start (GTK_BOX (util_vbox), delete_button, FALSE, FALSE, 0);
config_button = gtk_button_new_with_label ("");
gtk_misc_set_padding (GTK_MISC (GTK_BIN (config_button)->child),
GNOME_PAD_SMALL, 0);
gtk_signal_connect (GTK_OBJECT (config_button), "clicked",
GTK_SIGNAL_FUNC (run_config), NULL);
gtk_box_pack_start (GTK_BOX (bottom), config_button, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
gtk_box_pack_end (GTK_BOX (vbox), bottom, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (capplet)->vbox), vbox,
TRUE, TRUE, 0);
gtk_widget_show_all (capplet);
update_gui();
}
static void do_get_xml (void)
{
xmlDocPtr doc;
doc = wm_list_write_to_xml ();
xmlDocDump (stdout, doc);
}
static void do_set_xml (void)
{
xmlDocPtr doc;
char *buffer;
int len = 0;
while (!feof (stdin)) {
if (!len) buffer = g_new (char, 16384);
else buffer = g_renew (char, buffer, len + 16384);
fread (buffer + len, 1, 16384, stdin);
len += 16384;
}
doc = xmlParseMemory (buffer, strlen (buffer));
init_session ();
wm_list_read_from_xml (doc);
wm_list_save ();
update_session ();
}
int
main (int argc, char **argv)
{
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();
wm_setup();
g_signal_connect (G_OBJECT (capplet), "response",
response_cb, NULL);
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;
}