cocoa: clear mouse focus based on NSEventTypeMouseExited events (#11991)
We can't directly set the mouse focus since we may get spammed by entered/exited events, but we can process the current focus later in the mouseMoved handler in line with the mouse motion event sequence. Fixes https://github.com/libsdl-org/SDL/issues/8188
This commit is contained in:
parent
5f4696ce63
commit
ea642fe9ff
4 changed files with 31 additions and 6 deletions
|
@ -76,6 +76,8 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
||||||
case NSEventTypeOtherMouseDragged: // usually middle mouse dragged
|
case NSEventTypeOtherMouseDragged: // usually middle mouse dragged
|
||||||
case NSEventTypeMouseMoved:
|
case NSEventTypeMouseMoved:
|
||||||
case NSEventTypeScrollWheel:
|
case NSEventTypeScrollWheel:
|
||||||
|
case NSEventTypeMouseEntered:
|
||||||
|
case NSEventTypeMouseExited:
|
||||||
Cocoa_HandleMouseEvent(_this, theEvent);
|
Cocoa_HandleMouseEvent(_this, theEvent);
|
||||||
break;
|
break;
|
||||||
case NSEventTypeKeyDown:
|
case NSEventTypeKeyDown:
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "SDL_cocoavideo.h"
|
#include "SDL_cocoavideo.h"
|
||||||
|
|
||||||
extern bool Cocoa_InitMouse(SDL_VideoDevice *_this);
|
extern bool Cocoa_InitMouse(SDL_VideoDevice *_this);
|
||||||
|
extern NSWindow *Cocoa_GetMouseFocus();
|
||||||
extern void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event);
|
extern void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event);
|
||||||
extern void Cocoa_HandleMouseWheel(SDL_Window *window, NSEvent *event);
|
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);
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
|
|
||||||
#include "../../events/SDL_mouse_c.h"
|
#include "../../events/SDL_mouse_c.h"
|
||||||
|
|
||||||
// #define DEBUG_COCOAMOUSE
|
#if 0
|
||||||
|
#define DEBUG_COCOAMOUSE
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_COCOAMOUSE
|
#ifdef DEBUG_COCOAMOUSE
|
||||||
#define DLog(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
|
#define DLog(fmt, ...) printf("%s: " fmt "\n", __func__, ##__VA_ARGS__)
|
||||||
|
@ -230,10 +232,10 @@ static bool Cocoa_ShowCursor(SDL_Cursor *cursor)
|
||||||
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
SDL_VideoDevice *device = SDL_GetVideoDevice();
|
||||||
SDL_Window *window = (device ? device->windows : NULL);
|
SDL_Window *window = (device ? device->windows : NULL);
|
||||||
for (; window != NULL; window = window->next) {
|
for (; window != NULL; window = window->next) {
|
||||||
SDL_CocoaWindowData *internal = (__bridge SDL_CocoaWindowData *)window->internal;
|
SDL_CocoaWindowData *data = (__bridge SDL_CocoaWindowData *)window->internal;
|
||||||
if (internal) {
|
if (data) {
|
||||||
[internal.nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
|
[data.nswindow performSelectorOnMainThread:@selector(invalidateCursorRectsForView:)
|
||||||
withObject:[internal.nswindow contentView]
|
withObject:[data.nswindow contentView]
|
||||||
waitUntilDone:NO];
|
waitUntilDone:NO];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -428,6 +430,13 @@ static void Cocoa_HandleTitleButtonEvent(SDL_VideoDevice *_this, NSEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NSWindow *Cocoa_MouseFocus;
|
||||||
|
|
||||||
|
NSWindow *Cocoa_GetMouseFocus()
|
||||||
|
{
|
||||||
|
return Cocoa_MouseFocus;
|
||||||
|
}
|
||||||
|
|
||||||
void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
|
void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
|
||||||
{
|
{
|
||||||
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
|
SDL_MouseID mouseID = SDL_DEFAULT_MOUSE_ID;
|
||||||
|
@ -437,7 +446,14 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
|
||||||
CGFloat lastMoveX, lastMoveY;
|
CGFloat lastMoveX, lastMoveY;
|
||||||
float deltaX, deltaY;
|
float deltaX, deltaY;
|
||||||
bool seenWarp;
|
bool seenWarp;
|
||||||
|
|
||||||
switch ([event type]) {
|
switch ([event type]) {
|
||||||
|
case NSEventTypeMouseEntered:
|
||||||
|
Cocoa_MouseFocus = [event window];
|
||||||
|
return;
|
||||||
|
case NSEventTypeMouseExited:
|
||||||
|
Cocoa_MouseFocus = NULL;
|
||||||
|
return;
|
||||||
case NSEventTypeMouseMoved:
|
case NSEventTypeMouseMoved:
|
||||||
case NSEventTypeLeftMouseDragged:
|
case NSEventTypeLeftMouseDragged:
|
||||||
case NSEventTypeRightMouseDragged:
|
case NSEventTypeRightMouseDragged:
|
||||||
|
|
|
@ -1776,6 +1776,12 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Cocoa_GetMouseFocus()) {
|
||||||
|
// The mouse is no longer over any window in the application
|
||||||
|
SDL_SetMouseFocus(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window = _data.window;
|
window = _data.window;
|
||||||
contentView = _data.sdlContentView;
|
contentView = _data.sdlContentView;
|
||||||
point = [theEvent locationInWindow];
|
point = [theEvent locationInWindow];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue