mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-31 14:29:14 +08:00
Base GCMouse raw input implementation
Fix duplicate button/scroll events when GCMouse active Fix duplicate events and add thread-safe atomic for GCMouse Fix GCMouse relative mode sync when connected after mode enabled Respect SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE in GCMouse handler Fix variable shadowing in GCMouse motion handler
This commit is contained in:
committed by
Sam Lantinga
parent
a48dee5ac1
commit
ad91384704
@@ -246,6 +246,22 @@ You are free to modify your Cocoa app with generally no consequence
|
|||||||
to SDL. You cannot, however, easily change the SDL window itself.
|
to SDL. You cannot, however, easily change the SDL window itself.
|
||||||
Functionality may be added in the future to help this.
|
Functionality may be added in the future to help this.
|
||||||
|
|
||||||
|
|
||||||
|
## Raw Mouse Input
|
||||||
|
|
||||||
|
On macOS 11.0 (Big Sur) and later, SDL uses the Game Controller framework's
|
||||||
|
GCMouse API to provide raw, unaccelerated mouse input in relative mode. This
|
||||||
|
is ideal for games and applications requiring precise 1:1 mouse movement.
|
||||||
|
|
||||||
|
On older macOS versions, SDL falls back to NSEvent-based mouse input, which
|
||||||
|
includes system mouse acceleration.
|
||||||
|
|
||||||
|
To use accelerated (system-scaled) mouse movement on macOS 11.0+, set the hint:
|
||||||
|
|
||||||
|
```c
|
||||||
|
SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_SYSTEM_SCALE, "1");
|
||||||
|
```
|
||||||
|
|
||||||
# Bug reports
|
# Bug reports
|
||||||
|
|
||||||
Bugs are tracked at [the GitHub issue tracker](https://github.com/libsdl-org/SDL/issues/).
|
Bugs are tracked at [the GitHub issue tracker](https://github.com/libsdl-org/SDL/issues/).
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ extern void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event);
|
|||||||
extern void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y);
|
extern void Cocoa_HandleMouseWarp(CGFloat x, CGFloat y);
|
||||||
extern void Cocoa_QuitMouse(SDL_VideoDevice *_this);
|
extern void Cocoa_QuitMouse(SDL_VideoDevice *_this);
|
||||||
|
|
||||||
|
extern void Cocoa_InitGCMouse(void);
|
||||||
|
extern bool Cocoa_GCMouseRelativeMode(void);
|
||||||
|
extern bool Cocoa_HasGCMouse(void);
|
||||||
|
extern void Cocoa_QuitGCMouse(void);
|
||||||
|
|
||||||
struct SDL_CursorData
|
struct SDL_CursorData
|
||||||
{
|
{
|
||||||
NSTimer *frameTimer;
|
NSTimer *frameTimer;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
|
|
||||||
|
#import <GameController/GameController.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define DEBUG_COCOAMOUSE
|
#define DEBUG_COCOAMOUSE
|
||||||
#endif
|
#endif
|
||||||
@@ -254,6 +256,219 @@ static SDL_Cursor *Cocoa_CreateDefaultCursor(void)
|
|||||||
return Cocoa_CreateSystemCursor(id);
|
return Cocoa_CreateSystemCursor(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GCMouse support for raw (unaccelerated) mouse input on macOS 11.0+
|
||||||
|
static id cocoa_mouse_connect_observer = nil;
|
||||||
|
static id cocoa_mouse_disconnect_observer = nil;
|
||||||
|
// Atomic for thread-safe access during high-frequency mouse input
|
||||||
|
static SDL_AtomicInt cocoa_gcmouse_relative_mode;
|
||||||
|
static bool cocoa_has_gcmouse = false;
|
||||||
|
static SDL_MouseWheelDirection cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL;
|
||||||
|
|
||||||
|
static void Cocoa_UpdateGCMouseScrollDirection(void)
|
||||||
|
{
|
||||||
|
Boolean keyExistsAndHasValidFormat = NO;
|
||||||
|
Boolean naturalScrollDirection = CFPreferencesGetAppBooleanValue(
|
||||||
|
CFSTR("com.apple.swipescrolldirection"),
|
||||||
|
kCFPreferencesAnyApplication,
|
||||||
|
&keyExistsAndHasValidFormat);
|
||||||
|
if (!keyExistsAndHasValidFormat) {
|
||||||
|
// Couldn't read the preference, assume natural scrolling direction
|
||||||
|
naturalScrollDirection = YES;
|
||||||
|
}
|
||||||
|
if (naturalScrollDirection) {
|
||||||
|
cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED;
|
||||||
|
} else {
|
||||||
|
cocoa_mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Cocoa_SetGCMouseRelativeMode(bool enabled)
|
||||||
|
{
|
||||||
|
SDL_SetAtomicInt(&cocoa_gcmouse_relative_mode, enabled ? 1 : 0);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Cocoa_OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button,
|
||||||
|
BOOL pressed)
|
||||||
|
{
|
||||||
|
Uint64 timestamp = SDL_GetTicksNS();
|
||||||
|
SDL_SendMouseButton(timestamp, SDL_GetMouseFocus(), mouseID, button,
|
||||||
|
pressed);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Cocoa_OnGCMouseConnected(GCMouse *mouse)
|
||||||
|
API_AVAILABLE(macos(11.0))
|
||||||
|
{
|
||||||
|
SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse;
|
||||||
|
|
||||||
|
SDL_AddMouse(mouseID, NULL);
|
||||||
|
cocoa_has_gcmouse = true;
|
||||||
|
|
||||||
|
// Sync with SDL's current relative mode state (may have been set before
|
||||||
|
// GCMouse connected)
|
||||||
|
SDL_Mouse *sdl_mouse = SDL_GetMouse();
|
||||||
|
if (sdl_mouse && sdl_mouse->relative_mode) {
|
||||||
|
SDL_SetAtomicInt(&cocoa_gcmouse_relative_mode, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse.mouseInput.leftButton.pressedChangedHandler =
|
||||||
|
^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||||
|
Cocoa_OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed);
|
||||||
|
};
|
||||||
|
mouse.mouseInput.middleButton.pressedChangedHandler =
|
||||||
|
^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||||
|
Cocoa_OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed);
|
||||||
|
};
|
||||||
|
mouse.mouseInput.rightButton.pressedChangedHandler =
|
||||||
|
^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||||
|
Cocoa_OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed);
|
||||||
|
};
|
||||||
|
|
||||||
|
int auxiliary_button = SDL_BUTTON_X1;
|
||||||
|
for (GCControllerButtonInput *btn in mouse.mouseInput.auxiliaryButtons) {
|
||||||
|
const int current_button = auxiliary_button;
|
||||||
|
btn.pressedChangedHandler =
|
||||||
|
^(GCControllerButtonInput *button, float value, BOOL pressed) {
|
||||||
|
Cocoa_OnGCMouseButtonChanged(mouseID, current_button, pressed);
|
||||||
|
};
|
||||||
|
++auxiliary_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse.mouseInput.mouseMovedHandler =
|
||||||
|
^(GCMouseInput *mouseInput, float deltaX, float deltaY) {
|
||||||
|
if (Cocoa_GCMouseRelativeMode()) {
|
||||||
|
// Skip raw input if user wants system-scaled (accelerated) deltas
|
||||||
|
SDL_Mouse *m = SDL_GetMouse();
|
||||||
|
if (m && m->enable_relative_system_scale) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Uint64 timestamp = SDL_GetTicksNS();
|
||||||
|
SDL_SendMouseMotion(timestamp, SDL_GetMouseFocus(), mouseID,
|
||||||
|
true, deltaX, -deltaY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mouse.mouseInput.scroll.valueChangedHandler =
|
||||||
|
^(GCControllerDirectionPad *dpad, float xValue, float yValue) {
|
||||||
|
Uint64 timestamp = SDL_GetTicksNS();
|
||||||
|
// Raw scroll values: vertical in first axis, horizontal in second.
|
||||||
|
// Vertical values are inverted compared to SDL conventions.
|
||||||
|
float vertical = -xValue;
|
||||||
|
float horizontal = yValue;
|
||||||
|
|
||||||
|
if (cocoa_mouse_scroll_direction == SDL_MOUSEWHEEL_FLIPPED) {
|
||||||
|
vertical = -vertical;
|
||||||
|
horizontal = -horizontal;
|
||||||
|
}
|
||||||
|
SDL_SendMouseWheel(timestamp, SDL_GetMouseFocus(), mouseID,
|
||||||
|
horizontal, vertical,
|
||||||
|
cocoa_mouse_scroll_direction);
|
||||||
|
};
|
||||||
|
Cocoa_UpdateGCMouseScrollDirection();
|
||||||
|
|
||||||
|
// Use high-priority queue for low-latency input
|
||||||
|
dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.mouse",
|
||||||
|
DISPATCH_QUEUE_SERIAL);
|
||||||
|
dispatch_set_target_queue(queue,
|
||||||
|
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
|
||||||
|
mouse.handlerQueue = queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Cocoa_OnGCMouseDisconnected(GCMouse *mouse)
|
||||||
|
API_AVAILABLE(macos(11.0))
|
||||||
|
{
|
||||||
|
SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse;
|
||||||
|
|
||||||
|
mouse.mouseInput.mouseMovedHandler = nil;
|
||||||
|
mouse.mouseInput.leftButton.pressedChangedHandler = nil;
|
||||||
|
mouse.mouseInput.middleButton.pressedChangedHandler = nil;
|
||||||
|
mouse.mouseInput.rightButton.pressedChangedHandler = nil;
|
||||||
|
mouse.mouseInput.scroll.valueChangedHandler = nil;
|
||||||
|
|
||||||
|
for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) {
|
||||||
|
button.pressedChangedHandler = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_RemoveMouse(mouseID);
|
||||||
|
|
||||||
|
// Check if any GCMouse devices remain
|
||||||
|
if (@available(macOS 11.0, *)) {
|
||||||
|
cocoa_has_gcmouse = ([GCMouse mice].count > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cocoa_InitGCMouse(void)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
if (@available(macOS 11.0, *)) {
|
||||||
|
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||||
|
|
||||||
|
cocoa_mouse_connect_observer = [center
|
||||||
|
addObserverForName:GCMouseDidConnectNotification
|
||||||
|
object:nil
|
||||||
|
queue:nil
|
||||||
|
usingBlock:^(NSNotification *note) {
|
||||||
|
GCMouse *mouse = note.object;
|
||||||
|
Cocoa_OnGCMouseConnected(mouse);
|
||||||
|
}];
|
||||||
|
|
||||||
|
cocoa_mouse_disconnect_observer = [center
|
||||||
|
addObserverForName:GCMouseDidDisconnectNotification
|
||||||
|
object:nil
|
||||||
|
queue:nil
|
||||||
|
usingBlock:^(NSNotification *note) {
|
||||||
|
GCMouse *mouse = note.object;
|
||||||
|
Cocoa_OnGCMouseDisconnected(mouse);
|
||||||
|
}];
|
||||||
|
|
||||||
|
// Enumerate already-connected mice
|
||||||
|
for (GCMouse *mouse in [GCMouse mice]) {
|
||||||
|
Cocoa_OnGCMouseConnected(mouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cocoa_GCMouseRelativeMode(void)
|
||||||
|
{
|
||||||
|
return SDL_GetAtomicInt(&cocoa_gcmouse_relative_mode) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cocoa_HasGCMouse(void)
|
||||||
|
{
|
||||||
|
return cocoa_has_gcmouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cocoa_QuitGCMouse(void)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
if (@available(macOS 11.0, *)) {
|
||||||
|
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
||||||
|
|
||||||
|
if (cocoa_mouse_connect_observer) {
|
||||||
|
[center removeObserver:cocoa_mouse_connect_observer
|
||||||
|
name:GCMouseDidConnectNotification
|
||||||
|
object:nil];
|
||||||
|
cocoa_mouse_connect_observer = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cocoa_mouse_disconnect_observer) {
|
||||||
|
[center removeObserver:cocoa_mouse_disconnect_observer
|
||||||
|
name:GCMouseDidDisconnectNotification
|
||||||
|
object:nil];
|
||||||
|
cocoa_mouse_disconnect_observer = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (GCMouse *mouse in [GCMouse mice]) {
|
||||||
|
Cocoa_OnGCMouseDisconnected(mouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
cocoa_has_gcmouse = false;
|
||||||
|
SDL_SetAtomicInt(&cocoa_gcmouse_relative_mode, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void Cocoa_FreeCursor(SDL_Cursor *cursor)
|
static void Cocoa_FreeCursor(SDL_Cursor *cursor)
|
||||||
{
|
{
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
@@ -360,19 +575,29 @@ static bool Cocoa_SetRelativeMouseMode(bool enabled)
|
|||||||
{
|
{
|
||||||
CGError result;
|
CGError result;
|
||||||
|
|
||||||
|
// Update GCMouse relative mode state if available
|
||||||
|
if (Cocoa_HasGCMouse()) {
|
||||||
|
Cocoa_SetGCMouseRelativeMode(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
SDL_Window *window = SDL_GetKeyboardFocus();
|
SDL_Window *window = SDL_GetKeyboardFocus();
|
||||||
if (window) {
|
if (window) {
|
||||||
/* We will re-apply the relative mode when the window finishes being moved,
|
/* We will re-apply the relative mode when the window finishes
|
||||||
* if it is being moved right now.
|
* being moved, if it is being moved right now.
|
||||||
*/
|
*/
|
||||||
SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
|
SDL_CocoaWindowData *data =
|
||||||
|
(__bridge SDL_CocoaWindowData *)window->internal;
|
||||||
if ([data.listener isMovingOrFocusClickPending]) {
|
if ([data.listener isMovingOrFocusClickPending]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the mouse isn't at the corner of the window, as this can confuse things if macOS thinks a window resize is happening on the first click.
|
// Make sure the mouse isn't at the corner of the window, as this
|
||||||
const CGPoint point = CGPointMake((float)(window->x + (window->w / 2)), (float)(window->y + (window->h / 2)));
|
// can confuse things if macOS thinks a window resize is happening
|
||||||
|
// on the first click.
|
||||||
|
const CGPoint point = CGPointMake(
|
||||||
|
(float)(window->x + (window->w / 2)),
|
||||||
|
(float)(window->y + (window->h / 2)));
|
||||||
Cocoa_HandleMouseWarp(point.x, point.y);
|
Cocoa_HandleMouseWarp(point.x, point.y);
|
||||||
CGWarpMouseCursorPosition(point);
|
CGWarpMouseCursorPosition(point);
|
||||||
}
|
}
|
||||||
@@ -590,6 +815,17 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When GCMouse is active in relative mode, it handles motion events
|
||||||
|
// directly with raw (unaccelerated) deltas. Skip NSEvent-based motion
|
||||||
|
// unless the user wants system-scaled (accelerated) input.
|
||||||
|
if (Cocoa_HasGCMouse() && Cocoa_GCMouseRelativeMode()) {
|
||||||
|
if (!mouse->enable_relative_system_scale) {
|
||||||
|
// GCMouse is providing raw input, skip NSEvent deltas
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// SYSTEM_SCALE is enabled: use NSEvent accelerated deltas instead
|
||||||
|
}
|
||||||
|
|
||||||
// Ignore events that aren't inside the client area (i.e. title bar.)
|
// Ignore events that aren't inside the client area (i.e. title bar.)
|
||||||
if ([event window]) {
|
if ([event window]) {
|
||||||
NSRect windowRect = [[[event window] contentView] frame];
|
NSRect windowRect = [[[event window] contentView] frame];
|
||||||
@@ -606,14 +842,21 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
|
|||||||
deltaX += (lastMoveX - data->lastWarpX);
|
deltaX += (lastMoveX - data->lastWarpX);
|
||||||
deltaY += ((videodata.mainDisplayHeight - lastMoveY) - data->lastWarpY);
|
deltaY += ((videodata.mainDisplayHeight - lastMoveY) - data->lastWarpY);
|
||||||
|
|
||||||
DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX], [event deltaY], deltaX, deltaY);
|
DLog("Motion was (%g, %g), offset to (%g, %g)", [event deltaX],
|
||||||
|
[event deltaY], deltaX, deltaY);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_SendMouseMotion(Cocoa_GetEventTimestamp([event timestamp]), mouse->focus, mouseID, true, deltaX, deltaY);
|
SDL_SendMouseMotion(Cocoa_GetEventTimestamp([event timestamp]),
|
||||||
|
mouse->focus, mouseID, true, deltaX, deltaY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
|
void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event)
|
||||||
{
|
{
|
||||||
|
// GCMouse handles scroll events directly, skip NSEvent path to avoid duplicates
|
||||||
|
if (Cocoa_HasGCMouse()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
|
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
|
||||||
SDL_MouseWheelDirection direction;
|
SDL_MouseWheelDirection direction;
|
||||||
CGFloat x, y;
|
CGFloat x, y;
|
||||||
|
|||||||
@@ -209,10 +209,14 @@ static bool Cocoa_VideoInit(SDL_VideoDevice *_this)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume we have a mouse and keyboard
|
// Initialize GCMouse for raw input on macOS 11.0+
|
||||||
// We could use GCMouse and GCKeyboard if we needed to, as is done in SDL_uikitevents.m
|
Cocoa_InitGCMouse();
|
||||||
|
|
||||||
|
// Add default keyboard and mouse if GCMouse didn't provide any
|
||||||
SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL);
|
SDL_AddKeyboard(SDL_DEFAULT_KEYBOARD_ID, NULL);
|
||||||
SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL);
|
if (!Cocoa_HasGCMouse()) {
|
||||||
|
SDL_AddMouse(SDL_DEFAULT_MOUSE_ID, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
data.allow_spaces = SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, true);
|
data.allow_spaces = SDL_GetHintBoolean(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, true);
|
||||||
data.trackpad_is_touch_only = SDL_GetHintBoolean(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, false);
|
data.trackpad_is_touch_only = SDL_GetHintBoolean(SDL_HINT_TRACKPAD_IS_TOUCH_ONLY, false);
|
||||||
@@ -233,6 +237,7 @@ void Cocoa_VideoQuit(SDL_VideoDevice *_this)
|
|||||||
SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
|
SDL_CocoaVideoData *data = (__bridge SDL_CocoaVideoData *)_this->internal;
|
||||||
Cocoa_QuitModes(_this);
|
Cocoa_QuitModes(_this);
|
||||||
Cocoa_QuitKeyboard(_this);
|
Cocoa_QuitKeyboard(_this);
|
||||||
|
Cocoa_QuitGCMouse();
|
||||||
Cocoa_QuitMouse(_this);
|
Cocoa_QuitMouse(_this);
|
||||||
Cocoa_QuitPen(_this);
|
Cocoa_QuitPen(_this);
|
||||||
SDL_DestroyMutex(data.swaplock);
|
SDL_DestroyMutex(data.swaplock);
|
||||||
|
|||||||
@@ -1717,6 +1717,11 @@ static NSCursor *Cocoa_GetDesiredCursor(void)
|
|||||||
|
|
||||||
static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_Window *window, Uint8 button, bool down)
|
static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL_Window *window, Uint8 button, bool down)
|
||||||
{
|
{
|
||||||
|
// GCMouse handles button events directly, skip NSEvent path to avoid duplicates
|
||||||
|
if (Cocoa_HasGCMouse()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
|
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
|
||||||
//const int clicks = (int)[theEvent clickCount];
|
//const int clicks = (int)[theEvent clickCount];
|
||||||
SDL_Window *focus = SDL_GetKeyboardFocus();
|
SDL_Window *focus = SDL_GetKeyboardFocus();
|
||||||
|
|||||||
Reference in New Issue
Block a user