Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getDisplayBounds() for nimx #516

Open
MCRusher opened this issue May 31, 2023 · 4 comments
Open

getDisplayBounds() for nimx #516

MCRusher opened this issue May 31, 2023 · 4 comments

Comments

@MCRusher
Copy link

MCRusher commented May 31, 2023

I like to scale my windows based on the monitor resolution, which most gui libraries have a mechanism to allow.

But I haven't been able to find a way to get this info in nimx without manually stepping into SDL2 or winapi

I have both an SDL2 implementation as well as a winapi implementation I've written for nimx for my application to allow this, I haven't written a linux or macos version since I can't test them currently (and I'd never be able to test a mac version, I don't own a mac)

It'd be nice to have this functionality in nimx itself, and if you find my code useful and not broken code that just happens to work, feel free to use it.

If it's acceptable (which I doubt since you might not want it calling quit), I'd be willing to make a PR myself if you'd like, though I'm not sure where best to put it, maybe in the nimx/private/windows/XX_window.nim files?

from nimx/types import Rect, newRect

proc getDisplayBounds*(): Rect

when defined(nimxAvoidSDL):
    when defined(windows):
        import winim/lean except RECT
        proc WinQuit() {.noreturn.} =
            var msg = newWString(4096)
            FormatMessage(
                dwFlags=FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS,
                lpSource=nil,
                dwMessageId=GetLastError(),
                dwLanguageId=DWORD MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                lpBuffer=msg,
                nSize=4096,
                Arguments=nil
            )
            quit($msg)
        proc getDisplayBounds(): Rect =
            let monitor = MonitorFromPoint(POINT(x: 0, y: 0), MONITOR_DEFAULTTOPRIMARY)
            var mInfo = MONITORINFO(cbSize: cast[DWORD](sizeof MONITORINFO))
            if GetMonitorInfo(monitor, mInfo.addr) == 0:
                WinQuit()
            let mb = mInfo.rcMonitor
            return newRect(mb.left.float32, mb.top.float32, (mb.right - mb.left).float32, (mb.bottom - mb.top).float32)
    elif defined(linux):
        import x11/xlib
        proc getDisplayBounds(): Rect =
            let display = XOpenDisplay(nil)
            if display == nil:
                quit("Could not open display")
            let screen = DefaultScreenOfDisplay(display)
            if screen == nil:
                quit("Could not get screen from display")
            
            let width = WidthOfScreen(screen)
            let height = HeightOfScreen(screen)

            return newRect(0, 0, width.float32, height.float32)
    else:
        {.fatal: "Not implemented".}
else:
    from sdl2 import nil
    proc getDisplayBounds(): Rect =
        if sdl2.wasInit(sdl2.InitVideo) == 0: # video subsystem has not been initialized
            if sdl2.initSubsystem(sdl2.InitVideo) != 0: # allows this function to be called before newWindow
                quit($sdl2.getError())
        var r: sdl2.Rect
        if sdl2.getDisplayBounds(0, r) != sdl2.SdlSuccess:
            quit($sdl2.getError())
        return newRect(r.x.float32, r.y.float32, r.w.float32, r.h.float32)
@yglukhov
Copy link
Owner

Nimx has a notion of Window.pixelRatio, please have a look at sdl_window to see how it is used. On most platforms it comes from screenScaleFactor(), which unfortunately is not implemented on windows, so you might want to look into that.

@yglukhov
Copy link
Owner

And then I reread your comment and understand that you meant something else entirely :)

Yes, getDisplayBounds() could be quite useful in nimx/screen.nim.

@MCRusher
Copy link
Author

MCRusher commented May 31, 2023

I could make a PR if you want, to add it to nimx/screen.nim, unless you'd rather/are planning to do it and would rather do it a different way

or if you want to make changes, like changing the error handling to throw an exception rather than call quit or something

Right now I'm on my linux laptop trying to bang out a linux X11 version and then I should have the three main desktop bases covered for this.

@MCRusher
Copy link
Author

The x11 one seems to be working now, so I edited the code above to add it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants