[gtk+] GDK W32: More flexible modal operation mode
- From: Руслан Ижбулатов <ruslanizhb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GDK W32: More flexible modal operation mode
- Date: Sat, 2 Dec 2017 11:24:07 +0000 (UTC)
commit 33de691d9faaf7ae7ab8dde3210ea0225218f954
Author: Руслан Ижбулатов <lrn1986 gmail com>
Date: Fri Aug 11 07:00:41 2017 +0000
GDK W32: More flexible modal operation mode
Instead of using a boolean to indicate a modal operation being in progress,
use a set of flags, and allow these to be set and unset independently.
Specifically, this allows WM_CAPTURECHANGED handler to only act when a drag-move or
drag-resize modal operation is in progress, and ignore DND (which can also cause
WM_CAPTURECHANGED to be posted). This avoids a crash due to assertion failure when
OLE2 DND code tries to end a modal operation that was already ended by the WM_CAPTURECHANGED
handler.
(This commit is cherry-picked from the gtk-3-22 branch)
https://bugzilla.gnome.org/show_bug.cgi?id=786121
gdk/win32/gdkdevicemanager-win32.c | 2 +-
gdk/win32/gdkdnd-win32.c | 4 +-
gdk/win32/gdkevents-win32.c | 59 ++++++++++++++++++++++--------------
gdk/win32/gdkglobals-win32.c | 2 +-
gdk/win32/gdkprivate-win32.h | 24 ++++++++++----
5 files changed, 57 insertions(+), 34 deletions(-)
---
diff --git a/gdk/win32/gdkdevicemanager-win32.c b/gdk/win32/gdkdevicemanager-win32.c
index 9dbf800..f6dbe60 100644
--- a/gdk/win32/gdkdevicemanager-win32.c
+++ b/gdk/win32/gdkdevicemanager-win32.c
@@ -974,7 +974,7 @@ gdk_input_other_event (GdkDisplay *display,
/* Don't produce any button or motion events while a window is being
* moved or resized, see bug #151090.
*/
- if (_modal_operation_in_progress)
+ if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
{
GDK_NOTE (EVENTS_OR_INPUT, g_print ("... ignored when moving/sizing\n"));
return FALSE;
diff --git a/gdk/win32/gdkdnd-win32.c b/gdk/win32/gdkdnd-win32.c
index a7eb521..742c435 100644
--- a/gdk/win32/gdkdnd-win32.c
+++ b/gdk/win32/gdkdnd-win32.c
@@ -1896,11 +1896,11 @@ _gdk_win32_dnd_do_dragdrop (void)
GDK_NOTE (DND, g_print ("Calling DoDragDrop\n"));
- _gdk_win32_begin_modal_call ();
+ _gdk_win32_begin_modal_call (GDK_WIN32_MODAL_OP_DND);
hr = DoDragDrop (&dobj->ido, &pending_src_context->ids,
DROPEFFECT_COPY | DROPEFFECT_MOVE,
&dwEffect);
- _gdk_win32_end_modal_call ();
+ _gdk_win32_end_modal_call (GDK_WIN32_MODAL_OP_DND);
GDK_NOTE (DND, g_print ("DoDragDrop returned %s\n",
(hr == DRAGDROP_S_DROP ? "DRAGDROP_S_DROP" :
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index b304a5b..eaafb4b 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1717,36 +1717,42 @@ modal_timer_proc (HWND hwnd,
{
int arbitrary_limit = 10;
- while (_modal_operation_in_progress &&
+ while (_modal_operation_in_progress != GDK_WIN32_MODAL_OP_NONE &&
g_main_context_pending (NULL) &&
arbitrary_limit--)
g_main_context_iteration (NULL, FALSE);
}
void
-_gdk_win32_begin_modal_call (void)
+_gdk_win32_begin_modal_call (GdkWin32ModalOpKind kind)
{
- g_assert (!_modal_operation_in_progress);
+ GdkWin32ModalOpKind was = _modal_operation_in_progress;
+ g_assert (!(_modal_operation_in_progress & kind));
- _modal_operation_in_progress = TRUE;
+ _modal_operation_in_progress |= kind;
- modal_timer = SetTimer (NULL, 0, 10, modal_timer_proc);
- if (modal_timer == 0)
- WIN32_API_FAILED ("SetTimer");
+ if (was == GDK_WIN32_MODAL_OP_NONE)
+ {
+ modal_timer = SetTimer (NULL, 0, 10, modal_timer_proc);
+
+ if (modal_timer == 0)
+ WIN32_API_FAILED ("SetTimer");
+ }
}
void
-_gdk_win32_end_modal_call (void)
+_gdk_win32_end_modal_call (GdkWin32ModalOpKind kind)
{
- g_assert (_modal_operation_in_progress);
+ g_assert (_modal_operation_in_progress & kind);
- _modal_operation_in_progress = FALSE;
+ _modal_operation_in_progress &= ~kind;
- if (modal_timer != 0)
+ if (_modal_operation_in_progress == GDK_WIN32_MODAL_OP_NONE &&
+ modal_timer != 0)
{
API_CALL (KillTimer, (NULL, modal_timer));
modal_timer = 0;
- }
+ }
}
static VOID CALLBACK
@@ -3245,30 +3251,37 @@ gdk_event_translate (MSG *msg,
break;
case WM_ENTERSIZEMOVE:
- case WM_ENTERMENULOOP:
- if (msg->message == WM_ENTERSIZEMOVE)
- _modal_move_resize_window = msg->hwnd;
-
- _gdk_win32_begin_modal_call ();
+ _modal_move_resize_window = msg->hwnd;
+ _gdk_win32_begin_modal_call (GDK_WIN32_MODAL_OP_SIZEMOVE_MASK);
break;
case WM_EXITSIZEMOVE:
- case WM_EXITMENULOOP:
- if (_modal_operation_in_progress)
+ if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
{
_modal_move_resize_window = NULL;
- _gdk_win32_end_modal_call ();
+ _gdk_win32_end_modal_call (GDK_WIN32_MODAL_OP_SIZEMOVE_MASK);
}
break;
+ case WM_ENTERMENULOOP:
+ _gdk_win32_begin_modal_call (GDK_WIN32_MODAL_OP_MENU);
+ break;
+
+ case WM_EXITMENULOOP:
+ if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_MENU)
+ _gdk_win32_end_modal_call (GDK_WIN32_MODAL_OP_MENU);
+ break;
+
+ break;
+
case WM_CAPTURECHANGED:
/* Sometimes we don't get WM_EXITSIZEMOVE, for instance when you
select move/size in the menu and then click somewhere without
moving/resizing. We work around this using WM_CAPTURECHANGED. */
- if (_modal_operation_in_progress)
+ if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
{
_modal_move_resize_window = NULL;
- _gdk_win32_end_modal_call ();
+ _gdk_win32_end_modal_call (GDK_WIN32_MODAL_OP_SIZEMOVE_MASK);
}
impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
@@ -3423,7 +3436,7 @@ gdk_event_translate (MSG *msg,
}
/* Call modal timer immediate so that we repaint faster after a resize. */
- if (_modal_operation_in_progress)
+ if (_modal_operation_in_progress & GDK_WIN32_MODAL_OP_SIZEMOVE_MASK)
modal_timer_proc (0,0,0,0);
/* Claim as handled, so that WM_SIZE and WM_MOVE are avoided */
diff --git a/gdk/win32/gdkglobals-win32.c b/gdk/win32/gdkglobals-win32.c
index 35cc221..c41b1b4 100644
--- a/gdk/win32/gdkglobals-win32.c
+++ b/gdk/win32/gdkglobals-win32.c
@@ -74,7 +74,7 @@ GdkWin32DndState _dnd_source_state = GDK_WIN32_DND_NONE;
gint _gdk_input_ignore_wintab = FALSE;
gint _gdk_max_colors = 0;
-gboolean _modal_operation_in_progress = FALSE;
+GdkWin32ModalOpKind _modal_operation_in_progress = GDK_WIN32_MODAL_OP_NONE;
HWND _modal_move_resize_window = NULL;
gboolean _ignore_destroy_clipboard = FALSE;
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index 6834562..1b8ff86 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -331,19 +331,29 @@ void _gdk_win32_ole2_dnd_property_change (GdkAtom type,
const guchar *data,
gint nelements);
-void _gdk_win32_begin_modal_call (void);
-void _gdk_win32_end_modal_call (void);
+typedef enum {
+ GDK_WIN32_MODAL_OP_NONE = 0x0,
+ GDK_WIN32_MODAL_OP_SIZE = 0x1 << 0,
+ GDK_WIN32_MODAL_OP_MOVE = 0x1 << 1,
+ GDK_WIN32_MODAL_OP_MENU = 0x1 << 2,
+ GDK_WIN32_MODAL_OP_DND = 0x1 << 3
+} GdkWin32ModalOpKind;
+
+#define GDK_WIN32_MODAL_OP_SIZEMOVE_MASK (GDK_WIN32_MODAL_OP_SIZE | GDK_WIN32_MODAL_OP_MOVE)
+
+/* Non-zero while a modal sizing, moving, or dnd operation is in progress */
+extern GdkWin32ModalOpKind _modal_operation_in_progress;
+
+extern HWND _modal_move_resize_window;
+
+void _gdk_win32_begin_modal_call (GdkWin32ModalOpKind kind);
+void _gdk_win32_end_modal_call (GdkWin32ModalOpKind kind);
/* Options */
extern gboolean _gdk_input_ignore_wintab;
extern gint _gdk_max_colors;
-/* TRUE while a modal sizing, moving, or dnd operation is in progress */
-extern gboolean _modal_operation_in_progress;
-
-extern HWND _modal_move_resize_window;
-
/* TRUE when we are emptying the clipboard ourselves */
extern gboolean _ignore_destroy_clipboard;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]