improve error about failing to open session manager.

2002-05-29  Havoc Pennington  <hp@pobox.com>

	* src/session.c (meta_session_init): improve error about failing
	to open session manager.
	(shutdown_cancelled_callback): send SmcSaveYourselfDone when we
	get cancelled
	(interact_callback): implement an interact callback that complains
	about lame clients that can't be saved. Still somewhat buggy
	in that it sends InteractDone before the user has closed the
	dialog.
This commit is contained in:
Havoc Pennington 2002-05-30 03:54:10 +00:00 committed by Havoc Pennington
parent f7c2b446f2
commit 90ff51acdb
3 changed files with 321 additions and 4 deletions

View File

@ -1,3 +1,14 @@
2002-05-29 Havoc Pennington <hp@pobox.com>
* src/session.c (meta_session_init): improve error about failing
to open session manager.
(shutdown_cancelled_callback): send SmcSaveYourselfDone when we
get cancelled
(interact_callback): implement an interact callback that complains
about lame clients that can't be saved. Still somewhat buggy
in that it sends InteractDone before the user has closed the
dialog.
2002-05-29 Havoc Pennington <hp@redhat.com>
* src/tools/metacity-mag.c: add a magnifier I'm using when making

View File

@ -109,6 +109,156 @@ kill_window_question (const char *window_name,
return 0;
}
static char*
latin1_to_utf8 (const char *text)
{
GString *str;
const char *p;
str = g_string_new ("");
p = text;
while (*p)
{
g_string_append_unichar (str, *p);
++p;
}
return g_string_free (str, FALSE);
}
enum
{
COLUMN_TITLE,
COLUMN_CLASS,
COLUMN_LAST
};
static GtkWidget*
create_lame_apps_list (char **lame_apps)
{
GtkTreeSelection *selection;
GtkCellRenderer *cell;
GtkWidget *tree_view;
GtkTreeViewColumn *column;
GtkListStore *model;
GtkTreeIter iter;
int i;
model = gtk_list_store_new (COLUMN_LAST,
G_TYPE_STRING,
G_TYPE_STRING);
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
g_object_unref (G_OBJECT (model));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
gtk_tree_selection_set_mode (GTK_TREE_SELECTION (selection),
GTK_SELECTION_NONE);
i = 0;
while (lame_apps[i])
{
char *s;
gtk_list_store_append (model, &iter);
/* window class is latin-1 */
s = latin1_to_utf8 (lame_apps[i+1]);
gtk_list_store_set (model,
&iter,
COLUMN_TITLE, lame_apps[i],
COLUMN_CLASS, s,
-1);
g_free (s);
i += 2;
}
cell = gtk_cell_renderer_text_new ();
g_object_set (G_OBJECT (cell),
"xpad", 2,
NULL);
column = gtk_tree_view_column_new_with_attributes (_("Title"),
cell,
"text", COLUMN_TITLE,
NULL);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_TITLE);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
GTK_TREE_VIEW_COLUMN (column));
cell = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Class"),
cell,
"text", COLUMN_CLASS,
NULL);
gtk_tree_view_column_set_sort_column_id (column, COLUMN_CLASS);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
GTK_TREE_VIEW_COLUMN (column));
return tree_view;
}
static int
warn_about_no_sm_support (char **lame_apps)
{
GtkWidget *dialog;
GtkWidget *list;
GtkWidget *sw;
dialog = gtk_message_dialog_new (NULL,
0,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_CLOSE,
_("These windows do not support \"save current setup\" and will have to be restarted manually next time you log in."));
g_signal_connect (G_OBJECT (dialog),
"response",
G_CALLBACK (gtk_main_quit),
NULL);
list = create_lame_apps_list (lame_apps);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_container_set_border_width (GTK_CONTAINER (sw), 3);
gtk_container_add (GTK_CONTAINER (sw), list);
/* sw as geometry widget */
gtk_window_set_geometry_hints (GTK_WINDOW (dialog),
sw, NULL, 0);
/* applies to geometry widget; try to avoid scrollbars,
* but don't make the window huge
*/
gtk_window_set_default_size (GTK_WINDOW (dialog),
400, 225);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
sw,
TRUE, TRUE, 0);
gtk_widget_show_all (dialog);
gtk_main ();
return 0;
}
int
main (int argc, char **argv)
{
@ -134,6 +284,17 @@ main (int argc, char **argv)
return kill_window_question (argv[2], argv[3]);
}
else if (strcmp (argv[1], "--warn-about-no-sm-support") == 0)
{
/* argc must be even because we want title-class pairs */
if (argc < 3 || (argc % 2) != 0)
{
g_printerr ("bad args to metacity-dialog\n");
return 1;
}
return warn_about_no_sm_support (&argv[2]);
}
g_printerr ("bad args to metacity-dialog\n");
return 1;

View File

