Win32: Use existing cursor creation path

This commit is contained in:
Camilla Löwy 2024-01-29 18:03:47 +01:00
parent efffd492dd
commit 6c1e3fd84c
2 changed files with 31 additions and 49 deletions

View File

@ -430,46 +430,6 @@ 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 = _glfw_calloc(cursorWidth * cursorHeight / 8, sizeof(unsigned char));
unsigned char* xorMask = _glfw_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);
_glfw_free(andMask);
_glfw_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 //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -738,14 +698,8 @@ int _glfwInitWin32(void)
if (!createHelperWindow()) if (!createHelperWindow())
return GLFW_FALSE; return GLFW_FALSE;
//Some hacks are needed to support Remote Desktop... // Check if the current process was started via Remote Desktop
initRemoteSession(); _glfw.win32.isRemoteSession = GetSystemMetrics(SM_REMOTESESSION) > 0;
if (_glfw.win32.isRemoteSession && _glfw.win32.blankCursor == NULL )
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create blank cursor for remote session.");
return GLFW_FALSE;
}
_glfwPollMonitorsWin32(); _glfwPollMonitorsWin32();
return GLFW_TRUE; return GLFW_TRUE;
@ -754,7 +708,7 @@ int _glfwInitWin32(void)
void _glfwTerminateWin32(void) void _glfwTerminateWin32(void)
{ {
if (_glfw.win32.blankCursor) if (_glfw.win32.blankCursor)
DestroyCursor(_glfw.win32.blankCursor); DestroyIcon((HICON) _glfw.win32.blankCursor);
if (_glfw.win32.deviceNotificationHandle) if (_glfw.win32.deviceNotificationHandle)
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle); UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);

View File

@ -1314,6 +1314,34 @@ static int createNativeWindow(_GLFWwindow* window,
} }
} }
if (_glfw.win32.isRemoteSession)
{
// NOTE: On Remote Desktop, setting the cursor to NULL does not hide it
// HACK: Create a transparent cursor and always set that instead of NULL
// When not on Remote Desktop, this handle is NULL and normal hiding is used
if (!_glfw.win32.blankCursor)
{
const int cursorWidth = GetSystemMetrics(SM_CXCURSOR);
const int cursorHeight = GetSystemMetrics(SM_CYCURSOR);
unsigned char* cursorPixels = _glfw_calloc(cursorWidth * cursorHeight, 4);
if (!cursorPixels)
return GLFW_FALSE;
// NOTE: Windows checks whether the image is fully transparent and if so
// just ignores the alpha channel and makes the whole cursor opaque
// HACK: Make one pixel slightly less transparent
cursorPixels[3] = 1;
const GLFWimage cursorImage = { cursorWidth, cursorHeight, cursorPixels };
_glfw.win32.blankCursor = createIcon(&cursorImage, 0, 0, FALSE);
_glfw_free(cursorPixels);
if (!_glfw.win32.blankCursor)
return GLFW_FALSE;
}
}
if (window->monitor) if (window->monitor)
{ {
MONITORINFO mi = { sizeof(mi) }; MONITORINFO mi = { sizeof(mi) };