Macbookよりも高い解像度の外部モニターをラップトップから取り外すと、ウィンドウの幅はほとんど保持されますが、サイズはMacBook画面の(小さい)高さにクリップされます。モニターを再び接続すると、そのサイズはイライラするほど小さいままです。
私の質問は、開いているすべてのウィンドウを繰り返し処理し、サイズを保存して、モニターが再び接続されたら復元する方法はありますか?
Macbookよりも高い解像度の外部モニターをラップトップから取り外すと、ウィンドウの幅はほとんど保持されますが、サイズはMacBook画面の(小さい)高さにクリップされます。モニターを再び接続すると、そのサイズはイライラするほど小さいままです。
私の質問は、開いているすべてのウィンドウを繰り返し処理し、サイズを保存して、モニターが再び接続されたら復元する方法はありますか?
次の 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 ソリューション (Anne の回答を参照) は、最も簡単です。
支援アクセスを有効にする方法を理解するのに頼ることができない友人にこれを渡したい場合、またはより広く配布したい場合は、次の行を追加するだけです:
do shell script ¬
"touch /private/var/db/.AccessibilityAPIEnabled" ¬
with administrator privileges
これにより、通常の認証ダイアログがポップアップし、権限を使用して補助アクセスが有効になります。
支援アクセスなしでこれを行うことは実際には可能ですが、CoreGraphics/Quartz ウィンドウ サービス内のプライベート関数、つまりCGSPrivate.hを使用する必要があります。
パブリック API を使用すると、すべてのウィンドウを簡単に列挙できます。
CFArrayRef windows =
CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly |
kCGWindowListExcludeDesktopElements,
kCGNullWindowID);
これは辞書の配列を返します。各辞書には、高さ、幅、X、および Y の整数値を持つ kCGWindowBounds 辞書が含まれています。
ただし、これらのパブリック 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);
}
明らかに、これは非常に厄介であり、支援アクセスを要求できないアプリを本当に配布する必要がある場合にのみ考慮する必要があります。
Window Server プロトコルをリバース エンジニアリングして直接通信することもできますが、これはさらに厄介です。