Window Visibility

Learn how to control the visibility of SDL2 windows, including showing, hiding, minimizing, and more
This lesson is part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, Unlimited Access
Abstract art representing computer programming
Ryan McCombe
Ryan McCombe
Updated

In this lesson, we’ll continue exploring window management with SDL2, focusing on visibility. We’ll cover:

  • Hiding and showing windows
  • Using always-on-top windows
  • Flashing windows to grab attention
  • Minimising and restoring windows

Hidden Windows

We can create a window that is initially hidden using the SDL_WINDOW_HIDDEN window flag:

SDL_CreateWindow(
  "My Program",
  100, 200, 600, 300,
  SDL_WINDOW_HIDDEN
);

Preview: Utility Windows

It may be unclear why we would ever want to hide a window. This is indeed unusual when our program is only managing a single window, however, many programs will be managing multiple windows.

It is often the case that programs manage more windows than we might initially realize. For example, it’s common to design UI elements like tooltips and menus as distinct windows. These are sometimes referred to as utility windows:

Screenshot showing a dropdown menu in macOS

Showing and hiding windows is primarily useful when we design our programs this way. We cover this technique in detail, and why we should use it, in the next lesson.

Checking if a Window is Hidden

The SDL_WINDOW_HIDDEN flag is kept up to date through the lifecycle of our window. As such, we can check if a window is currently hidden by using SDL_GetWindowFlags() and using the & operator to isolate the SDL_WINDOW_HIDDEN bit:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_HIDDEN
  )};

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (Flags & SDL_WINDOW_HIDDEN) {
  std::cout << "Window is hidden\n";
}
Window is hidden

SDL_HideWindow()

We can hide an existing window by passing its SDL_Window pointer to the SDL_HideWindow() function:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    0 // Not hidden initially
  )};

// Hide the window later
SDL_HideWindow(Window);

Showing Windows

The opposite of the SDL_WINDOW_HIDDEN flag is SDL_WINDOW_SHOWN. Windows are shown by default, but we can include this flag in the SDL_CreateWindow() invocation if we want to be explicit:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_SHOWN
  )};

Checking if a Window is Shown

As usual, we can check the SDL_WINDOW_SHOWN flag to determine if a window is currently visible:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    0 // Not explicit, but window will be shown
  )};

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (Flags & SDL_WINDOW_SHOWN) {
  std::cout << "Window is shown by default\n";
}
Window is shown by default

SDL_ShowWindow()

We can show a window that is currently hidden by passing its SDL_Window pointer to SDL_ShowWindow():

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_HIDDEN
  )};

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (Flags & SDL_WINDOW_HIDDEN) {
  std::cout << "Window is hidden\n";
}

SDL_ShowWindow(Window);

Flags = SDL_GetWindowFlags(Window);
if (Flags & SDL_WINDOW_SHOWN) {
  std::cout << "Not any more!\n";
}
Window is hidden
Not any more!

Minimising and Restoring Windows

When we hide a window, our player has no realistic way to make that window visible again. It is hidden until we use SDL_ShowWindow() to make it visible again.

Of course, we can call SDL_ShowWindow() in response to some user input, thereby giving them that capability. However, desktop platforms typically offer the option to minimize a window rather than hide it entirely.

A minimized window remains visible on the user’s task bar (in Windows) or Dock (in MacOS). They can then use those platform-specific mechanisms to restore the window and continue to interact with it.

We can create a window that is initially minimized using the SDL_WINDOW_MINIMIZED flag:

SDL_CreateWindow(
  "My Program",
  100, 200, 600, 300,
  SDL_WINDOW_MINIMIZED
)

Checking if a Window is Minimized

Unlike visibility, whether a window is minimized is something that can easily be controlled by our players. Platforms typically allow users to minimize a window by clicking on a button on the window’s title bar.

We can check if a window is currently minimized by using the & operator on its window flags:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_MINIMIZED
  )};

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (Flags & SDL_WINDOW_MINIMIZED) {
  std::cout << "Window is minimized\n";
}
Window is minimized

Size of Minimized Windows

Whilst a minimized window typically occupies no space on the user’s screen, SDL will report the size it was prior to the window being minimized. This will also be the size of the window once the user restores it:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_MINIMIZED
  )};

int x, y;
SDL_GetWindowSize(Window, &x, &y);
std::cout << "Window size: " << x << 'x' << y;
Window size: 600x300

In most scenarios where our logic depends on the window size, we’d also want to check that the window is minimized in addition to its size.

SDL_MinimizeWindow()

We can programmatically minimize an existing window by passing its SDL_Window pointer to SDL_MinimizeWindow():

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    0 // Not initially minimized
  )};

SDL_MinimizeWindow(Window);

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (Flags & SDL_WINDOW_MINIMIZED) {
  std::cout << "Window is now minimized\n";
}
Window is now minimized

SDL_RestoreWindow()

We can restore a minimized window to its previous size by passing its SDL_Window pointer to SDL_RestoreWindow():

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_MINIMIZED
  )};

SDL_RestoreWindow(Window);

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (!(Flags & SDL_WINDOW_MINIMIZED)) {
  std::cout << "Window is no longer minimized";
}
Window is no longer minimized

Window Minimize and Restore Events

When a window is minimized or restored, an SDL_WindowEvent is dispatched through the SDL’s event queue. If we need to react to these events, we can check through them through our event loop.

When a window is minimized or restored, the event field of the SDL_WindowEvent will contain either SDL_WINDOWEVENT_MINIMIZED or SDL_WINDOWEVENT_RESTORED:

#include <SDL.h>
#include <iostream>
#include "Window.h"

