From b2343762b19efb428b3fb47f0a7b66a41c785cba Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 27 Jun 2005 21:06:33 +0000 Subject: [PATCH] Ignore GrabBroken events which are caused by overgrabbing inside the 2005-06-27 Matthias Clasen * gtk/gtkmenushell.c (gtk_menu_shell_grab_broken): Ignore GrabBroken events which are caused by overgrabbing inside the application; menus rely on these for their operation. * gdk/gdkevents.h (struct _GdkEventGrabBroken): Add a grab_window field. * gdk/win32/gdkevents-win32.c (gdk_event_translate): Set grab_window to NULL when generating GrabBroken events for WM_KILLFOCUS messages. * gdk/x11/gdkmain-x11.c (_gdk_xgrab_check_unmap) (_gdk_xgrab_check_destroy): Set grab_window to NULL when generating GrabBroken events when the grab window becomes unviewable or is destroyed. * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab): Generate GrabBroken events when overriding a grab inside the application. In this case, set grab_window to the new grab_window. --- ChangeLog | 27 ++++++++++++++ ChangeLog.pre-2-10 | 27 ++++++++++++++ ChangeLog.pre-2-8 | 27 ++++++++++++++ docs/reference/ChangeLog | 4 +++ docs/reference/gdk/tmpl/event_structs.sgml | 3 ++ gdk/gdkevents.h | 1 + gdk/win32/gdkevents-win32.c | 2 ++ gdk/x11/gdkmain-x11.c | 41 +++++++++------------- gtk/gtkmenushell.c | 13 +++---- 9 files changed, 114 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index d37854800d..f06c29e422 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2005-06-27 Matthias Clasen + + * gtk/gtkmenushell.c (gtk_menu_shell_grab_broken): Ignore + GrabBroken events which are caused by overgrabbing inside + the application; menus rely on these for their operation. + + * gdk/gdkevents.h (struct _GdkEventGrabBroken): Add a + grab_window field. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Set + grab_window to NULL when generating GrabBroken events for + WM_KILLFOCUS messages. + + * gdk/x11/gdkmain-x11.c (_gdk_xgrab_check_unmap) + (_gdk_xgrab_check_destroy): Set grab_window to NULL when + generating GrabBroken events when the grab window becomes + unviewable or is destroyed. + + * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab): + Generate GrabBroken events when overriding a grab inside + the application. In this case, set grab_window to the new + grab_window. + 2005-06-27 Matthias Clasen * gtk/gtkbutton.c (gtk_real_button_activate): Continue @@ -5,9 +28,13 @@ (gtk_button_finish_activate): Only ungrab when we have a keyboard grab. (#172998, William Jon McCann) +2005-06-27 Matthias Clasen + * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize): Avoid a segfault. (#309054) +2005-06-27 Matthias Clasen + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add fields for grab timestamps. diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index d37854800d..f06c29e422 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,26 @@ +2005-06-27 Matthias Clasen + + * gtk/gtkmenushell.c (gtk_menu_shell_grab_broken): Ignore + GrabBroken events which are caused by overgrabbing inside + the application; menus rely on these for their operation. + + * gdk/gdkevents.h (struct _GdkEventGrabBroken): Add a + grab_window field. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Set + grab_window to NULL when generating GrabBroken events for + WM_KILLFOCUS messages. + + * gdk/x11/gdkmain-x11.c (_gdk_xgrab_check_unmap) + (_gdk_xgrab_check_destroy): Set grab_window to NULL when + generating GrabBroken events when the grab window becomes + unviewable or is destroyed. + + * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab): + Generate GrabBroken events when overriding a grab inside + the application. In this case, set grab_window to the new + grab_window. + 2005-06-27 Matthias Clasen * gtk/gtkbutton.c (gtk_real_button_activate): Continue @@ -5,9 +28,13 @@ (gtk_button_finish_activate): Only ungrab when we have a keyboard grab. (#172998, William Jon McCann) +2005-06-27 Matthias Clasen + * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize): Avoid a segfault. (#309054) +2005-06-27 Matthias Clasen + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add fields for grab timestamps. diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index d37854800d..f06c29e422 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,26 @@ +2005-06-27 Matthias Clasen + + * gtk/gtkmenushell.c (gtk_menu_shell_grab_broken): Ignore + GrabBroken events which are caused by overgrabbing inside + the application; menus rely on these for their operation. + + * gdk/gdkevents.h (struct _GdkEventGrabBroken): Add a + grab_window field. + + * gdk/win32/gdkevents-win32.c (gdk_event_translate): Set + grab_window to NULL when generating GrabBroken events for + WM_KILLFOCUS messages. + + * gdk/x11/gdkmain-x11.c (_gdk_xgrab_check_unmap) + (_gdk_xgrab_check_destroy): Set grab_window to NULL when + generating GrabBroken events when the grab window becomes + unviewable or is destroyed. + + * gdk/x11/gdkmain-x11.c (gdk_pointer_grab, gdk_keyboard_grab): + Generate GrabBroken events when overriding a grab inside + the application. In this case, set grab_window to the new + grab_window. + 2005-06-27 Matthias Clasen * gtk/gtkbutton.c (gtk_real_button_activate): Continue @@ -5,9 +28,13 @@ (gtk_button_finish_activate): Only ungrab when we have a keyboard grab. (#172998, William Jon McCann) +2005-06-27 Matthias Clasen + * modules/input/gtkimcontextxim.c (gtk_im_context_xim_finalize): Avoid a segfault. (#309054) +2005-06-27 Matthias Clasen + * gdk/x11/gdkdisplay-x11.h (struct _GdkDisplayX11): Add fields for grab timestamps. diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 7fc72db2c7..34c178ca58 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2005-06-27 Matthias Clasen + + * gdk/tmpl/event_structs.sgml: Update docs. + 2005-06-25 Matthias Clasen * gdk/gdk-sections.txt: Add GdkEventGrabBroken. diff --git a/docs/reference/gdk/tmpl/event_structs.sgml b/docs/reference/gdk/tmpl/event_structs.sgml index 438bb6e39f..ed81d237db 100644 --- a/docs/reference/gdk/tmpl/event_structs.sgml +++ b/docs/reference/gdk/tmpl/event_structs.sgml @@ -438,6 +438,9 @@ again. @send_event: %TRUE if the event was sent explicitly (e.g. using XSendEvent). @keyboard: %TRUE if a keyboard grab was broken, %FALSE if a pointer grab was broken +@grab_window: If this event is caused by another grab in the same + application, @grab_window contains the new grab window. Otherwise + @grab_window id %NULL. @Since: 2.8 diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index 797bee7460..bf4db6ead1 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -436,6 +436,7 @@ struct _GdkEventGrabBroken { GdkWindow *window; gint8 send_event; gboolean keyboard; + GdkWindow *grab_window; }; /* Event types for DND */ diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 23f92a241e..b3edd4c2ce 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -2926,6 +2926,7 @@ gdk_event_translate (GdkDisplay *display, event->grab_broken.window = p_grab_window; event->grab_broken.send_event = 0; event->grab_broken.keyboard = FALSE; + event->grab_broken.grab_window = NULL; append_event (display, event); } @@ -2936,6 +2937,7 @@ gdk_event_translate (GdkDisplay *display, event->grab_broken.window = k_grab_window; event->grab_broken.send_event = 0; event->grab_broken.keyboard = TRUE; + event->grab_broken.grab_window = NULL; append_event (display, event); } diff --git a/gdk/x11/gdkmain-x11.c b/gdk/x11/gdkmain-x11.c index 366f709fe7..b92bd64330 100644 --- a/gdk/x11/gdkmain-x11.c +++ b/gdk/x11/gdkmain-x11.c @@ -139,6 +139,7 @@ gdk_x11_convert_grab_status (gint status) static void generate_grab_broken_event (GdkWindow *window, + GdkWindow *grab_window, gboolean keyboard) { GdkEvent event; @@ -147,7 +148,8 @@ generate_grab_broken_event (GdkWindow *window, event.grab_broken.window = window; event.grab_broken.send_event = 0; event.grab_broken.keyboard = keyboard; - + event.grab_broken.grab_window = grab_window; + gdk_event_put (&event); } @@ -251,14 +253,10 @@ gdk_pointer_grab (GdkWindow * window, if (return_val == GrabSuccess) { GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window)); - if (display_x11->pointer_xgrab_window != NULL) - { - g_print ("overgrab pointer\n"); -#if 0 - generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), - FALSE); -#endif - } + if (display_x11->pointer_xgrab_window != NULL && + display_x11->pointer_xgrab_window != window) + generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), + window, FALSE); display_x11->pointer_xgrab_window = (GdkWindowObject *)window; display_x11->pointer_xgrab_serial = serial; @@ -358,14 +356,11 @@ gdk_keyboard_grab (GdkWindow * window, if (return_val == GrabSuccess) { GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window)); - if (display_x11->keyboard_xgrab_window != NULL) - { - g_print ("overgrab keyboard\n"); -#if 0 - generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), - TRUE); -#endif - } + if (display_x11->keyboard_xgrab_window != NULL && + display_x11->keyboard_xgrab_window != window) + generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), + window, TRUE); + display_x11->keyboard_xgrab_window = (GdkWindowObject *)window; display_x11->keyboard_xgrab_serial = serial; display_x11->keyboard_xgrab_owner_events = owner_events; @@ -439,9 +434,8 @@ _gdk_xgrab_check_unmap (GdkWindow *window, if (tmp) { - g_print ("pointer grab broken from check unmap\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), - FALSE); + NULL, FALSE); display_x11->pointer_xgrab_window = NULL; } } @@ -458,9 +452,8 @@ _gdk_xgrab_check_unmap (GdkWindow *window, if (tmp) { - g_print ("keyboard grab broken from check unmap\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), - TRUE); + NULL, TRUE); display_x11->keyboard_xgrab_window = NULL; } } @@ -480,17 +473,15 @@ _gdk_xgrab_check_destroy (GdkWindow *window) if ((GdkWindowObject *)window == display_x11->pointer_xgrab_window) { - g_print ("pointer grab broken from check destroy\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->pointer_xgrab_window), - FALSE); + NULL, FALSE); display_x11->pointer_xgrab_window = NULL; } if ((GdkWindowObject *)window == display_x11->keyboard_xgrab_window) { - g_print ("keyboard grab broken from check destroy\n"); generate_grab_broken_event (GDK_WINDOW (display_x11->keyboard_xgrab_window), - TRUE); + NULL, TRUE); display_x11->keyboard_xgrab_window = NULL; } } diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c index f207da7cb3..afd9c5c31b 100644 --- a/gtk/gtkmenushell.c +++ b/gtk/gtkmenushell.c @@ -611,14 +611,15 @@ static gboolean gtk_menu_shell_grab_broken (GtkWidget *widget, GdkEventGrabBroken *event) { - GtkMenuShell *menu_shell; + GtkMenuShell *menu_shell = GTK_MENU_SHELL (widget); - g_return_val_if_fail (GTK_IS_MENU_SHELL (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - menu_shell = GTK_MENU_SHELL (widget); - if (menu_shell->active) + if (menu_shell->have_xgrab && event->grab_window == NULL) { + /* Unset the active menu item so gtk_menu_popdown() doesn't see it. + */ + + gtk_menu_shell_deselect (menu_shell); + gtk_menu_shell_deactivate (menu_shell); g_signal_emit (menu_shell, menu_shell_signals[SELECTION_DONE], 0); }