Skip to content

Conversation

@Kawaritai
Copy link
Contributor

@Kawaritai Kawaritai commented Nov 11, 2025

Fix #17999

This PR enables the preset dropdown options for window sizes in Layout Settings.

  • The Layout Settings stores fullscreen size and window size separately.
  • The "Default" size (9999x9999) makes the window maximised.
  • This does not add resolution changes for Borderless, it's suggested here that Borderless should stay at native desktop resolution.

@Kawaritai Kawaritai marked this pull request as draft November 11, 2025 21:23
@Kawaritai
Copy link
Contributor Author

Currently: Selecting a resolution with the max height can hide the titlebar. Selecting the native resolution effectively makes the app Borderless and the resize handles inaccessible. MS Windows won't handle the overflowing titlebar unless the user starts manual-resizing the app.

Classic osu!'s resize behaviour is to always center the window and do a safe resize that keeps the titlebar in display.

Issue: I'd like to always keep the titlebar in display, but the IWindow interface isn't helpful here (?), since Position is read-only and the desktop's safe area isn't known. Maybe we could expose this into the IWindow, or have the framework handle safe resizing/positioning?

@bdach bdach self-requested a review November 12, 2025 08:08
@bdach
Copy link
Collaborator

bdach commented Nov 12, 2025

The "Default" size (9999x9999) makes the window maximised.

Selecting this option shows the following toast:

Screenshot 2025-11-12 at 09 26 12

This should not be the case. That looks broken.

Selecting a resolution with the max height can hide the titlebar. Selecting the native resolution effectively makes the app Borderless and the resize handles inaccessible. MS Windows won't handle the overflowing titlebar unless the user starts manual-resizing the app.

Not sure what you're expecting to happen here. Yes some framework-side changes are likely going to be required. Probably will need to use https://wiki.libsdl.org/SDL2/SDL_GetWindowBordersSize framework-side.

I don't have any particular strong feelings as to whether the framework should be doing the safety logic or not. Maybe fine to put it in framework. Maybe @Susko3 @smoogipoo have differing opinions.

@Susko3
Copy link
Member

Susko3 commented Nov 12, 2025

