オープンソースのTaskRail-MacをもとにしたspacesKitフレームワークを利用して、現在のSpacesのIDを取得する実験的なAppleScriptです。
–> Download spacesKit.framework (To ~/Library/Frameworks/)
Spaces変更通知を正確に受信したい
Spacesの変更操作についてはNotificationを受信できます。でも、Spacesの切り替え表示から「元と同じSpace」を選んで、Spacesの切り替えが発生しなかったとしても同様にNotificationが発生します。「現在選択中のSpaces」の情報を取得できないのでNotificationを利用しただけでは実用性がいまひとつでした。
Spacesごとに別々のDesktop Pictureを指定していればDesktop Pictureのパスをもとに特定できなくはありませんが、すべてのSpacesで同じDesktop Pictureが設定されていると区別できません。
そこで、TaskRail-Macの機能を利用して現在有効なSpacesのIDを取得し、本当に別のSpacesに切り替えたことを検出できました。
ただ、そこまでやってもいろいろ試してみると意外な伏兵に遭遇。
アプリケーションのフルスクリーン動作画面というのはOS的には動的に生成する別のテンポラリSpacesを利用しているようです。アプリケーションをフルスクリーン表示にしたり、YouTubeのムービーを全画面表示させるとSpaces切り替えNotificationを受信したりで、この「フルスクリーン表示」状態を検出・除外する方法を知りたいところです。
TaskRail-Macの返してくるSpacesのID
Spaces関連では、Terminal上から、
defaults read com.apple.spaces
と操作することで詳細な情報を取得できますが、spacesKitフレームワーク(TaskRail-Mac)で得られるIDはこのdefaltsコマンドの結果とは異なっています。
TaskRail-MacのObjective-Cのコードを読んでみると単にカウントを行なっているだけでIDに(OS内の設定値にもとづいた)根拠はないように見えます。
TaskRail-Macが返すIDは、defaults readで設定値を読み取った中に該当するものが見つかりませんでした。
▲spacesKitが返してくるID。左側のものが17207、右側デフォルトのものが311@macOS 10.14
また、複数ディスプレイを接続した環境でも、返ってくるIDは1つのみであり、メインディスプレイ以外でSpacesが変更されてもID値に変更はないため、メインディスプレイのSpacesのIDを返してくるものと考えてください。
ここで言う「メインディスプレイ」とは、MacBook系のノート型マシンの本体内蔵ディスプレイではなく、デスクトップが表示されるソフトウェア的なメインディスプレイを指します。
元になっているTaskRail-Mac自体がかなり実験的なプログラムであり、広範なハードウェアコンフィグレーション環境下でテストされたものでなく、「ディスプレイごとに個別のスペース」設定を行なっていない環境のみを考慮したものとうかがわれます。
これは、別にTaskRail-Macが悪いのではなく、AppleがSpaces関連のAPIを整備・公開していないためです。
macOS 10.14上で動かす場合には、アプレット書き出しを行なってアプレットのバンドル内にFrameworkを格納するか、~/Library/FrameworksにFrameworkをインストールしてScript Debugger上で実行、あるいはSIPを解除してスクリプトエディタ上で実行することが可能です。
AppleScript名:spacesKitで現在のSpacesのIDを取得する.scptd |
— – Created by: Takaaki Naganoya – Created on: 2019/02/09 — – Copyright © 2019 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "spacesKit" –https://github.com/DamianSullivan/TaskRail-Mac use scripting additions set aSwitcher to current application’s TRDesktopSwitcher’s alloc()’s init() set aRes to aSwitcher’s getCurrentSpaceId() |
AppleScript名:space notifier |
— – Created by: Takaaki Naganoya – Created on: 2019/01/25 — – Copyright © 2019 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use framework "AppKit" use framework "spacesKit" –https://github.com/DamianSullivan/TaskRail-Mac use scripting additions property aSwitcher : missing value property currentSpace : 0 set aCenter to current application’s NSWorkspace’s sharedWorkspace()’s notificationCenter() aCenter’s addObserver:me selector:"spacesChanged:" |name|:"NSWorkspaceActiveSpaceDidChangeNotification" object:(missing value) set aSwitcher to current application’s TRDesktopSwitcher’s alloc()’s init() set currentSpace to aSwitcher’s getCurrentSpaceId() as integer on spacesChanged:aNotif set aRes to aSwitcher’s getCurrentSpaceId() as integer if aRes is not equal to currentSpace then log aRes display notification "Active Spaces changed to " & (aRes as string) say "Active Spaces changed to " & (aRes as string) using "Tom" set currentSpace to aRes end if end spacesChanged: |