Rework timestamp pinging

If a window temporarily goes unresponsive, and then returns later, we
should hide the kill dialog that we showed to the user.
This commit is contained in:
Jasper St. Pierre 2014-05-20 14:48:08 -04:00
parent 56906a29e0
commit 4053c92abf
4 changed files with 94 additions and 116 deletions

View File

@ -39,35 +39,58 @@
#include "wayland/meta-wayland-surface.h" #include "wayland/meta-wayland-surface.h"
static void meta_window_present_delete_dialog (MetaWindow *window,
guint32 timestamp);
static void
delete_ping_reply_func (MetaWindow *window,
guint32 timestamp,
void *user_data)
{
meta_topic (META_DEBUG_PING, "Got reply to delete ping for %s\n", window->desc);
/* we do nothing */
}
static void static void
dialog_exited (GPid pid, int status, gpointer user_data) dialog_exited (GPid pid, int status, gpointer user_data)
{ {
MetaWindow *ours = (MetaWindow*) user_data; MetaWindow *window = user_data;
ours->dialog_pid = -1; window->dialog_pid = -1;
/* exit status of 1 means the user pressed "Force Quit" */ /* exit status of 1 means the user pressed "Force Quit" */
if (WIFEXITED (status) && WEXITSTATUS (status) == 1) if (WIFEXITED (status) && WEXITSTATUS (status) == 1)
meta_window_kill (ours); meta_window_kill (window);
} }
static void static void
delete_ping_timeout_func (MetaWindow *window, present_existing_delete_dialog (MetaWindow *window,
guint32 timestamp, guint32 timestamp)
void *user_data) {
meta_topic (META_DEBUG_PING,
"Presenting existing ping dialog for %s\n",
window->desc);
if (window->dialog_pid >= 0)
{
GSList *windows;
GSList *tmp;
/* Activate transient for window that belongs to
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->transient_for == window && w->res_class &&
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
{
meta_window_activate (w, timestamp);
break;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
}
static void
show_delete_dialog (MetaWindow *window,
guint32 timestamp)
{ {
char *window_title; char *window_title;
gchar *window_content, *tmp; gchar *window_content, *tmp;
@ -79,7 +102,7 @@ delete_ping_timeout_func (MetaWindow *window,
if (window->dialog_pid >= 0) if (window->dialog_pid >= 0)
{ {
meta_window_present_delete_dialog (window, timestamp); present_existing_delete_dialog (window, timestamp);
return; return;
} }
@ -128,15 +151,33 @@ delete_ping_timeout_func (MetaWindow *window,
g_child_watch_add (dialog_pid, dialog_exited, window); g_child_watch_add (dialog_pid, dialog_exited, window);
} }
static void
kill_delete_dialog (MetaWindow *window)
{
if (window->dialog_pid > -1)
kill (window->dialog_pid, SIGTERM);
}
void
meta_window_set_alive (MetaWindow *window,
gboolean is_alive)
{
if (window->is_alive == is_alive)
return;
window->is_alive = is_alive;
if (window->is_alive)
kill_delete_dialog (window);
else
show_delete_dialog (window, CurrentTime);
}
void void
meta_window_check_alive (MetaWindow *window, meta_window_check_alive (MetaWindow *window,
guint32 timestamp) guint32 timestamp)
{ {
meta_display_ping_window (window, meta_display_ping_window (window, timestamp);
timestamp,
delete_ping_reply_func,
delete_ping_timeout_func,
NULL);
} }
void void
@ -191,39 +232,3 @@ meta_window_free_delete_dialog (MetaWindow *window)
window->dialog_pid = -1; window->dialog_pid = -1;
} }
} }
static void
meta_window_present_delete_dialog (MetaWindow *window, guint32 timestamp)
{
meta_topic (META_DEBUG_PING,
"Presenting existing ping dialog for %s\n",
window->desc);
if (window->dialog_pid >= 0)
{
GSList *windows;
GSList *tmp;
/* Activate transient for window that belongs to
* mutter-dialog
*/
windows = meta_display_list_windows (window->display, META_LIST_DEFAULT);
tmp = windows;
while (tmp != NULL)
{
MetaWindow *w = tmp->data;
if (w->transient_for == window && w->res_class &&
g_ascii_strcasecmp (w->res_class, "mutter-dialog") == 0)
{
meta_window_activate (w, timestamp);
break;
}
tmp = tmp->next;
}
g_slist_free (windows);
}
}

