Mac の JXA で現在のデスクトップの壁紙を変更する

  • 5
    いいね
  • 0
    コメント

最近は作業環境の自動化を細々と進めています。

AppleScript は何度読んでも読めないので JXA は非常にありがたいのですが、ちょっと込み入ったことをすると所望の動作をどう書けばいいか分からなくて、勉強の必要性を感じます。スクリプトエディタのヘルプがそっけなさすぎて分からないし、検索して出てきたものが AppleScript だと JXA に翻訳して読めない…。

前置きはこのくらいにしておきつつ、今回はデスクトップの壁紙を変更する方法です。これも AppleScript での方法はよくひっかかるのですが、JXA で書かれた例をあまり見なかったので記事を書くことにしました。

JXA で現在のデスクトップの壁紙を変更

System Events がカギです。私は最初 Finder の配下なのかなと思って無駄にヘルプを読み漁ってしまいました。

var se = Application("System Events");
var path = "/Library/Desktop Pictures/Yosemite 5.jpg";
se.currentDesktop.picture.set(path);

osascript のインタラクティブモードで上記を入力してみると良いでしょう。

$ osascript -i -l JavaScript

現在フォーカスがあたっているデスクトップの壁紙を指定されたパスのもので変更します。

AppleScript の場合は、ここは POSIX 云々で変換して…とありますが、JXA のこの場合はそのまま渡してもよいようです。

コマンドライン引数で指定された画像ファイルで現在のデスクトップ壁紙を変更

シェバン行に osascript を書くことで実行ファイルとすることもできます。

#!/usr/bin/osascript -l JavaScript

function run (arg) {
    var se = Application("System Events");
    if ( arg.length == 1 ) {
        se.currentDesktop.picture.set(arg[0]);
    }
}

C言語の main 関数のように、run 関数を書いておくとコマンドライン引数を上記の例のように受け取れます。

Bash とハイブリッドにする

もっとも、Bash の知識がそこそこあって、それを援用すると効率的である場合には、ハイブリッドのようなスクリプトを書くのも悪くないかなと思っています(パフォーマンスがことさら要求されることではないので)。

macgui
#!/bin/bash
set -o errexit

ARG1="$1"
shift

JSRUN="osascript -l JavaScript"

function dispatch_wallpaper {
    local path="$1"
    if [ -n "$path" -a ! -f "$path" ] ; then
        echo "\"$path\" is not found" >&2
        exit 1
    fi
    shift
    $JSRUN <<EOF
var path = "$path";
var se = Application("System Events");
se.currentDesktop.picture.get();
if ( path ) {
    se.currentDesktop.picture.set(path);
}
EOF
}

###
### main
###

if type "dispatch_$ARG1" &>/dev/null ; then
    dispatch_$ARG1 "$@" 2>&1
else
    echo "Usage:"
    COMMAND_LIST=$( grep "^function dispatch_" $0| sed -e 's/function  *dispatch_//' -e 's/ .*//' )
    echo "  $(basename $0) [$COMMAND_LIST]"
fi

このようなスクリプトを書いておくと、 dispatch_ で始まる名前の Bash 関数をサブコマンドで選ぶことができるので便利かもしれません。

$ macgui wallpaper "/Library/Desktop Pictures//Yosemite 5.jpg"

現在のデスクトップ以外のデスクトップを対象としたり、応用的な部分は気が向いたら追記していきます。こんな感じでできたよという方は、コメントなどでアドバイスしていただければ取り込んでいきたいなと思っています。