Merge pull request #457 from MarioLiebisch/issue-437

Fixed mouse clicks not activating windows (Win32) (#437, #455)
This commit is contained in:
Laurent Gomila 2013-09-24 22:36:36 -07:00
commit cd84e84286
2 changed files with 88 additions and 27 deletions

View File

@ -73,7 +73,8 @@ m_icon (NULL),
m_keyRepeatEnabled(true), m_keyRepeatEnabled(true),
m_lastSize (0, 0), m_lastSize (0, 0),
m_resizing (false), m_resizing (false),
m_surrogate (0) m_surrogate (0),
m_mouseInside (false)
{ {
if (m_handle) if (m_handle)
{ {
@ -93,7 +94,8 @@ m_icon (NULL),
m_keyRepeatEnabled(true), m_keyRepeatEnabled(true),
m_lastSize (mode.width, mode.height), m_lastSize (mode.width, mode.height),
m_resizing (false), m_resizing (false),
m_surrogate (0) m_surrogate (0),
m_mouseInside (false)
{ {
// Register the window class at first call // Register the window class at first call
if (windowCount == 0) if (windowCount == 0)
@ -405,6 +407,24 @@ void WindowImplWin32::cleanup()
// Unhide the mouse cursor (in case it was hidden) // Unhide the mouse cursor (in case it was hidden)
setMouseCursorVisible(true); setMouseCursorVisible(true);
// No longer track the cursor
setTracking(false);
// No longer capture the cursor
ReleaseCapture();
}
////////////////////////////////////////////////////////////
void WindowImplWin32::setTracking(bool track)
{
TRACKMOUSEEVENT mouseEvent;
mouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
mouseEvent.dwFlags = track ? TME_LEAVE : TME_CANCEL;
mouseEvent.hwndTrack = m_handle;
mouseEvent.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&mouseEvent);
} }
@ -464,14 +484,14 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
} }
// Start resizing // Start resizing
case WM_ENTERSIZEMOVE: case WM_ENTERSIZEMOVE :
{ {
m_resizing = true; m_resizing = true;
break; break;
} }
// Stop resizing // Stop resizing
case WM_EXITSIZEMOVE: case WM_EXITSIZEMOVE :
{ {
m_resizing = false; m_resizing = false;
@ -536,7 +556,6 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
} }
else else
{ {
// Check if it is the second part of a surrogate pair, or a regular character // Check if it is the second part of a surrogate pair, or a regular character
if ((character >= 0xDC00) && (character <= 0xDFFF)) if ((character >= 0xDC00) && (character <= 0xDFFF))
{ {
@ -703,6 +722,22 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
break; break;
} }
// Mouse leave event
case WM_MOUSELEAVE :
{
// Avoid this firing a second time in case the cursor is dragged outside
if (m_mouseInside)
{
m_mouseInside = false;
// Generate a MouseLeft event
Event event;
event.type = Event::MouseLeft;
pushEvent(event);
}
break;
}
// Mouse move event // Mouse move event
case WM_MOUSEMOVE : case WM_MOUSEMOVE :
{ {
@ -714,43 +749,60 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
RECT area; RECT area;
GetClientRect(m_handle, &area); GetClientRect(m_handle, &area);
// Check the mouse position against the window // Capture the mouse in case the user wants to drag it outside
if ((wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) == 0)
{
// Only release the capture if we really have it
if (GetCapture() == m_handle)
ReleaseCapture();
}
else if (GetCapture() != m_handle)
{
// Set the capture to continue receiving mouse events
SetCapture(m_handle);
}
// If the cursor is outside the client area...
if ((x < area.left) || (x > area.right) || (y < area.top) || (y > area.bottom)) if ((x < area.left) || (x > area.right) || (y < area.top) || (y > area.bottom))
{ {
// Mouse is outside // and it used to be inside, the mouse left it.
if (m_mouseInside)
{
m_mouseInside = false;
// Release the mouse capture // No longer care for the mouse leaving the window
ReleaseCapture(); setTracking(false);
// Generate a MouseLeft event // Generate a MouseLeft event
Event event; Event event;
event.type = Event::MouseLeft; event.type = Event::MouseLeft;
pushEvent(event); pushEvent(event);
}
} }
else else
{ {
// Mouse is inside // and vice-versa
if (GetCapture() != m_handle) if (!m_mouseInside)
{ {
// Mouse was previously outside the window m_mouseInside = true;
// Capture the mouse // Look for the mouse leaving the window
SetCapture(m_handle); setTracking(true);
// Generate a MouseEntered event // Generate a MouseEntered event
Event event; Event event;
event.type = Event::MouseEntered; event.type = Event::MouseEntered;
pushEvent(event); pushEvent(event);
} }
// Generate a MouseMove event
Event event;
event.type = Event::MouseMoved;
event.mouseMove.x = x;
event.mouseMove.y = y;
pushEvent(event);
break;
} }
// Generate a MouseMove event
Event event;
event.type = Event::MouseMoved;
event.mouseMove.x = x;
event.mouseMove.y = y;
pushEvent(event);
break;
} }
} }
} }

View File

@ -193,6 +193,14 @@ private :
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void processEvent(UINT message, WPARAM wParam, LPARAM lParam); void processEvent(UINT message, WPARAM wParam, LPARAM lParam);
////////////////////////////////////////////////////////////
/// \brief Enables or disables tracking for the mouse cursor leaving the window
///
/// \param track True to enable, false to disable
///
////////////////////////////////////////////////////////////
void setTracking(bool track);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Convert a Win32 virtual key code to a SFML key code /// \brief Convert a Win32 virtual key code to a SFML key code
/// ///
@ -237,8 +245,9 @@ private :
HICON m_icon; ///< Custom icon assigned to the window HICON m_icon; ///< Custom icon assigned to the window
bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events
Vector2u m_lastSize; ///< The last handled size of the window Vector2u m_lastSize; ///< The last handled size of the window
bool m_resizing; ///< Is the window being resized ? bool m_resizing; ///< Is the window being resized?
Uint16 m_surrogate; ///< First half of the surrogate pair, in case we're receiving a Unicode character in two events Uint16 m_surrogate; ///< First half of the surrogate pair, in case we're receiving a Unicode character in two events
bool m_mouseInside; ///< Mouse is inside the window?
}; };
} // namespace priv } // namespace priv