I'm opposed to a resolution dropdown in windowed mode. If you want to have a certain resolution, you can resize the window while looking at the screen resolution toast. If your mouse sensitivity isn't awful, you can always perfectly resize the window, but it may take a little fiddling. (You'll need to use multithreaded mode due to current technical limitations.)

If you would like to instantly switch between different resolutions, I would recommend using simple third-party applications, like Sizer.

But if there was to be a preset resolution dropdown, I would not have the native resolution or a "maximised"/"default"/9999x9999. If you want to have a maximised window, press the maximise button, and if you want your window to take up the entire display, use borderless.

ShowsDefaultIndicator = false,
ItemSource = resolutions,
Current = sizeFullscreen
Current = currentResolution
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is forcing two unrelated settings (fullscreen size and windowed size) onto the same dropdown. I would make two dropdowns and hide and show them depending on the current screen mode.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is forcing two unrelated settings (fullscreen size and windowed size) onto the same dropdown. I would make two dropdowns and hide and show them depending on the current screen mode.

Ok, I separated the dropdowns and source lists (435cd27).

@smoogipoo
Copy link
Contributor

smoogipoo commented Nov 13, 2025

How do you re-centre your window after resizing it @Susko3? That's fine for other desktop applications but osu! (and maybe games in general) wants to be centred.
I don't think we should be recommending third-party software to do this...

@Susko3
Copy link
Member

Susko3 commented Nov 13, 2025

Right, if the resolution dropdown also centers the window, it makes more sense. This PR would need to be updated to handle that, probably by setting both WindowedPosition{X,Y} to 0.5.

@bdach
Copy link
Collaborator

bdach commented Nov 13, 2025

I'm opposed to a resolution dropdown in windowed mode.

It's there in stable and therefore it should be there in lazer. I'm not interested in discussion on whether we want this or not, there wouldn't be an issue open for it if we didn't want it, and it's a feature many users would like.

Only interested in figuring out how to make this happen not if.

@Kawaritai
Copy link
Contributor Author

The "Default" size (9999x9999) makes the window maximised.

After separating the dropdowns, I omitted the 9999x9999 option from the windowed sizes list. We probably want to have a different generator for the presets (like Standard/Widescreen are in classic), rather than the DisplayModes.

@Kawaritai
Copy link
Contributor Author

In sizeWindowed.BindValueChanged(...):

windowedPositionX.Value = 0.5;
windowedPositionY.Value = 0.5;

This currently works for centering the window after selecting a size, while the window can still use resize handles normally.

It's rather hacky though, because these lines fire on every resizing change. I tried to find a place to hook in for manual item selections (and w/out side effects like ignoring keyboard-based selections, or resetting position on settings open). I could use some help 🙏

@Kawaritai
Copy link
Contributor Author

Not sure what you're expecting to happen here. Yes some framework-side changes are likely going to be required. Probably will need to use https://wiki.libsdl.org/SDL2/SDL_GetWindowBordersSize framework-side.

I think having the titlebar always in-display seems to be acceptable, so long as a window is maneuverable after any resize.

Some code I trialed would adjust for top decorations, to cover most systems, and assumes bottom/left/right decorations don't matter. With this, selecting an option w/ max height will be clamped down. On Windows, when I adjusted for bottom/left/right decorations (~8 units), the window doesn't become flush with the sides of the display. Obv this solution isn't resilient if the system doesn't use top-titlebars.
^ Opened ppy/osu-framework#6667 for reference, but only changed SDL2 and I'm not confident where correctly to apply sizing effects.

@bdach
Copy link
Collaborator

bdach commented Nov 14, 2025

It's rather hacky though, because these lines fire on every resizing change. I tried to find a place to hook in for manual item selections (and w/out side effects like ignoring keyboard-based selections, or resetting position on settings open). I could use some help 🙏

You would probably need to:

  • use a separate bindable in resolutionSettingsDropdown, not just use Current = sizeWindowed directly
  • manually synchronise values of both via .BindValueChanged() callbacks...
  • ...but only apply the centering logic in the dropdown -> config direction, and not apply it in the config -> dropdown direction

@Kawaritai
Copy link
Contributor Author

Hi, I'm having some trouble with adjusting window position within the windowedPositionX/Y interface.

I planned on keeping the max resolution options and use the usableBounds and decorations information to position the window. However, if the ClientArea and Display have equal dimensions anywhere, the normalised Position cannot translate it.
Due to moveWindowTo in osu-framework : SDL2Window_Windowing.cs, a full width/height makes a fixed position at 0:

            int windowX = (int)Math.Round((displayBounds.Width - windowSize.Width) * newPosition.X);
            int windowY = (int)Math.Round((displayBounds.Height - windowSize.Height) * newPosition.Y);

Currently, normalised Position only cares about the client area position, sliding around the screen. Could it makes sense to treat the client area + decorations as one window during movement? This is what I attempted in this code, but it requires a framework change. The difference here is that Positions like (0,0), (0.5,0.5), (1,1) are aligning the entire window footprint, not solely the client area.

Any other suggestions on how should I approach window movement during Layout Settings changes, I'm happy to hear.

@Susko3
Copy link
Member

Susko3 commented Nov 17, 2025

Please stop trying to change framework behaviour. Your changes could have undesired consequences. Specifically for your suggestion: the size of the window border is not known during startup by definition, so calculations of the initial window position when first starting the game would be wrong.

If you have code that can calculate the desired correct IWindow.Position and IWindow.ClientSize, you can convert this to FrameworkSetting.WindowedSize, FrameworkSetting.WindowedPositionX and FrameworkSetting.WindowedPositionY by making your own inverse of moveWindowTo() and applying simple transformations. It's just math at the end of the day.

Copy link
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks to behave pretty well on windows 11 and on macOS. I can't get myself to even pretend to care about linux because I know this will be broken on linux on ${SPECIAL_SNOWFLAKE_WAYLAND_COMPOSITOR_DU_JOUR} and I'm at the acceptance stage of that.

Not sure it's merge-ready just yet pending discussion of a few sticking points below, but pretty good.


var dBounds = currentDisplay.Value.Bounds;
var dUsable = currentDisplay.Value.UsableBounds;
float topBar = host.Window?.BorderSize.Value.Top ?? 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warrants an inline comment as to why we're discarding the rest of the border size. Just restate what you said previously and it should suffice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, thanks for your patience

@bdach bdach mentioned this pull request Nov 18, 2025
@bdach bdach marked this pull request as ready for review November 19, 2025 08:52
Copy link
Collaborator

@bdach bdach left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's see how this goes I guess

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow changing resolution in windowed/borderless modes

4 participants