From a8836b0766e000de082c4c946ff700d5ad28bd95 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 15 Dec 2012 00:30:17 +0000 Subject: [PATCH] Improvements from Alfred: - Add new SDL_WINDOW_FULLSCREEN_DESKTOP video mode, makes a fullscreen window the size of the desktop (i.e no window manager mode change) - Fix crash in warp mouse if you specified null as the window - Added new SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS Hint, if set to 0 then don't minimize a fullscreen window on focus lost (if not set or set to non-zero then minimize on focus loss) --- include/SDL_hints.h | 7 ++++ include/SDL_video.h | 3 +- src/events/SDL_mouse.c | 6 ++++ src/video/SDL_video.c | 54 ++++++++++++++++++++++++------- src/video/cocoa/SDL_cocoawindow.m | 17 ++++++++++ test/automated/surface/surface.c | 0 6 files changed, 74 insertions(+), 13 deletions(-) mode change 100755 => 100644 test/automated/surface/surface.c diff --git a/include/SDL_hints.h b/include/SDL_hints.h index 8b2fcb91c..c81a0954b 100644 --- a/include/SDL_hints.h +++ b/include/SDL_hints.h @@ -163,6 +163,13 @@ extern "C" { */ #define SDL_HINT_GRAB_KEYBOARD "SDL_GRAB_KEYBOARD" +/** + * \brief Minimize your SDL_Window if it loses key focus when in Fullscreen mode. Defaults to true. + * + */ +#define SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS" + + /** * \brief A variable controlling whether the idle timer is disabled on iOS. * diff --git a/include/SDL_video.h b/include/SDL_video.h index 5fdba063f..31cb4c32a 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -108,6 +108,7 @@ typedef enum SDL_WINDOW_INPUT_GRABBED = 0x00000100, /**< window has grabbed input focus */ SDL_WINDOW_INPUT_FOCUS = 0x00000200, /**< window has input focus */ SDL_WINDOW_MOUSE_FOCUS = 0x00000400, /**< window has mouse focus */ + SDL_WINDOW_FULLSCREEN_DESKTOP = ( SDL_WINDOW_FULLSCREEN | 0x00001000 ), SDL_WINDOW_FOREIGN = 0x00000800 /**< window not created by SDL */ } SDL_WindowFlags; @@ -604,7 +605,7 @@ extern DECLSPEC void SDLCALL SDL_RestoreWindow(SDL_Window * window); * \sa SDL_GetWindowDisplayMode() */ extern DECLSPEC int SDLCALL SDL_SetWindowFullscreen(SDL_Window * window, - SDL_bool fullscreen); + Uint32 flags); /** * \brief Get the SDL surface associated with the window. diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c index a61f21520..00a421216 100644 --- a/src/events/SDL_mouse.c +++ b/src/events/SDL_mouse.c @@ -379,6 +379,12 @@ void SDL_WarpMouseInWindow(SDL_Window * window, int x, int y) { SDL_Mouse *mouse = SDL_GetMouse(); + + if ( window == NULL ) + window = mouse->focus; + + if ( window == NULL ) + return; if (mouse->WarpMouse) { mouse->WarpMouse(window, x, y); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index e3109481e..4b0116b08 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -1001,6 +1001,7 @@ int SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) { SDL_DisplayMode fullscreen_mode; + SDL_VideoDisplay *display; CHECK_WINDOW_MAGIC(window, -1); @@ -1011,8 +1012,15 @@ SDL_GetWindowDisplayMode(SDL_Window * window, SDL_DisplayMode * mode) if (!fullscreen_mode.h) { fullscreen_mode.h = window->h; } + + display = SDL_GetDisplayForWindow(window); - if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), + /* if in desktop size mode, just return the size of the desktop */ + if ( ( window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) == SDL_WINDOW_FULLSCREEN_DESKTOP ) + { + fullscreen_mode = display->desktop_mode; + } + else if (!SDL_GetClosestDisplayModeForDisplay(SDL_GetDisplayForWindow(window), &fullscreen_mode, &fullscreen_mode)) { SDL_SetError("Couldn't find display mode match"); @@ -1087,7 +1095,13 @@ SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool fullscreen) resized = SDL_FALSE; } - SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); + /* only do the mode change if we want exclusive fullscreen */ + if ( ( window->flags & SDL_WINDOW_FULLSCREEN_DESKTOP ) != SDL_WINDOW_FULLSCREEN_DESKTOP ) + SDL_SetDisplayModeForDisplay(display, &fullscreen_mode); + else + SDL_SetDisplayModeForDisplay(display, NULL); + + if (_this->SetWindowFullscreen) { _this->SetWindowFullscreen(_this, other, display, SDL_TRUE); } @@ -1140,7 +1154,7 @@ SDL_FinishWindowCreation(SDL_Window *window, Uint32 flags) SDL_MinimizeWindow(window); } if (flags & SDL_WINDOW_FULLSCREEN) { - SDL_SetWindowFullscreen(window, SDL_TRUE); + SDL_SetWindowFullscreen(window, flags); } if (flags & SDL_WINDOW_INPUT_GRABBED) { SDL_SetWindowGrab(window, SDL_TRUE); @@ -1696,19 +1710,22 @@ SDL_RestoreWindow(SDL_Window * window) } } +#define FULLSCREEN_MASK ( SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN ) int -SDL_SetWindowFullscreen(SDL_Window * window, SDL_bool fullscreen) +SDL_SetWindowFullscreen(SDL_Window * window, Uint32 flags) { CHECK_WINDOW_MAGIC(window, -1); - if (!!fullscreen == !!(window->flags & SDL_WINDOW_FULLSCREEN)) { + flags &= FULLSCREEN_MASK; + + if ( flags == (window->flags & FULLSCREEN_MASK) ) { return 0; } - if (fullscreen) { - window->flags |= SDL_WINDOW_FULLSCREEN; - } else { - window->flags &= ~SDL_WINDOW_FULLSCREEN; - } + + /* clear the previous flags and OR in the new ones */ + window->flags &= ~FULLSCREEN_MASK; + window->flags |= flags; + SDL_UpdateFullscreenMode(window, FULLSCREEN_VISIBLE(window)); return 0; @@ -1973,6 +1990,19 @@ SDL_OnWindowFocusGained(SDL_Window * window) SDL_UpdateWindowGrab(window); } +static SDL_bool ShouldMinimizeOnFocusLoss() +{ + const char *hint = SDL_GetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS); + if (hint) { + if (*hint == '0') { + return SDL_FALSE; + } else { + return SDL_TRUE; + } + } + return SDL_TRUE; +} + void SDL_OnWindowFocusLost(SDL_Window * window) { @@ -1983,8 +2013,8 @@ SDL_OnWindowFocusLost(SDL_Window * window) SDL_UpdateWindowGrab(window); /* If we're fullscreen on a single-head system and lose focus, minimize */ - if ((window->flags & SDL_WINDOW_FULLSCREEN) && _this->num_displays == 1) { - SDL_MinimizeWindow(window); + if ((window->flags & SDL_WINDOW_FULLSCREEN) && ShouldMinimizeOnFocusLoss() ) { + SDL_MinimizeWindow(window); } } diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index cf880325d..c5b0d2acf 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -996,6 +996,23 @@ - (void)rightMouseDown:(NSEvent *)theEvent cgpoint.y = window->y + y; CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint); } + + if ( window->flags & SDL_WINDOW_FULLSCREEN ) + { + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + + if (window->flags & SDL_WINDOW_INPUT_FOCUS) + { + /* OpenGL is rendering to the window, so make it visible! */ + [data->nswindow setLevel:CGShieldingWindowLevel()]; + } + else + { + [data->nswindow setLevel:kCGNormalWindowLevel]; + } + + } + } void diff --git a/test/automated/surface/surface.c b/test/automated/surface/surface.c old mode 100755 new mode 100644