Make dialogs that Metacity shows follow focus-stealing-prevention

2004-08-25  Elijah Newren  <newren@math.utah.edu>

	Make dialogs that Metacity shows follow focus-stealing-prevention
	conventions. (fixes one issue in #149028; see comments 47-54)

	* src/delete.c (delete_ping_reply_func,
	delete_ping_timeout_func): Make callback functions take a
	timestamp arg, (delete_ping_timeout_func): pass the timestamp to
	metacity-dialog

	* src/display.c (meta_display_ping_timeout): add a timestamp to
	the call to the ping_timeout_func, (meta_display_ping_window,
	process_pong_message): add a timestamp to the call to the
	ping_reply_func

	* src/display.h (MetaWindowPingFunc typedef): add a timestamp to
	this function typedef

	* src/keybindings.c (error_on_command): require a timestamp and
	pass the timestamp on to metacity-dialog, (handle_run_command):
	pass a timestamp to error_on_command

	* src/metacity-dialog.c (copy_of_gdk_x11_window_set_user_time):
	new function (temporary; only for use while using gtk+-2.4),
	(kill_window_question, warn_about_no_sm_support,
	error_about_command): make these functions take a timestamp and
	call copy_of_gdk_x11_window_set_user_time, (main): require the
	first two args to the program to be "--timestamp <timestamp>"

	* src/session.c (warn_about_lame_clients_and_finish_inter): pass a
	timestamp of 0 to metacity-dialog to prevent focus (it's a popup
	not generated by and kind of user request).
This commit is contained in:
Elijah Newren 2004-08-26 00:59:12 +00:00 committed by Elijah Newren
parent 07c406cad9
commit 044d8999a3
7 changed files with 133 additions and 31 deletions

View File

@ -1,3 +1,36 @@
2004-08-25 Elijah Newren <newren@math.utah.edu>
Make dialogs that Metacity shows follow focus-stealing-prevention
conventions. (fixes one issue in #149028; see comments 47-54)
* src/delete.c (delete_ping_reply_func,
delete_ping_timeout_func): Make callback functions take a
timestamp arg, (delete_ping_timeout_func): pass the timestamp to
metacity-dialog
* src/display.c (meta_display_ping_timeout): add a timestamp to
the call to the ping_timeout_func, (meta_display_ping_window,
process_pong_message): add a timestamp to the call to the
ping_reply_func
* src/display.h (MetaWindowPingFunc typedef): add a timestamp to
this function typedef
* src/keybindings.c (error_on_command): require a timestamp and
pass the timestamp on to metacity-dialog, (handle_run_command):
pass a timestamp to error_on_command
* src/metacity-dialog.c (copy_of_gdk_x11_window_set_user_time):
new function (temporary; only for use while using gtk+-2.4),
(kill_window_question, warn_about_no_sm_support,
error_about_command): make these functions take a timestamp and
call copy_of_gdk_x11_window_set_user_time, (main): require the
first two args to the program to be "--timestamp <timestamp>"
* src/session.c (warn_about_lame_clients_and_finish_inter): pass a
timestamp of 0 to metacity-dialog to prevent focus (it's a popup
not generated by and kind of user request).
Fri Aug 20 12:54:12 2004 Soeren Sandmann <sandmann@daimi.au.dk> Fri Aug 20 12:54:12 2004 Soeren Sandmann <sandmann@daimi.au.dk>
* src/display.c (meta_display_end_grab_op): Move wireframe code * src/display.c (meta_display_end_grab_op): Move wireframe code

View File

@ -38,6 +38,7 @@ static void meta_window_present_delete_dialog (MetaWindow *window);
static void static void
delete_ping_reply_func (MetaDisplay *display, delete_ping_reply_func (MetaDisplay *display,
Window xwindow, Window xwindow,
Time timestamp,
void *user_data) void *user_data)
{ {
meta_topic (META_DEBUG_PING, meta_topic (META_DEBUG_PING,
@ -290,14 +291,16 @@ io_from_ping_dialog (GIOChannel *channel,
static void static void
delete_ping_timeout_func (MetaDisplay *display, delete_ping_timeout_func (MetaDisplay *display,
Window xwindow, Window xwindow,
Time timestamp,
void *user_data) void *user_data)
{ {
MetaWindow *window = user_data; MetaWindow *window = user_data;
GError *err; GError *err;
int child_pid; int child_pid;
int outpipe; int outpipe;
char *argv[7]; char *argv[9];
char numbuf[32]; char numbuf[32];
char timestampbuf[32];
char *window_id_str; char *window_id_str;
GIOChannel *channel; GIOChannel *channel;
@ -314,14 +317,17 @@ delete_ping_timeout_func (MetaDisplay *display,
window_id_str = g_strdup_printf ("0x%lx", window->xwindow); window_id_str = g_strdup_printf ("0x%lx", window->xwindow);
sprintf (numbuf, "%d", window->screen->number); sprintf (numbuf, "%d", window->screen->number);
sprintf (timestampbuf, "%lu", timestamp);
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog"; argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
argv[1] = "--screen"; argv[1] = "--screen";
argv[2] = numbuf; argv[2] = numbuf;
argv[3] = "--kill-window-question"; argv[3] = "--timestamp";
argv[4] = window->title; argv[4] = timestampbuf;
argv[5] = window_id_str; argv[5] = "--kill-window-question";
argv[6] = NULL; argv[6] = window->title;
argv[7] = window_id_str;
argv[8] = NULL;
err = NULL; err = NULL;
if (!g_spawn_async_with_pipes ("/", if (!g_spawn_async_with_pipes ("/",

View File

@ -3675,7 +3675,7 @@ meta_display_ping_timeout (gpointer data)
ping_data->timestamp, ping_data->xwindow); ping_data->timestamp, ping_data->xwindow);
(* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow, (* ping_data->ping_timeout_func) (ping_data->display, ping_data->xwindow,
ping_data->user_data); ping_data->timestamp, ping_data->user_data);
ping_data->display->pending_pings = ping_data->display->pending_pings =
g_slist_remove (ping_data->display->pending_pings, g_slist_remove (ping_data->display->pending_pings,
@ -3704,7 +3704,7 @@ meta_display_ping_window (MetaDisplay *display,
if (!window->net_wm_ping) if (!window->net_wm_ping)
{ {
if (ping_reply_func) if (ping_reply_func)
(* ping_reply_func) (display, window->xwindow, user_data); (* ping_reply_func) (display, window->xwindow, timestamp, user_data);
return; return;
} }
@ -3830,7 +3830,9 @@ process_pong_message (MetaDisplay *display,
} }
/* Call callback */ /* Call callback */
(* ping_data->ping_reply_func) (display, ping_data->xwindow, (* ping_data->ping_reply_func) (display,
ping_data->xwindow,
ping_data->timestamp,
ping_data->user_data); ping_data->user_data);
ping_data_free (ping_data); ping_data_free (ping_data);

View File

@ -69,6 +69,7 @@ typedef struct _MetaGroupPropHooks MetaGroupPropHooks;
typedef void (* MetaWindowPingFunc) (MetaDisplay *display, typedef void (* MetaWindowPingFunc) (MetaDisplay *display,
Window xwindow, Window xwindow,
Time timestamp,
gpointer user_data); gpointer user_data);

View File

@ -2486,12 +2486,14 @@ static void
error_on_command (int command_index, error_on_command (int command_index,
const char *command, const char *command,
const char *message, const char *message,
int screen_number) int screen_number,
Time timestamp)
{ {
GError *err; GError *err;
char *argv[8]; char *argv[10];
char *key; char *key;
char numbuf[32]; char numbuf[32];
char timestampbuf[32];
meta_warning ("Error on command %d \"%s\": %s\n", meta_warning ("Error on command %d \"%s\": %s\n",
command_index, command, message); command_index, command, message);
@ -2499,15 +2501,18 @@ error_on_command (int command_index,
key = meta_prefs_get_gconf_key_for_command (command_index); key = meta_prefs_get_gconf_key_for_command (command_index);
sprintf (numbuf, "%d", screen_number); sprintf (numbuf, "%d", screen_number);
sprintf (timestampbuf, "%lu", timestamp);
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog"; argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
argv[1] = "--screen"; argv[1] = "--screen";
argv[2] = numbuf; argv[2] = numbuf;
argv[3] = "--command-failed-error"; argv[3] = "--timestamp";
argv[4] = key; argv[4] = timestampbuf;
argv[5] = (char*) (command ? command : ""); argv[5] = "--command-failed-error";
argv[6] = (char*) message; argv[6] = key;
argv[7] = NULL; argv[7] = (char*) (command ? command : "");
argv[8] = (char*) message;
argv[9] = NULL;
err = NULL; err = NULL;
if (!g_spawn_async_with_pipes ("/", if (!g_spawn_async_with_pipes ("/",
@ -2596,7 +2601,7 @@ handle_run_command (MetaDisplay *display,
s = g_strdup_printf (_("No command %d has been defined.\n"), s = g_strdup_printf (_("No command %d has been defined.\n"),
which + 1); which + 1);
error_on_command (which, NULL, s, screen->number); error_on_command (which, NULL, s, screen->number, event->xkey.time);
g_free (s); g_free (s);
return; return;
@ -2605,7 +2610,7 @@ handle_run_command (MetaDisplay *display,
err = NULL; err = NULL;
if (!meta_spawn_command_line_async_on_screen (command, screen, &err)) if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
{ {
error_on_command (which, command, err->message, screen->number); error_on_command (which, command, err->message, screen->number, event->xkey.time);
g_error_free (err); g_error_free (err);
} }

View File

@ -30,6 +30,30 @@
#define N_(x) x #define N_(x) x
#include <gdk/gdkx.h> #include <gdk/gdkx.h>
#include <X11/Xatom.h>
/* FIXME: When we switch to gtk+-2.6, use of this function should be
* replaced by using the real gdk_x11_window_set_user_time.
*/
static void
copy_of_gdk_x11_window_set_user_time (GdkWindow *window,
Time timestamp)
{
GdkDisplay *display;
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
if (GDK_WINDOW_DESTROYED (window))
return;
display = gdk_drawable_get_display (window);
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
XA_CARDINAL, 32, PropModeReplace,
(guchar *)&timestamp, 1);
}
static Window static Window
window_from_string (const char *str) window_from_string (const char *str)
@ -76,7 +100,8 @@ on_realize (GtkWidget *dialog,
static int static int
kill_window_question (const char *window_name, kill_window_question (const char *window_name,
const char *parent_str) const char *parent_str,
Time timestamp)
{ {
GtkWidget *dialog; GtkWidget *dialog;
char *str, *tmp; char *str, *tmp;
@ -109,6 +134,9 @@ kill_window_question (const char *window_name,
g_signal_connect (G_OBJECT (dialog), "realize", g_signal_connect (G_OBJECT (dialog), "realize",
G_CALLBACK (on_realize), (char*) parent_str); G_CALLBACK (on_realize), (char*) parent_str);
gtk_widget_realize (dialog);
copy_of_gdk_x11_window_set_user_time (dialog->window, timestamp);
/* return our PID, then window ID that should be killed */ /* return our PID, then window ID that should be killed */
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
g_print ("%d\n%s\n", (int) getpid (), parent_str); g_print ("%d\n%s\n", (int) getpid (), parent_str);
@ -220,7 +248,8 @@ create_lame_apps_list (char **lame_apps)
} }
static int static int
warn_about_no_sm_support (char **lame_apps) warn_about_no_sm_support (char **lame_apps,
Time timestamp)
{ {
GtkWidget *dialog; GtkWidget *dialog;
GtkWidget *list; GtkWidget *list;
@ -267,6 +296,9 @@ warn_about_no_sm_support (char **lame_apps)
sw, sw,
TRUE, TRUE, 0); TRUE, TRUE, 0);
gtk_widget_realize (dialog);
copy_of_gdk_x11_window_set_user_time (dialog->window, timestamp);
gtk_widget_show_all (dialog); gtk_widget_show_all (dialog);
gtk_main (); gtk_main ();
@ -277,7 +309,8 @@ warn_about_no_sm_support (char **lame_apps)
static int static int
error_about_command (const char *gconf_key, error_about_command (const char *gconf_key,
const char *command, const char *command,
const char *error) const char *error,
Time timestamp)
{ {
GtkWidget *dialog; GtkWidget *dialog;
@ -296,6 +329,9 @@ error_about_command (const char *gconf_key,
GTK_BUTTONS_CLOSE, GTK_BUTTONS_CLOSE,
"%s", error); "%s", error);
gtk_widget_realize (dialog);
copy_of_gdk_x11_window_set_user_time (dialog->window, timestamp);
gtk_dialog_run (GTK_DIALOG (dialog)); gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy (dialog);
@ -306,52 +342,61 @@ error_about_command (const char *gconf_key,
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
Time timestamp;
bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, METACITY_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE); textdomain (GETTEXT_PACKAGE);
gtk_init (&argc, &argv); gtk_init (&argc, &argv);
if (argc < 2)
{
g_printerr ("bad args to metacity-dialog\n");
return 1;
}
if (strcmp (argv[1], "--kill-window-question") == 0)
{
if (argc < 4) if (argc < 4)
{ {
g_printerr ("bad args to metacity-dialog\n"); g_printerr ("bad args to metacity-dialog\n");
return 1; return 1;
} }
return kill_window_question (argv[2], argv[3]); if (strcmp (argv[1], "--timestamp") != 0)
}
else if (strcmp (argv[1], "--warn-about-no-sm-support") == 0)
{ {
/* argc must be even because we want title-class pairs */ g_printerr ("bad args to metacity-dialog\n");
if (argc < 3 || (argc % 2) != 0) return 1;
}
timestamp = strtoul (argv[2], NULL, 10);
if (strcmp (argv[3], "--kill-window-question") == 0)
{
if (argc < 6)
{ {
g_printerr ("bad args to metacity-dialog\n"); g_printerr ("bad args to metacity-dialog\n");
return 1; return 1;
} }
return warn_about_no_sm_support (&argv[2]); return kill_window_question (argv[4], argv[5], timestamp);
} }
else if (strcmp (argv[1], "--command-failed-error") == 0) else if (strcmp (argv[3], "--warn-about-no-sm-support") == 0)
{
/* argc must be even because we want title-class pairs */
if (argc < 5 || (argc % 2) != 0)
{
g_printerr ("bad args to metacity-dialog\n");
return 1;
}
return warn_about_no_sm_support (&argv[4], timestamp);
}
else if (strcmp (argv[3], "--command-failed-error") == 0)
{ {
/* the args are the gconf key of the failed command, the text of /* the args are the gconf key of the failed command, the text of
* the command, and the error message * the command, and the error message
*/ */
if (argc != 5) if (argc != 7)
{ {
g_printerr ("bad args to metacity-dialog\n"); g_printerr ("bad args to metacity-dialog\n");
return 1; return 1;
} }
return error_about_command (argv[2], argv[3], argv[4]); return error_about_command (argv[4], argv[5], argv[6], timestamp);
} }
g_printerr ("bad args to metacity-dialog\n"); g_printerr ("bad args to metacity-dialog\n");

View File

@ -1851,6 +1851,8 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
GError *err; GError *err;
GIOChannel *channel; GIOChannel *channel;
LameClientsDialogData *d; LameClientsDialogData *d;
Time timestamp;
char timestampbuf[32];
lame = NULL; lame = NULL;
displays = meta_displays_list (); displays = meta_displays_list ();
@ -1893,8 +1895,12 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title); lame = g_slist_sort (lame, (GCompareFunc) windows_cmp_by_title);
timestamp = 0;
sprintf (timestampbuf, "%lu", timestamp);
len = g_slist_length (lame); len = g_slist_length (lame);
len *= 2; /* titles and also classes */ len *= 2; /* titles and also classes */
len += 2; /* --timestamp flag and actual timestamp */
len += 1; /* NULL term */ len += 1; /* NULL term */
len += 2; /* metacity-dialog command and option */ len += 2; /* metacity-dialog command and option */
@ -1904,6 +1910,10 @@ warn_about_lame_clients_and_finish_interact (gboolean shutdown)
argv[i] = METACITY_LIBEXECDIR"/metacity-dialog"; argv[i] = METACITY_LIBEXECDIR"/metacity-dialog";
++i; ++i;
argv[i] = "--timestamp";
++i;
argv[i] = timestampbuf;
++i;
argv[i] = "--warn-about-no-sm-support"; argv[i] = "--warn-about-no-sm-support";
++i; ++i;