Troubles with SDL2 Screen modes and resolutions

I have an app that uses SDL2 where you can change screen mode and resolution in runtime.
No problems with initial screen mode and resolution but there are troubles after changing to Fullscreen in runtime.

When i go from from SDL_WINDOW_FULLSCREEN to SDL_WINDOW_FULLSCREEN_DESKTOP or Windowed (with decorations) result is not as i expect.

What i expect:
FullscreenBorderless or Windowed at the center of the screen.

What i get:
Windowed at left top corner with resolution that differs from one was set and AlwaysOnTop that i can’t turn off.

Here is some code:

void ScreenResolution(const crx::TPoint& p, NScreenMode smd) {
	int curW = 0;
	int curH = 0;
	SDL_GetWindowSize(m_pWin, &curW, &curH);

	if( curW==p.x && curH==p.y && smd==ScreenMode() ) return;
	
	ScreenMode(smd);

	if(smd==NScreenMode::Windowed) {
		SDL_SetWindowSize(m_pWin, p.x, p.y);
		SDL_SetWindowPosition(m_pWin, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);

	} else if(smd==NScreenMode::FullScreen) {
		auto modesNum = SDL_GetNumDisplayModes(0);
		SDL_DisplayMode mode;

		for(int i=0; i<modesNum; ++i) {
			if( SDL_GetDisplayMode(0, i, &mode)!=0 || mode.w!=p.x || mode.h!=p.y) continue;

			if( SDL_SetWindowDisplayMode(m_pWin, &mode)!=0 ) _ERROR( SDL_GetError() );

			break;
		}
	}
}

void ScreenMode(NScreenMode mode) {
	if( ScreenMode()==mode ) return;

	BeforeChangeScreenMode(mode);

	SDL_SetWindowFullscreen( m_pWin, ScreenModeToSDLWindowMode(mode) );

	if(mode==NScreenMode::Windowed) {
		SDL_SetWindowBordered(m_pWin, SDL_TRUE);
	} else if(mode==NScreenMode::WindowedFullScreen) {
		// Hardfix for troubles that happen on switch from Fullscreen with not max Resolution to WindowedFullScreen
		SDL_MinimizeWindow(m_pWin);
		SDL_MaximizeWindow(m_pWin);
	}
}

int ScreenModeToSDLWindowMode(NScreenMode newMode) {
	// 0 for Windowed
	int md = 0;

	if(newMode==NScreenMode::FullScreen) {
		md = SDL_WINDOW_FULLSCREEN;
	} else if(newMode==NScreenMode::WindowedFullScreen) {
		md = SDL_WINDOW_FULLSCREEN_DESKTOP;
	}

	return md;
}

For SDL_WINDOW_FULLSCREEN_DESKTOP i found solution in SDL_MinimizeWindow & SDL_MaximizeWindow but that not working for Windowed mode.

Also i have troubles with SDL_GetDesktopDisplayMode when desktop resolution is lower that was set in Fullscreen mode in runtime.
For ex. when desktop is FullHD and in Fullscreen was set 4K i receive 4K instead if FullHD.

Code:

TPoint GetDesktopSize() {
	SDL_DisplayMode dm;
	SDL_GetDesktopDisplayMode(0, &dm);
	return { dm.w, dm.h };
}

Also sometimes have wrong resolution and Fullscreen after switching to Windowed and back.
FullHD Fullscreen → FullHD Windowed → HD Windowed → FullHD Fullscreen (when set HD Fullscreen)

Am i doing something wrong?

Log with FullHd Desktop started in FullHD Windowed, gone into Fullscreen changed resolution, after 4K Fullscreen gone into FullHD Windowed but ended up in 4K Windowed.

Log:
(12:35:14) : * Change screen mode from Windowed to FullScreen *
(12:35:14) : * Apply mode = FullScreen, res = 1920;1080 *
(12:35:16) : * SDL_WINDOWEVENT_SIZE_CHANGED TApplication x=0; y=0; w=1920; h=1080 *
(12:35:19) : * Change ScreenResolution to 3840;2160 *
(12:35:19) : * Apply mode = FullScreen res = 3840;2160 *
(12:35:21) : * SDL_WINDOWEVENT_SIZE_CHANGED TApplication x=0; y=0; w=3840; h=2160 *
(12:35:27) : * Change ScreenResolution to 2560;1600 *
(12:35:27) : * Apply mode = FullScreen, res = 2560;1600 *
(12:35:28) : * SDL_WINDOWEVENT_SIZE_CHANGED TApplication x=0; y=0; w=2560; h=1600 *
(12:35:32) : * Change ScreenResolution to 3840;2160 *
(12:35:32) : * Apply mode = FullScreen res = 3840;2160 *
(12:35:34) : * SDL_WINDOWEVENT_SIZE_CHANGED TApplication x=0; y=0; w=3840; h=2160 *
(12:35:39) : * Change screen mode from FullScreen to Windowed *
(12:35:39) : * Validated Resolution from << 3840x2160 to 1920x1080 * (P.S. cause Resolution was less Desktop Resolution)
(12:35:39) : * Change ScreenResolution to 1920;1080 *
(12:35:39) : * Apply mode = Windowed res = 1920;1080 *
(12:35:39) : * SDL_WINDOWEVENT_SIZE_CHANGED TApplication x=8; y=31; w=3824; h=2121 *

For some reason i receive size and position that differs from which i asked.
Oh, and AlwaysOnTop also. (can’t view anything over running app)

I seen windows act differently on different OSes (and I really don’t like how windows 11 does it). What OS are you testing on? That resolution is fairly high. Out of curiosity, I don’t think it’s related to the problem but are you using high DPI? Are you calling SDL_RenderSetLogicalSize?

Im testing it on Win11 and Win10.

Thats a game and i need to support resolution at least to 4K.
Current textures are FullHD (not scaled) but i plan scale setting in future.
In my project those problems are reproduced on resolutions that are lesser than FullHd.

Im not used SDL_RenderSetLogicalSize in this project.
I tried it out of curiosity maybe used it improperly, got result that broke image output and gone from it. Postponed it until im gonna work on scale settings.

Yeah SDL_RenderSetLogicalSize doesn’t seem for this case. I seen devices that had roughly a 4K display with a high pixel density. For that I used it.

I never deal with fullscreen so I don’t think I can help