如果你的屏幕分辨率是 1920×1080,那么一个全屏的窗口程序尺寸是多少呢?想都不用想,是 1920×1080。
那么输入设备输入的坐标是多少呢?是 X∈[0, 1919]
?还是 X∈[1, 1920]
?还是 X∈[0, 1920]
?
鼠标输入与触摸输入
一个有趣的问题,因为 1920×1080 分辨率的屏幕,其横向只有 1920 个像素,也就是说如果需要区分一个像素,那么只需要 1920 个数值就够了。这意味着 X∈[0, 1919]
或者 X∈[1, 1920]
的取值范围就能表示横向的所有像素了。
那么实际上最左侧的点的输入数值是多少呢?最右侧的点的输入数值是多少呢?
我写了一个最大化全屏的程序专门用来测试鼠标和触摸输入的数值是多少。
▲ 在鼠标输入的情况下,最右侧其实是 1919(我的屏幕是 2560×1080,所以最右侧是 2559)
测量的时候,鼠标是直接往右移动到底,移到不能动为止。
那么在触摸输入的时候又如何?
▲ 在触摸输入的情况下,最右侧是 1920(我的屏幕是 2560×1080,所以最右侧是 2560)
测量的时候,是让手指近乎在屏幕外触摸,不断触摸到能够在屏幕上看到的最小或最大值为止。
有趣的 1 像素
发现上面实验中有趣的现象了吗?明明只有 1920×1080 的屏幕分辨率,窗口明明只有 1920×1080 那么大,鼠标下收到正常范围内的输入坐标,而触摸下我们能收到超出我们窗口大小 1 像素的触摸事件!
问题并没有完——
如果说,触摸给了你超出窗口大小的坐标,那么你能如何使用这个坐标呢?虽然程序里收到什么坐标都无所谓(至少不崩),但如果你真拿它来渲染,就会在屏幕之外。
更有趣的是,虽然你能收到这个“在屏幕边缘之外”的坐标,但这个消息并不总会发送到你的程序里。更多的时候,你的程序根本就不会收到这个触摸事件,于是我们也就不能在程序里面更新窗口上显示的坐标到 1920 了,就像鼠标一样。
于是,你可能遇到的问题是:
- 如果你在屏幕的左侧边缘触摸,你的程序可以一直收到触摸事件,你能够得到正确的响应;
- 如果你在屏幕的右侧边缘触摸,你将仅能偶尔收到零星的刚好超出窗口大小的触摸坐标,大多数时候收不到触摸事件,于是你可能无法获知用户在屏幕右侧边缘进行触摸。
防踩坑秘籍
林德熙小伙伴告诉我说可以特意把窗口的尺寸做大一个像素。我试过了,确实能够让触摸在整个屏幕上生效,但对于双屏用户来说,就能在另外一个屏幕上看到“露馅儿”了的窗口,对于我这种强迫症患者来说,显然是不能接受的。
我的建议是,并不需要对这种情况进行什么特殊的处理。
本文会经常更新,请阅读原文: https://dotnet-campus.github.io//post/the-fantastic-one-pixel-of-the-touch-screen.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 dotnet 职业技术学院 (包含链接: https://dotnet-campus.github.io/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。