Saving Window Position
How can I save the window's position so it opens in the same place next time?
Saving and restoring window positions is a common requirement for professional applications. Here's how to implement this feature using file I/O.
Basic Position Saving
First, let's create a simple system to save and load window positions:
#include <SDL.h>
#include <fstream>
#include <string>
#include "Window.h"
class PersistentWindow : public Window {
public:
void SavePosition(
const std::string& Filename) {
int X, Y;
SDL_GetWindowPosition(SDLWindow, &X, &Y);
std::ofstream File{Filename};
if (File) { File << X << ' ' << Y; }
}
bool LoadPosition(
const std::string& Filename) {
std::ifstream File{Filename};
int X, Y;
if (File >> X >> Y) {
SDL_SetWindowPosition(SDLWindow, X, Y);
return true;
}
return false;
}
};
Complete Implementation with Error Handling
Here's a more robust implementation that handles multiple monitors and screen boundaries:
#include <SDL.h>
#include <filesystem>
#include <fstream>
#include <string>
class PersistentWindow : public Window {
public:
struct WindowState {
int X, Y;
int Width, Height;
bool IsMaximized;
};
void SaveState(const std::string& Filename) {
WindowState State;
// Get current state
SDL_GetWindowPosition(
SDLWindow, &State.X, &State.Y);
SDL_GetWindowSize(
SDLWindow, &State.Width, &State.Height);
State.IsMaximized = SDL_GetWindowFlags(
SDLWindow) & SDL_WINDOW_MAXIMIZED;
// Save to file
std::ofstream File{
Filename, std::ios::binary};
if (File) {
File.write(
reinterpret_cast<char*>(&State),
sizeof(WindowState)
);
}
}
bool RestoreState(
const std::string& Filename) {
// Check if file exists
if (!std::filesystem::exists(Filename)) {
return false;
}
// Read saved state
WindowState State;
std::ifstream File{
Filename, std::ios::binary};
if (!File.read(reinterpret_cast<char*>(
&State),
sizeof(WindowState))) {
return false;
}
// Ensure position is on screen
if (EnsureOnScreen(State)) {
// Apply state
SDL_SetWindowSize(
SDLWindow, State.Width, State.Height);
SDL_SetWindowPosition(
SDLWindow, State.X, State.Y);
if (State.IsMaximized) {
SDL_MaximizeWindow(SDLWindow);
}
return true;
}
return false;
}
private:
bool EnsureOnScreen(WindowState& State) {
SDL_DisplayMode Display;
if (SDL_GetCurrentDisplayMode(
0, &Display) != 0) { return false; }
// Ensure window is at least partially visible
State.X = std::max(
-State.Width / 2,
std::min(
State.X,
Display.w - State.Width / 2
)
);
State.Y = std::max(
0, std::min(State.Y, Display.h - 100));
return true;
}
};
Usage Example
Here's how to use the persistent window:
#include <SDL.h>
#include "PersistentWindow.h"
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO);
PersistentWindow Window;
// Try to restore previous position
if (!Window.RestoreState("window.dat")) {
// If no saved position, start centered
SDL_SetWindowPosition(
Window.SDLWindow,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED
);
}
SDL_Event E;
while (true) {
while (SDL_PollEvent(&E)) {
if (E.type == SDL_QUIT) {
// Save position before exit
Window.SaveState("window.dat");
SDL_Quit();
return 0;
}
}
}
}
This implementation includes several important features:
- Saves both position and size information
- Handles maximized state
- Ensures the window remains visible on screen
- Uses binary file I/O for efficient storage
- Includes error handling for file operations
Remember to consider multi-monitor setups and different screen resolutions when restoring window positions. A position that was valid when saved might not be valid when the application is next launched.
Managing Window Position
Learn how to control and monitor the position of SDL windows on screen