[mutter/wip/carlosg/frozen-app-behavior: 1/2] core: Change behavior of "application is alive" checks
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/carlosg/frozen-app-behavior: 1/2] core: Change behavior of "application is alive" checks
- Date: Mon, 1 Nov 2021 17:28:50 +0000 (UTC)
commit 2e92eba642d5e203ed4f699f2d2027ac2fa76c40
Author: Carlos Garnacho <carlosg gnome org>
Date: Fri Sep 3 23:38:12 2021 +0200
core: Change behavior of "application is alive" checks
Change some things in these "app is alive" checks:
- Pings are more pervasive, they are now non-configurable, have
a shorter timeout (400ms) to declare an application dead, and are
produced more often during user interaction.
- The dialog timeout is separated from this logic, it is still
configurable, and has been fixed so dismissing reenables this
timeout from the start, instead of the last failed ping (a new
dialog popping up shortly after dismissing was likely a sore
point with this feature that users failed to formulate).
- As we want to tap into this logic further, MetaWindow now has
a is-alive property, that other places in code can fetch and
subscribe.
This results in a separate logic between "the application does
not respond" and "we are showing the close dialog" so that the
former happens as timely as possible, while the latter might
never happen.
src/core/delete.c | 31 +++++++++++-----------
src/core/display.c | 4 ++-
src/core/events.c | 5 +++-
src/core/window-private.h | 9 +++++++
src/core/window.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 97 insertions(+), 17 deletions(-)
---
diff --git a/src/core/delete.c b/src/core/delete.c
index 058764b088..26f52165df 100644
--- a/src/core/delete.c
+++ b/src/core/delete.c
@@ -39,6 +39,8 @@ close_dialog_response_cb (MetaCloseDialog *dialog,
{
if (response == META_CLOSE_DIALOG_RESPONSE_FORCE_CLOSE)
meta_window_kill (window);
+ else
+ meta_window_ensure_close_dialog_timeout (window);
}
static void
@@ -57,23 +59,22 @@ meta_window_ensure_close_dialog (MetaWindow *window)
}
void
-meta_window_set_alive (MetaWindow *window,
- gboolean is_alive)
+meta_window_show_close_dialog (MetaWindow *window)
{
- if (is_alive && window->close_dialog)
- {
- meta_close_dialog_hide (window->close_dialog);
- }
- else if (!is_alive)
- {
- meta_window_ensure_close_dialog (window);
- meta_close_dialog_show (window->close_dialog);
+ meta_window_ensure_close_dialog (window);
+ meta_close_dialog_show (window->close_dialog);
- if (window->display &&
- window->display->event_route == META_EVENT_ROUTE_NORMAL &&
- window == window->display->focus_window)
- meta_close_dialog_focus (window->close_dialog);
- }
+ if (window->display &&
+ window->display->event_route == META_EVENT_ROUTE_NORMAL &&
+ window == window->display->focus_window)
+ meta_close_dialog_focus (window->close_dialog);
+}
+
+void
+meta_window_hide_close_dialog (MetaWindow *window)
+{
+ if (window->close_dialog)
+ meta_close_dialog_hide (window->close_dialog);
}
void
diff --git a/src/core/display.c b/src/core/display.c
index 532d024f80..3ada3cd35a 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -178,6 +178,8 @@ static guint display_signals [LAST_SIGNAL] = { 0 };
#define META_GRAB_OP_GET_BASE_TYPE(op) (op & 0x00FF)
+#define CHECK_ALIVE_TIMEOUT_MS 400
+
/*
* The display we're managing. This is a singleton object. (Historically,
* this was a list of displays, but there was never any way to add more
@@ -2223,7 +2225,7 @@ meta_display_ping_window (MetaWindow *window,
ping_data->window = window;
ping_data->serial = serial;
ping_data->ping_timeout_id =
- g_timeout_add (check_alive_timeout,
+ g_timeout_add (CHECK_ALIVE_TIMEOUT_MS,
meta_display_ping_timeout,
ping_data);
g_source_set_name_by_id (ping_data->ping_timeout_id, "[mutter] meta_display_ping_timeout");
diff --git a/src/core/events.c b/src/core/events.c
index 8afc720efd..cd99fde277 100644
--- a/src/core/events.c
+++ b/src/core/events.c
@@ -201,7 +201,7 @@ meta_display_handle_event (MetaDisplay *display,
const ClutterEvent *event)
{
MetaBackend *backend = meta_get_backend ();
- MetaWindow *window;
+ MetaWindow *window = NULL;
gboolean bypass_clutter = FALSE;
G_GNUC_UNUSED gboolean bypass_wayland = FALSE;
MetaGestureTracker *gesture_tracker;
@@ -474,6 +474,9 @@ meta_display_handle_event (MetaDisplay *display,
#ifdef HAVE_WAYLAND
if (compositor && !bypass_wayland)
{
+ if (window && event->any.time != CLUTTER_CURRENT_TIME)
+ meta_window_check_alive (window, event->any.time);
+
if (meta_wayland_compositor_handle_event (compositor, event))
bypass_clutter = TRUE;
}
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 3bd75fe47a..ed821c2d57 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -436,6 +436,9 @@ struct _MetaWindow
/* whether focus should be restored on map */
guint restore_focus_on_map : 1;
+ /* Whether the window is alive */
+ guint is_alive : 1;
+
/* if non-NULL, the bounds of the window frame */
cairo_region_t *frame_bounds;
@@ -563,6 +566,7 @@ struct _MetaWindow
} placement;
guint unmanage_idle_id;
+ guint close_dialog_timeout_id;
pid_t client_pid;
@@ -876,6 +880,11 @@ void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
void meta_window_set_alive (MetaWindow *window, gboolean is_alive);
+gboolean meta_window_get_alive (MetaWindow *window);
+
+void meta_window_show_close_dialog (MetaWindow *window);
+void meta_window_hide_close_dialog (MetaWindow *window);
+void meta_window_ensure_close_dialog_timeout (MetaWindow *window);
gboolean meta_window_has_pointer (MetaWindow *window);
diff --git a/src/core/window.c b/src/core/window.c
index 0f0c644d6d..6fd47e926e 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -214,6 +214,7 @@ enum
PROP_GTK_APP_MENU_OBJECT_PATH,
PROP_GTK_MENUBAR_OBJECT_PATH,
PROP_ON_ALL_WORKSPACES,
+ PROP_IS_ALIVE,
PROP_LAST,
};
@@ -633,6 +634,13 @@ meta_window_class_init (MetaWindowClass *klass)
FALSE,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+ obj_props[PROP_IS_ALIVE] =
+ g_param_spec_boolean ("is-alive",
+ "Is alive",
+ "Whether the window responds to pings",
+ FALSE,
+ G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
window_signals[WORKSPACE_CHANGED] =
@@ -729,6 +737,7 @@ meta_window_init (MetaWindow *self)
{
self->stamp = next_window_stamp++;
meta_prefs_add_listener (prefs_changed_callback, self);
+ self->is_alive = TRUE;
}
static gboolean
@@ -8808,3 +8817,59 @@ meta_window_get_client_type (MetaWindow *window)
{
return window->client_type;
}
+
+static gboolean
+meta_window_close_dialog_timeout (MetaWindow *window)
+{
+ meta_window_show_close_dialog (window);
+ window->close_dialog_timeout_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
+void
+meta_window_ensure_close_dialog_timeout (MetaWindow *window)
+{
+ guint check_alive_timeout = meta_prefs_get_check_alive_timeout ();
+
+ if (window->is_alive)
+ return;
+ if (window->close_dialog_timeout_id != 0)
+ return;
+ if (check_alive_timeout == 0)
+ return;
+
+ window->close_dialog_timeout_id =
+ g_timeout_add (check_alive_timeout,
+ (GSourceFunc) meta_window_close_dialog_timeout,
+ window);
+ g_source_set_name_by_id (window->close_dialog_timeout_id,
+ "[mutter] meta_window_close_dialog_timeout");
+}
+
+void
+meta_window_set_alive (MetaWindow *window,
+ gboolean is_alive)
+{
+ if (window->is_alive == is_alive)
+ return;
+
+ window->is_alive = is_alive;
+ g_object_notify_by_pspec (G_OBJECT (window), obj_props[PROP_IS_ALIVE]);
+
+ if (is_alive)
+ {
+ g_clear_handle_id (&window->close_dialog_timeout_id, g_source_remove);
+ meta_window_hide_close_dialog (window);
+ }
+ else
+ {
+ meta_window_ensure_close_dialog_timeout (window);
+ }
+}
+
+gboolean
+meta_window_get_alive (MetaWindow *window)
+{
+ return window->is_alive;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]