diff options
author | Cody Russell <bratsche@gnome.org> | 2008-02-05 16:47:24 +0000 |
---|---|---|
committer | Cody Russell <bratsche@src.gnome.org> | 2008-02-05 16:47:24 +0000 |
commit | db58254c5ce8a11c94df356b7bf7947f389bcbb6 (patch) | |
tree | 301c90001b6023e9773d2b2b0d210766edffb876 | |
parent | ea8ffe42aab3063c83dd4fe28b5d45b84f889ac3 (diff) | |
download | gdk-pixbuf-db58254c5ce8a11c94df356b7bf7947f389bcbb6.tar.gz |
gdk/win32/gdkprivate-win32.h gdk/win32/gdkevents-win32.c
2008-02-05 Cody Russell <bratsche@gnome.org>
* gdk/win32/gdkprivate-win32.h
* gdk/win32/gdkevents-win32.c
* gdk/win32/gdkwindow-win32.c
* gdk/win32/gdkwindow-win32.h
* gdk/win32/gdkwin32.h:
Modal window rework. (#455627 and #511111)
svn path=/trunk/; revision=19463
-rw-r--r-- | ChangeLog | 9 | ||||
-rw-r--r-- | gdk/win32/gdkevents-win32.c | 84 | ||||
-rw-r--r-- | gdk/win32/gdkprivate-win32.h | 5 | ||||
-rw-r--r-- | gdk/win32/gdkwin32.h | 2 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.c | 74 | ||||
-rw-r--r-- | gdk/win32/gdkwindow-win32.h | 1 |
6 files changed, 155 insertions, 20 deletions
@@ -1,3 +1,12 @@ +2008-02-05 Cody Russell <bratsche@gnome.org> + + * gdk/win32/gdkprivate-win32.h + * gdk/win32/gdkevents-win32.c + * gdk/win32/gdkwindow-win32.c + * gdk/win32/gdkwindow-win32.h + * gdk/win32/gdkwin32.h: + Modal window rework. (#455627 and #511111) + 2008-02-04 Michael Natterer <mitch@imendio.com> * gtk/gtkcombobox.c (gtk_combo_box_cell_layout_add_attribute): diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 584c2145e..739c451ec 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -94,6 +94,7 @@ static gboolean gdk_event_dispatch (GSource *source, gpointer user_data); static void append_event (GdkEvent *event); +static gboolean is_modally_blocked (GdkWindow *window); /* Private variable declarations */ @@ -1767,6 +1768,13 @@ static gboolean doesnt_want_key (gint mask, MSG *msg) { + GdkWindow *modal_current = _gdk_modal_current (); + GdkWindow *window = (GdkWindow *) gdk_win32_handle_table_lookup ((GdkNativeWindow)msg->hwnd); + gboolean modally_blocked = modal_current != NULL ? gdk_window_get_toplevel (window) != modal_current : FALSE; + + if (modally_blocked == TRUE) + return TRUE; + return (((msg->message == WM_KEYUP || msg->message == WM_SYSKEYUP) && !(mask & GDK_KEY_RELEASE_MASK)) || ((msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) && @@ -2811,6 +2819,18 @@ gdk_event_translate (MSG *msg, *ret_valp = MA_NOACTIVATE; return_val = TRUE; } + + GdkWindow *tmp = _gdk_modal_current (); + + if (tmp != NULL) + { + if (gdk_window_get_toplevel (window) != tmp) + { + *ret_valp = MA_NOACTIVATEANDEAT; + return_val = TRUE; + } + } + break; case WM_KILLFOCUS: @@ -2916,10 +2936,14 @@ gdk_event_translate (MSG *msg, case WM_SYSCOMMAND: - if (msg->wParam == SC_MINIMIZE || msg->wParam == SC_RESTORE) + switch (msg->wParam) { + case SC_MINIMIZE: + case SC_RESTORE: show_window_internal (window, msg->wParam == SC_MINIMIZE ? TRUE : FALSE); + break; } + break; case WM_SIZE: @@ -2967,10 +2991,12 @@ gdk_event_translate (MSG *msg, show_window_internal (window, FALSE); } else if (msg->wParam == SIZE_MAXIMIZED) - gdk_synthesize_window_state (window, - GDK_WINDOW_STATE_ICONIFIED | - withdrawn_bit, - GDK_WINDOW_STATE_MAXIMIZED); + { + gdk_synthesize_window_state (window, + GDK_WINDOW_STATE_ICONIFIED | + withdrawn_bit, + GDK_WINDOW_STATE_MAXIMIZED); + } if (((GdkWindowObject *) window)->resize_count > 1) ((GdkWindowObject *) window)->resize_count -= 1; @@ -3226,6 +3252,7 @@ gdk_event_translate (MSG *msg, break; } } + *ret_valp = TRUE; return_val = TRUE; GDK_NOTE (EVENTS, g_print (" (handled ASPECT: %s)", @@ -3359,7 +3386,10 @@ gdk_event_translate (MSG *msg, append_event (event); } else - return_val = TRUE; + { + return_val = TRUE; + } + break; case WM_RENDERFORMAT: @@ -3394,7 +3424,9 @@ gdk_event_translate (MSG *msg, /* Now the clipboard owner should have rendered */ if (!_delayed_rendering_data) - GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)")); + { + GDK_NOTE (EVENTS, g_print (" (no _delayed_rendering_data?)")); + } else { if (msg->wParam == CF_DIB) @@ -3408,6 +3440,7 @@ gdk_event_translate (MSG *msg, break; } } + /* The requestor is holding the clipboard, no * OpenClipboard() is required/possible */ @@ -3419,6 +3452,18 @@ gdk_event_translate (MSG *msg, case WM_ACTIVATE: + /* We handle mouse clicks for modally-blocked windows under WM_MOUSEACTIVATE, + * but we still need to deal with alt-tab, or with SetActiveWindow() type + * situations. */ + if (is_modally_blocked (window) && msg->wParam == WA_ACTIVE) + { + GdkWindow *modal_current = _gdk_modal_current (); + SetActiveWindow (GDK_WINDOW_HWND (modal_current)); + *ret_valp = 0; + return_val = TRUE; + break; + } + /* Bring any tablet contexts to the top of the overlap order when * one of our windows is activated. * NOTE: It doesn't seem to work well if it is done in WM_ACTIVATEAPP @@ -3454,10 +3499,12 @@ gdk_event_translate (MSG *msg, event = gdk_event_new (GDK_NOTHING); event->any.window = window; g_object_ref (window); + if (_gdk_input_other_event (event, msg, window)) append_event (event); else gdk_event_free (event); + break; } @@ -3515,11 +3562,15 @@ gdk_event_check (GSource *source) GDK_THREADS_ENTER (); if (event_poll_fd.revents & G_IO_IN) - retval = (_gdk_event_queue_find_first (_gdk_display) != NULL || - (modal_win32_dialog == NULL && - PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE))); + { + retval = (_gdk_event_queue_find_first (_gdk_display) != NULL || + (modal_win32_dialog == NULL && + PeekMessageW (&msg, NULL, 0, 0, PM_NOREMOVE))); + } else - retval = FALSE; + { + retval = FALSE; + } GDK_THREADS_LEAVE (); @@ -3557,6 +3608,13 @@ gdk_win32_set_modal_dialog_libgtk_only (HWND window) modal_win32_dialog = window; } +static gboolean +is_modally_blocked (GdkWindow *window) +{ + GdkWindow *modal_current = _gdk_modal_current (); + return modal_current != NULL ? gdk_window_get_toplevel (window) != modal_current : FALSE; +} + static void check_for_too_much_data (GdkEvent *event) { @@ -3564,7 +3622,9 @@ check_for_too_much_data (GdkEvent *event) event->client.data.l[2] || event->client.data.l[3] || event->client.data.l[4]) - g_warning ("Only four bytes of data are passed in client messages on Win32\n"); + { + g_warning ("Only four bytes of data are passed in client messages on Win32\n"); + } } gboolean diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h index 61e67c48f..46c3348b1 100644 --- a/gdk/win32/gdkprivate-win32.h +++ b/gdk/win32/gdkprivate-win32.h @@ -276,6 +276,11 @@ void _gdk_wchar_text_handle (GdkFont *font, void *), void *arg); +void _gdk_push_modal_window (GdkWindow *window); +void _gdk_remove_modal_window (GdkWindow *window); +GdkWindow *_gdk_modal_current (); + + #ifdef G_ENABLE_DEBUG gchar *_gdk_win32_color_to_string (const GdkColor *color); void _gdk_win32_print_paletteentries (const PALETTEENTRY *pep, diff --git a/gdk/win32/gdkwin32.h b/gdk/win32/gdkwin32.h index 1e79ce94c..06ff05596 100644 --- a/gdk/win32/gdkwin32.h +++ b/gdk/win32/gdkwin32.h @@ -85,7 +85,7 @@ void gdk_win32_selection_add_targets (GdkWindow *owner, GdkAtom *targets); /* For internal GTK use only */ -GdkPixbuf * gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon); +GdkPixbuf *gdk_win32_icon_to_pixbuf_libgtk_only (HICON hicon); HICON gdk_win32_pixbuf_to_hicon_libgtk_only (GdkPixbuf *pixbuf); void gdk_win32_set_modal_dialog_libgtk_only (HWND window); diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c index c0905c161..b81357643 100644 --- a/gdk/win32/gdkwindow-win32.c +++ b/gdk/win32/gdkwindow-win32.c @@ -51,6 +51,7 @@ static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass); static void gdk_window_impl_win32_finalize (GObject *object); static gpointer parent_class = NULL; +static GSList *modal_window_stack = NULL; static void update_style_bits (GdkWindow *window); static gboolean _gdk_window_get_functions (GdkWindow *window, @@ -154,14 +155,17 @@ gdk_window_impl_win32_finalize (GObject *object) { if (GetCursor () == window_impl->hcursor) SetCursor (NULL); + GDI_CALL (DestroyCursor, (window_impl->hcursor)); window_impl->hcursor = NULL; } + if (window_impl->hicon_big != NULL) { GDI_CALL (DestroyIcon, (window_impl->hicon_big)); window_impl->hicon_big = NULL; } + if (window_impl->hicon_small != NULL) { GDI_CALL (DestroyIcon, (window_impl->hicon_small)); @@ -338,6 +342,7 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint) wcl.hInstance = _gdk_app_hmodule; wcl.hIcon = 0; wcl.hIconSm = 0; + /* initialize once! */ if (0 == hAppIcon && 0 == hAppIconSm) { @@ -346,12 +351,16 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint) if (0 != GetModuleFileName (_gdk_app_hmodule, sLoc, MAX_PATH)) { ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1); + if (0 == hAppIcon && 0 == hAppIconSm) { if (0 != GetModuleFileName (_gdk_dll_hinstance, sLoc, MAX_PATH)) - ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1); + { + ExtractIconEx (sLoc, 0, &hAppIcon, &hAppIconSm, 1); + } } } + if (0 == hAppIcon && 0 == hAppIconSm) { hAppIcon = LoadImage (NULL, IDI_APPLICATION, IMAGE_ICON, @@ -362,6 +371,7 @@ RegisterGdkClass (GdkWindowType wtype, GdkWindowTypeHint wtype_hint) GetSystemMetrics (SM_CYSMICON), 0); } } + if (0 == hAppIcon) hAppIcon = hAppIconSm; else if (0 == hAppIconSm) @@ -844,6 +854,9 @@ _gdk_windowing_window_destroy (GdkWindow *window, if (private->extension_events != 0) _gdk_input_window_destroy (window); + /* Remove ourself from the modal stack */ + _gdk_remove_modal_window (window); + /* Remove all our transient children */ tmp = window_impl->transient_children; while (tmp != NULL) @@ -1775,7 +1788,9 @@ get_effective_window_decorations (GdkWindow *window, if (((GdkWindowObject *) window)->window_type != GDK_WINDOW_TOPLEVEL && ((GdkWindowObject *) window)->window_type != GDK_WINDOW_DIALOG) - return FALSE; + { + return FALSE; + } if ((impl->hint_flags & GDK_HINT_MIN_SIZE) && (impl->hint_flags & GDK_HINT_MAX_SIZE) && @@ -1783,12 +1798,17 @@ get_effective_window_decorations (GdkWindow *window, impl->hints.min_height == impl->hints.max_height) { *decoration = GDK_DECOR_ALL | GDK_DECOR_RESIZEH | GDK_DECOR_MAXIMIZE; + if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG || impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU || impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR) - *decoration |= GDK_DECOR_MINIMIZE; + { + *decoration |= GDK_DECOR_MINIMIZE; + } else if (impl->type_hint == GDK_WINDOW_TYPE_HINT_SPLASHSCREEN) - *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE; + { + *decoration |= GDK_DECOR_MENU | GDK_DECOR_MINIMIZE; + } return TRUE; } @@ -1798,7 +1818,10 @@ get_effective_window_decorations (GdkWindow *window, if (impl->type_hint == GDK_WINDOW_TYPE_HINT_DIALOG || impl->type_hint == GDK_WINDOW_TYPE_HINT_MENU || impl->type_hint == GDK_WINDOW_TYPE_HINT_TOOLBAR) - *decoration |= GDK_DECOR_MINIMIZE; + { + *decoration |= GDK_DECOR_MINIMIZE; + } + return TRUE; } else @@ -2013,6 +2036,38 @@ gdk_window_set_transient_for (GdkWindow *window, } void +_gdk_push_modal_window (GdkWindow *window) +{ + modal_window_stack = g_slist_prepend (modal_window_stack, + window); +} + +void +_gdk_remove_modal_window (GdkWindow *window) +{ + g_return_if_fail (window != NULL); + + /* It's possible to be NULL here if someone sets the modal hint of the window + * to FALSE before a modal window stack has ever been created. */ + if (modal_window_stack == NULL) + return; + + /* Find the requested window in the stack and remove it. Yeah, I realize this + * means we're not a 'real stack', strictly speaking. Sue me. :) */ + GSList *tmp = g_slist_find (modal_window_stack, window); + if (tmp != NULL) + { + modal_window_stack = g_slist_delete_link (modal_window_stack, tmp); + } +} + +GdkWindow * +_gdk_modal_current () +{ + return modal_window_stack != NULL ? modal_window_stack->data : NULL; +} + +void gdk_window_set_background (GdkWindow *window, const GdkColor *color) { @@ -3470,13 +3525,20 @@ gdk_window_set_modal_hint (GdkWindow *window, private->modal_hint = modal; -#if 1 +#if 0 /* Not sure about this one.. -- Cody */ if (GDK_WINDOW_IS_MAPPED (window)) API_CALL (SetWindowPos, (GDK_WINDOW_HWND (window), modal ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)); +#else + + if (modal) + _gdk_push_modal_window (window); + else + _gdk_remove_modal_window (window); + #endif } diff --git a/gdk/win32/gdkwindow-win32.h b/gdk/win32/gdkwindow-win32.h index 8583ab35f..fbc461c94 100644 --- a/gdk/win32/gdkwindow-win32.h +++ b/gdk/win32/gdkwindow-win32.h @@ -96,7 +96,6 @@ struct _GdkWindowImplWin32 struct _GdkWindowImplWin32Class { GdkDrawableImplWin32Class parent_class; - }; GType _gdk_window_impl_win32_get_type (void); |