mirror of https://github.com/encounter/SDL.git
windows: Fix handling of swapped mouse buttons
GetAsyncKeyState() and GetRawInputData() report the state of the physical buttons without applying the user's primary/secondary mouse button swap preference. Swap the buttons returned from these functions, so we expose a consistent view of the buttons to SDL callers. This new behavior also matches the behavior of macOS and X11 backends. See the Remarks section of the GetAsyncKeyState() function on MSDN.
This commit is contained in:
parent
771732ed32
commit
72379ba510
|
@ -244,8 +244,17 @@ WIN_ShouldIgnoreFocusClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePressed, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
|
WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, Uint32 mouseFlags, SDL_bool bSwapButtons, SDL_WindowData *data, Uint8 button, SDL_MouseID mouseID)
|
||||||
{
|
{
|
||||||
|
if (bSwapButtons) {
|
||||||
|
if (button == SDL_BUTTON_LEFT) {
|
||||||
|
button = SDL_BUTTON_RIGHT;
|
||||||
|
}
|
||||||
|
else if (button == SDL_BUTTON_RIGHT) {
|
||||||
|
button = SDL_BUTTON_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data->focus_click_pending & SDL_BUTTON(button)) {
|
if (data->focus_click_pending & SDL_BUTTON(button)) {
|
||||||
/* Ignore the button click for activation */
|
/* Ignore the button click for activation */
|
||||||
if (!bwParamMousePressed) {
|
if (!bwParamMousePressed) {
|
||||||
|
@ -257,9 +266,9 @@ WIN_CheckWParamMouseButton(SDL_bool bwParamMousePressed, SDL_bool bSDLMousePress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bwParamMousePressed && !bSDLMousePressed) {
|
if (bwParamMousePressed && !(mouseFlags & SDL_BUTTON(button))) {
|
||||||
SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
|
SDL_SendMouseButton(data->window, mouseID, SDL_PRESSED, button);
|
||||||
} else if (!bwParamMousePressed && bSDLMousePressed) {
|
} else if (!bwParamMousePressed && (mouseFlags & SDL_BUTTON(button))) {
|
||||||
SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
|
SDL_SendMouseButton(data->window, mouseID, SDL_RELEASED, button);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,11 +282,14 @@ WIN_CheckWParamMouseButtons(WPARAM wParam, SDL_WindowData *data, SDL_MouseID mou
|
||||||
{
|
{
|
||||||
if (wParam != data->mouse_button_flags) {
|
if (wParam != data->mouse_button_flags) {
|
||||||
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
|
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
|
||||||
WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, mouseID);
|
|
||||||
WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, mouseID);
|
/* WM_LBUTTONDOWN and friends handle button swapping for us. No need to check SM_SWAPBUTTON here. */
|
||||||
WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, mouseID);
|
WIN_CheckWParamMouseButton((wParam & MK_LBUTTON), mouseFlags, SDL_FALSE, data, SDL_BUTTON_LEFT, mouseID);
|
||||||
WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, mouseID);
|
WIN_CheckWParamMouseButton((wParam & MK_MBUTTON), mouseFlags, SDL_FALSE, data, SDL_BUTTON_MIDDLE, mouseID);
|
||||||
WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, mouseID);
|
WIN_CheckWParamMouseButton((wParam & MK_RBUTTON), mouseFlags, SDL_FALSE, data, SDL_BUTTON_RIGHT, mouseID);
|
||||||
|
WIN_CheckWParamMouseButton((wParam & MK_XBUTTON1), mouseFlags, SDL_FALSE, data, SDL_BUTTON_X1, mouseID);
|
||||||
|
WIN_CheckWParamMouseButton((wParam & MK_XBUTTON2), mouseFlags, SDL_FALSE, data, SDL_BUTTON_X2, mouseID);
|
||||||
|
|
||||||
data->mouse_button_flags = wParam;
|
data->mouse_button_flags = wParam;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,26 +299,27 @@ WIN_CheckRawMouseButtons(ULONG rawButtons, SDL_WindowData *data)
|
||||||
{
|
{
|
||||||
if (rawButtons != data->mouse_button_flags) {
|
if (rawButtons != data->mouse_button_flags) {
|
||||||
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
|
Uint32 mouseFlags = SDL_GetMouseState(NULL, NULL);
|
||||||
|
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
|
if ((rawButtons & RI_MOUSE_BUTTON_1_DOWN))
|
||||||
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
|
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_1_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
|
if ((rawButtons & RI_MOUSE_BUTTON_1_UP))
|
||||||
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
|
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_1_UP), mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
|
if ((rawButtons & RI_MOUSE_BUTTON_2_DOWN))
|
||||||
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
|
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_2_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
|
if ((rawButtons & RI_MOUSE_BUTTON_2_UP))
|
||||||
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
|
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_2_UP), mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
|
if ((rawButtons & RI_MOUSE_BUTTON_3_DOWN))
|
||||||
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
|
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_3_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
|
if ((rawButtons & RI_MOUSE_BUTTON_3_UP))
|
||||||
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
|
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_3_UP), mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
|
if ((rawButtons & RI_MOUSE_BUTTON_4_DOWN))
|
||||||
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
|
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_4_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
|
if ((rawButtons & RI_MOUSE_BUTTON_4_UP))
|
||||||
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
|
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_4_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
|
if ((rawButtons & RI_MOUSE_BUTTON_5_DOWN))
|
||||||
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
|
WIN_CheckWParamMouseButton((rawButtons & RI_MOUSE_BUTTON_5_DOWN), mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0);
|
||||||
if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
|
if ((rawButtons & RI_MOUSE_BUTTON_5_UP))
|
||||||
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
|
WIN_CheckWParamMouseButton(!(rawButtons & RI_MOUSE_BUTTON_5_UP), mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0);
|
||||||
data->mouse_button_flags = rawButtons;
|
data->mouse_button_flags = rawButtons;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -316,31 +329,33 @@ WIN_CheckAsyncMouseRelease(SDL_WindowData *data)
|
||||||
{
|
{
|
||||||
Uint32 mouseFlags;
|
Uint32 mouseFlags;
|
||||||
SHORT keyState;
|
SHORT keyState;
|
||||||
|
SDL_bool swapButtons;
|
||||||
|
|
||||||
/* mouse buttons may have changed state here, we need to resync them,
|
/* mouse buttons may have changed state here, we need to resync them,
|
||||||
but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also
|
but we will get a WM_MOUSEMOVE right away which will fix things up if in non raw mode also
|
||||||
*/
|
*/
|
||||||
mouseFlags = SDL_GetMouseState(NULL, NULL);
|
mouseFlags = SDL_GetMouseState(NULL, NULL);
|
||||||
|
swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||||
|
|
||||||
keyState = GetAsyncKeyState(VK_LBUTTON);
|
keyState = GetAsyncKeyState(VK_LBUTTON);
|
||||||
if (!(keyState & 0x8000)) {
|
if (!(keyState & 0x8000)) {
|
||||||
WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_LMASK), data, SDL_BUTTON_LEFT, 0);
|
WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_LEFT, 0);
|
||||||
}
|
}
|
||||||
keyState = GetAsyncKeyState(VK_RBUTTON);
|
keyState = GetAsyncKeyState(VK_RBUTTON);
|
||||||
if (!(keyState & 0x8000)) {
|
if (!(keyState & 0x8000)) {
|
||||||
WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_RMASK), data, SDL_BUTTON_RIGHT, 0);
|
WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_RIGHT, 0);
|
||||||
}
|
}
|
||||||
keyState = GetAsyncKeyState(VK_MBUTTON);
|
keyState = GetAsyncKeyState(VK_MBUTTON);
|
||||||
if (!(keyState & 0x8000)) {
|
if (!(keyState & 0x8000)) {
|
||||||
WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_MMASK), data, SDL_BUTTON_MIDDLE, 0);
|
WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_MIDDLE, 0);
|
||||||
}
|
}
|
||||||
keyState = GetAsyncKeyState(VK_XBUTTON1);
|
keyState = GetAsyncKeyState(VK_XBUTTON1);
|
||||||
if (!(keyState & 0x8000)) {
|
if (!(keyState & 0x8000)) {
|
||||||
WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X1MASK), data, SDL_BUTTON_X1, 0);
|
WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_X1, 0);
|
||||||
}
|
}
|
||||||
keyState = GetAsyncKeyState(VK_XBUTTON2);
|
keyState = GetAsyncKeyState(VK_XBUTTON2);
|
||||||
if (!(keyState & 0x8000)) {
|
if (!(keyState & 0x8000)) {
|
||||||
WIN_CheckWParamMouseButton(SDL_FALSE, (mouseFlags & SDL_BUTTON_X2MASK), data, SDL_BUTTON_X2, 0);
|
WIN_CheckWParamMouseButton(SDL_FALSE, mouseFlags, swapButtons, data, SDL_BUTTON_X2, 0);
|
||||||
}
|
}
|
||||||
data->mouse_button_flags = 0;
|
data->mouse_button_flags = 0;
|
||||||
}
|
}
|
||||||
|
@ -485,11 +500,12 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
if (LOWORD(wParam) == WA_CLICKACTIVE) {
|
||||||
|
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||||
if (GetAsyncKeyState(VK_LBUTTON)) {
|
if (GetAsyncKeyState(VK_LBUTTON)) {
|
||||||
data->focus_click_pending |= SDL_BUTTON_LMASK;
|
data->focus_click_pending |= !swapButtons ? SDL_BUTTON_LMASK : SDL_BUTTON_RMASK;
|
||||||
}
|
}
|
||||||
if (GetAsyncKeyState(VK_RBUTTON)) {
|
if (GetAsyncKeyState(VK_RBUTTON)) {
|
||||||
data->focus_click_pending |= SDL_BUTTON_RMASK;
|
data->focus_click_pending |= !swapButtons ? SDL_BUTTON_RMASK : SDL_BUTTON_LMASK;
|
||||||
}
|
}
|
||||||
if (GetAsyncKeyState(VK_MBUTTON)) {
|
if (GetAsyncKeyState(VK_MBUTTON)) {
|
||||||
data->focus_click_pending |= SDL_BUTTON_MMASK;
|
data->focus_click_pending |= SDL_BUTTON_MMASK;
|
||||||
|
@ -658,9 +674,11 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
|
||||||
/* if in the window, WM_MOUSEMOVE, etc, will cover it. */
|
/* if in the window, WM_MOUSEMOVE, etc, will cover it. */
|
||||||
if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) {
|
if(currentHnd != hwnd || pt.x < 0 || pt.y < 0 || pt.x > hwndRect.right || pt.y > hwndRect.right) {
|
||||||
|
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||||
|
|
||||||
SDL_SendMouseMotion(data->window, 0, 0, (int)pt.x, (int)pt.y);
|
SDL_SendMouseMotion(data->window, 0, 0, (int)pt.x, (int)pt.y);
|
||||||
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT);
|
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT);
|
||||||
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT);
|
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, !swapButtons ? SDL_BUTTON_RIGHT : SDL_BUTTON_LEFT);
|
||||||
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_MIDDLE);
|
||||||
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
|
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X1);
|
||||||
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
|
SDL_SendMouseButton(data->window, 0, GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_X2);
|
||||||
|
|
|
@ -276,12 +276,14 @@ WIN_GetGlobalMouseState(int *x, int *y)
|
||||||
{
|
{
|
||||||
Uint32 retval = 0;
|
Uint32 retval = 0;
|
||||||
POINT pt = { 0, 0 };
|
POINT pt = { 0, 0 };
|
||||||
|
SDL_bool swapButtons = GetSystemMetrics(SM_SWAPBUTTON) != 0;
|
||||||
|
|
||||||
GetCursorPos(&pt);
|
GetCursorPos(&pt);
|
||||||
*x = (int) pt.x;
|
*x = (int) pt.x;
|
||||||
*y = (int) pt.y;
|
*y = (int) pt.y;
|
||||||
|
|
||||||
retval |= GetAsyncKeyState(VK_LBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0;
|
retval |= GetAsyncKeyState(!swapButtons ? VK_LBUTTON : VK_RBUTTON) & 0x8000 ? SDL_BUTTON_LMASK : 0;
|
||||||
retval |= GetAsyncKeyState(VK_RBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0;
|
retval |= GetAsyncKeyState(!swapButtons ? VK_RBUTTON : VK_LBUTTON) & 0x8000 ? SDL_BUTTON_RMASK : 0;
|
||||||
retval |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0;
|
retval |= GetAsyncKeyState(VK_MBUTTON) & 0x8000 ? SDL_BUTTON_MMASK : 0;
|
||||||
retval |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0;
|
retval |= GetAsyncKeyState(VK_XBUTTON1) & 0x8000 ? SDL_BUTTON_X1MASK : 0;
|
||||||
retval |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0;
|
retval |= GetAsyncKeyState(VK_XBUTTON2) & 0x8000 ? SDL_BUTTON_X2MASK : 0;
|
||||||
|
|
Loading…
Reference in New Issue