Mac OS XでのAlfredの使用を模倣したいと思います。検索後にアプリを開こうとすると、プログラムがまだ実行されていない場合にのみ新しいウィンドウが開きます。そうでない場合は、そのアプリケーションの現在実行中のインスタンス。とにかく、新しいウィンドウを開く前にこれを確認するためにランチャーのデフォルトの動作を変更する必要はありますか?
4月7日更新:別のバージョンが追加され、Albertが見つかりました。更新とボーナスをご覧ください!!!
ダッシュ機能について:「」と尋ねました。とにかく、ランチャーのデフォルトの動作を変更して、開く前にこれを確認します新しいウィンドウ」。基本的な答えは、いや、通常のユーザーとしては、その動作をダッシュに追加する方法はありません。ただし、それを実装するユニティスコープ開発者がいる場合は、解決策と学習意欲がある場合は、それらにアプローチするか、自分で開発することができます。私のコーディングスキルは非常に控えめであるため、回避策としてシェルスクリプトとスクリプトのグラフィカルフロントエンドを使用します。
元の投稿:
私は、Zenityダイアログとwmctrlを使用して、あなたが求めたものを達成するスクリプトを書きました。これはグラフィカルスクリプトであることに注意してください。つまり、GUIのウィンドウでのみ機能し、ttyで何かを起動しようとしても機能しません。その上、私が理解していることから、アルフレッドはまったく同じことをしています。 here および here の説明に従って、デスクトップショートカットまたはランチャーショートカットを作成できます。
#!/bin/bash
# Author: Serg Kolo
# Description: A launcher script that checks whether
# or not a window of a particular program already exists
# If a window of such program is open, bring it to focus
# Otherwise - launch a new window
# Written for https://askubuntu.com/q/440142/295286
# Date: April 6 , 2015
#
MYPROG=$( zenity --entry --title='MY LAUNCHER' --text='Type the name of application to run' )
sleep 0.5
wmctrl -lx | awk '{print $3}' | grep -i "$MYPROG"
if [ $? -eq 0 ]; then
sleep 1
wmctrl -xa $MYPROG
#as an alternative try the line bellow
#wmctrl -a $MYPROG
exit 1
else
$MYPROG &
exit 0
fi
サイドノート:以前のバージョンでは、スクリプトはecho $?を使用して、以前の式が正常に終了したかどうかをテストしました。 muruの提案(編集から)に従って、コードをややコンパクトなバージョンに変更したため、以前のバージョンと現在のバージョンを確認することをお勧めします。
また、以前はwmctrl -a $MYPROG
はgoogle-chromeまたはchrome-browserのテストでは機能しませんでした。いくつかの愚かな理由で、一部のプログラムはウィンドウのWM_CLASSプロパティが大文字になっていますが、dpkg --get-selections
でリストされているプログラムは小文字です(man wmctrl
を読み取ってwmctrl -lx
を実行します)。 -axを追加することでこれを処理できます。スクリプトは、既に開いているクロムウィンドウを表示します
別のこと-wmctlrは時々遅延を必要とする(別のスクリプトでそれを経験した)という点でやや奇妙なので、sleep 1
行を追加する必要がありました。以前は、Firefoxでのオンとオフのようなものでしたが、現在は泳ぎながら動作します。
動作中のスクリプト
以下のアニメーションでは、スクリプトの最初の実行時に、Firefoxのインスタンスが1つ開いており、スクリプトがそのウィンドウにフォーカスを切り替えていることがわかります。 2番目のテストでは、これまで開いていなかったgoogle-chromeの新しいインスタンスを開きます。 (サイドノート:ちなみに、カイロドックを備えたopenboxであるデスクトップについて熱心な場合)
コメントの提案ごとに、埋め込みアニメーションが削除され、リンクのみが投稿されました。壊れている場合は報告してください! http://i.stack.imgur.com/puuPZ.gif
4月7日更新
Zenityのドロップダウンエントリボックスにリストされているすべてのプログラムを作成するために、スクリプトをいくらか改善しました。これで、ユーザーは各プログラムを記憶する必要がなくなりましたが、矢印キーを使用してそれらのリストをスクロールするか、ドロップダウンメニューを開くだけで済みます。また、この改善されたバージョンは、名前ではなくウィンドウIDによってウィンドウを上げるため、パフォーマンスが大幅に向上します。注:.desktopファイルを使用する方法は、cutコマンドを2回使用することで冗長になりますが、これまでのscript-fuはあまり良くないので、これですべてができます。改善のための提案を歓迎します!
#!/bin/bash
# Author: Serg Kolo
# Description: Second version of a launcher script that checks whether
# or not a window of a particular program already exists
# If a window of such program is open, bring it to focus
# Otherwise - launch a new window
# Written for https://askubuntu.com/q/440142/295286
# Date: April 7 , 2015
#
set -x
MYPROG=$(zenity --entry --text 'Select program from list' --entry-text $(ls /usr/share/applications/*.desktop | cut -d'/' -f5 | cut -d'.' -f1 | xargs echo))
sleep 0.5
# Do we have a window of such program ?
wmctrl -lx| awk '{print $3}' | grep -i $MYPROG
if [ $? -eq 0 ]; then
sleep 0.5 # if yes, find that window id, and raise it
WINID=$(wmctrl -lx | grep -i $MYPROG | awk 'NR==1{print $1}')
wmctrl -ia $WINID &
# exit 0
else
echo $MYPROG | grep -i libreoffice
if [ $? -eq 0 ]
then
MYPROG=$(echo $MYPROG | sed 's/-/ --/g')
fi
$MYPROG &
# exit 0
fi
ボーナス:
実際に Albert を見つけました。これはLinuxバージョンのAlfredですが、自分で試したことはありません。しかし、チェックアウトする価値があります。しかし、ジェイコブがすでに指摘したように、まだバグがあります。
Gnome-Doと呼ばれるアプリがあります。これは、Alfredにグラフィカルに似ていますが、このスクリプトと同じ機能はありません。
このスクリプトが気に入った場合、修正が必要な場合はお知らせください。役立つと思われる場合は、回答を忘れずに投票してください。
質問で説明されているようにアプリケーションを実行する場合、Dashの代替として使用できるスクリプトの下。
Dashと同じ機能を持つウィンドウが存在します。アプリケーションの1つ以上の文字を入力すると、アプリケーションがリストに表示されます。押す Enter 既に実行中かどうかに応じて、アプリケーションを起動または起動します。
ショートカットキーの組み合わせから呼び出すか、ランチャーでアイコンを設定してDashと同様に使用できます(以下を参照)。
#!/usr/bin/env python3
import subprocess
import os
import getpass
import time
user = getpass.getuser()
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
skip = ["%F", "%U", "%f", "%u"]; trim = ["chrome", "chromium", "nautilus"]
def apply(command):
if "libreoffice" in command:
proc = [l.split()[0] for l in get("ps -u "+user).splitlines() if "soffice.bin" in l]
module = command.split("--")[-1]
time.sleep(0.1)
try:
ws = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if process in w and module in w.lower()] for process in proc], [])[0]
subprocess.call(["wmctrl", "-ia", ws])
except IndexError:
subprocess.Popen(["/bin/bash", "-c", command+"&"])
else:
check = command.split("/")[-1][:14]
proc = [p.split()[0] for p in get("ps -u "+user).splitlines() if check in p]
time.sleep(0.5)
try:
ws = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if process in w] for process in proc], [])
if command == "nautilus":
real_window = [w for w in ws if "_NET_WM_WINDOW_TYPE_NORMAL" in get("xprop -id "+w)][0]
else:
real_window = ws[0]
subprocess.call(["wmctrl", "-ia", real_window])
except IndexError:
subprocess.Popen(["/bin/bash", "-c", command+"&"])
# default directories of .desktop files; globally, locally, LibreOffice- specific when separately installed
globally = "/usr/share/applications"; locally = os.environ["HOME"]+"/.local/share/applications"; lo_dir = "/opt/libreoffice4.4/share/xdg"
# create list of .desktop files; local ones have preference
local_files = [it for it in os.listdir(locally) if it.endswith(".desktop")]
global_files = [it for it in os.listdir(globally) if it.endswith(".desktop")]
lo_spec = [it for it in os.listdir(lo_dir) if it.endswith(".desktop")] if os.path.exists(lo_dir) else []
for f in [f for f in local_files if f in global_files]:
global_files.remove(f)
for f in [f for f in local_files if f in lo_spec]:
lo_spec.remove(f)
dtfiles = [globally+"/"+f for f in global_files]+[locally+"/"+f for f in local_files]+[lo_dir+"/"+f for f in lo_spec]
# create list of application names / commands
valid = []
for f in dtfiles:
content = open(f).read()
if all(["NoDisplay=true" not in content,"Exec=" in content]):
lines = content.splitlines()
name = [l.replace("Name=", "") for l in lines if "Name=" in l][0]
command = [l.replace("Exec=", "") for l in lines if all(["Exec=" in l, not "TryExec=" in l])][0]
valid.append((name, command))
valid.sort(key=lambda x: x[0])
# create zenity list + window
list_items = '"'+'" "'.join([f[0] for f in valid])+'"'
proposed = 'zenity --list --text "Type one or more characters... " --column="Application List" '+\
'--title="Dash the Second" --height 450 --width 300 '+list_items
try:
choice = subprocess.check_output(["/bin/bash", "-c", proposed]).decode("utf-8").strip().split("|")[0]
command = [r[1] for r in valid if r[0] == choice][0]
# command fixes:
for s in skip:
command = command.replace(" "+s, "")
for t in trim:
if t in command:
command = t
apply(command)
except subprocess.CalledProcessError:
pass
スクリプトにはwmctrl
がインストールされている必要があります。
Sudo apt-get install wmctrl
次に:
dash_alternative.py
として保存しますショートカットキーの組み合わせに追加します。[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]を選択します。 「+」をクリックして、コマンドを追加します。
python3 /path/to/dash_alternative.py
スクリプトが実行されると、/usr/share/applications
で表されるすべてのアプリケーションがリストされます。 .dektop
ファイルを検索し、すべてのアプリケーション名のリスト(最初の "Name ="行から)と、アプリケーションを実行するコマンド(最初の "Exec ="行から)を作成します。
その後、Zenityリストが作成され、すべてのアプリケーションがソートされた方法で表示されます。
アプリケーションが選択されるたびに、スクリプトはアプリケーションが実行されている場合、実行中のプロセスのリストを調べます。その場合、対応するウィンドウが表示されます。そうでない場合は、新しいインスタンスが開かれます。
12.04でスクリプトを実行するには(元の質問に12.04
というタグが付けられていたため、単にShebangを#!/usr/bin/env python
に変更し、コマンドで実行します。
python /path/to/dash_alternative.py
私がテストした限り、スクリプトは正常に機能します。コマンドおよびそれらの(ではない)対応するプロセス名(例:LibreOffice
<> soffice.bin
)、異なるウィンドウタイプ(nautilus
には、「実際の」ウィンドウ以外にいくつかの異なるウィンドウタイプがあります)、複数のpidアプリケーションごと(Chromium
、Google-chrome
)例外が発生する可能性がありますが、上記の例で修正しました。誰かが問題に遭遇した場合、それを言及してください。
下のアイコンを右クリックして[セーフ]としてdash_alternative.png
として保存します
以下のコードを空のファイルにコピーし、~/.local/share/applications
としてdash_thesecond.desktop
として保存します。 /path/to/dash_alternative.py
(スクリプト)および/path/to/dash_alternative.png
(アイコン)の正しいパスを設定します
[Desktop Entry]
Name=Dash the Second
Exec=python3 /path/to/dash_alternative.py
Icon=/path/to/dash_alternative.png
Type=Application
Hidden=false
.desktop
ファイルをランチャーにドラッグします。
launcher(画面の左側の垂直パネル)の場合、これはタスク切り替えインターフェイスであるため、既にデフォルトの動作です。
dash(Ubuntuロゴをクリックすると開く大きなビット)の場合、おそらくソースコード自体に大幅な変更を加えることなく、この方法で動作を変更する方法はありません。
ただし、一部のアプリは、そのように動作するように設計されているため、既にこれを行っている場合があります。ただし、すべてのアプリは、このような方法で実装されているわけではなく、必ずしも実装されるべきではありません。
ただし、別の機能として、ウィンドウを開いた場合、 Super+W、アプリケーション名の入力を開始すると、そのアプリケーションのウィンドウのみが表示されます。