當您從筆記本電腦上拔下具有較高分辨率的外接顯示器時,Windows大多保留其寬度,但其大小會被剪裁到macbook屏幕的(較小)高度。當你重新插入顯示器時,它們的尺寸仍然很小。有沒有辦法在Mac OS X中遍歷所有打開的窗口?
我的問題是:有什麼辦法可以遍歷所有打開的窗口,保存它們的大小,並在顯示器重新插入後還原它們?
當您從筆記本電腦上拔下具有較高分辨率的外接顯示器時,Windows大多保留其寬度,但其大小會被剪裁到macbook屏幕的(較小)高度。當你重新插入顯示器時,它們的尺寸仍然很小。有沒有辦法在Mac OS X中遍歷所有打開的窗口?
我的問題是:有什麼辦法可以遍歷所有打開的窗口,保存它們的大小,並在顯示器重新插入後還原它們?
下面的AppleScript展示如何:
代碼:
tell application "System Events"
set theProcesses to application processes
repeat with theProcess from 1 to count theProcesses
tell process theProcess
repeat with x from 1 to (count windows)
set windowPosition to position of window x
set windowSize to size of window x
set position of window x to {0, 0}
set size of window to {100, 100}
end repeat
end tell
end repeat
end tell
注:腳本需要輔助裝置(AFAD)訪問:
「系統偏好設置」→「通用艾策斯」→「啓用輔助設備的訪問」
編輯(應答評論)
啓用來自AppleScipt的AfAD可能會改善用戶體驗,但不要在每次腳本執行時都這樣做,只有在禁用了AfAD的情況下才啓用AfAD。在不通知用戶的情況下啓用功能不是很好的做法,請提示用戶啓用AfAD。
例子:
set AccesEnables to do shell script "[ -e \"/private/var/db/.AccessibilityAPIEnabled\" ] && echo \"Yes\" || echo \"No\""
if (AccesEnables is equal to "No") then
set askUser to display dialog "This application requires access for assistive devices. Enable this feature?" default button 2
set answer to button returned of askUser
if answer is equal to "OK" then
do shell script "touch /private/var/db/.AccessibilityAPIEnabled" with administrator privileges
else
close
end if
end if
的AppleScript的解決方案,用於其見安妮的回答,是迄今爲止最容易的。
如果你想要把這個交給誰不能上依賴的朋友要弄清楚如何啓用輔助訪問,或者更廣泛地分發,只需添加這行:
do shell script ¬
"touch /private/var/db/.AccessibilityAPIEnabled" ¬
with administrator privileges
這會彈出通常的驗證對話框,然後使用權限打開輔助訪問。
實際上可以在沒有輔助訪問的情況下執行此操作,但它需要在CoreGraphics/Quartz Window Services中使用私有函數,即CGSPrivate.h。
隨着公共API,你可以輕鬆地枚舉所有的窗戶:
CFArrayRef windows =
CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly |
kCGWindowListExcludeDesktopElements,
kCGNullWindowID);
這將返回字典的數組,每個字典包含kCGWindowBounds字典,它具有高度,寬度,X和Y整值。
但是這些公共API是嚴格只讀的。實際移動的窗口,你必須動用CGSPrivate.h做這樣的事情:
CGSConnection conn = _CGSDefaultConnection();
for (NSDictionary *window in windows) {
CGSWindow wid = (CGSWindow)[[window objectForKey:@"kCGWindowNumber"] intValue];
CGRect bounds;
CGRectMakeWithDictionaryRepresentation([window objectForKey:@"kCGWindowBounds"],
&bounds);
CGSMoveWindow(conn, wid, bounds.origin);
}
顯然,這是非常討厭的,你應該只考慮它,如果你真的需要分發應用程序,可以不要求輔助訪問。
你也反向工程窗口服務器協議,並直接與之對話,但這是令人討厭連。
+1,但它可能是值得展示如何以編程的輔助訪問通過要求授權(做shell腳本......具有管理員權限)轉動。 – abarnert 2012-07-09 21:19:23
太糟糕了,我不能再+1 ......但「以管理員權限」已經彈出一個對話框,詢問是否給予許可,讓你不想彈出一個對話框,詢問是否要彈出對話框,要求准予,除非你是Windows Vista的忠實粉絲。 :) – abarnert 2012-07-09 22:17:45
這並非完全正確。第一個對話框通知用戶需要啓用其他功能才能使用該應用程序。第二個對話框只需要輸入密碼,但不能解釋原因。使用這兩個對話框,用戶知道發生了什麼,並可以閹選擇啓用該功能與否。此外,您可以第一個對話框,需要具有管理員權限,並在下一個窗口中暖用戶會要求輸入密碼。通知用戶永久更改設置是不好的做法,這就是爲什麼應該使用附加對話框。 – Anne 2012-07-09 22:27:31