Browse Source

Fix an annoying issue (wxMSW specific) about X_VIEW_CONTROLS::CaptureCursor()

On MSW, CaptureMouse() was sometimes called event if the GAL panel has
captured the mouse (that was not accepted by wxMSW), although HasCapture()
returns false.
(Perhaps some race condition between events)
The fix add a flag to avoid calling twice CaptureMouse() after only one
wxEVT_MOUSE_CAPTURE_LOST event was received.
Fixes #8239
https://gitlab.com/kicad/code/kicad/issues/8239
6.0.7
jean-pierre charras 5 years ago
parent
commit
1bfa3dc6a5
  1. 1
      common/draw_panel_gal.cpp
  2. 28
      common/view/wx_view_controls.cpp
  3. 9
      include/class_draw_panel_gal.h

1
common/draw_panel_gal.cpp

@ -71,6 +71,7 @@ EDA_DRAW_PANEL_GAL::EDA_DRAW_PANEL_GAL( wxWindow* aParentWindow, wxWindowID aWin
m_stealsFocus( true )
{
m_parent = aParentWindow;
m_MouseCapturedLost = false;
SetLayoutDirection( wxLayout_LeftToRight );

28
common/view/wx_view_controls.cpp

@ -3,7 +3,7 @@
*
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2013-2015 CERN
* Copyright (C) 2012-2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2012-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
@ -36,6 +36,7 @@
#include <settings/common_settings.h>
#include <math/util.h> // for KiROUND
#include <widgets/ui_common.h>
#include <class_draw_panel_gal.h>
#if defined __WXMSW__
#define USE_MOUSE_CAPTURE
@ -65,7 +66,7 @@ static std::unique_ptr<ZOOM_CONTROLLER> GetZoomControllerForPlatform( bool aAcce
}
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, wxScrolledCanvas* aParentPanel ) :
WX_VIEW_CONTROLS::WX_VIEW_CONTROLS( VIEW* aView, EDA_DRAW_PANEL_GAL* aParentPanel ) :
VIEW_CONTROLS( aView ),
m_state( IDLE ),
m_parentPanel( aParentPanel ),
@ -472,7 +473,12 @@ void WX_VIEW_CONTROLS::onLeave( wxMouseEvent& aEvent )
void WX_VIEW_CONTROLS::onCaptureLost( wxMouseEvent& aEvent )
{
// This method must be present to suppress the capture-lost assertion
// This method must be present to suppress the capture-lost assertion
// Set the flag to allow calling m_parentPanel->CaptureMouse()
// Nots: One cannot call m_parentPanel->CaptureMouse() twice, thit is not accepted
// by wxWidgets (MSW specific) so we need this guard
m_parentPanel->m_MouseCapturedLost = true;
}
void WX_VIEW_CONTROLS::onTimer( wxTimerEvent& aEvent )
@ -590,11 +596,25 @@ void WX_VIEW_CONTROLS::onScroll( wxScrollWinEvent& aEvent )
void WX_VIEW_CONTROLS::CaptureCursor( bool aEnabled )
{
#if defined USE_MOUSE_CAPTURE
if( aEnabled && !m_parentPanel->HasCapture() )
// Note: for some reason, m_parentPanel->HasCapture() can be false even if CaptureMouse()
// was called (i.e. mouse was captured, so when need to test m_MouseCapturedLost to be
// sure a wxEVT_MOUSE_CAPTURE_LOST event was fired before. Otherwise wxMSW complains
if( aEnabled && !m_parentPanel->HasCapture() && m_parentPanel->m_MouseCapturedLost )
{
m_parentPanel->CaptureMouse();
// Clear the flag to allow calling m_parentPanel->CaptureMouse()
// Calling it without calling ReleaseMouse() is not accepted by wxWidgets (MSW specific)
m_parentPanel->m_MouseCapturedLost = false;
}
else if( !aEnabled && m_parentPanel->HasCapture()
&& m_state != DRAG_PANNING && m_state != DRAG_ZOOMING )
{
m_parentPanel->ReleaseMouse();
// Mouse is released, calling CaptureMouse() is allowed now:
m_parentPanel->m_MouseCapturedLost = true;
}
#endif
VIEW_CONTROLS::CaptureCursor( aEnabled );
}

9
include/class_draw_panel_gal.h

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2018 CERN
* Copyright (C) 2013-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013-2021 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
@ -226,6 +226,13 @@ public:
*/
void ClearDebugOverlay();
/**
* used on wxMSW: true after a wxEVT_MOUSE_CAPTURE_LOST was received
* false after the mouse is recaptured.
* Used to avoid calling twice a CaptureMouse(), not accepted by wxMSW
*/
bool m_MouseCapturedLost;
protected:
virtual void onPaint( wxPaintEvent& WXUNUSED( aEvent ) );
void onSize( wxSizeEvent& aEvent );

Loading…
Cancel
Save