Skip to content

Commit 09f5317

Browse files
committed
Implement Cocoa mouse button state synchronization
1 parent adf638c commit 09f5317

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

Sources/SwiftSDL3/src/video/cocoa/SDL_cocoawindow.m

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,6 +1703,56 @@ - (BOOL)processHitTest:(NSEvent *)theEvent
17031703
return NO; // not a special area, carry on.
17041704
}
17051705

1706+
static void Cocoa_SyncMouseButtonState(SDL_Mouse *mouse, SDL_MouseID mouseID)
1707+
{
1708+
const NSUInteger actualButtons = [NSEvent pressedMouseButtons];
1709+
Uint32 actualButtonState = 0;
1710+
Uint32 sdlButtonState = 0;
1711+
1712+
// Convert NSEvent button mask to SDL button mask
1713+
if (actualButtons & (1 << 0)) {
1714+
actualButtonState |= SDL_BUTTON_LMASK;
1715+
}
1716+
if (actualButtons & (1 << 1)) {
1717+
actualButtonState |= SDL_BUTTON_RMASK;
1718+
}
1719+
if (actualButtons & (1 << 2)) {
1720+
actualButtonState |= SDL_BUTTON_MMASK;
1721+
}
1722+
if (actualButtons & (1 << 3)) {
1723+
actualButtonState |= SDL_BUTTON_X1MASK;
1724+
}
1725+
if (actualButtons & (1 << 4)) {
1726+
actualButtonState |= SDL_BUTTON_X2MASK;
1727+
}
1728+
1729+
// Get SDL's tracked button state
1730+
for (int i = 0; i < mouse->num_sources; ++i) {
1731+
if (mouseID == SDL_GLOBAL_MOUSE_ID || mouseID == SDL_TOUCH_MOUSEID) {
1732+
if (mouse->sources[i].mouseID != SDL_TOUCH_MOUSEID) {
1733+
sdlButtonState |= mouse->sources[i].buttonstate;
1734+
}
1735+
} else {
1736+
if (mouseID == mouse->sources[i].mouseID) {
1737+
sdlButtonState = mouse->sources[i].buttonstate;
1738+
break;
1739+
}
1740+
}
1741+
}
1742+
1743+
// Sync any buttons that are out of sync
1744+
for (Uint8 btn = SDL_BUTTON_LEFT; btn <= SDL_BUTTON_X2; ++btn) {
1745+
Uint32 buttonMask = SDL_BUTTON_MASK(btn);
1746+
bool sdlPressed = (sdlButtonState & buttonMask) != 0;
1747+
bool actuallyPressed = (actualButtonState & buttonMask) != 0;
1748+
1749+
if (sdlPressed != actuallyPressed) {
1750+
// Send synthetic event to sync state
1751+
SDL_SendMouseButton(0, mouse->focus, mouseID, btn, actuallyPressed);
1752+
}
1753+
}
1754+
}
1755+
17061756
static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_Window *window, Uint8 button, bool down)
17071757
{
17081758
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
@@ -1919,6 +1969,9 @@ - (void)mouseMoved:(NSEvent *)theEvent
19191969
}
19201970
}
19211971

1972+
// Sync button state with hardware before sending motion event
1973+
Cocoa_SyncMouseButtonState(mouse, mouseID);
1974+
19221975
SDL_SendMouseMotion(Cocoa_GetEventTimestamp([theEvent timestamp]), window, mouseID, false, x, y);
19231976
}
19241977

0 commit comments

Comments
 (0)