mirror of
https://github.com/glfw/glfw.git
synced 2024-11-10 00:51:47 +00:00
Win 32: Fix disabled cursor mode when connected over RDP
Fixes #1276 Based on PR #1279 by @Pokechu22 Co-authored-by: Pokechu22 <8334194+Pokechu22@users.noreply.github.com>
This commit is contained in:
parent
8e6c8d7eff
commit
c8521b7fda
@ -279,6 +279,8 @@ video tutorials.
|
|||||||
- Jonas Ådahl
|
- Jonas Ådahl
|
||||||
- Lasse Öörni
|
- Lasse Öörni
|
||||||
- Leonard König
|
- Leonard König
|
||||||
|
- Pokechu22
|
||||||
|
- Guillaume Lebrun
|
||||||
- All the unmentioned and anonymous contributors in the GLFW community, for bug
|
- All the unmentioned and anonymous contributors in the GLFW community, for bug
|
||||||
reports, patches, feedback, testing and encouragement
|
reports, patches, feedback, testing and encouragement
|
||||||
|
|
||||||
|
@ -236,6 +236,7 @@ information on what to include when reporting a bug.
|
|||||||
- [Win32] Bugfix: `glfwWaitEventsTimeout` did not return for some sent messages (#2408)
|
- [Win32] Bugfix: `glfwWaitEventsTimeout` did not return for some sent messages (#2408)
|
||||||
- [Win32] Bugfix: Fix pkg-config for dynamic library on Windows (#2386, #2420)
|
- [Win32] Bugfix: Fix pkg-config for dynamic library on Windows (#2386, #2420)
|
||||||
- [Win32] Bugfix: XInput could reportedly provide invalid DPad bit masks (#2291)
|
- [Win32] Bugfix: XInput could reportedly provide invalid DPad bit masks (#2291)
|
||||||
|
- [Win32] Bugfix: Disabled cursor mode doesn't work right when connected over RDP (#1276)
|
||||||
- [Win32] Bugfix: Rapid clipboard calls could fail due to Clipboard History
|
- [Win32] Bugfix: Rapid clipboard calls could fail due to Clipboard History
|
||||||
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
|
||||||
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
|
||||||
|
@ -430,6 +430,47 @@ static GLFWbool createHelperWindow(void)
|
|||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creates the blank cursor
|
||||||
|
//
|
||||||
|
static void createBlankCursor(void)
|
||||||
|
{
|
||||||
|
// HACK: Create a transparent cursor as using the NULL cursor breaks
|
||||||
|
// using SetCursorPos when connected over RDP
|
||||||
|
int cursorWidth = GetSystemMetrics(SM_CXCURSOR);
|
||||||
|
int cursorHeight = GetSystemMetrics(SM_CYCURSOR);
|
||||||
|
unsigned char* andMask = calloc(cursorWidth * cursorHeight / 8, sizeof(unsigned char));
|
||||||
|
unsigned char* xorMask = calloc(cursorWidth * cursorHeight / 8, sizeof(unsigned char));
|
||||||
|
|
||||||
|
if (andMask != NULL && xorMask != NULL) {
|
||||||
|
|
||||||
|
memset(andMask, 0xFF, (size_t)(cursorWidth * cursorHeight / 8));
|
||||||
|
|
||||||
|
// Cursor creation might fail, but that's fine as we get NULL in that case,
|
||||||
|
// which serves as an acceptable fallback blank cursor (other than on RDP)
|
||||||
|
_glfw.win32.blankCursor = CreateCursor(NULL, 0, 0, cursorWidth, cursorHeight, andMask, xorMask);
|
||||||
|
|
||||||
|
free(andMask);
|
||||||
|
free(xorMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize for remote sessions
|
||||||
|
//
|
||||||
|
static void initRemoteSession(void)
|
||||||
|
{
|
||||||
|
//Check if the current progress was started with Remote Desktop.
|
||||||
|
_glfw.win32.isRemoteSession = GetSystemMetrics(SM_REMOTESESSION) > 0;
|
||||||
|
|
||||||
|
// With Remote desktop, we need to create a blank cursor because of the cursor is Set to NULL
|
||||||
|
// if cannot be moved to center in capture mode. If not Remote Desktop win32.blankCursor stays NULL
|
||||||
|
// and will perform has before (normal).
|
||||||
|
if (_glfw.win32.isRemoteSession)
|
||||||
|
{
|
||||||
|
createBlankCursor();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
////// GLFW internal API //////
|
////// GLFW internal API //////
|
||||||
@ -699,12 +740,19 @@ int _glfwInitWin32(void)
|
|||||||
if (!createHelperWindow())
|
if (!createHelperWindow())
|
||||||
return GLFW_FALSE;
|
return GLFW_FALSE;
|
||||||
|
|
||||||
|
//Some hacks are needed to support Remote Desktop...
|
||||||
|
initRemoteSession();
|
||||||
|
|
||||||
_glfwPollMonitorsWin32();
|
_glfwPollMonitorsWin32();
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwTerminateWin32(void)
|
void _glfwTerminateWin32(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (_glfw.win32.blankCursor)
|
||||||
|
DestroyCursor(_glfw.win32.blankCursor);
|
||||||
|
|
||||||
if (_glfw.win32.deviceNotificationHandle)
|
if (_glfw.win32.deviceNotificationHandle)
|
||||||
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
|
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
|
||||||
|
|
||||||
|
@ -430,6 +430,7 @@ typedef struct _GLFWwindowWin32
|
|||||||
|
|
||||||
// The last received cursor position, regardless of source
|
// The last received cursor position, regardless of source
|
||||||
int lastCursorPosX, lastCursorPosY;
|
int lastCursorPosX, lastCursorPosY;
|
||||||
|
|
||||||
// The last received high surrogate when decoding pairs of UTF-16 messages
|
// The last received high surrogate when decoding pairs of UTF-16 messages
|
||||||
WCHAR highSurrogate;
|
WCHAR highSurrogate;
|
||||||
} _GLFWwindowWin32;
|
} _GLFWwindowWin32;
|
||||||
@ -457,6 +458,10 @@ typedef struct _GLFWlibraryWin32
|
|||||||
RAWINPUT* rawInput;
|
RAWINPUT* rawInput;
|
||||||
int rawInputSize;
|
int rawInputSize;
|
||||||
UINT mouseTrailSize;
|
UINT mouseTrailSize;
|
||||||
|
// Indicate if the process was started behind Remote Destop
|
||||||
|
BOOL isRemoteSession;
|
||||||
|
// An invisible cursor, needed for special cases (see WM_INPUT handler)
|
||||||
|
HCURSOR blankCursor;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
HINSTANCE instance;
|
HINSTANCE instance;
|
||||||
|
@ -232,7 +232,10 @@ static void updateCursorImage(_GLFWwindow* window)
|
|||||||
SetCursor(LoadCursorW(NULL, IDC_ARROW));
|
SetCursor(LoadCursorW(NULL, IDC_ARROW));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetCursor(NULL);
|
//Connected via Remote Desktop, NULL cursor will present SetCursorPos the move the cursor.
|
||||||
|
//using a blank cursor fix that.
|
||||||
|
//When not via Remote Desktop, win32.blankCursor should be NULL
|
||||||
|
SetCursor(_glfw.win32.blankCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the cursor clip rect to the window content area
|
// Sets the cursor clip rect to the window content area
|
||||||
@ -897,6 +900,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||||||
HRAWINPUT ri = (HRAWINPUT) lParam;
|
HRAWINPUT ri = (HRAWINPUT) lParam;
|
||||||
RAWINPUT* data = NULL;
|
RAWINPUT* data = NULL;
|
||||||
int dx, dy;
|
int dx, dy;
|
||||||
|
int width, height;
|
||||||
|
POINT pos;
|
||||||
|
|
||||||
if (_glfw.win32.disabledCursorWindow != window)
|
if (_glfw.win32.disabledCursorWindow != window)
|
||||||
break;
|
break;
|
||||||
@ -924,8 +929,29 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||||||
data = _glfw.win32.rawInput;
|
data = _glfw.win32.rawInput;
|
||||||
if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
|
if (data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE)
|
||||||
{
|
{
|
||||||
dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
|
if (_glfw.win32.isRemoteSession)
|
||||||
dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
|
{
|
||||||
|
//Remote Desktop Mode...
|
||||||
|
// As per https://github.com/Microsoft/DirectXTK/commit/ef56b63f3739381e451f7a5a5bd2c9779d2a7555
|
||||||
|
// MOUSE_MOVE_ABSOLUTE is a range from 0 through 65535, based on the screen size.
|
||||||
|
// As far as I can tell, absolute mode only occurs over RDP though.
|
||||||
|
width = GetSystemMetrics((data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) ? SM_CXVIRTUALSCREEN : SM_CXSCREEN);
|
||||||
|
height = GetSystemMetrics((data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) ? SM_CYVIRTUALSCREEN : SM_CYSCREEN);
|
||||||
|
|
||||||
|
pos.x = (int)((data->data.mouse.lLastX / 65535.0f) * width);
|
||||||
|
pos.y = (int)((data->data.mouse.lLastY / 65535.0f) * height);
|
||||||
|
ScreenToClient(window->win32.handle, &pos);
|
||||||
|
|
||||||
|
dx = pos.x - window->win32.lastCursorPosX;
|
||||||
|
dy = pos.y - window->win32.lastCursorPosY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Normal mode... We should have the right absolute coords in data.mouse
|
||||||
|
dx = data->data.mouse.lLastX - window->win32.lastCursorPosX;
|
||||||
|
dy = data->data.mouse.lLastY - window->win32.lastCursorPosY;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1432,11 +1458,13 @@ static int createNativeWindow(_GLFWwindow* window,
|
|||||||
window->win32.transparent = GLFW_TRUE;
|
window->win32.transparent = GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
|
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);
|
||||||
|
|
||||||
return GLFW_TRUE;
|
return GLFW_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window,
|
GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window,
|
||||||
const _GLFWwndconfig* wndconfig,
|
const _GLFWwndconfig* wndconfig,
|
||||||
const _GLFWctxconfig* ctxconfig,
|
const _GLFWctxconfig* ctxconfig,
|
||||||
@ -1525,6 +1553,7 @@ void _glfwDestroyWindowWin32(_GLFWwindow* window)
|
|||||||
|
|
||||||
if (window->win32.smallIcon)
|
if (window->win32.smallIcon)
|
||||||
DestroyIcon(window->win32.smallIcon);
|
DestroyIcon(window->win32.smallIcon);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title)
|
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title)
|
||||||
@ -2102,6 +2131,7 @@ void _glfwPollEventsWin32(void)
|
|||||||
|
|
||||||
// NOTE: Re-center the cursor only if it has moved since the last call,
|
// NOTE: Re-center the cursor only if it has moved since the last call,
|
||||||
// to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
|
// to avoid breaking glfwWaitEvents with WM_MOUSEMOVE
|
||||||
|
// The re-center is required in order to prevent the mouse cursor stopping at the edges of the screen.
|
||||||
if (window->win32.lastCursorPosX != width / 2 ||
|
if (window->win32.lastCursorPosX != width / 2 ||
|
||||||
window->win32.lastCursorPosY != height / 2)
|
window->win32.lastCursorPosY != height / 2)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user