window_manager icon indicating copy to clipboard operation
window_manager copied to clipboard

`setPosition` seems not to take consider into the scale factor

Open idlist opened this issue 5 months ago • 2 comments

平台是 Windows 11。

似乎 setPosition 不会考虑屏幕的缩放倍率:

我的场景是我想做一个能够记录窗口位置的功能,而我平时用两个显示屏,主屏幕缩放率 250% 放在右边,而副屏幕 100% 缩放倍率放在左边,主屏幕的左上角和副屏幕的右上角对齐。

当通过 getPosition 获得了窗口位置,再用 setPosition 还原时,如果窗口在副屏幕上,它的实际位置会变成 位置 * (主屏幕倍率 / 副屏幕倍率) (在这个情况下也就是 2.5 倍),结果就是随便挪挪窗口就跑出屏幕外拖不回来了 🤔

虽然应该是可以通过 screen_retriever 的数据在 Dart 端手工计算正确的位置,但是显然如果 setPosition 自身能够正确处理的话还是会更省事一点的。

idlist avatar Mar 21 '24 19:03 idlist

试着用 screen_retreiver 在 Dart 端手动修复了这个问题,修起来似乎很简单,只要 setPosition 的时候把缩放倍率比例乘回去就行了。但我没有更多屏幕的环境,所以并不清楚对不对。

idlist avatar Mar 22 '24 03:03 idlist

试着查了一下问题出在哪里:

https://github.com/leanflutter/window_manager/blob/ef786b1574455ca141cea899ca2db788731163d4/windows/window_manager.cpp#L722-L725

这里乘了个 devicePixelRatio,而

https://github.com/leanflutter/window_manager/blob/ef786b1574455ca141cea899ca2db788731163d4/windows/window_manager.cpp#L708-L709

可能这里的 devicePixelRatio 拿的是主屏幕的缩放倍率而不是窗口位置所在屏幕的倍率,不过没仔细往下看,不一定对。

似乎只要这个倍率调一下就行了。这里 是我自用的小工具的处理方法。


我自己后来又测了一下,发现其实这个问题还和窗口大小有关……

当窗口在两个屏幕的交界处的时候,Windows 会根据窗口主要在哪边来决定显示倍率(确切地说是以窗口大小的一半为分界线),而这会导致在 setPosition 的时候如果窗口在缩放倍率不一致的非主屏幕上,但是位置在 (窗口大小的一半 * 缩放倍率比) (比如窗口大小为 200px,缩放倍率比为 2.5,那么这个范围就是 250px)的范围内时,窗口仍然被算作在主屏幕内,那么这个时候再把缩放倍率比乘回去反而会出问题……

试着自己调整了一下,但是感觉除非能够指定 setPosition 时设置在哪个显示器上,目前没有完美的方法。

idlist avatar Mar 23 '24 06:03 idlist