diff options
author | Tor Lillqvist <tml@iki.fi> | 2004-11-11 22:00:11 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 2004-11-11 22:00:11 +0000 |
commit | 430a02d8542a1a70d451f9eb454aec06f804e968 (patch) | |
tree | d5480485a2906de1c2f91fe82d5b885b667b1ef8 /gdk | |
parent | d1a02aaa34a606bdc5a6dcd84b45e32fad78ac89 (diff) | |
download | gtk+-430a02d8542a1a70d451f9eb454aec06f804e968.tar.gz |
Fix for #137551, by Robert Ögren:
2004-11-11 Tor Lillqvist <tml@iki.fi>
Fix for #137551, by Robert Ögren:
* gdk/win32/gdkevents-win32.c (generate_focus_event): New function.
(gdk_keyboard_grab, gdk_keyboard_ungrab): Generate focus change
events.
(gdk_event_translate): Check for keyboard grabs and not pointer
grabs when handling WM_{SET,KILL}FOCUS. Use generate_focus_event().
Diffstat (limited to 'gdk')
-rw-r--r-- | gdk/win32/gdkevents-win32.c | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 03b7421332..8cc9fbdfca 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -112,6 +112,9 @@ static gboolean gdk_event_dispatch (GSource *source, GSourceFunc callback, gpointer user_data); +static void append_event (GdkDisplay *display, + GdkEvent *event); + /* Private variable declarations */ @@ -230,6 +233,19 @@ _gdk_win32_get_next_tick (gulong suggested_tick) return cur_tick = suggested_tick; } +static void +generate_focus_event (GdkWindow *window, + gboolean in) +{ + GdkEvent *event; + + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = window; + event->focus_change.in = in; + + append_event (gdk_drawable_get_display (window), event); +} + static LRESULT inner_window_procedure (HWND hwnd, UINT message, @@ -716,6 +732,8 @@ gdk_keyboard_grab (GdkWindow *window, gboolean owner_events, guint32 time) { + GdkWindow *real_focus_window, *grab_focus_window; + gint return_val; g_return_val_if_fail (window != NULL, 0); @@ -733,7 +751,31 @@ gdk_keyboard_grab (GdkWindow *window, return_val = GDK_GRAB_ALREADY_GRABBED; if (return_val == GDK_GRAB_SUCCESS) - k_grab_window = window; + { + k_grab_window = window; + + if (!k_grab_owner_events) + { + real_focus_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ()); + if (real_focus_window) + real_focus_window = gdk_window_get_toplevel (real_focus_window); + grab_focus_window = gdk_window_get_toplevel (k_grab_window); + if (real_focus_window != grab_focus_window) + { + /* Generate events for focus change from the window that really + * has focus to the grabber. + */ + if (real_focus_window && !GDK_WINDOW_DESTROYED (real_focus_window) + && (((GdkWindowObject *) real_focus_window)->event_mask + & GDK_FOCUS_CHANGE_MASK)) + generate_focus_event (real_focus_window, FALSE); + + if (((GdkWindowObject *) grab_focus_window)->event_mask + & GDK_FOCUS_CHANGE_MASK) + generate_focus_event (grab_focus_window, TRUE); + } + } + } return return_val; } @@ -742,10 +784,39 @@ void gdk_display_keyboard_ungrab (GdkDisplay *display, guint32 time) { + GdkWindow *real_focus_window, *grab_focus_window; + g_return_if_fail (display == gdk_display_get_default ()); GDK_NOTE (EVENTS, g_print ("gdk_keyboard_ungrab\n")); + if (k_grab_window && !k_grab_owner_events) + { + real_focus_window = gdk_win32_handle_table_lookup ((GdkNativeWindow) GetFocus ()); + if (real_focus_window) + real_focus_window = gdk_window_get_toplevel (real_focus_window); + if (!GDK_WINDOW_DESTROYED (k_grab_window)) + grab_focus_window = gdk_window_get_toplevel (k_grab_window); + else + grab_focus_window = NULL; + if (real_focus_window != grab_focus_window) + { + /* Generate events for focus change from grabber to the window that + * really has focus. Important for example if a new window is created + * while focus is grabbed. + */ + if (grab_focus_window + && (((GdkWindowObject *) grab_focus_window)->event_mask + & GDK_FOCUS_CHANGE_MASK)) + generate_focus_event (grab_focus_window, FALSE); + + if (real_focus_window && !GDK_WINDOW_DESTROYED (real_focus_window) + && (((GdkWindowObject *) real_focus_window)->event_mask + & GDK_FOCUS_CHANGE_MASK)) + generate_focus_event (real_focus_window, TRUE); + } + } + k_grab_window = NULL; } @@ -2831,7 +2902,7 @@ gdk_event_translate (GdkDisplay *display, case WM_SETFOCUS: case WM_KILLFOCUS: - if (p_grab_window != NULL && !p_grab_owner_events && !(p_grab_mask & GDK_FOCUS_CHANGE_MASK)) + if (k_grab_window != NULL && !k_grab_owner_events) break; if (!(((GdkWindowObject *) window)->event_mask & GDK_FOCUS_CHANGE_MASK)) @@ -2840,12 +2911,7 @@ gdk_event_translate (GdkDisplay *display, if (GDK_WINDOW_DESTROYED (window)) break; - event = gdk_event_new (GDK_FOCUS_CHANGE); - event->focus_change.window = window; - event->focus_change.in = (msg->message == WM_SETFOCUS); - - append_event (display, event); - + generate_focus_event (window, (msg->message == WM_SETFOCUS)); return_val = TRUE; break; |