Added ability to grab the cursor (w/ Windows impl.)
* When grabbed, the mouse cursor may not be moved outside a window's client frame. * Fullscreen windows always grab the mouse cursor. * The effect is only active while the SFML window is the active foreground window. * Right now this is only implemented for Windows. Signed-off-by: Marco Antognini <antognini.marco@gmail.com>
This commit is contained in:
parent
ba9383f25e
commit
f7dcc10a70
@ -348,6 +348,21 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void setMouseCursorVisible(bool visible);
|
void setMouseCursorVisible(bool visible);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor
|
||||||
|
///
|
||||||
|
/// If set, grabs the mouse cursor inside this window's client
|
||||||
|
/// area so it may no longer be moved outside its bounds.
|
||||||
|
/// Note that grabbing is only active while the window has
|
||||||
|
/// focus and calling this function for fullscreen windows
|
||||||
|
/// won't have any effect (fullscreen windows always grab the
|
||||||
|
/// cursor).
|
||||||
|
///
|
||||||
|
/// \param grabbed True to enable, false to disable
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void setMouseCursorGrabbed(bool grabbed);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable or disable automatic key-repeat
|
/// \brief Enable or disable automatic key-repeat
|
||||||
///
|
///
|
||||||
|
@ -313,6 +313,14 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setMouseCursorVisible(bool visible);
|
virtual void setMouseCursorVisible(bool visible);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor
|
||||||
|
///
|
||||||
|
/// \param grabbed True to enable, false to disable
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void setMouseCursorGrabbed(bool grabbed);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable or disable automatic key-repeat
|
/// \brief Enable or disable automatic key-repeat
|
||||||
///
|
///
|
||||||
|
@ -486,6 +486,13 @@ void WindowImplCocoa::setMouseCursorVisible(bool visible)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +96,12 @@ namespace sf {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(BOOL)isMouseInside;
|
-(BOOL)isMouseInside;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(void)setCursorGrabbed:(bool)grabbed;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Get window position
|
/// \brief Get window position
|
||||||
///
|
///
|
||||||
|
@ -366,7 +366,8 @@ m_hiddenCursor (0),
|
|||||||
m_keyRepeat (true),
|
m_keyRepeat (true),
|
||||||
m_previousSize (-1, -1),
|
m_previousSize (-1, -1),
|
||||||
m_useSizeHints (false),
|
m_useSizeHints (false),
|
||||||
m_fullscreen (false)
|
m_fullscreen (false),
|
||||||
|
m_cursorGrabbed (false)
|
||||||
{
|
{
|
||||||
// Open a connection with the X server
|
// Open a connection with the X server
|
||||||
m_display = OpenDisplay();
|
m_display = OpenDisplay();
|
||||||
@ -420,7 +421,8 @@ m_hiddenCursor (0),
|
|||||||
m_keyRepeat (true),
|
m_keyRepeat (true),
|
||||||
m_previousSize (-1, -1),
|
m_previousSize (-1, -1),
|
||||||
m_useSizeHints (false),
|
m_useSizeHints (false),
|
||||||
m_fullscreen ((style & Style::Fullscreen) != 0)
|
m_fullscreen ((style & Style::Fullscreen) != 0),
|
||||||
|
m_cursorGrabbed (m_fullscreen)
|
||||||
{
|
{
|
||||||
// Open a connection with the X server
|
// Open a connection with the X server
|
||||||
m_display = OpenDisplay();
|
m_display = OpenDisplay();
|
||||||
@ -952,6 +954,26 @@ void WindowImplX11::setMouseCursorVisible(bool visible)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplX11::setMouseCursorGrabbed(bool grabbed)
|
||||||
|
{
|
||||||
|
// This has no effect in fullscreen mode
|
||||||
|
if (m_fullscreen || (m_cursorGrabbed == grabbed))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (grabbed)
|
||||||
|
{
|
||||||
|
// TODO XGrabPointer(m_display, m_window, true, 0, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
|
||||||
|
m_cursorGrabbed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO XUngrabPointer(m_display, CurrentTime);
|
||||||
|
m_cursorGrabbed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplX11::setKeyRepeatEnabled(bool enabled)
|
void WindowImplX11::setKeyRepeatEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
@ -1661,6 +1683,10 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
|||||||
if (m_inputContext)
|
if (m_inputContext)
|
||||||
XSetICFocus(m_inputContext);
|
XSetICFocus(m_inputContext);
|
||||||
|
|
||||||
|
// Grab cursor
|
||||||
|
if (m_cursorGrabbed)
|
||||||
|
;// TODO XGrabPointer(m_display, m_window, true, 0, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::GainedFocus;
|
event.type = Event::GainedFocus;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
@ -1703,6 +1729,10 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
|||||||
if (m_inputContext)
|
if (m_inputContext)
|
||||||
XUnsetICFocus(m_inputContext);
|
XUnsetICFocus(m_inputContext);
|
||||||
|
|
||||||
|
// Release cursor
|
||||||
|
if (m_cursorGrabbed)
|
||||||
|
;// TODO XUngrabPointer(m_display, CurrentTime);
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::LostFocus;
|
event.type = Event::LostFocus;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
|
@ -147,6 +147,14 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setMouseCursorVisible(bool visible);
|
virtual void setMouseCursorVisible(bool visible);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor
|
||||||
|
///
|
||||||
|
/// \param grabbed True to enable, false to disable
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void setMouseCursorGrabbed(bool grabbed);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable or disable automatic key-repeat
|
/// \brief Enable or disable automatic key-repeat
|
||||||
///
|
///
|
||||||
@ -318,7 +326,8 @@ private:
|
|||||||
bool m_keyRepeat; ///< Is the KeyRepeat feature enabled?
|
bool m_keyRepeat; ///< Is the KeyRepeat feature enabled?
|
||||||
Vector2i m_previousSize; ///< Previous size of the window, to find if a ConfigureNotify event is a resize event (could be a move event only)
|
Vector2i m_previousSize; ///< Previous size of the window, to find if a ConfigureNotify event is a resize event (could be a move event only)
|
||||||
bool m_useSizeHints; ///< Is the size of the window fixed with size hints?
|
bool m_useSizeHints; ///< Is the size of the window fixed with size hints?
|
||||||
bool m_fullscreen; ///< Is window in fullscreen?
|
bool m_fullscreen; ///< Is the window in fullscreen?
|
||||||
|
bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
@ -132,7 +132,9 @@ 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)
|
m_mouseInside (false),
|
||||||
|
m_fullscreen (false),
|
||||||
|
m_cursorGrabbed (false)
|
||||||
{
|
{
|
||||||
// Set that this process is DPI aware and can handle DPI scaling
|
// Set that this process is DPI aware and can handle DPI scaling
|
||||||
setProcessDpiAware();
|
setProcessDpiAware();
|
||||||
@ -156,7 +158,9 @@ 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)
|
m_mouseInside (false),
|
||||||
|
m_fullscreen (style & Style::Fullscreen),
|
||||||
|
m_cursorGrabbed (m_fullscreen)
|
||||||
{
|
{
|
||||||
// Set that this process is DPI aware and can handle DPI scaling
|
// Set that this process is DPI aware and can handle DPI scaling
|
||||||
setProcessDpiAware();
|
setProcessDpiAware();
|
||||||
@ -187,8 +191,7 @@ m_mouseInside (false)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// In windowed mode, adjust width and height so that window will have the requested client area
|
// In windowed mode, adjust width and height so that window will have the requested client area
|
||||||
bool fullscreen = (style & Style::Fullscreen) != 0;
|
if (!m_fullscreen)
|
||||||
if (!fullscreen)
|
|
||||||
{
|
{
|
||||||
RECT rectangle = {0, 0, width, height};
|
RECT rectangle = {0, 0, width, height};
|
||||||
AdjustWindowRect(&rectangle, win32Style, false);
|
AdjustWindowRect(&rectangle, win32Style, false);
|
||||||
@ -204,7 +207,7 @@ m_mouseInside (false)
|
|||||||
setSize(Vector2u(mode.width, mode.height));
|
setSize(Vector2u(mode.width, mode.height));
|
||||||
|
|
||||||
// Switch to fullscreen if requested
|
// Switch to fullscreen if requested
|
||||||
if (fullscreen)
|
if (m_fullscreen)
|
||||||
switchToFullscreen(mode);
|
switchToFullscreen(mode);
|
||||||
|
|
||||||
// Increment window count
|
// Increment window count
|
||||||
@ -277,6 +280,9 @@ Vector2i WindowImplWin32::getPosition() const
|
|||||||
void WindowImplWin32::setPosition(const Vector2i& position)
|
void WindowImplWin32::setPosition(const Vector2i& position)
|
||||||
{
|
{
|
||||||
SetWindowPos(m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
SetWindowPos(m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
||||||
|
|
||||||
|
if(m_cursorGrabbed)
|
||||||
|
grabCursor(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -363,6 +369,14 @@ void WindowImplWin32::setMouseCursorVisible(bool visible)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplWin32::setMouseCursorGrabbed(bool grabbed)
|
||||||
|
{
|
||||||
|
m_cursorGrabbed = grabbed;
|
||||||
|
grabCursor(m_cursorGrabbed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
|
void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
@ -485,6 +499,23 @@ void WindowImplWin32::setTracking(bool track)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImplWin32::grabCursor(bool grabbed)
|
||||||
|
{
|
||||||
|
if (grabbed)
|
||||||
|
{
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(m_handle, &rect);
|
||||||
|
MapWindowPoints(m_handle, NULL, reinterpret_cast<LPPOINT>(&rect), 2);
|
||||||
|
ClipCursor(&rect);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ClipCursor(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
@ -536,6 +567,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
event.size.width = m_lastSize.x;
|
event.size.width = m_lastSize.x;
|
||||||
event.size.height = m_lastSize.y;
|
event.size.height = m_lastSize.y;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
|
|
||||||
|
// Restore/update cursor grabbing
|
||||||
|
grabCursor(m_cursorGrabbed);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -544,6 +578,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
{
|
{
|
||||||
m_resizing = true;
|
m_resizing = true;
|
||||||
|
grabCursor(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,6 +600,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
event.size.height = m_lastSize.y;
|
event.size.height = m_lastSize.y;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore/update cursor grabbing
|
||||||
|
grabCursor(m_cursorGrabbed);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,6 +620,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
// Gain focus event
|
// Gain focus event
|
||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
{
|
{
|
||||||
|
// Restore cursor grabbing
|
||||||
|
grabCursor(m_cursorGrabbed);
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::GainedFocus;
|
event.type = Event::GainedFocus;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
@ -591,6 +632,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
// Lost focus event
|
// Lost focus event
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
{
|
{
|
||||||
|
// Ungrab the cursor
|
||||||
|
grabCursor(false);
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::LostFocus;
|
event.type = Event::LostFocus;
|
||||||
pushEvent(event);
|
pushEvent(event);
|
||||||
|
@ -145,6 +145,14 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setMouseCursorVisible(bool visible);
|
virtual void setMouseCursorVisible(bool visible);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor
|
||||||
|
///
|
||||||
|
/// \param grabbed True to enable, false to disable
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void setMouseCursorGrabbed(bool grabbed);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable or disable automatic key-repeat
|
/// \brief Enable or disable automatic key-repeat
|
||||||
///
|
///
|
||||||
@ -216,6 +224,19 @@ private:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void setTracking(bool track);
|
void setTracking(bool track);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor
|
||||||
|
///
|
||||||
|
/// This is not to be confused with setMouseCursorGrabbed.
|
||||||
|
/// Here m_cursorGrabbed is not modified; it is used,
|
||||||
|
/// for example, to release the cursor when switching to
|
||||||
|
/// another application.
|
||||||
|
///
|
||||||
|
/// \param grabbed True to enable, false to disable
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void grabCursor(bool grabbed);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Convert a Win32 virtual key code to a SFML key code
|
/// \brief Convert a Win32 virtual key code to a SFML key code
|
||||||
///
|
///
|
||||||
@ -252,6 +273,8 @@ private:
|
|||||||
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?
|
bool m_mouseInside; ///< Mouse is inside the window?
|
||||||
|
bool m_fullscreen; ///< Is the window fullscreen?
|
||||||
|
bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace priv
|
} // namespace priv
|
||||||
|
@ -288,6 +288,14 @@ void Window::setMouseCursorVisible(bool visible)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void Window::setMouseCursorGrabbed(bool grabbed)
|
||||||
|
{
|
||||||
|
if (m_impl)
|
||||||
|
m_impl->setMouseCursorGrabbed(grabbed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Window::setKeyRepeatEnabled(bool enabled)
|
void Window::setKeyRepeatEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
|
@ -186,6 +186,14 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual void setMouseCursorVisible(bool visible) = 0;
|
virtual void setMouseCursorVisible(bool visible) = 0;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Grab or release the mouse cursor and keeps it from leaving
|
||||||
|
///
|
||||||
|
/// \param grabbed True to enable, false to disable
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
virtual void setMouseCursorGrabbed(bool grabbed) = 0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Enable or disable automatic key-repeat
|
/// \brief Enable or disable automatic key-repeat
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user