Skip to content

getPosition and setPosition don't work correctly on Windows with multiple scaled screens #474

Closed as not planned

Description

@ToH2002

When using window_manager with a configuration with multiple screens in a Windows environment, the values from getPosition diverge massively from the ones reported by Windows directly.

Example:

  • main screen is 3840x2160, set to scale 125%
  • second screen (to the right) is 1920x1080, scale 175%

Putting a window on the second screen, Windows reports a horizontal position of 3120, which (taking into account the 1.25 scaling of the first screen) is perfectly fine to identify as being on the second screen. The physical position in unscaled pixels (x*1.25) is 3900, so finding the correct window is easy.

window_manager reports a horizontal position of 2242 - which suggests that the window sits fully on the first screen. There is no way to find out from window_manager's getPosition data that the window is actually on the second screen. It looks like window_manager uses the scale of the second screen to divide the pixel position, but even that doesn't fully work out (3900 / 1.75 would be 2228)

TL/DR: getPosition is broken when using multiple screens with different scaling!

Second issue is around setPosition:

When using the value I get from getPosition with the setPosition function, scaling strikes again:

  • window_manager uses the scale of the screen the window is currently on to calculate the actual position. So there is no predictable way to get a window to a specific position on multiple screens. Where setPosition() moves the window always depends on where it is currently. I can work around this by always using setPosition(0,0) first, but that's really a mess.

Also, of course, since the original position received by getPosition may be incorrect, I have no correct position to set the window to.

I could work around some of the problems by translating the incorrect values to something that setPosition can deal with, but if the values provided by getPosition don't even let my reliably find out what screen the window is currently on, such a correction function will only work correctly for some specific situation, and not at all in others (if two windows on different screens report the same x coordinate, there's no way I can correct for that - mathematics will just not allow it...).

I truly hope that this can be addressed - ideally, I could trust the position reported by getPosition so that simply using setPosition with that value puts the window to where it was before. This is essential for any app storing its window position on exit and restoring on start. Currently, this is pretty much unusable, unless all monitors use the same scaling (which is not always the case, especially with small "side screens".

Activity

  1. wantroba commented on Sep 21, 2026

    @wantroba

    I can reproduce this issue consistently on Windows with two monitors using different DPI scaling (100% + 125%).

    After some investigation, I found an interesting behavior:

    await windowManager.setPosition(targetPosition);
    final actual = await windowManager.getPosition();
    

    The first call places the window in the wrong position when restoring it to a monitor with a different DPI than the one where the application was initially created.

    However, calling setPosition() a second time with exactly the same coordinates immediately fixes the position:

    await windowManager.setPosition(targetPosition);
    
    final current = await windowManager.getPosition();
    if ((current - targetPosition).distance > 1) {
      await windowManager.setPosition(targetPosition);
    }
    

    In my tests:

    Same monitor: works on the first call.
    Moving the window manually between monitors: works.
    Restoring a previously saved position on another monitor (different DPI): the first setPosition() is incorrect, the second one always restores the correct position.

    This suggests that the first call triggers some DPI/monitor transition internally, and the window position is only stable after that transition completes.

    I don't know the root cause yet, but this workaround has been reliable for me so far.

  2. lijy91 commented on Sep 21, 2026

    @lijy91
    Member

    window_manager 0.5.x is no longer maintained: from 0.6.0 window_manager is rebuilt on nativeapi (Flutter package: nativeapi), and its platform code moves there.

    nativeapi doesn't handle this yet either, so it's now tracked in libnativeapi/nativeapi#63. Please follow it and add details there; once it's fixed there, it reaches window_manager through nativeapi.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions