[gtk/wip/carlosg/input-cleanups: 2/26] gtkmain: Look up transient-for hierarchies to determine modality
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/carlosg/input-cleanups: 2/26] gtkmain: Look up transient-for hierarchies to determine modality
- Date: Wed, 24 Jun 2020 18:36:39 +0000 (UTC)
commit 31b95ce47f214965323d980bd09a7a1bed65ed7e
Author: Carlos Garnacho <carlosg gnome org>
Date: Mon Jun 22 15:31:36 2020 +0200
gtkmain: Look up transient-for hierarchies to determine modality
Windows that are not modal, but are transient-for a modal window should
still be able to receive and handle events. Inspect the window hierarchy
in those cases, so these windows are handled just like widgets within
the modal dialog.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/2851
Related: https://gitlab.gnome.org/GNOME/gtk/-/issues/2850
gtk/gtkmain.c | 28 ++++++++++++++++++++++++++--
1 file changed, 26 insertions(+), 2 deletions(-)
---
diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c
index 84e7efdc8d..fd43c9eb77 100644
--- a/gtk/gtkmain.c
+++ b/gtk/gtkmain.c
@@ -1663,6 +1663,25 @@ handle_key_event (GdkEvent *event)
return focus_widget ? focus_widget : event_widget;
}
+static gboolean
+is_transient_for (GtkWindow *child,
+ GtkWindow *parent)
+{
+ GtkWindow *transient_for;
+
+ transient_for = gtk_window_get_transient_for (child);
+
+ while (transient_for)
+ {
+ if (transient_for == parent)
+ return TRUE;
+
+ transient_for = gtk_window_get_transient_for (transient_for);
+ }
+
+ return FALSE;
+}
+
void
gtk_main_do_event (GdkEvent *event)
{
@@ -1726,11 +1745,16 @@ gtk_main_do_event (GdkEvent *event)
/* If the grab widget is an ancestor of the event widget
* then we send the event to the original event widget.
- * This is the key to implementing modality.
+ * This is the key to implementing modality. This also applies
+ * across windows that are directly or indirectly transient-for
+ * the modal one.
*/
if (!grab_widget ||
((gtk_widget_is_sensitive (target_widget) || gdk_event_get_event_type (event) == GDK_SCROLL) &&
- gtk_widget_is_ancestor (target_widget, grab_widget)))
+ gtk_widget_is_ancestor (target_widget, grab_widget)) ||
+ (GTK_IS_WINDOW (grab_widget) &&
+ grab_widget != event_widget &&
+ is_transient_for (GTK_WINDOW (event_widget), GTK_WINDOW (grab_widget))))
grab_widget = target_widget;
g_object_ref (target_widget);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]