View File

@ -53,10 +53,6 @@ typedef struct _MetaWindowPropHooks MetaWindowPropHooks;
typedef struct MetaEdgeResistanceData MetaEdgeResistanceData; typedef struct MetaEdgeResistanceData MetaEdgeResistanceData;
typedef void (* MetaWindowPingFunc) (MetaWindow *window,
guint32 timestamp,
gpointer user_data);
typedef enum { typedef enum {
META_LIST_DEFAULT = 0, /* normal windows */ META_LIST_DEFAULT = 0, /* normal windows */
META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */ META_LIST_INCLUDE_OVERRIDE_REDIRECT = 1 << 0, /* normal and O-R */
@ -393,13 +389,10 @@ const char* meta_event_detail_to_string (int d);
void meta_display_queue_retheme_all_windows (MetaDisplay *display); void meta_display_queue_retheme_all_windows (MetaDisplay *display);
void meta_display_retheme_all (void); void meta_display_retheme_all (void);
void meta_display_ping_window (MetaWindow *window, void meta_display_ping_window (MetaWindow *window,
guint32 timestamp, guint32 serial);
MetaWindowPingFunc ping_reply_func, void meta_display_pong_for_serial (MetaDisplay *display,
MetaWindowPingFunc ping_timeout_func, guint32 serial);
void *user_data);
void meta_display_pong_for_serial (MetaDisplay *display,
guint32 serial);
int meta_resize_gravity_from_grab_op (MetaGrabOp op); int meta_resize_gravity_from_grab_op (MetaGrabOp op);

View File

@ -98,12 +98,9 @@
*/ */
typedef struct typedef struct
{ {
MetaWindow *window; MetaWindow *window;
guint32 timestamp; guint32 serial;
MetaWindowPingFunc ping_reply_func; guint ping_timeout_id;
MetaWindowPingFunc ping_timeout_func;
void *user_data;
guint ping_timeout_id;
} MetaPingData; } MetaPingData;
G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT); G_DEFINE_TYPE(MetaDisplay, meta_display, G_TYPE_OBJECT);
@ -2303,15 +2300,16 @@ static gboolean
meta_display_ping_timeout (gpointer data) meta_display_ping_timeout (gpointer data)
{ {
MetaPingData *ping_data = data; MetaPingData *ping_data = data;
MetaDisplay *display = ping_data->window->display; MetaWindow *window = ping_data->window;
MetaDisplay *display = window->display;
meta_window_set_alive (window, FALSE);
ping_data->ping_timeout_id = 0; ping_data->ping_timeout_id = 0;
meta_topic (META_DEBUG_PING, meta_topic (META_DEBUG_PING,
"Ping %u on window %s timed out\n", "Ping %u on window %s timed out\n",
ping_data->timestamp, ping_data->window->desc); ping_data->serial, ping_data->window->desc);
(* ping_data->ping_timeout_func) (ping_data->window, ping_data->timestamp, ping_data->user_data);
display->pending_pings = g_slist_remove (display->pending_pings, ping_data); display->pending_pings = g_slist_remove (display->pending_pings, ping_data);
ping_data_free (ping_data); ping_data_free (ping_data);
@ -2325,11 +2323,6 @@ meta_display_ping_timeout (gpointer data)
* @window: The #MetaWindow to send the ping to * @window: The #MetaWindow to send the ping to
* @timestamp: The timestamp of the ping. Used for uniqueness. * @timestamp: The timestamp of the ping. Used for uniqueness.
* Cannot be CurrentTime; use a real timestamp! * Cannot be CurrentTime; use a real timestamp!
* @ping_reply_func: The callback to call if we get a response.
* @ping_timeout_func: The callback to call if we don't get a response.
* @user_data: Arbitrary data that will be passed to the callback
* function. (In practice it's often a pointer to
* the window.)
* *
* Sends a ping request to a window. The window must respond to * Sends a ping request to a window. The window must respond to
* the request within a certain amount of time. If it does, we * the request within a certain amount of time. If it does, we
@ -2341,35 +2334,24 @@ meta_display_ping_timeout (gpointer data)
* the callbacks will be called from the event loop. * the callbacks will be called from the event loop.
*/ */
void void
meta_display_ping_window (MetaWindow *window, meta_display_ping_window (MetaWindow *window,
guint32 timestamp, guint32 serial)
MetaWindowPingFunc ping_reply_func,
MetaWindowPingFunc ping_timeout_func,
gpointer user_data)
{ {
MetaDisplay *display = window->display; MetaDisplay *display = window->display;
MetaPingData *ping_data; MetaPingData *ping_data;
if (timestamp == CurrentTime) if (serial == 0)
{ {
meta_warning ("Tried to ping a window with CurrentTime! Not allowed.\n"); meta_warning ("Tried to ping a window with a bad serial! Not allowed.\n");
return; return;
} }
if (!window->can_ping) if (!window->can_ping)
{ return;
if (ping_reply_func)
(* ping_reply_func) (window, timestamp, user_data);
return;
}
ping_data = g_new (MetaPingData, 1); ping_data = g_new (MetaPingData, 1);
ping_data->window = window; ping_data->window = window;
ping_data->timestamp = timestamp; ping_data->serial = serial;
ping_data->ping_reply_func = ping_reply_func;
ping_data->ping_timeout_func = ping_timeout_func;
ping_data->user_data = user_data;
ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY, ping_data->ping_timeout_id = g_timeout_add (PING_TIMEOUT_DELAY,
meta_display_ping_timeout, meta_display_ping_timeout,
ping_data); ping_data);
@ -2378,10 +2360,10 @@ meta_display_ping_window (MetaWindow *window,
display->pending_pings = g_slist_prepend (display->pending_pings, ping_data); display->pending_pings = g_slist_prepend (display->pending_pings, ping_data);
meta_topic (META_DEBUG_PING, meta_topic (META_DEBUG_PING,
"Sending ping with timestamp %u to window %s\n", "Sending ping with serial %u to window %s\n",
timestamp, window->desc); serial, window->desc);
META_WINDOW_GET_CLASS (window)->ping (window, timestamp); META_WINDOW_GET_CLASS (window)->ping (window, serial);
} }
/** /**
@ -2405,11 +2387,11 @@ meta_display_pong_for_serial (MetaDisplay *display,
{ {
MetaPingData *ping_data = tmp->data; MetaPingData *ping_data = tmp->data;
if (serial == ping_data->timestamp) if (serial == ping_data->serial)
{ {
meta_topic (META_DEBUG_PING, meta_topic (META_DEBUG_PING,
"Matching ping found for pong %u\n", "Matching ping found for pong %u\n",
ping_data->timestamp); ping_data->serial);
/* Remove the ping data from the list */ /* Remove the ping data from the list */
display->pending_pings = g_slist_remove (display->pending_pings, display->pending_pings = g_slist_remove (display->pending_pings,
@ -2422,13 +2404,8 @@ meta_display_pong_for_serial (MetaDisplay *display,
ping_data->ping_timeout_id = 0; ping_data->ping_timeout_id = 0;
} }
/* Call callback */ meta_window_set_alive (ping_data->window, TRUE);
(* ping_data->ping_reply_func) (ping_data->window,
ping_data->timestamp,
ping_data->user_data);
ping_data_free (ping_data); ping_data_free (ping_data);
break; break;
} }
} }

View File

@ -441,8 +441,9 @@ struct _MetaWindow
MetaStackLayer layer; MetaStackLayer layer;
int stack_position; /* see comment in stack.h */ int stack_position; /* see comment in stack.h */
/* Current dialog open for this window */ /* Managed by delete.c */
int dialog_pid; int dialog_pid;
guint is_alive : 1;
/* maintained by group.c */ /* maintained by group.c */
MetaGroup *group; MetaGroup *group;
@ -739,4 +740,6 @@ void meta_window_move_resize_internal (MetaWindow *window,
void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op); void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op); void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
#endif #endif