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:
parent
56906a29e0
commit
4053c92abf
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user