Mac csshX在外接屏无法正确获取屏幕大小的bug问题

Mac OS X 出了 10.9 之后, 外接屏支持显示独立的菜单栏, 以前csshX能在外接屏上正确的排列窗口, 没有重叠的情况出现. 现在因为多了菜单栏, 导致csshX获取的屏幕大小(包含了菜单栏面积)与实际可用的面积不相同, 也就出现了csshX排列出来的窗口有一定程度的重叠问题.

没办法只得看看csshX的源代码, 发现它用的是系统提供的NSScreen类中的visibleFrame方法来获取屏幕大小\位置等信息, 并没有针对外接屏和自带的屏幕有什么外理.

在Apple的开发者网站是搜到这个visibleFrame的解释, 看E文是说visibleFrame就是去除了dock和menu bar的矩形

visibleFrame
Returns the current location and dimensions of the visible screen.

- (NSRect)visibleFrame
Return Value
The rectangle defining the portion of the screen in which it is currently safe to draw your application content.

Discussion
The returned rectangle is always based on the current user-interface settings and does not include the area currently occupied by the dock and menu bar. Because it is based on the current user -interface settings, the returned rectangle can change between calls and should not be cached.

来源: NSScreen Class Reference

但实际用起来发现, 在外接屏下, 并不是这样的, 怀疑是OS X 10.9加入了外接屏支持显示独立的菜单栏的功能, 对应的系统库却没有跟进而产生的bug.

至此, 我也明白是冤枉了csshX了, 不过我的问题依旧没能解决, 通过help信息, 我找到csshX支持config file的设置, 想到也许可能用配置文件来强制指定实际的屏幕大小, 我就开始折腾.

根据指引, 我写了下面的配置信息

screen_bounds = { -1680,-282,1680,1028 }

前两段是屏幕的位置信息, 后面两段是屏幕大小(我减去了menu bar的大小), 不过试来试去, 都无法根据我指定的大小来工作, 很是纳闷. 只能继续看代码.

调试到最后, 发现有这么一段代码导致不工作, 仔细看那正则, 它用来过滤不符合格式的配置, 我的配置包含了负数, 不能匹配成功. 应该是作者当时没想到位置信息可以是负数的(负数的位置, 说明我的外接屏在主屏的左边).

172 sub parse_bounds {
173     my ($obj,$value) = @_;
174     if ($value =~ /^\s*\{\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\}\     s*$/) {
175     ¦   return [$1,$2,$3,$4];
176     }
177 }

打个patch先

--- /usr/bin/csshX 2014-03-20 17:13:23.000000000 +0800
+++ /tmp/csshX  2014-03-20 17:53:29.000000000 +0800
@@ -171,7 +171,7 @@

 sub parse_bounds {
     my ($obj,$value) = @_;
-    if ($value =~ /^\s*\{\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\}\s*$/) {
+    if ($value =~ /^\s*\{\s*(-?\d+)\s*,\s*(-?\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\}\s*$/) {
         return [$1,$2,$3,$4];
     }
 }

最后它终于能正常的在外接屏工作了, ^_^

2014-03-21 10:48489