ウィンドウを「グループ化」する方法はありますか?つまり、2つ以上のウィンドウの端を結合して、一方が移動するともう一方も一緒に移動して、1つの大きなウィンドウとして機能するようにする方法はありますか?または、少なくとも1つのウィンドウを移動すると、もう1つのウィンドウも同じように移動するという点で似ていますか? Ubuntu GNOME 15.10とGNOME 3.18を実行しています。
一見、wmctrl
を使用すると非常にうまくいくように見えますが、いつものように、現実は理論よりも(はるかに)複雑です。
これは回答として投稿することをheしています。これは実験的な概念的な回答であり、いくつかのバグのためにすぐに使えるソリューションではありません(まだ)。それにもかかわらず、現在のバージョンの問題を解決するための情報を得るために投稿しています。この質問は、スムーズなソリューションを作成できるかどうかを確認するためのさらなる開発(IMO)にとって十分興味深いものです。
スクリプトはPython
で作成しましたが、この言語は私が実行している問題とは無関係です。主にwmctrl
の使用の特性に関連しています。
Icouldはウィンドウを配置するためにxdotool
を使用できますが、OPは一連のウィンドウを別のワークスペースに移動することに言及しているため、wmctrl
にはいくつかの利点があります。 Gnomeを使用します。ワークスペースはUnityとは異なります。
ウィンドウをグループとして移動する
上記の画面キャストの例はUnityで作成されました。ただし、Gnome
でも同様に機能するはずです(逸脱は別として、スクリプトについては以下を参照してください)。
a
で呼び出して、最前面のウィンドウをグループに追加することにより、ウィンドウのグループを作成できます。スクリーンキャストでは、コマンドを(Unity)ランチャーにGnome
に追加しました。これはショートカットキーで実行できます。r
を使用してスクリプトが呼び出されると、スクリプトはすべてのウィンドウを同様にグループから移動し、ウィンドウを相互に復元します。a
を指定して実行すると、以下のスクリプトは現在アクティブなウィンドウ、その位置とサイズ(wmctrl -lG
の出力の対応する行のように)をファイルwgroup_data.txt
(~
内)に追加します。r
を指定して実行すると、スクリプトはファイルを読み取り、位置を変更したウィンドウを探し、古い位置と新しい位置の間のベクトルを計算し、それに応じて他のウィンドウを移動します。これまでのところ問題ありません。
ただし、、ウィンドウの1つが現在のワークスペースの境界線に完全に収まらない場合、、スクリプトは失敗します。実際、wmctrl
コマンドは失敗します。これは、スクリプトの「外部」でも失敗し、単一のコマンドとして実行されるためです。
#!/usr/bin/env python3
import subprocess
import os
import sys
arg = sys.argv[1]
# vertical deviation for Unity (use 0 for Gnome)
deviation = 28
fdata = os.environ["HOME"]+"/wgroup_data.txt"
def get_wmctrl():
# try because of buggy wmctrl...
try:
return subprocess.check_output(["wmctrl", "-lG"]).decode("utf-8")
except subprocess.CalledProcessError:
pass
def remove_window(window):
data = open(fdata).readlines()
[data.remove(l) for l in data if l.startswith(window)]
open(fdata, "wt").write(("").join(data))
def addwindow():
relevant = get_wmctrl()
frontmost = hex(int((subprocess.check_output(["xdotool", "getactivewindow"]).decode("utf-8").strip())))
frontmost = frontmost[:2]+str((10-len(frontmost))*"0")+frontmost[2:]
open(fdata, "+a").write([l+("\n") for l in get_wmctrl().splitlines() if frontmost in l][0])
print(frontmost)
def rearrange():
wlist = get_wmctrl()
if wlist != None:
group = [(l.strip(), l.split()) for l in open(fdata).read().splitlines() if not l in ("", "\n")]
try:
changed = [w for w in group if (w[0] in wlist, w[1][0] in wlist) == (False, True)][0] #
# only proceed if one of the grouped windows moved (give priority to a light loop if not):
follow = []
for w in group:
if not w == changed:
test = (w[0] in wlist, w[1][0] in wlist)
if test == (True, True):
follow.append(w)
Elif test == (False, False):
# remove closed window from list
remove_window(w[1][0])
# only proceed if there are windows to move:
if follow:
# find match of the moved window (new coords)
wlines = wlist.splitlines()
match = [l.split() for l in wlines if changed[1][0] in l][0]
# calculate the move vector
x_move = int(match[2])-(int(changed[1][2])); y_move = int(match[3])-(int(changed[1][3]))
for w in follow:
# should be changed to try?
w[1][2] = str(int(w[1][2]) + x_move); w[1][3] = str(int(w[1][3]) + y_move - deviation)
subprocess.Popen([
"wmctrl", "-ir", w[1][0], "-e",
(",").join([w[1][1], w[1][2], w[1][3], w[1][4], w[1][5]])
])
# update grouplist
while True:
try:
newlines = sum([[l for l in get_wmctrl().splitlines() if w in l] for w in [match[0]]+[item[1][0] for item in follow]], [])
open(fdata, "wt").write(("\n").join(newlines))
break
except AttributeError:
pass
except IndexError:
print("nothing changed")
if arg == "a":
addwindow()
Elif arg == "r":
rearrange()
スクリプトにはwmctrl
とxdotool
の両方が必要です
Sudo apt-get install xdotool wmctrl
スクリプトを空のファイルにコピーし、group_windows.py
として保存します
Gnomeを使用している場合:
スクリプトのヘッドセクションで、次の行を変更します。
deviation = 28
に
deviation = 0
異なるショートカットに2つのコマンドを追加します。
python3 /path/to/group_windows.py a
グループにウィンドウを追加する
python3 /path/to/group_windows.py r
スクリーンキャストに示すように、ウィンドウを再配置します
スクリーンキャストに示すように、グループにいくつかのウィンドウを追加してスクリプトをテストし、それらを移動して相対位置を復元します。
この問題は、いずれかのウィンドウが現在のワークスペースから出ることが予想される場合に、ウィンドウの移動を拒否することで、コードごとに解決できます。その場合、移動したばかりのウィンドウでも初期位置に戻して、相対位置を維持する必要があります。
ただし、これには大規模な計算が必要になり(コンピューターには何も必要ありませんが、コーディングが複雑になります)、現在のワークスペース外での部分的な配置を可能にするとよりエレガントになります。ウィンドウが「エッジの上または上」に手動で配置されても問題ありません。
この問題を解決するための提案は大歓迎です。