@ -73,6 +73,7 @@ static char* load_state (const char *previous_save_file);
static void regenerate_save_file (void);
static const char* full_save_file (void);
static const char* base_save_file (void);
static void warn_about_lame_clients (void);
/* This is called when data is available on an ICE connection. */
static gboolean
@ -181,6 +182,8 @@ typedef enum
STATE_SAVING_PHASE_1,
STATE_WAITING_FOR_PHASE_2,
STATE_SAVING_PHASE_2,
STATE_WAITING_FOR_INTERACT,
STATE_DONE_WITH_INTERACT,
STATE_FROZEN,
STATE_REGISTERING
} ClientState;
@ -206,6 +209,7 @@ static void set_clone_restart_commands (void);
static char *client_id = NULL;
static gpointer session_connection = NULL;
static ClientState current_state = STATE_DISCONNECTED;
static gboolean interaction_allowed = FALSE;
void
meta_session_init (const char *previous_client_id,
@ -266,7 +270,7 @@ meta_session_init (const char *previous_client_id,
if (session_connection == NULL)
{
meta_warning ("Failed to open connection to session manager: %s\n", buf);
meta_warning (_("Failed to a open connection to a session manager, so window positions will not be saved: %s\n"), buf);
goto out;
}
@ -374,8 +378,26 @@ save_yourself_possibly_done (gboolean shutdown,
current_state = STATE_WAITING_FOR_PHASE_2;
}
if (current_state == STATE_SAVING_PHASE_2 &&
interaction_allowed)
{
Status status;
status = SmcInteractRequest (session_connection,
/* ignore this feature of the protocol by always
* claiming normal
*/
SmDialogNormal,
interact_callback,
GINT_TO_POINTER (shutdown));
if (status)
current_state = STATE_WAITING_FOR_INTERACT;
}
if (current_state == STATE_SAVING_PHASE_1 ||
current_state == STATE_SAVING_PHASE_2)
current_state == STATE_SAVING_PHASE_2 ||
current_state == STATE_DONE_WITH_INTERACT)
{
SmcSaveYourselfDone (session_connection,
successful);
@ -387,7 +409,6 @@ save_yourself_possibly_done (gboolean shutdown,
}
}
static void
save_phase_2_callback (SmcConn smc_conn, SmPointer client_data)
{
@ -435,6 +456,8 @@ save_yourself_callback (SmcConn smc_conn,
}
#endif
interaction_allowed = interact_style != SmInteractStyleNone;
current_state = STATE_SAVING_PHASE_1;
regenerate_save_file ();
@ -462,13 +485,29 @@ save_complete_callback (SmcConn smc_conn, SmPointer client_data)
static void
shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
{
/* nothing */
if (session_connection != NULL &&
(current_state != STATE_IDLE && current_state != STATE_FROZEN))
{
SmcSaveYourselfDone (session_connection, True);
current_state = STATE_IDLE;
}
}
static void
interact_callback (SmcConn smc_conn, SmPointer client_data)
{
/* nothing */
gboolean shutdown;
shutdown = GPOINTER_TO_INT (client_data);
current_state = STATE_DONE_WITH_INTERACT;
warn_about_lame_clients ();
SmcInteractDone (session_connection, False /* don't cancel logout */);
save_yourself_possibly_done (shutdown, TRUE);
}
static void
@ -1546,4 +1585,110 @@ base_save_file (void)
return relative_save_path;
}
static int
windows_cmp_by_title (MetaWindow *a,
MetaWindow *b)
{
return g_utf8_collate (a->title, b->title);
}
static void
warn_about_lame_clients (void)
{
GSList *displays;
GSList *display_iter;
GSList *lame;
char **argv;
int i;
GSList *tmp;
int len;
int child_pid;
GError *err;
lame = NULL;
displays = meta_displays_list ();
display_iter = displays;
while (display_iter != NULL)
{
GSList *windows;
windows = meta_display_list_windows (display_iter->data);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *window;
window = tmp->data;
/* only complain about normal windows, the others
* are kind of dumb to worry about
*/
if (window->sm_client_id == NULL &&
window->type == META_WINDOW_NORMAL)
lame = g_slist_prepend (lame, window);
tmp = tmp->next;
}
g_slist_free (windows);
display_iter = display_iter->next;
}
/* don't need to free displays */
displays = NULL;
lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
len = g_slist_length (lame);
len *= 2; /* titles and also classes */
len += 1; /* NULL term */
len += 2; /* metacity-dialog command and option */
argv = g_new0 (char*, len);
i = 0;
argv[i] = METACITY_LIBEXECDIR"/metacity-dialog";
++i;
argv[i] = "--warn-about-no-sm-support";
++i;
tmp = lame;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
argv[i] = w->title;
++i;
argv[i] = w->res_class ? w->res_class : "";
++i;
tmp = tmp->next;
}
err = NULL;
if (!g_spawn_async_with_pipes ("/",
argv,
NULL,
0,
NULL, NULL,
&child_pid,
NULL,
NULL,
NULL,
&err))
{
meta_warning (_("Error launching metacity-dialog to warn about apps that don't support session management: %s\n"),
err->message);
g_error_free (err);
}
g_free (argv);
g_slist_free (lame);
/* FIXME we need to keep a pipe to the child open to detect when it exits, and
* only send InteractDone when the child has exited.
*/
}
#endif /* HAVE_SM */