From c21722a39780abcd692cb01978fbf57fc7d06a45 Mon Sep 17 00:00:00 2001 From: Diederick Niehorster Date: Wed, 27 Feb 2013 11:36:14 +0000 Subject: [PATCH] now that mouse capture was properly implemented, menus could be opened outside the window when the window had capture because another mouse button was depressed. fixed Also implemented WM_CANCELMODE, which could be important as we should cancel capture when it comes in git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1526 7f0cb862-5218-0410-a997-914c9d46530a --- src/fg_menu.c | 16 ++++++++++++---- src/mswin/fg_main_mswin.c | 21 ++++++++++++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/fg_menu.c b/src/fg_menu.c index e60a5f8..d44c6f4 100644 --- a/src/fg_menu.c +++ b/src/fg_menu.c @@ -667,10 +667,18 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed, ( window->Menu[ button ] ) && pressed ) { - /* XXX Posting a requisite Redisplay seems bogus. */ - window->State.Redisplay = GL_TRUE; - fghActivateMenu( window, button ); - return GL_TRUE; + /* If mouseclick was outside the parent window, ignore. This can + * happen when another mouse button is already depressed and the + * window thus has mouse capture + */ + if (window->State.MouseX>0 && window->State.MouseY>0 && + window->State.MouseXState.Width && window->State.MouseXState.Height) + { + /* XXX Posting a requisite Redisplay seems bogus. */ + window->State.Redisplay = GL_TRUE; + fghActivateMenu( window, button ); + return GL_TRUE; + } } return GL_FALSE; diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index e4fcce5..baf4b3b 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -361,6 +361,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR { SFG_Window *window; LRESULT lRet = 1; + static int setCaptureActive = 0; FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ; @@ -623,6 +624,17 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR */ return 0; + case WM_CANCELMODE: + /* + * The window manager sends this message when it detects a change + * that requires that an application cancel any modal state it has + * entered. If we've called SetCapture in the mouse button handler, + * call ReleaseCapture. + */ + if (setCaptureActive) + ReleaseCapture(); + break; + case WM_MOUSEMOVE: { #if defined(_WIN32_WCE) @@ -743,7 +755,11 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR * This is consistent with the behavior on X11. */ if ( pressed == GL_TRUE ) - SetCapture ( window->Window.Handle ) ; + { + if (!setCaptureActive) + SetCapture ( window->Window.Handle ) ; + setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */ + } else if (!GetAsyncKeyState(VK_LBUTTON) && !GetAsyncKeyState(VK_MBUTTON) && !GetAsyncKeyState(VK_RBUTTON)) /* Make sure all mouse buttons are released before releasing capture */ ReleaseCapture () ; @@ -864,6 +880,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR break; case WM_CAPTURECHANGED: + if (!lParam || !fgWindowByHandle((HWND)lParam)) + /* Capture released or capture taken by non-FreeGLUT window */ + setCaptureActive = 0; /* User has finished resizing the window, force a redraw */ INVOKE_WCB( *window, Display, ( ) ); lRet = 0; /* Per docs, should return zero */ -- 1.7.10.4