Make gtk_widget_set_extension_events() work on already realized widgets

2007-03-14  Michael Natterer  <mitch@imendio.com>

	Make gtk_widget_set_extension_events() work on already realized
	widgets (bug #379550, Tommi Komulainen)

	* gdk/x11/gdkinput.c (gdk_input_set_extension_events): allow to be
	called multiple times without leaking and work correctly when
	already realized (don't rely on a configure event following).

	* gtk/gtkwidget.c (gtk_widget_set_extension_events_internal): new
	internal function which walks the GdkWindow tree and sets the
	extension events on all windows that belong to the widget.

	(gtk_widget_realize)
	(gtk_widget_set_extension_events): use the new function.


svn path=/trunk/; revision=17515
This commit is contained in:
Michael Natterer
2007-03-14 13:55:12 +00:00
committed by Michael Natterer
parent 86ea351bd7
commit d953ce8775
3 changed files with 93 additions and 25 deletions

View File

@ -1,3 +1,19 @@
2007-03-14 Michael Natterer <mitch@imendio.com>
Make gtk_widget_set_extension_events() work on already realized
widgets (bug #379550, Tommi Komulainen)
* gdk/x11/gdkinput.c (gdk_input_set_extension_events): allow to be
called multiple times without leaking and work correctly when
already realized (don't rely on a configure event following).
* gtk/gtkwidget.c (gtk_widget_set_extension_events_internal): new
internal function which walks the GdkWindow tree and sets the
extension events on all windows that belong to the widget.
(gtk_widget_realize)
(gtk_widget_set_extension_events): use the new function.
2007-03-14 Emmanuele Bassi <ebassi@gnome.org> 2007-03-14 Emmanuele Bassi <ebassi@gnome.org>
Various clean ups in the GtkRecent code. (see #338843) Various clean ups in the GtkRecent code. (see #338843)

View File

@ -313,29 +313,42 @@ gdk_input_set_extension_events (GdkWindow *window, gint mask,
if (mode == GDK_EXTENSION_EVENTS_NONE) if (mode == GDK_EXTENSION_EVENTS_NONE)
mask = 0; mask = 0;
iw = _gdk_input_window_find (window);
if (mask != 0) if (mask != 0)
{ {
iw = g_new(GdkInputWindow,1); if (!iw)
{
iw = g_new(GdkInputWindow,1);
iw->window = window; iw->window = window;
iw->mode = mode; iw->mode = mode;
iw->obscuring = NULL; iw->obscuring = NULL;
iw->num_obscuring = 0; iw->num_obscuring = 0;
iw->grabbed = FALSE; iw->grabbed = FALSE;
display_x11->input_windows = g_list_append(display_x11->input_windows,iw);
}
display_x11->input_windows = g_list_append(display_x11->input_windows,iw);
window_private->extension_events = mask; window_private->extension_events = mask;
#ifndef XINPUT_NONE
/* Add enter window events to the event mask */ /* Add enter window events to the event mask */
/* FIXME, this is not needed for XINPUT_NONE */ /* this is not needed for XINPUT_NONE */
gdk_window_set_events (window, gdk_window_set_events (window,
gdk_window_get_events (window) | gdk_window_get_events (window) |
GDK_ENTER_NOTIFY_MASK); GDK_ENTER_NOTIFY_MASK);
/* we might not receive ConfigureNotify so get the root_relative_geometry
* now, just in case */
_gdk_input_get_root_relative_geometry (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XWINDOW (window),
&iw->root_x, &iw->root_y, NULL, NULL);
#endif /* !XINPUT_NONE */
} }
else else
{ {
iw = _gdk_input_window_find (window);
if (iw) if (iw)
{ {
display_x11->input_windows = g_list_remove(display_x11->input_windows,iw); display_x11->input_windows = g_list_remove(display_x11->input_windows,iw);

View File

@ -2618,6 +2618,51 @@ gtk_widget_unmap (GtkWidget *widget)
} }
} }
static void
gtk_widget_set_extension_events_internal (GtkWidget *widget,
GdkExtensionMode mode,
GList *window_list)
{
GList *free_list = NULL;
GList *l;
if (window_list == NULL)
{
if (!GTK_WIDGET_NO_WINDOW (widget))
window_list = g_list_prepend (NULL, widget->window);
else
window_list = gdk_window_get_children (widget->window);
free_list = window_list;
}
for (l = window_list; l != NULL; l = l->next)
{
GdkWindow *window = l->data;
gpointer user_data;
gdk_window_get_user_data (window, &user_data);
if (user_data == widget)
{
GList *children;
gdk_input_set_extension_events (window,
gdk_window_get_events (window),
mode);
children = gdk_window_get_children (window);
if (children)
{
gtk_widget_set_extension_events_internal (widget, mode, children);
g_list_free (children);
}
}
}
if (free_list)
g_list_free (free_list);
}
/** /**
* gtk_widget_realize: * gtk_widget_realize:
* @widget: a #GtkWidget * @widget: a #GtkWidget
@ -2645,7 +2690,6 @@ gtk_widget_unmap (GtkWidget *widget)
void void
gtk_widget_realize (GtkWidget *widget) gtk_widget_realize (GtkWidget *widget)
{ {
gint events;
GdkExtensionMode mode; GdkExtensionMode mode;
GtkWidgetShapeInfo *shape_info; GtkWidgetShapeInfo *shape_info;
@ -2691,16 +2735,9 @@ gtk_widget_realize (GtkWidget *widget)
shape_info->offset_x, shape_info->offset_x,
shape_info->offset_y); shape_info->offset_y);
if (!GTK_WIDGET_NO_WINDOW (widget)) mode = gtk_widget_get_extension_events (widget);
{ if (mode != GDK_EXTENSION_EVENTS_NONE)
mode = gtk_widget_get_extension_events (widget); gtk_widget_set_extension_events_internal (widget, mode, NULL);
if (mode != GDK_EXTENSION_EVENTS_NONE)
{
events = gtk_widget_get_events (widget);
gdk_input_set_extension_events (widget->window, events, mode);
}
}
} }
} }
@ -6572,21 +6609,23 @@ gtk_widget_add_events (GtkWidget *widget,
* *
* Sets the extension events mask to @mode. See #GdkExtensionMode * Sets the extension events mask to @mode. See #GdkExtensionMode
* and gdk_input_set_extension_events(). * and gdk_input_set_extension_events().
*
**/ **/
void void
gtk_widget_set_extension_events (GtkWidget *widget, gtk_widget_set_extension_events (GtkWidget *widget,
GdkExtensionMode mode) GdkExtensionMode mode)
{ {
GdkExtensionMode *modep; GdkExtensionMode *modep;
g_return_if_fail (GTK_IS_WIDGET (widget)); g_return_if_fail (GTK_IS_WIDGET (widget));
modep = g_object_get_qdata (G_OBJECT (widget), quark_extension_event_mode); modep = g_object_get_qdata (G_OBJECT (widget), quark_extension_event_mode);
if (!modep) if (!modep)
modep = g_slice_new (GdkExtensionMode); modep = g_slice_new (GdkExtensionMode);
if (GTK_WIDGET_REALIZED (widget))
gtk_widget_set_extension_events_internal (widget, mode, NULL);
*modep = mode; *modep = mode;
g_object_set_qdata (G_OBJECT (widget), quark_extension_event_mode, modep); g_object_set_qdata (G_OBJECT (widget), quark_extension_event_mode, modep);
g_object_notify (G_OBJECT (widget), "extension-events"); g_object_notify (G_OBJECT (widget), "extension-events");