void HandleWindowEvent(SDL_WindowEvent& E) {
  if (E.event == SDL_WINDOWEVENT_MINIMIZED) {
    std::cout << "Window minimized\n";
  } else if (E.event == SDL_WINDOWEVENT_RESTORED) {
    std::cout << "Window restored\n";
  }
}

int main(int argc, char** argv) {
  SDL_Init(SDL_INIT_VIDEO);
  Window GameWindow;

  SDL_Event E;
  while (true) {
    while (SDL_PollEvent(&E)) {
      if (E.type == SDL_WINDOWEVENT) {
        HandleWindowEvent(E.window);
      } else if (E.type == SDL_QUIT) {
        SDL_Quit();
        return 0;
      }
    }
    GameWindow.Update();
    GameWindow.Render();
  }
}
Window minimized
Window restored

Always-On-Top Windows

Many platforms allow us to create windows that always visually appear to be on top of other windows, even if those other windows have input focus.

This can be useful for tools like task managers, music players, or notifications that need to remain accessible.

We can configure a window to be always on top using the SDL_WINDOW_ALWAYS_ON_TOP flag:

SDL_CreateWindow(
  "My Program",
  100, 200, 600, 300,
  SDL_WINDOW_ALWAYS_ON_TOP
)};

SDL_SetWindowAlwaysOnTop()

We can update an existing window’s always-on-top configuration using the SDL_SetWindowAlwaysOnTop() function. We pass the SDL_Window pointer as our first argument. The second argument will be SDL_TRUE to enable always-on-top, and SDL_FALSE to disable it:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300, 0
)};

// Enable always-on-top
SDL_SetWindowAlwaysOnTop(Window, SDL_TRUE);

// Disable always-on-top
SDL_SetWindowAlwaysOnTop(Window, SDL_FALSE);

Checking if a Window is Always On Top

We can check if a window is currently configured to be always-on-top by examining the SDL_WINDOW_ALWAYS_ON_TOP flag:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300,
    SDL_WINDOW_ALWAYS_ON_TOP
)};

Uint32 Flags{SDL_GetWindowFlags(Window)};
if (Flags & SDL_WINDOW_ALWAYS_ON_TOP) {
  std::cout << "Window is always on top\n";
}

SDL_SetWindowAlwaysOnTop(Window, SDL_FALSE);

Flags = SDL_GetWindowFlags(Window);
if (!(Flags & SDL_WINDOW_ALWAYS_ON_TOP)) {
  std::cout << "Not any more!\n";
}
Window is always on top
Not any more!

Flashing Windows

We’ve now seen two ways to draw the user’s attention to a window. We can raise the window and cause it to grab input focus using SDL_RaiseWindow(), or set a window to be always on top.

However, these techniques should be used sparingly, as they can be disruptive when the user is trying to work with other programs.

Most platforms provide a friendlier mechanism for windows to request the user’s attention. This is called "flashing" the window, but the specific visual effect of "flashing" varies from platform to platform.

On Windows, for example, flashing a window means it will be highlighted in the user’s taskbar:

Screenshot of a program flashing on the Windows taskbar

The SDL_FlashWindow() function lets us access these attention-grabbing mechanisms:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300, 0
  )};

SDL_FlashWindow(Window, SDL_FLASH_BRIEFLY);

Our first argument is the SDL_Window* we want to attract attention, and the second argument is one of three possible values:

  • SDL_FLASH_BRIEFLY - Briefly flash the window to attract attention
  • SDL_FLASH_UNTIL_FOCUSED - Attract attention continuously until the user moves input focus to our window, or until we cancel the flashing
  • SDL_FLASH_CANCEL - Stop flashing

Error Handling

The SDL_FlashWindow() function includes error reporting. If the invocation was successful, the function will return 0, or a negative error code otherwise.

We can check this return value to check if the window flashing failed, and use SDL_GetError() to understand why:

SDL_Window* Window{
  SDL_CreateWindow(
    "My Program",
    100, 200, 600, 300, 0
  )};

if (SDL_FlashWindow(
  Window, SDL_FLASH_BRIEFLY) < 0) {
  std::cout << "Error flashing window: "
    << SDL_GetError();
}

Summary

In this lesson, we explored how to manage the visibility and state of SDL2 windows. We learned how to hide, show, minimize, and restore windows, as well as how to check their current state using window flags.

Additionally, we covered techniques for making windows always stay on top and attracting user attention through flashing. Key takeaways:

  • Use SDL_WINDOW_HIDDEN to create hidden windows and SDL_HideWindow() to hide an existing window.
  • Show hidden windows using SDL_ShowWindow().
  • Minimize and restore windows with SDL_WINDOW_MINIMIZED, SDL_MinimizeWindow(), and SDL_RestoreWindow().
  • Set a window to always stay on top using SDL_WINDOW_ALWAYS_ON_TOP and SDL_SetWindowAlwaysOnTop().
  • Flash windows to attract attention using SDL_FlashWindow().

Was this lesson useful?

Next Lesson

Handling Mouse Scrolling

Learn how to detect and handle mouse scroll wheel events in SDL2, including vertical and horizontal scrolling, as well as scroll wheel button events.
Abstract art representing computer programming
Ryan McCombe
Ryan McCombe
Updated
sdl2-promo.jpg
This lesson is part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, Unlimited Access
Window Management
  • 60.GPUs and Rasterization
  • 61.SDL Renderers
Next Lesson

Handling Mouse Scrolling

Learn how to detect and handle mouse scroll wheel events in SDL2, including vertical and horizontal scrolling, as well as scroll wheel button events.
Abstract art representing computer programming
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved