ほとんどの作業は、Webブラウザーとエディターの2つのアプリケーションで行います。私はAlt-Tabで頻繁にそれらの間を行き来します。また、常にIMクライアント(Hipchat)を開いていますが、他の2つのアプリと比較して操作することはほとんどありません。
繰り返し発生する不快な点は、Hipchatウィンドウを操作してAlt-Tabを(たとえば)エディターに戻した後、別のAlt-Tabがブラウザーに集中することを期待するように筋肉のメモリが調整され、再びHipchatに戻ることです。
Hipchatが何らかの方法でフォーカスを失った後、スタックまたはリーセンシーリストの一番下、またはそれが何であれ送信されるようにする方法はありますか?
あなたが尋ねるのは、特定のアプリケーションのウィンドウがonlyを最初または最後に表示できるようにすることです位置、z方向。
geditウィンドウ(この例では)がフォーカスを失うと、1つの位置だけを降下するのではなく、最後の位置(z方向、半透明のターミナルウィンドウの下)に送信されます :
それは可能ですが、いくつかの深刻な問題を克服する必要があります。ウィンドウが最後の位置に送られると、他のすべてのウィンドウのZオーダーを維持する必要があります。ただし、現在のところ、このzオーダーのウィンドウを提供できるツールはありません。 xdotool
とwmctrl
のどちらも、これに関する情報を提供していません。
ただし、(すべての)ウィンドウのフォーカス履歴を追跡することができます。別のウィンドウがフォーカスを取得すると、ウィンドウは1つの位置を下るので、バックグラウンドスクリプトを実行してウィンドウのフォーカス履歴を監視すると、ウィンドウのzオーダーを結論付けることができます。
以下のソリューションは、同時に実行する2つの小さなバックグラウンドスクリプトで構成されています。
focus_history.py
set_z.py
focus-history.py
#!/usr/bin/env python3
import subprocess
import time
import os
rootdata = os.environ["HOME"]+"/.focus_history"
open(rootdata, "wt").write("This is an empty line")
def current_windows():
try:
return subprocess.check_output(["wmctrl", "-lp"]).decode("utf-8")
except subprocess.CalledProcessError:
pass
def convert_format(w_id):
return w_id[:2]+(10-len(w_id))*"0"+w_id[2:]
def read_data():
return open(rootdata).read().splitlines()
def get_top(wlist):
try:
top = convert_format(
[l.split("#")[-1].strip() for l in subprocess.check_output(
["xprop", "-root"]
).decode("utf-8").splitlines() \
if "_NET_ACTIVE_WINDOW(WINDOW)" in l][0])
return [l for l in wlist if top in l][0]
except IndexError:
pass
if __name__ == "__main__":
while True:
time.sleep(1)
wdata = current_windows()
if wdata != None:
wlist = wdata.splitlines()
# get frontmost window (as in wmctrl -lG)
top = get_top(wlist)
oldlist = read_data()
if not any([top == oldlist[0], top == None]):
# clean up closed windows
[oldlist.remove(l) for l in oldlist if not l.split()[0] in wdata]
# remove possible other mentions of the active window
[oldlist.remove(l) for l in oldlist if l.startswith(top.split()[0])]
open(rootdata, "wt").write(("\n").join([top]+oldlist))
#!/usr/bin/python3
import subprocess
import time
import focus_history
# --- set the process name of your application below
proc = "gedit"
# ---
focus_hist = focus_history.rootdata
def get(val):
try:
return subprocess.check_output(val).decode("utf-8").strip()
except subprocess.CalledProcessError:
pass
def front_w():
get_front = str(hex(int(get(["xdotool", "getactivewindow"]))))
return get_front[:2]+(10-len(get_front))*"0"+get_front[2:]
while True:
time.sleep(1)
pid = get(["pgrep", proc])
front1 = ""
while pid:
time.sleep(1)
frontpid = get(["xdotool", "getactivewindow", "getwindowpid"])
front2 = frontpid == pid
if front2 != front1:
if front2 == False:
zdata = [l for l in open(focus_hist).read().splitlines()]
wins = list(reversed([l.split()[0] for l in zdata if not pid in l]))
for w in wins+[front_w()]:
cmd = ["xdotool", "windowraise", w]
subprocess.call(cmd)
pid = get(["pgrep", proc])
front1 = front2
スクリプトはwmctrl
とxdotool
の両方を使用します
Sudo apt-get install wmctrl xdotool
スクリプト1を空のファイルにコピーし、focus_history.py
として(正確に)保存します
スクリプト2を空のファイルにコピーし、set_z.py
としてまったく同じディレクトリに保存しますスクリプト1として。
スクリプトのヘッドセクションの次の行:
proc = "gedit"
"gedit"
をアプリケーションのプロセス名に置き換えます(引用符の間)
スクリプトのテスト実行:(追加の)ウィンドウを開く前に、コマンドでスクリプト1を起動します:
python3 /path/to/focus_history.py & python3 /path/to/set_z.py
[スクリプトは、少なくとも1回フォーカスされたウィンドウを認識します。ログイン時にスクリプトが実行される場合はそうなります]
前述のように、スクリプトは同じレベルの同じディレクトリにある必要があります。
次に、ウィンドウを開いて、その動作を確認します。アプリケーションは、フォーカスを失った場合、(非常に)バックグラウンドに移動する必要があります。
すべてが正常に機能する場合は、それをスタートアップアプリケーションに追加します。ダッシュ>スタートアップアプリケーション>追加。次のコマンドを追加します。
/bin/bash -c "sleep 15 && python3 /path/to/focus_history.py & python3 /path/to/set_z.py"
別の方法として、 here で説明されているように、ショートカットキーを設定して、特定のアプリケーションのウィンドウが存在する場合はそれを表示することもできます。
ただし、最初のアプリケーションのウィンドウに戻るには別のショートカットが必要です。
を除いて...、
2つのアプリケーションを切り替える1つのショートカットを設定します。しかし、それはこの質問の範囲外です...