Add better backward compatibility when not remote desktop

This commit is contained in:
Hilderin 2023-12-08 07:47:50 -05:00
parent d3890d2e0e
commit 152e476adb
2 changed files with 100 additions and 19 deletions

View File

@ -431,6 +431,9 @@ 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;
// Indicate if the process was started behind Remote Destop
BOOL isRemoteSession;
// An invisible cursor, needed for special cases (see WM_INPUT handler) // An invisible cursor, needed for special cases (see WM_INPUT handler)
HCURSOR blankCursor; HCURSOR blankCursor;

View File

@ -236,6 +236,7 @@ static void updateCursorImage(_GLFWwindow* window)
else else
//Connected via Remote Desktop, NULL cursor will present SetCursorPos the move the cursor. //Connected via Remote Desktop, NULL cursor will present SetCursorPos the move the cursor.
//using a blank cursor fix that. //using a blank cursor fix that.
//When not via Remote Desktop, win32.blankCursor should be NULL
SetCursor(window->win32.blankCursor); SetCursor(window->win32.blankCursor);
} }
@ -428,6 +429,64 @@ static void createBlankCursor(_GLFWwindow* window)
} }
// Check if the session was started in Remote Desktop
// Reference: https://learn.microsoft.com/en-us/windows/win32/termserv/detecting-the-terminal-services-environment
static BOOL isCurrentRemoteSession()
{
BOOL fIsRemoteable = FALSE;
if (GetSystemMetrics(SM_REMOTESESSION))
{
fIsRemoteable = TRUE;
}
else
{
HKEY hRegKey = NULL;
LONG lResult;
lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\"),
0, // ulOptions
KEY_READ,
&hRegKey
);
if (lResult == ERROR_SUCCESS)
{
DWORD dwGlassSessionId;
DWORD cbGlassSessionId = sizeof(dwGlassSessionId);
DWORD dwType;
lResult = RegQueryValueEx(
hRegKey,
TEXT("GlassSessionId"),
NULL, // lpReserved
&dwType,
(BYTE*)&dwGlassSessionId,
&cbGlassSessionId
);
if (lResult == ERROR_SUCCESS)
{
DWORD dwCurrentSessionId;
if (ProcessIdToSessionId(GetCurrentProcessId(), &dwCurrentSessionId))
{
fIsRemoteable = (dwCurrentSessionId != dwGlassSessionId);
}
}
}
if (hRegKey)
{
RegCloseKey(hRegKey);
}
}
return fIsRemoteable;
}
// Retrieves and translates modifier keys // Retrieves and translates modifier keys
// //
static int getKeyMods(void) static int getKeyMods(void)
@ -957,26 +1016,36 @@ 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)
{ {
// As per https://github.com/Microsoft/DirectXTK/commit/ef56b63f3739381e451f7a5a5bd2c9779d2a7555 if (window->win32.isRemoteSession)
// 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. //Remote Desktop Mode...
width = GetSystemMetrics((data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); // As per https://github.com/Microsoft/DirectXTK/commit/ef56b63f3739381e451f7a5a5bd2c9779d2a7555
height = GetSystemMetrics((data->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); // 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.x = (int)((data->data.mouse.lLastX / 65535.0f) * width);
pos.y = (int)((data->data.mouse.lLastY / 65535.0f) * height); pos.y = (int)((data->data.mouse.lLastY / 65535.0f) * height);
ScreenToClient(window->win32.handle, &pos); ScreenToClient(window->win32.handle, &pos);
_glfwGetWindowSizeWin32(window, &window_width, &window_height); _glfwGetWindowSizeWin32(window, &window_width, &window_height);
// One other unfortunate thing is that re-centering the cursor will still fire an // One other unfortunate thing is that re-centering the cursor will still fire an
// input event; assume that any motion to the center is our re-centering and ignore it // input event; assume that any motion to the center is our re-centering and ignore it
if (pos.x == window_width / 2 && pos.y == window_height / 2) if (pos.x == window_width / 2 && pos.y == window_height / 2)
break; break;
dx = pos.x - window->win32.lastCursorPosX; dx = pos.x - window->win32.lastCursorPosX;
dy = pos.y - window->win32.lastCursorPosY; 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
@ -1484,7 +1553,16 @@ static int createNativeWindow(_GLFWwindow* window,
window->win32.transparent = GLFW_TRUE; window->win32.transparent = GLFW_TRUE;
} }
createBlankCursor(window); //Check if the current progress was started with Remote Desktop.
window->win32.isRemoteSession = isCurrentRemoteSession();
//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 (window->win32.isRemoteSession)
{
createBlankCursor(window);
}
_glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height); _glfwGetWindowSizeWin32(window, &window->win32.width, &window->win32.height);