mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
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:
parent
f7c2b446f2
commit
90ff51acdb
11
ChangeLog
11
ChangeLog
@ -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>
|
2002-05-29 Havoc Pennington <hp@redhat.com>
|
||||||
|
|
||||||
* src/tools/metacity-mag.c: add a magnifier I'm using when making
|
* src/tools/metacity-mag.c: add a magnifier I'm using when making
|
||||||
|
@ -109,6 +109,156 @@ kill_window_question (const char *window_name,
|
|||||||
return 0;
|
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
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
@ -134,6 +284,17 @@ main (int argc, char **argv)
|
|||||||
|
|
||||||
return kill_window_question (argv[2], argv[3]);
|
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");
|
g_printerr ("bad args to metacity-dialog\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
153
src/session.c
153
src/session.c
@ -73,6 +73,7 @@ static char* load_state (const char *previous_save_file);
|
|||||||
static void regenerate_save_file (void);
|
static void regenerate_save_file (void);
|
||||||
static const char* full_save_file (void);
|
static const char* full_save_file (void);
|
||||||
static const char* base_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. */
|
/* This is called when data is available on an ICE connection. */
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -181,6 +182,8 @@ typedef enum
|
|||||||
STATE_SAVING_PHASE_1,
|
STATE_SAVING_PHASE_1,
|
||||||
STATE_WAITING_FOR_PHASE_2,
|
STATE_WAITING_FOR_PHASE_2,
|
||||||
STATE_SAVING_PHASE_2,
|
STATE_SAVING_PHASE_2,
|
||||||
|
STATE_WAITING_FOR_INTERACT,
|
||||||
|
STATE_DONE_WITH_INTERACT,
|
||||||
STATE_FROZEN,
|
STATE_FROZEN,
|
||||||
STATE_REGISTERING
|
STATE_REGISTERING
|
||||||
} ClientState;
|
} ClientState;
|
||||||
@ -206,6 +209,7 @@ static void set_clone_restart_commands (void);
|
|||||||
static char *client_id = NULL;
|
static char *client_id = NULL;
|
||||||
static gpointer session_connection = NULL;
|
static gpointer session_connection = NULL;
|
||||||
static ClientState current_state = STATE_DISCONNECTED;
|
static ClientState current_state = STATE_DISCONNECTED;
|
||||||
|
static gboolean interaction_allowed = FALSE;
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_session_init (const char *previous_client_id,
|
meta_session_init (const char *previous_client_id,
|
||||||
@ -266,7 +270,7 @@ meta_session_init (const char *previous_client_id,
|
|||||||
|
|
||||||
if (session_connection == NULL)
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -374,8 +378,26 @@ save_yourself_possibly_done (gboolean shutdown,
|
|||||||
current_state = STATE_WAITING_FOR_PHASE_2;
|
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 ||
|
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,
|
SmcSaveYourselfDone (session_connection,
|
||||||
successful);
|
successful);
|
||||||
@ -387,7 +409,6 @@ save_yourself_possibly_done (gboolean shutdown,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
save_phase_2_callback (SmcConn smc_conn, SmPointer client_data)
|
save_phase_2_callback (SmcConn smc_conn, SmPointer client_data)
|
||||||
{
|
{
|
||||||
@ -435,6 +456,8 @@ save_yourself_callback (SmcConn smc_conn,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
interaction_allowed = interact_style != SmInteractStyleNone;
|
||||||
|
|
||||||
current_state = STATE_SAVING_PHASE_1;
|
current_state = STATE_SAVING_PHASE_1;
|
||||||
|
|
||||||
regenerate_save_file ();
|
regenerate_save_file ();
|
||||||
@ -462,13 +485,29 @@ save_complete_callback (SmcConn smc_conn, SmPointer client_data)
|
|||||||
static void
|
static void
|
||||||
shutdown_cancelled_callback (SmcConn smc_conn, SmPointer client_data)
|
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
|
static void
|
||||||
interact_callback (SmcConn smc_conn, SmPointer client_data)
|
interact_callback (SmcConn smc_conn, SmPointer client_data)
|
||||||
{
|
{
|
||||||
/* nothing */
|
/* 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
|
static void
|
||||||
@ -1546,4 +1585,110 @@ base_save_file (void)
|
|||||||
return relative_save_path;
|
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 */
|
#endif /* HAVE_SM */
|
||||||
|
Loading…
Reference in New Issue
Block a user