LinuxでUnified Remoteをちょっと使いやすくする

# 概要

Unified RemoteはWindowsを始めMac、Linux(Raspberry Pi)をスマホからリモート操作できる便利なアプリですが、
Linux(Raspberry Pi)はあんまり使われていないのか不便な部分があるので修正してみる。

実はUnified Remoteのリモート先の操作部分はほとんどLuaスクリプトで構成されているので修正は難しくないです。


# Lancher

Lancherはスタートメニューに登録されているアプリ一覧からアプリを起動できますが、シェルに戻ってこないアプリを起動すると終了までリモートコントロールができなくなります…。

これはコマンドをリモートに送るCommandや予め設定したプログラムを起動するCustom Runでも同じです…。

上記はLua組み込みのos.execute関数でアプリ起動を実現しています、察しの良い方はもうお気づきでしょうが、os.execute関数は起動したアプリが終了するまでブロックする仕様なのでこんなことになるんですね…。

Luaにはブロックしないexecuteのような関数は標準では存在しないのでどうするのかというと、Windowsではstartコマンドをつけて、Linuxでは末尾に&をつけてバックグラウンド実行するのが***Lua公式で提示されている対応法***になっています…。

というわけで強制的に&をつけて常にバックグラウンド実行するように改造しましょう。

```/opt/urserver/remotes/Unified/Main/Launcher (Linux)/remote.lua```がLancherの操作部分なので、その中のactions.tap(タップされたときに動作する関数定義)を修正します。

os.execute関数の引数の最後に" &"を文字列結合演算子で結合しています。

```remote.lua
--コードの一部です
actions.tap = function (index)
	local item = list[index+1];

    local file = io.input(item);
    for line in io.lines() do
        if string.sub(line,1,5) == "Exec=" then --find the executable
            j = string.find(line,"%%"); --find any command line input
            if j ~= nil then
                --os.execute(string.sub(line,6,j-1));
                os.execute(string.sub(line,6,j-1) .. " &");
            else
                --os.execute(string.sub(line,6));
                os.execute(string.sub(line,6) .. " &");
            end
            break
        end
    end
    io.close(file);
end

```

# Send Text (クリップボード)

テキストボックスに打ち込んだ文字列をリモートのPCに送るコマンドです。

流石に日本語には非対応(というかキーボードストロークで送ってる？)で日本語は直接送れないんですが、クリップボード経由なら可能なようです。

ただ、Linux版の場合はクリップボードへの保存にxclipを使っていますが、xclipコマンドは***意図的に標準出力を閉じない仕様***になっている関係で終了したとみなされずにブロックしたまま戻ってこないことがあるようです。そうなると先程と同じくその後一切リモート操作を受け付けなくなります。

というわけでほぼ同等のプログラムで上記仕様になっていないxselに書き換えます。xselが入っていない場合はxselのインストールが必要です。(Raspberry Piには標準で入っていないようです…)

SendTextのプログラムは```/opt/urserver/remotes/Unified/Main/Send Text/remote.lua``` になります。

```remote.lua
--これも一部です
--@help Copy to clipboard
actions.copy = function()
	local code = utf8.replace(_text, "\"", "\\\"");
	print("Copying " .. code .. " into clipboard");
	if OS_WINDOWS then
		script.shell("echo \"" .. code .. "\" | clip");
	elseif OS_OSX then
		script.apple("set the clipboard to \"" .. code .."\"");
	elseif OS_LINUX then
		-- Might not work on every distribution..
		-- script.shell("echo \"" .. code .. "\" | xclip -selection c");
		script.shell("echo \"" .. code .. "\" | xsel -bi");
	else 
		print("WTF!?");
	end
end
```

「SEND TEXT」ボタンでも日本語テキストを送りたい場合は、一度クリップボードに保存して貼り付け(Ctrl + V)のキーコードを送るしかない模様。

```remote.lua
--一部です
--@help Send current text
actions.send = function()
	-- keyboard.text(_text);

	actions.copy();
	if OS_LINUX then
		--Chromiumで二重にキーコードを送る現象があるようなのでxdotoolでキーコードを送る(要xdotoolインストール)
		script.shell("xdotool key ctrl+v");
	else
		keyboard.stroke("ctrl", "v");
	end
end
```

# カスタムリモートの作成

自分で独自に作成したコードでリモート操作ができるカスタムリモートを作ることができます。

```/opt/urserver/remotes/Unified/Examples``` にサンプルがあるので、どれか一つをディレクトリごと(Runが無難)

```/opt/urserver/custom``` または ```~/.urserver/remotes/custom``` ディレクトリにコピーして書き換えます。


以下のファイルで構成されています。

- icon.png
- icon_hires.png
- layout.xml
- meta.prop
- remote.lua

*.pngはアプリに表示されるアイコンです、差し替えたいなら差し替えましょう。
meta.propでリモート名や概要などを設定します。
layout.xmlでリモートのUIを設定します。
remote.luaでリモートの動作をLua言語でコーディングします。

適当に、ボタンを押すと、アクティブになってるプログラムを終了するリモートを作成してみます。xdotoolでAlt+F4を送るだけです。

```meta.prop
meta.name: Application Killer
meta.author: Kill Application
meta.description: Send Alt+F4
meta.tags: example
```

```layout.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
	<row>
		<button text="Kill Program" ontap="commandkill" />
	</row>
</layout>
```

```remote.lua
--@help Kill Application
actions.commandkill = function ()
	-- os.start("C:\\foobar.exe");
	os.execute("xdotool key alt+F4");
end
```