Ubuntu 18.04のカスタマイズのついでに、自作Gnome Shell Extensionsにチャレンジ。ネットを探してもあまりサンプル例がなく、最初はこちらを参考にしました。
今回つくろうとしたもの:
・トップバーにアイコン(下画像:左から3個目のアイコン)をつける
・アイコンをクリックすると、Anacondaの仮想環境に入った状態でターミナル起動
というものです。
Anacondaの仮想環境を使っているため、通常はターミナルを立ち上げて、
を打ち込んで仮想環境に入りますが、この部分をワンクリックでできないかというものです。設定した「py36」という仮想環境には、機械学習用にTensorfowやPytorchなどのライブラリが入っています。
「source activate py36」のシェルスクリプト:
まず、仮想環境に入るためのコマンドである「source activate py36」を記入する「py36.sh」ファイルをつくります。そのまま「source activate py36」を実行させればいいというわけではなく(やってみたら失敗)、こちらを参考にしました。「source 〜」の場合は以下のようにやるといいようです。
追記:その後「conda activate py36」へ変更しました(こちらへ)。
・「py36.sh」ファイルをつくる(場所は問わず)。
・「py36.sh」の中に、以下の2行を書いて保存。
・「py36.sh」を実行可能にするために、ファイルを右クリックで「プロパティ>アクセス権>プログラムとして実行可能」にチェック(「chmod +x py36.sh」でも可)。
・「.bashrc」ファイル末尾のほうに
を書き込んでおく。以上。
・「py36.sh」ファイルをダブルクリックすれば先程の画像のように仮想環境に入った状態で起動するはず。そのままランチャーにしてもいいし、desktopファイルと連携してもいいと思います。
そのままコマンドを書いただけだと実行したらターミナルは終了となってしまうので、今回のようにターミナルが起動する直前に「eval」を使って「.bashrc」からコマンドを実行させると大丈夫なようです。
あとは、このシェルスクリプトを実行させるGnome Shell Extensionsをつくります。
screenを使った場合(おまけ:その1):
「eval」の方法が分からず「screen」で仮想環境をつくって試したこともありました。
以下のスクリプトをランチャーのようにダブルクリックで起動させると、screenで仮想環境のなかのAnacondaの仮想環境の中に入った状態でターミナルが起動します。
一応大丈夫なのですが、消し忘れるとすっど動いているということと、ここまで無理する必要もないかと、ようやく今回の方法に至りました。screenの勉強にはなったのでいずれ何かに使えればと。
尚、「sudo apt-get install screen」でインストール。
xdotoolを使った場合(おまけ:その2):
キー入力を自動化してくれる「xdotool」というのがあり、そのまま今回の「source activate py36(リターン)」を打ち込ませるスクリプトを書くだけ。
「py36.sh」などと保存し、右クリックで「プロパティ>アクセス権>プログラムとして実行可能」にチェック。ダブルクリックすればターミナルを起動しコマンドを実行してくれます。
長いスクリプトは「type」、一文字打つだけなら「key」を使って、普段ターミナルで打ち込むコマンドを書けばいいだけです。
この他、画面にフォーカスを与えたりマウス入力も可能なので、いろんなものを簡単に自動化できます。
xdotoolは、「sudo apt-get install xdotool」でインストール。
Gnome Shell Extensions(サンプル)をつくる:
Javascriptなので簡単なのかと思ったら独特の構文でわかりにくく、ネットで検索してもチュートリアルやサンプルも少なかったり(古かったり)するので、フルスクラッチでコーディングするよりも似たようなものを書き換えたほうがいいらしいです。
まずはこちらを参考に、ターミナルで以下を入力すると
対話形式で名前や説明など(とりあえず簡単に書いておく)を決めていくと、
「Hello World」サンプルをつくることができます。今回つくろうとしたもの:
・トップバーにアイコン(下画像:左から3個目のアイコン)をつける
・アイコンをクリックすると、Anacondaの仮想環境に入った状態でターミナル起動
というものです。
Anacondaの仮想環境を使っているため、通常はターミナルを立ち上げて、
source activate py36
を打ち込んで仮想環境に入りますが、この部分をワンクリックでできないかというものです。設定した「py36」という仮想環境には、機械学習用にTensorfowやPytorchなどのライブラリが入っています。
「source activate py36」のシェルスクリプト:
まず、仮想環境に入るためのコマンドである「source activate py36」を記入する「py36.sh」ファイルをつくります。そのまま「source activate py36」を実行させればいいというわけではなく(やってみたら失敗)、こちらを参考にしました。「source 〜」の場合は以下のようにやるといいようです。
追記:その後「conda activate py36」へ変更しました(こちらへ)。
・「py36.sh」ファイルをつくる(場所は問わず)。
・「py36.sh」の中に、以下の2行を書いて保存。
eval '$BASH_POST_RC'
BASH_POST_RC='source activate py36' gnome-terminal
・「py36.sh」を実行可能にするために、ファイルを右クリックで「プロパティ>アクセス権>プログラムとして実行可能」にチェック(「chmod +x py36.sh」でも可)。
・「.bashrc」ファイル末尾のほうに
eval "$BASH_POST_RC"
を書き込んでおく。以上。
・「py36.sh」ファイルをダブルクリックすれば先程の画像のように仮想環境に入った状態で起動するはず。そのままランチャーにしてもいいし、desktopファイルと連携してもいいと思います。
そのままコマンドを書いただけだと実行したらターミナルは終了となってしまうので、今回のようにターミナルが起動する直前に「eval」を使って「.bashrc」からコマンドを実行させると大丈夫なようです。
あとは、このシェルスクリプトを実行させるGnome Shell Extensionsをつくります。
screenを使った場合(おまけ:その1):
「eval」の方法が分からず「screen」で仮想環境をつくって試したこともありました。
以下のスクリプトをランチャーのようにダブルクリックで起動させると、screenで仮想環境のなかのAnacondaの仮想環境の中に入った状態でターミナルが起動します。
#!/bin/bash
#まず外部からscreen仮想環境をつくる
screen -dmS sc1
#外部から、そのscreen仮想環境にAnaconda仮想環境をつくる
screen -S sc1 -X stuff 'source ~/.pyenv/versions/anaconda3-5.1.0/bin/activate py36'`echo -ne '\015'`
#最後にその二重の仮想環境に入る
gnome-terminal -e 'screen -x'
一応大丈夫なのですが、消し忘れるとすっど動いているということと、ここまで無理する必要もないかと、ようやく今回の方法に至りました。screenの勉強にはなったのでいずれ何かに使えればと。
尚、「sudo apt-get install screen」でインストール。
xdotoolを使った場合(おまけ:その2):
キー入力を自動化してくれる「xdotool」というのがあり、そのまま今回の「source activate py36(リターン)」を打ち込ませるスクリプトを書くだけ。
#!/bin/bash
#まずターミナル起動
gnome-terminal
#ターミナルが開くまで1秒ディレイ
sleep 1s
#仮想環境に入るコマンド
xdotool type 'source activate py36'
#最後にリターンキー入力
xdotool key Return
「py36.sh」などと保存し、右クリックで「プロパティ>アクセス権>プログラムとして実行可能」にチェック。ダブルクリックすればターミナルを起動しコマンドを実行してくれます。
長いスクリプトは「type」、一文字打つだけなら「key」を使って、普段ターミナルで打ち込むコマンドを書けばいいだけです。
この他、画面にフォーカスを与えたりマウス入力も可能なので、いろんなものを簡単に自動化できます。
xdotoolは、「sudo apt-get install xdotool」でインストール。
Gnome Shell Extensions(サンプル)をつくる:
Javascriptなので簡単なのかと思ったら独特の構文でわかりにくく、ネットで検索してもチュートリアルやサンプルも少なかったり(古かったり)するので、フルスクラッチでコーディングするよりも似たようなものを書き換えたほうがいいらしいです。
まずはこちらを参考に、ターミナルで以下を入力すると
gnome-shell-extension-tool --create-extension
対話形式で名前や説明など(とりあえず簡単に書いておく)を決めていくと、
Name: Open_py36
Description: Open Terminal @py36
Uuid: 記入しなかったため自動的に「Open_py__@mne-ubu」になった
そうすると、以下のような画面がでてきます。
これは、メインのスクリプトの「extension.js」。
あとは、CSSとJSONファイルが付属しています。
これらのデータは、「~/.local/share/gnome-shell/extensions/」にあります。
サンプルを動かしてみる:
サンプルを動かすには再起動が必要なのですが、「Alt+F2」を押すと画面はそのままでExtensionsの再起動ができます。「Alt+F2」を押すと以下の画面がでてくるのでここで「r」を入力してリターンを押します。
ちょっと画面が変化して再起動します。
「Gnome-Tweaks>機能拡張」を開くと、先程のExtensionがリストに加わっているのでオンにします(以下:上から二段目)。
そうすると、トップバー右上にアイコンがでてきます。
このサンプルはトップバー上のアイコンをクリックすると画面中央に「Hello World」という文字が出現してフェイドアウトしていく(2秒間)というものなので、「Gnome-Tweaks>外観>アニメーション」をオンにしておく必要があります。
スクリプトを書き換える:
次は、このサンプルをベースに最初につくった「py36.sh」を実行させるプログラムに書き換えます。
スクリプトを実行させるファンクションは、検索するとここが参考になりました。
const Util = imports.misc.util;
Util.spawnCommandLine("script");
一行目でライブラリをインポートし、二行目はスクリプト実行するファンクションのようです。「script」のところに、「py36.sh」のパスを入れればよさそうです。
「Hellow World」の表示内容を「env: py36」に変更し、位置も少し上の方に変えておきます。
const St = imports.gi.St;
const Main = imports.ui.main;
const Tweener = imports.ui.tweener;
//追加:ライブラリインポート
const Util = imports.misc.util;
let text, button;
function _hideHello() {
Main.uiGroup.remove_actor(text);
text = null;
}
function _showHello() {
//以下表示テキスト内容を「env: py36」へ変更
if (!text) {
text = new St.Label({ style_class: 'helloworld-label', text: "env: py36" });
Main.uiGroup.add_actor(text);
}
text.opacity = 255;
let monitor = Main.layoutManager.primaryMonitor;
//以下の高さ(monitor.height / 4)へ変更
text.set_position(monitor.x + Math.floor(monitor.width / 2 - text.width / 2),
monitor.y + Math.floor(monitor.height / 4 - text.height / 2));
Tweener.addTween(text,
{ opacity: 0,
time: 2,
transition: 'easeOutQuad',
onComplete: _hideHello });
//以下のスクリプト実行コマンドを追加
Util.spawnCommandLine("/home/mirrornerror/Documents/myshell/py36.sh");
}
function init() {
button = new St.Bin({ style_class: 'panel-button',
reactive: true,
can_focus: true,
x_fill: true,
y_fill: false,
track_hover: true });
//以下のアイコンをターミナルへ変更
let icon = new St.Icon({ icon_name: 'utilities-terminal-symbolic',
style_class: 'system-status-icon' });
button.set_child(icon);
button.connect('button-press-event', _showHello);
}
function enable() {
Main.panel._rightBox.insert_child_at_index(button, 0);
}
function disable() {
Main.panel._rightBox.remove_child(button);
}
5箇所ほど変更追加(赤文字)しただけです。
アイコンについては、「Icon Browser」が便利です。
以下のようにアプリケーションとして、既存のアイコンリストを見ることができます。
たしか「sudo apt-get gtk3-icon-browser」でインストールできたはずです。
NormalとSymbolicというのがあり、Symbolicがシンプルなアイコンです。
今回参考としたサイト:
あまりないのですが、以下。あとは既存のExtensionsのコードを参考に改造していくほうが早そうです。
・GNOME Shellの拡張機能を作ってみよう
・How I developed my first gnome-shell extension
・GNOME WIKI: Extensions
・github gnome-shell-extensions
・GNOME Developer: Tutorial for beginners and code samples
・GNOME Developer: gtk3-icon-browser
「Argos」というGnome-shell-extensions:
簡単なものであれば、gnome-shell-extensionsにある「Argos」というextensionが非常に便利です。トップバーに追加できる機能拡張で、よく使うフォルダや自作のスクリプトなども実行できます。
Argosのgithubサイトに使い方など詳しくのっています。
今回つくったAnaconda仮想環境に入るためのスクリプトも入れてみましたが結構簡単に実装できました。
この画像にあるように比較的よく使うものを組み込んでみました。
・普通のターミナル起動
・Anaconda仮想環境ターミナル起動
・ローカルネットワークサーバ起動
・各ディレクトリ(Home/Documents/Downloads)
一番下にある「argos.r.sh」をクリックするとスクリプトを書くためのファイルが開きます(以下)。
#!/usr/bin/env bash
URL="github.com/p-e-w/argos"
DIR=$(dirname "$0")
HOME=/home/mirrornerror
DOC=/home/mirrornerror/Documents
DWN=/home/mirrornerror/Downloads
PYTHON=/home/mirrornerror/.pyenv/versions/anaconda3-5.1.0/bin//python
echo "| iconName=view-more-symbolic"
echo "---"
echo "Terminal | iconName=utilities-terminal-symbolic bash=pwd terminal=true"
echo "Anaconda py36 | iconName=utilities-terminal-symbolic bash='/home/mirrornerror/Documents/myshell/py36.sh' && 'terminal=false'"
echo "192.168.3.7:8008 | iconName=utilities-terminal-symbolic bash='$PYTHON -m http.server 8008 --bind 192.168.3.7' && 'terminal=true'"
echo "---"
echo "home | iconName=folder-symbolic href='file://$HOME'"
echo "Documents | iconName=folder-symbolic href='file://$DOC'"
echo "Downloads | iconName=folder-symbolic href='file://$DWN'"
echo "---"
echo "more"
echo "--$URL | iconName=help-faq-symbolic href='https://$URL'"
echo "--$DIR | iconName=folder-symbolic href='file://$DIR'"
いまのところこんな感じです。
echoを追加していくことで、内容がリスト化(ネストも可)されていきます。あとはタイトルとアイコン、そしてコマンドを記入していきます。外部にシェルスクリプトを配置しておけば、ここからコマンド起動させることができるので、いろんなことができそうです。
関連:
gnome shell extensions:自作その2