mirror of
https://github.com/SFML/SFML.git
synced 2025-02-19 06:39:59 +08:00
Fix the cursor not always grabbed again correctly after a focus gain
This commit is contained in:
parent
6f3273b7a6
commit
61526628d1
@ -34,6 +34,7 @@
|
|||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#include <SFML/System/Mutex.hpp>
|
#include <SFML/System/Mutex.hpp>
|
||||||
#include <SFML/System/Lock.hpp>
|
#include <SFML/System/Lock.hpp>
|
||||||
|
#include <SFML/System/Sleep.hpp>
|
||||||
#include <xcb/xcb_image.h>
|
#include <xcb/xcb_image.h>
|
||||||
#include <xcb/randr.h>
|
#include <xcb/randr.h>
|
||||||
#include <X11/Xlibint.h>
|
#include <X11/Xlibint.h>
|
||||||
@ -72,6 +73,8 @@ namespace
|
|||||||
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
|
||||||
XCB_EVENT_MASK_VISIBILITY_CHANGE;
|
XCB_EVENT_MASK_VISIBILITY_CHANGE;
|
||||||
|
|
||||||
|
static const unsigned int maxTrialsCount = 5;
|
||||||
|
|
||||||
// Filter the events received by windows (only allow those matching a specific window)
|
// Filter the events received by windows (only allow those matching a specific window)
|
||||||
Bool checkEvent(::Display*, XEvent* event, XPointer userData)
|
Bool checkEvent(::Display*, XEvent* event, XPointer userData)
|
||||||
{
|
{
|
||||||
@ -978,32 +981,39 @@ void WindowImplX11::setMouseCursorGrabbed(bool grabbed)
|
|||||||
|
|
||||||
if (grabbed)
|
if (grabbed)
|
||||||
{
|
{
|
||||||
sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
// Try multiple times to grab the cursor
|
||||||
|
for (unsigned int trial = 0; trial < maxTrialsCount; ++trial)
|
||||||
|
{
|
||||||
|
sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
||||||
|
|
||||||
sf::priv::ScopedXcbPtr<xcb_grab_pointer_reply_t> grabPointerReply(xcb_grab_pointer_reply(
|
sf::priv::ScopedXcbPtr<xcb_grab_pointer_reply_t> grabPointerReply(xcb_grab_pointer_reply(
|
||||||
m_connection,
|
|
||||||
xcb_grab_pointer(
|
|
||||||
m_connection,
|
m_connection,
|
||||||
true,
|
xcb_grab_pointer(
|
||||||
m_window,
|
m_connection,
|
||||||
XCB_NONE,
|
true,
|
||||||
XCB_GRAB_MODE_ASYNC,
|
m_window,
|
||||||
XCB_GRAB_MODE_ASYNC,
|
XCB_NONE,
|
||||||
m_window,
|
XCB_GRAB_MODE_ASYNC,
|
||||||
XCB_NONE,
|
XCB_GRAB_MODE_ASYNC,
|
||||||
XCB_CURRENT_TIME
|
m_window,
|
||||||
),
|
XCB_NONE,
|
||||||
&error
|
XCB_CURRENT_TIME
|
||||||
));
|
),
|
||||||
|
&error
|
||||||
|
));
|
||||||
|
|
||||||
if (!error && grabPointerReply && (grabPointerReply->status == XCB_GRAB_STATUS_SUCCESS))
|
if (!error && grabPointerReply && (grabPointerReply->status == XCB_GRAB_STATUS_SUCCESS))
|
||||||
{
|
{
|
||||||
m_cursorGrabbed = true;
|
m_cursorGrabbed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The cursor grab failed, trying again after a small sleep
|
||||||
|
sf::sleep(sf::milliseconds(50));
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
if (!m_cursorGrabbed)
|
||||||
err() << "Failed to grab mouse cursor" << std::endl;
|
err() << "Failed to grab mouse cursor" << std::endl;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1739,30 +1749,39 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
|||||||
// Grab cursor
|
// Grab cursor
|
||||||
if (m_cursorGrabbed)
|
if (m_cursorGrabbed)
|
||||||
{
|
{
|
||||||
sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
// Try multiple times to grab the cursor
|
||||||
|
for (unsigned int trial = 0; trial < maxTrialsCount; ++trial)
|
||||||
sf::priv::ScopedXcbPtr<xcb_grab_pointer_reply_t> grabPointerReply(xcb_grab_pointer_reply(
|
|
||||||
m_connection,
|
|
||||||
xcb_grab_pointer(
|
|
||||||
m_connection,
|
|
||||||
true,
|
|
||||||
m_window,
|
|
||||||
XCB_NONE,
|
|
||||||
XCB_GRAB_MODE_ASYNC,
|
|
||||||
XCB_GRAB_MODE_ASYNC,
|
|
||||||
m_window,
|
|
||||||
XCB_NONE,
|
|
||||||
XCB_CURRENT_TIME
|
|
||||||
),
|
|
||||||
&error
|
|
||||||
));
|
|
||||||
|
|
||||||
if (error || !grabPointerReply || (grabPointerReply->status != XCB_GRAB_STATUS_SUCCESS))
|
|
||||||
{
|
{
|
||||||
err() << "Failed to grab mouse cursor" << std::endl;
|
sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
|
||||||
|
|
||||||
m_cursorGrabbed = false;
|
sf::priv::ScopedXcbPtr<xcb_grab_pointer_reply_t> grabPointerReply(xcb_grab_pointer_reply(
|
||||||
|
m_connection,
|
||||||
|
xcb_grab_pointer(
|
||||||
|
m_connection,
|
||||||
|
true,
|
||||||
|
m_window,
|
||||||
|
XCB_NONE,
|
||||||
|
XCB_GRAB_MODE_ASYNC,
|
||||||
|
XCB_GRAB_MODE_ASYNC,
|
||||||
|
m_window,
|
||||||
|
XCB_NONE,
|
||||||
|
XCB_CURRENT_TIME
|
||||||
|
),
|
||||||
|
&error
|
||||||
|
));
|
||||||
|
|
||||||
|
if (!error && grabPointerReply && (grabPointerReply->status == XCB_GRAB_STATUS_SUCCESS))
|
||||||
|
{
|
||||||
|
m_cursorGrabbed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The cursor grab failed, trying again after a small sleep
|
||||||
|
sf::sleep(sf::milliseconds(50));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_cursorGrabbed)
|
||||||
|
err() << "Failed to grab mouse cursor" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user