From b24e4a427e5504580f81f7cce569b9f5a87c51a6 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 3 Dec 2009 08:33:39 +0000 Subject: [PATCH] Fixed mouse events for fullscreen windows on Mac OS X --- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 2 + src/video/cocoa/SDL_cocoaevents.m | 14 ++++++ src/video/cocoa/SDL_cocoamouse.h | 1 + src/video/cocoa/SDL_cocoamouse.m | 82 +++++++++++++++++++++++++++++++ src/video/cocoa/SDL_cocoawindow.m | 13 +---- 6 files changed, 102 insertions(+), 11 deletions(-) diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index eb8dc52ed..2e55e5f2a 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -171,6 +171,7 @@ struct SDL_VideoDisplay int num_windows; SDL_Window *windows; + SDL_Window *fullscreen_window; SDL_Renderer *current_renderer; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index bb6feb54f..bd3a0f8ea 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -768,6 +768,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt) SDL_DisplayMode fullscreen_mode; if (SDL_GetWindowDisplayMode(window->id, &fullscreen_mode) == 0) { SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); + display->fullscreen_window = window; return; } } @@ -775,6 +776,7 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt) /* Nope, restore the desktop mode */ SDL_SetDisplayModeForDisplay(display, NULL); + display->fullscreen_window = NULL; } int diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index 4a74de08b..dfc00c6e6 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -187,6 +187,20 @@ - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sende break; } switch ([event type]) { + case NSLeftMouseDown: + case NSOtherMouseDown: + case NSRightMouseDown: + case NSLeftMouseUp: + case NSOtherMouseUp: + case NSRightMouseUp: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: /* usually middle mouse dragged */ + case NSMouseMoved: + Cocoa_HandleMouseEvent(_this, event); + /* Pass through to NSApp to make sure everything stays in sync */ + [NSApp sendEvent:event]; + break; case NSKeyDown: case NSKeyUp: case NSFlagsChanged: diff --git a/src/video/cocoa/SDL_cocoamouse.h b/src/video/cocoa/SDL_cocoamouse.h index 9700fc093..e19eeadbf 100644 --- a/src/video/cocoa/SDL_cocoamouse.h +++ b/src/video/cocoa/SDL_cocoamouse.h @@ -25,6 +25,7 @@ #define _SDL_cocoamouse_h extern void Cocoa_InitMouse(_THIS); +extern void Cocoa_HandleMouseEvent(_THIS, NSEvent * event); extern void Cocoa_QuitMouse(_THIS); #endif /* _SDL_cocoamouse_h */ diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m index be2f87cb8..c6c4b5920 100644 --- a/src/video/cocoa/SDL_cocoamouse.m +++ b/src/video/cocoa/SDL_cocoamouse.m @@ -21,6 +21,7 @@ */ #include "SDL_config.h" +#include "SDL_events.h" #include "SDL_cocoavideo.h" #include "../../events/SDL_mouse_c.h" @@ -35,6 +36,87 @@ data->mouse = SDL_AddMouse(&mouse, "Mouse", 0, 0, 1); } +static int +ConvertMouseButtonToSDL(int button) +{ + switch (button) + { + case 0: + return(SDL_BUTTON_LEFT); /* 1 */ + case 1: + return(SDL_BUTTON_RIGHT); /* 3 */ + case 2: + return(SDL_BUTTON_MIDDLE); /* 2 */ + } + return button; +} + +void +Cocoa_HandleMouseEvent(_THIS, NSEvent *event) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + SDL_Mouse *mouse = SDL_GetMouse(data->mouse); + int i; + NSPoint point; + SDL_Window *window; + + /* See if there are any fullscreen windows that might handle this event */ + window = NULL; + for (i = 0; i < _this->num_displays; ++i) { + SDL_VideoDisplay *display = &_this->displays[i]; + SDL_Window *candidate = display->fullscreen_window; + + if (candidate) { + SDL_DisplayData *displaydata = (SDL_DisplayData *)display->driverdata; + NSRect rect = CGDisplayBounds(displaydata->display); + + point = [NSEvent mouseLocation]; + point.x = point.x - rect.origin.x; + point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - rect.origin.y; + if (point.x < 0 || point.x >= candidate->w || + point.y < 0 || point.y >= candidate->h) { + /* The mouse is out of this fullscreen display */ + if (mouse->focus == candidate->id) { + SDL_SetMouseFocus(data->mouse, 0); + } + } else { + /* This is it! */ + window = candidate; + break; + } + } + } + if (!window) { + return; + } + + /* Set the focus appropriately */ + if (mouse->focus != window->id) { + SDL_SetMouseFocus(data->mouse, window->id); + } + + switch ([event type]) { + case NSLeftMouseDown: + case NSOtherMouseDown: + case NSRightMouseDown: + SDL_SendMouseButton(data->mouse, SDL_PRESSED, ConvertMouseButtonToSDL([event buttonNumber])); + break; + case NSLeftMouseUp: + case NSOtherMouseUp: + case NSRightMouseUp: + SDL_SendMouseButton(data->mouse, SDL_RELEASED, ConvertMouseButtonToSDL([event buttonNumber])); + break; + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: /* usually middle mouse dragged */ + case NSMouseMoved: + SDL_SendMouseMotion(data->mouse, 0, (int)point.x, (int)point.y, 0); + break; + default: /* just to avoid compiler warnings */ + break; + } +} + void Cocoa_QuitMouse(_THIS) { diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 5bd068579..2cb454877 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -235,17 +235,8 @@ - (void)mouseMoved:(NSEvent *)theEvent index = _data->videodata->mouse; mouse = SDL_GetMouse(index); - - point = [NSEvent mouseLocation]; - if ( (window->flags & SDL_WINDOW_FULLSCREEN) ) { - NSRect rect = CGDisplayBounds(_data->display); - - point.x = point.x - rect.origin.x; - point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - rect.origin.y; - } else { - point.x = point.x - window->x; - point.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - point.y - window->y; - } + point = [theEvent locationInWindow]; + point.y = window->h - point.y; if ( point.x < 0 || point.x >= window->w || point.y < 0 || point.y >= window->h ) { if (mouse->focus != 0) {