Whenever a window becomes fullscreen, shown, unminimized, and has input focus it will change the display to the corresponding fullscreen video mode.
authorSam Lantinga
Tue, 01 Dec 2009 08:56:12 +0000
changeset 350298a819296cdc
parent 3501 467e67d301f3
child 3503 7931094e4c48
Whenever a window becomes fullscreen, shown, unminimized, and has input focus it will change the display to the corresponding fullscreen video mode.
If it loses any of those properties the desktop mode will be restored.
src/events/SDL_keyboard.c
src/events/SDL_windowevents.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
     1.1 --- a/src/events/SDL_keyboard.c	Tue Dec 01 06:15:10 2009 +0000
     1.2 +++ b/src/events/SDL_keyboard.c	Tue Dec 01 08:56:12 2009 +0000
     1.3 @@ -652,17 +652,16 @@
     1.4      int i;
     1.5      SDL_bool focus;
     1.6  
     1.7 -    if (!keyboard || (keyboard->focus == windowID)) {
     1.8 +    if (!keyboard) {
     1.9          return;
    1.10      }
    1.11  
    1.12      /* See if the current window has lost focus */
    1.13 -    if (keyboard->focus) {
    1.14 +    if (keyboard->focus && keyboard->focus != windowID) {
    1.15          focus = SDL_FALSE;
    1.16          for (i = 0; i < SDL_num_keyboards; ++i) {
    1.17 -            SDL_Keyboard *check;
    1.18              if (i != index) {
    1.19 -                check = SDL_GetKeyboard(i);
    1.20 +                SDL_Keyboard *check = SDL_GetKeyboard(i);
    1.21                  if (check && check->focus == keyboard->focus) {
    1.22                      focus = SDL_TRUE;
    1.23                      break;
    1.24 @@ -678,21 +677,8 @@
    1.25      keyboard->focus = windowID;
    1.26  
    1.27      if (keyboard->focus) {
    1.28 -        focus = SDL_FALSE;
    1.29 -        for (i = 0; i < SDL_num_keyboards; ++i) {
    1.30 -            SDL_Keyboard *check;
    1.31 -            if (i != index) {
    1.32 -                check = SDL_GetKeyboard(i);
    1.33 -                if (check && check->focus == keyboard->focus) {
    1.34 -                    focus = SDL_TRUE;
    1.35 -                    break;
    1.36 -                }
    1.37 -            }
    1.38 -        }
    1.39 -        if (!focus) {
    1.40 -            SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED,
    1.41 -                                0, 0);
    1.42 -        }
    1.43 +        SDL_SendWindowEvent(keyboard->focus, SDL_WINDOWEVENT_FOCUS_GAINED,
    1.44 +                            0, 0);
    1.45      }
    1.46  }
    1.47  
     2.1 --- a/src/events/SDL_windowevents.c	Tue Dec 01 06:15:10 2009 +0000
     2.2 +++ b/src/events/SDL_windowevents.c	Tue Dec 01 08:56:12 2009 +0000
     2.3 @@ -86,6 +86,7 @@
     2.4              return 0;
     2.5          }
     2.6          window->flags |= SDL_WINDOW_MINIMIZED;
     2.7 +        SDL_OnWindowMinimized(window);
     2.8          break;
     2.9      case SDL_WINDOWEVENT_MAXIMIZED:
    2.10          if (window->flags & SDL_WINDOW_MAXIMIZED) {
    2.11 @@ -98,6 +99,7 @@
    2.12              return 0;
    2.13          }
    2.14          window->flags &= ~(SDL_WINDOW_MINIMIZED | SDL_WINDOW_MAXIMIZED);
    2.15 +        SDL_OnWindowRestored(window);
    2.16          break;
    2.17      case SDL_WINDOWEVENT_ENTER:
    2.18          if (window->flags & SDL_WINDOW_MOUSE_FOCUS) {
     3.1 --- a/src/video/SDL_sysvideo.h	Tue Dec 01 06:15:10 2009 +0000
     3.2 +++ b/src/video/SDL_sysvideo.h	Tue Dec 01 08:56:12 2009 +0000
     3.3 @@ -147,6 +147,7 @@
     3.4  #define FULLSCREEN_VISIBLE(W) \
     3.5      (((W)->flags & SDL_WINDOW_FULLSCREEN) && \
     3.6       ((W)->flags & SDL_WINDOW_SHOWN) && \
     3.7 +     ((W)->flags & SDL_WINDOW_INPUT_FOCUS) && \
     3.8       !((W)->flags & SDL_WINDOW_MINIMIZED))
     3.9  
    3.10  /*
    3.11 @@ -160,6 +161,7 @@
    3.12      SDL_DisplayMode *display_modes;
    3.13      SDL_DisplayMode desktop_mode;
    3.14      SDL_DisplayMode current_mode;
    3.15 +    SDL_bool updating_fullscreen;
    3.16      SDL_Palette *palette;
    3.17  
    3.18      Uint16 *gamma;
    3.19 @@ -426,6 +428,8 @@
    3.20  extern void SDL_OnWindowShown(SDL_Window * window);
    3.21  extern void SDL_OnWindowHidden(SDL_Window * window);
    3.22  extern void SDL_OnWindowResized(SDL_Window * window);
    3.23 +extern void SDL_OnWindowMinimized(SDL_Window * window);
    3.24 +extern void SDL_OnWindowRestored(SDL_Window * window);
    3.25  extern void SDL_OnWindowFocusGained(SDL_Window * window);
    3.26  extern void SDL_OnWindowFocusLost(SDL_Window * window);
    3.27  extern SDL_WindowID SDL_GetFocusWindow(void);
     4.1 --- a/src/video/SDL_video.c	Tue Dec 01 06:15:10 2009 +0000
     4.2 +++ b/src/video/SDL_video.c	Tue Dec 01 08:56:12 2009 +0000
     4.3 @@ -599,30 +599,31 @@
     4.4      SDL_DisplayMode current_mode;
     4.5      int i, ncolors;
     4.6  
     4.7 -    if (!mode) {
     4.8 -        mode = &display->desktop_mode;
     4.9 -    }
    4.10 -    display_mode = *mode;
    4.11 -
    4.12 -    /* Default to the current mode */
    4.13 -    if (!display_mode.format) {
    4.14 -        display_mode.format = display->current_mode.format;
    4.15 -    }
    4.16 -    if (!display_mode.w) {
    4.17 -        display_mode.w = display->current_mode.w;
    4.18 -    }
    4.19 -    if (!display_mode.h) {
    4.20 -        display_mode.h = display->current_mode.h;
    4.21 -    }
    4.22 -    if (!display_mode.refresh_rate) {
    4.23 -        display_mode.refresh_rate = display->current_mode.refresh_rate;
    4.24 -    }
    4.25 -
    4.26 -    /* Get a good video mode, the closest one possible */
    4.27 -    if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
    4.28 -        SDL_SetError("No video mode large enough for %dx%d",
    4.29 -                     display_mode.w, display_mode.h);
    4.30 -        return -1;
    4.31 +    if (mode) {
    4.32 +        display_mode = *mode;
    4.33 +
    4.34 +        /* Default to the current mode */
    4.35 +        if (!display_mode.format) {
    4.36 +            display_mode.format = display->current_mode.format;
    4.37 +        }
    4.38 +        if (!display_mode.w) {
    4.39 +            display_mode.w = display->current_mode.w;
    4.40 +        }
    4.41 +        if (!display_mode.h) {
    4.42 +            display_mode.h = display->current_mode.h;
    4.43 +        }
    4.44 +        if (!display_mode.refresh_rate) {
    4.45 +            display_mode.refresh_rate = display->current_mode.refresh_rate;
    4.46 +        }
    4.47 +
    4.48 +        /* Get a good video mode, the closest one possible */
    4.49 +        if (!SDL_GetClosestDisplayModeForDisplay(display, &display_mode, &display_mode)) {
    4.50 +            SDL_SetError("No video mode large enough for %dx%d",
    4.51 +                         display_mode.w, display_mode.h);
    4.52 +            return -1;
    4.53 +        }
    4.54 +    } else {
    4.55 +        display_mode = display->desktop_mode;
    4.56      }
    4.57  
    4.58      /* See if there's anything left to do */
    4.59 @@ -719,6 +720,63 @@
    4.60      return 0;
    4.61  }
    4.62  
    4.63 +static void
    4.64 +SDL_UpdateFullscreenMode(SDL_Window * window, SDL_bool attempt)
    4.65 +{
    4.66 +    SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
    4.67 +    int i;
    4.68 +
    4.69 +    /* See if we're already processing a window */
    4.70 +    if (display->updating_fullscreen) {
    4.71 +        return;
    4.72 +    }
    4.73 +
    4.74 +    display->updating_fullscreen = SDL_TRUE;
    4.75 +
    4.76 +    /* See if we even want to do anything here */
    4.77 +    if ((window->flags & SDL_WINDOW_FULLSCREEN) &&
    4.78 +        (window->flags & SDL_WINDOW_SHOWN)) {
    4.79 +        if (attempt) {
    4.80 +            /* We just gained some state, try to gain all states */
    4.81 +            if (window->flags & SDL_WINDOW_MINIMIZED) {
    4.82 +                SDL_RestoreWindow(window->id);
    4.83 +            } else {
    4.84 +                SDL_RaiseWindow(window->id);
    4.85 +            }
    4.86 +        } else {
    4.87 +            /* We just lost some state, try to release all states */
    4.88 +            SDL_MinimizeWindow(window->id);
    4.89 +        }
    4.90 +    }
    4.91 +
    4.92 +    if (FULLSCREEN_VISIBLE(window)) {
    4.93 +        /* Hide any other fullscreen windows */
    4.94 +        for (i = 0; i < display->num_windows; ++i) {
    4.95 +            SDL_Window *other = &display->windows[i];
    4.96 +            if (other != window && FULLSCREEN_VISIBLE(other)) {
    4.97 +                SDL_MinimizeWindow(other->id);
    4.98 +            }
    4.99 +        }
   4.100 +    }
   4.101 +
   4.102 +    display->updating_fullscreen = SDL_FALSE;
   4.103 +
   4.104 +    /* See if there are any fullscreen windows */
   4.105 +    for (i = 0; i < display->num_windows; ++i) {
   4.106 +        window = &display->windows[i];
   4.107 +        if (FULLSCREEN_VISIBLE(window)) {
   4.108 +            SDL_DisplayMode fullscreen_mode;
   4.109 +            if (SDL_GetWindowDisplayMode(window->id, &fullscreen_mode) == 0) {
   4.110 +                SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);
   4.111 +                return;
   4.112 +            }
   4.113 +        }
   4.114 +    }
   4.115 +
   4.116 +    /* Nope, restore the desktop mode */
   4.117 +    SDL_SetDisplayModeForDisplay(display, NULL);
   4.118 +}
   4.119 +
   4.120  int
   4.121  SDL_SetPaletteForDisplay(SDL_VideoDisplay * display, const SDL_Color * colors, int firstcolor, int ncolors)
   4.122  {
   4.123 @@ -1223,6 +1281,9 @@
   4.124      }
   4.125      if (_this->RaiseWindow) {
   4.126          _this->RaiseWindow(_this, window);
   4.127 +    } else {
   4.128 +        /* FIXME: What we really want is a way to request focus */
   4.129 +        SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
   4.130      }
   4.131  }
   4.132  
   4.133 @@ -1289,29 +1350,11 @@
   4.134      if (fullscreen) {
   4.135          window->flags |= SDL_WINDOW_FULLSCREEN;
   4.136  
   4.137 -        if (FULLSCREEN_VISIBLE(window)) {
   4.138 -            SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   4.139 -            SDL_DisplayMode fullscreen_mode;
   4.140 -
   4.141 -            /* Hide any other fullscreen windows */
   4.142 -            int i;
   4.143 -            for (i = 0; i < display->num_windows; ++i) {
   4.144 -                SDL_Window *other = &display->windows[i];
   4.145 -                if (other->id != windowID && FULLSCREEN_VISIBLE(other)) {
   4.146 -                    SDL_MinimizeWindow(other->id);
   4.147 -                }
   4.148 -            }
   4.149 -
   4.150 -            if (SDL_GetWindowDisplayMode(windowID, &fullscreen_mode) == 0) {
   4.151 -                SDL_SetDisplayModeForDisplay(display, &fullscreen_mode);
   4.152 -            }
   4.153 -        }
   4.154 +        SDL_UpdateFullscreenMode(window, SDL_TRUE);
   4.155      } else {
   4.156          window->flags &= ~SDL_WINDOW_FULLSCREEN;
   4.157  
   4.158 -        if (FULLSCREEN_VISIBLE(window)) {
   4.159 -            SDL_SetDisplayMode(NULL);
   4.160 -        }
   4.161 +        SDL_UpdateFullscreenMode(window, SDL_FALSE);
   4.162      }
   4.163      return 0;
   4.164  }
   4.165 @@ -1354,17 +1397,14 @@
   4.166  void
   4.167  SDL_OnWindowShown(SDL_Window * window)
   4.168  {
   4.169 -    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   4.170 -        SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
   4.171 -    }
   4.172 +    SDL_RaiseWindow(window->id);
   4.173 +    SDL_UpdateFullscreenMode(window, SDL_TRUE);
   4.174  }
   4.175  
   4.176  void
   4.177  SDL_OnWindowHidden(SDL_Window * window)
   4.178  {
   4.179 -    if (window->flags & SDL_WINDOW_FULLSCREEN) {
   4.180 -        SDL_SendWindowEvent(window->id, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
   4.181 -    }
   4.182 +    SDL_UpdateFullscreenMode(window, SDL_FALSE);
   4.183  }
   4.184  
   4.185  void
   4.186 @@ -1378,13 +1418,24 @@
   4.187  }
   4.188  
   4.189  void
   4.190 +SDL_OnWindowMinimized(SDL_Window * window)
   4.191 +{
   4.192 +    SDL_UpdateFullscreenMode(window, SDL_FALSE);
   4.193 +}
   4.194 +
   4.195 +void
   4.196 +SDL_OnWindowRestored(SDL_Window * window)
   4.197 +{
   4.198 +    SDL_RaiseWindow(window->id);
   4.199 +    SDL_UpdateFullscreenMode(window, SDL_TRUE);
   4.200 +}
   4.201 +
   4.202 +void
   4.203  SDL_OnWindowFocusGained(SDL_Window * window)
   4.204  {
   4.205      SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   4.206  
   4.207 -    if (FULLSCREEN_VISIBLE(window)) {
   4.208 -        SDL_SetDisplayMode(&window->fullscreen_mode);
   4.209 -    }
   4.210 +    SDL_UpdateFullscreenMode(window, SDL_TRUE);
   4.211      if (display->gamma && _this->SetDisplayGammaRamp) {
   4.212          _this->SetDisplayGammaRamp(_this, display, display->gamma);
   4.213      }
   4.214 @@ -1399,10 +1450,7 @@
   4.215  {
   4.216      SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   4.217  
   4.218 -    if (FULLSCREEN_VISIBLE(window)) {
   4.219 -        SDL_MinimizeWindow(window->id);
   4.220 -        SDL_SetDisplayMode(NULL);
   4.221 -    }
   4.222 +    SDL_UpdateFullscreenMode(window, SDL_FALSE);
   4.223      if (display->gamma && _this->SetDisplayGammaRamp) {
   4.224          _this->SetDisplayGammaRamp(_this, display, display->saved_gamma);
   4.225      }