I'm working on my new video game project, in which I want to support ”split screen” in the form of splitting the game into two independent windows (one game process with two windows), if the player have PC with two monitors or one monitor and TV. I have no problems with handling two windows, also no problem with handling exclusive video mode for one window. Both cannot be run in exclusive video mode, so the solution is to create one window in exclusive video mode and second in desktop fullscreen.
When the main window is displayed on main monitor, I can use
SDL_SetWindowGrab — mouse position is limited to window/screen area. If I have two windows, when main window use exclusive wideo mode on main screen and second window use desktop fullscreen on secondary monitor, I can use
SDL_SetWindowGrab for main window — works perfectly. But if I would like to set grabbing for secondary window, it doesn't work — I can move cursor between both screens.
I know that the description above looks complicated, so below are samples to illustrate what is going on.
// one window, shown on main screen in 800x600 exclusive video mode
// mouse is grabbed properly
SDL_GetDisplayMode(0, 5, @Mode); // 5th mode means 800x600 (on my computer)
SDL_GetDisplayBounds(0, @Bounds); // bounds of the main screen
Window1 := SDL_CreateWindow('Main', Bounds.X, Bounds.Y, Mode.W, Mode.H, SDL_WINDOW_FULLSCREEN);
Renderer1 := SDL_CreateRenderer(Window1, 0, SDL_RENDERER_ACCELERATED);
SDL_SetWindowGrab(Window1, SDL_TRUE);
// one window, shown on secondary screen in 800x600 exclusive video mode
// mouse is grabbed properly
SDL_GetDisplayMode(1, 13, @Mode); // 13th mode means 800x600 (on my computer)
SDL_GetDisplayBounds(1, @Bounds); // bounds of the secondary screen
Window1 := SDL_CreateWindow('Main', Bounds.X, Bounds.Y, Mode.W, Mode.H, SDL_WINDOW_FULLSCREEN);
Renderer1 := SDL_CreateRenderer(Window1, 0, SDL_RENDERER_ACCELERATED);
SDL_SetWindowGrab(Window1, SDL_TRUE);
// two windows:
// - 1st shown on main screen in 800x600 exclusive video mode
// - 2nd shown on secondary screen in desktop fullscreen mode
// mouse is grabbed properly (in the main window on main screen)
SDL_GetDisplayMode(0, 5, @Mode); // 5th mode means 800x600 (on my computer)
SDL_GetDisplayBounds(0, @Bounds); // bounds of the main screen
Window1 := SDL_CreateWindow('Main', Bounds.X, Bounds.Y, Mode.W, Mode.H, SDL_WINDOW_FULLSCREEN);
Renderer1 := SDL_CreateRenderer(Window1, 0, SDL_RENDERER_ACCELERATED);
SDL_GetCurrentDisplayMode(1, @Mode); // current resolution of secondary screen
SDL_GetDisplayBounds(1, @Bounds); // current bounds of secondary screen
Window2 := SDL_CreateWindow('Side', Bounds.X, Bounds.Y, Mode.W, Mode.H, SDL_WINDOW_FULLSCREEN_DESKTOP or SDL_WINDOW_ALWAYS_ON_TOP or SDL_WINDOW_SKIP_TASKBAR);
Renderer2 := SDL_CreateRenderer(Window2, 0, SDL_RENDERER_ACCELERATED);
SDL_SetWindowGrab(Window1, SDL_TRUE);
// two windows:
// - 1st shown on main screen in desktop fullscreen mode
// - 2nd shown on secondary screen in 800x600 exclusive video mode
// mouse is not grabbed in the secondary window (shown on secondary screen)
SDL_GetCurrentDisplayMode(0, @Mode); // current resolution of main screen
SDL_GetDisplayBounds(0, @Bounds); // current bounds of main screen
Window1 := SDL_CreateWindow('Main', Bounds.X, Bounds.Y, Mode.W, Mode.H, SDL_WINDOW_FULLSCREEN_DESKTOP or SDL_WINDOW_ALWAYS_ON_TOP or SDL_WINDOW_SKIP_TASKBAR);
Renderer1 := SDL_CreateRenderer(Window1, 0, SDL_RENDERER_ACCELERATED);
SDL_GetDisplayMode(1, 13, @Mode); // 13th mode means 800x600 (on my computer)
SDL_GetDisplayBounds(1, @Bounds); // bounds of the secondary screen
Window2 := SDL_CreateWindow('Side', Bounds.X, Bounds.Y, Mode.W, Mode.H, SDL_WINDOW_FULLSCREEN);
Renderer2 := SDL_CreateRenderer(Window2, 0, SDL_RENDERER_ACCELERATED);
SDL_SetWindowGrab(Window2, SDL_TRUE); // does not work
The last example properly set the exclusive video mode and custom resolution on the secondary monitor and shows main window on the main screen in desktop fullscreen, but mouse is not limited to the bounds of secondary monitor. It does not matter if the exclusive video mode is enabled or not, because if I create both windows using desktop fullscreen, still I cannot set grabbing in secondary window.
It appears that
SDL_SetWindowGrab is limited or has a bug. Grabbing mouse in window that is displayed on secondary screen (when there are two windows) is imposible. Anyone can confirm this behavior?
I'm interested mainly on Windows 7-11 (64 bit) solution, because this platform is the only target for my game (for now). I'm using SDL headers from the
PascalGameDevelopment/SDL2-for-Pascal repository and the
SDL 2.0.20 dll file (this is the latest version).