From 8f24df1c199fdc849e7bf6281408c703ad9dfde0 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Fri, 31 Mar 2017 17:49:21 +0200 Subject: [PATCH] gtk: Update GtkPointerFocus targets on mapping/sensitivity changes Those are situations that must cause foci on these widgets to repick themselves. --- gtk/gtkwidget.c | 18 ++++++++++++++++++ gtk/gtkwindow.c | 28 ++++++++++++++++++++++++++++ gtk/gtkwindowprivate.h | 3 +++ 3 files changed, 49 insertions(+) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 915e54e63d..96465ca90b 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -4448,6 +4448,19 @@ gtk_widget_hide_on_delete (GtkWidget *widget) return TRUE; } +static void +update_cursor_on_state_change (GtkWidget *widget) +{ + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (widget); + if (!GTK_IS_WINDOW (toplevel)) + return; + + gtk_window_update_pointer_focus_on_state_change (GTK_WINDOW (toplevel), + widget); +} + /** * gtk_widget_map: * @widget: a #GtkWidget @@ -4471,6 +4484,8 @@ gtk_widget_map (GtkWidget *widget) g_signal_emit (widget, widget_signals[MAP], 0); + update_cursor_on_state_change (widget); + if (!_gtk_widget_get_has_window (widget)) gtk_widget_queue_draw (widget); @@ -4501,6 +4516,8 @@ gtk_widget_unmap (GtkWidget *widget) g_signal_emit (widget, widget_signals[UNMAP], 0); + update_cursor_on_state_change (widget); + gtk_widget_pop_verify_invariants (widget); g_object_unref (widget); } @@ -8405,6 +8422,7 @@ gtk_widget_set_sensitive (GtkWidget *widget, } gtk_widget_propagate_state (widget, &data); + update_cursor_on_state_change (widget); } g_object_notify_by_pspec (G_OBJECT (widget), widget_props[PROP_SENSITIVE]); diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 7e878897e0..56082ca74a 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -11456,3 +11456,31 @@ gtk_window_update_pointer_focus (GtkWindow *window, gtk_window_add_pointer_focus (window, focus); } } + +void +gtk_window_update_pointer_focus_on_state_change (GtkWindow *window, + GtkWidget *widget) +{ + GList *l = window->priv->foci, *cur; + + while (l) + { + GtkPointerFocus *focus = l->data; + + cur = l; + focus = cur->data; + l = cur->next; + + if (GTK_WIDGET (focus->toplevel) == widget) + { + /* Unmapping the toplevel, remove pointer focus */ + gtk_window_remove_pointer_focus (window, focus); + gtk_pointer_focus_free (focus); + } + else if (focus->target == widget || + gtk_widget_is_ancestor (focus->target, widget)) + { + gtk_pointer_focus_repick_target (focus); + } + } +} diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h index b8485c72aa..7f62cc7f38 100644 --- a/gtk/gtkwindowprivate.h +++ b/gtk/gtkwindowprivate.h @@ -154,6 +154,9 @@ void gtk_window_update_pointer_focus (GtkWindow *window, gdouble x, gdouble y); +void gtk_window_update_pointer_focus_on_state_change (GtkWindow *window, + GtkWidget *widget); + G_END_DECLS #endif /* __GTK_WINDOW_PRIVATE_H__ */