開いているすべてのchromeウィンドウを識別し、それらを大きな画面のグリッドレイアウトに移動するスクリプトを記述しようとしています
最適な解像度がどうなるかわからないので、手動で配列に追加し、1 chromeウィンドウが利用可能な場合は2 = chrome使用可能なウィンドウは、そのサイズの配列に移動しますか?
現時点では、画面上のすべてのウィンドウを移動できます(これを行うとディスプレイが壊れます)が、chrome画面だけを移動する方法を見つけることができますか?
以下のスクリプトは私が持っていたいくつかのアイデアですが、スクリプトが機能しない瞬間に正しい方向を指摘してください
#!/bin/bash
#Chrome window crontroller
# Monitor 1920 X 1800
# Choose array for number of screens available
# Different screen positions
G=0
win1_X=5; win1_Y=24; win1_W=639; win1_H=499;
win2_X=642; win2_Y=24; win2_W=639; win2_H=499;
win3_X=1280; win3_Y=24; win3_W=639; win3_H=499;
win4_X=5; win4_Y=552; win4_W=639; win4_H=499;
ChromesAvailable()
{
CA=$(wmctrl -lx | grep Chromium | wc -l)
}
GetNumOfChrome()
{
WID=$(wmctrl -l | grep n | awk '{print$1}')
#echo "INFO: window id = $WID"
}
PlaceWindow()
{
X=${n}_X; Y=${n}_Y; W=${n}_W; H=${n}_H;
wmctrl -i -r "$WID" -e $G,${!X},${!Y},${!W},${!H}
}
if [ "$#" -gt 0 ]; then
case "$1" in
*)
echo "ERROR: invalid option $1"
echo "see --help for usage"
exit 1
;;
esac
exit 0
else
for n in win{1..4}; do
GetNumOfChrome
PlaceWindow
done
fi
編集-物事をより良く説明するために:-)
grep n
を使用すると、システム上で開いているすべてのウィンドウが読み込まれるので、grep Chromimum
を使用しようとしましたが、スクリプトはこれを好まない
GetNumOfChrome()
{
WID=$(wmctrl -l | grep n | awk '{print$1}')
#echo "INFO: window id = $WID"
}
別のアプローチは、ウィンドウを事前定義された(カスタマイズ可能な)グリッド(列/行)に配置することです。
例:
(cols
を3に設定、rows
を2に設定)に再配置:
(cols
を4に設定、rows
を2に設定)に再配置:
以下のスクリプトを使用してそれを行うことができます。前述のように、列と行の数、およびウィンドウ間のパディングを設定できます。スクリプトは、ウィンドウを配置する位置とサイズを計算します。
wmctrl
コマンドは、ランチャーまたはパネルの近くまたは非常に近くにウィンドウを移動するために使用すると、いくつかの特性を示します。したがって、マージン:
left_margin = 70; top_margin = 30
ゼロに設定することはできません。パネルとランチャーの両方に対して少なくとも数ピクセルの距離を保つ必要があります。両方のマージン値をそのままにすることをお勧めします。他のすべての値、パディング、列、行は、自由に操作して設定できます。
#!/usr/bin/env python3
import subprocess
import getpass
import sys
#--- set your preferences below: columns, rows, padding between windows, margin(s)
cols = 2; rows = 2; padding = 10; left_margin = 70; top_margin = 30
#---
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def get_res():
xr = get("xrandr").split(); pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
# get resolution
res = get_res()
# define (calculate) the area to divide
area_h = res[0] - left_margin; area_v = res[1] - top_margin
# create a list of calculated coordinates
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
# calculate the corresponding window size, given the padding, margins, columns and rows
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
# find windows of the application, identified by their pid
pids = [p.split()[0] for p in get("ps -e").splitlines() if sys.argv[1] in p]
w_list = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if p in w] for p in pids], [])
print(pids, w_list, coords)
# remove possibly maximization, move the windows
for n, w in enumerate(w_list):
data = (",").join([str(item) for item in coords[n]])+","+(",").join(w_size)
cmd1 = "wmctrl -ir "+w+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+w+" -e 0,"+data
for cmd in [cmd1, cmd2, cmd3]:
subprocess.Popen(["/bin/bash", "-c", cmd])
wmctrl
がインストールされていることを確認してください:)rearrange_windows.py
として保存します次のコマンドで実行します:
python3 /path/to/rearrange_windows.py <application>
例:chromium
ウィンドウを再配置するには:
python3 /path/to/rearrange_windows.py chromium
chrome
ウィンドウを再配置するには
python3 /path/to/rearrange_windows.py chrome
アプリケーションのプロセス名が引数として使用されるため、スクリプトを使用して、任意のアプリケーションのウィンドウをグリッドに配置できます。
コメントで要求されているように、スクリプトの動的バージョンの下。このバージョンのスクリプトは、ウィンドウの数に応じて列と行の数を計算します。再配置されたウィンドウの比率は、画面の比率に似ています。
セットアップと使用方法は上記のバージョンとほぼ同じで、列と行の数のみが自動的に設定されるようになりました。
#!/usr/bin/env python3
import subprocess
import getpass
import sys
import math
#--- set your preferences below: padding between windows, margin(s)
padding = 10; left_margin = 70; top_margin = 30
#---
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def get_res():
xr = get("xrandr").split(); pos = xr.index("current")
return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
# find windows of the application, identified by their pid
pids = [p.split()[0] for p in get("ps -e").splitlines() if sys.argv[1] in p]
w_list = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if p in w] for p in pids], [])
# calculate the columns/rows, depending on the number of windows
cols = math.ceil(math.sqrt(len(w_list))); rows = cols
# define (calculate) the area to divide
res = get_res()
area_h = res[0] - left_margin; area_v = res[1] - top_margin
# create a list of calculated coordinates
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
# calculate the corresponding window size, given the padding, margins, columns and rows
if cols != 0:
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
# remove possibly maximization, move the windows
for n, w in enumerate(w_list):
data = (",").join([str(item) for item in coords[n]])+","+(",").join(w_size)
cmd1 = "wmctrl -ir "+w+" -b remove,maximized_horz"
cmd2 = "wmctrl -ir "+w+" -b remove,maximized_vert"
cmd3 = "wmctrl -ir "+w+" -e 0,"+data
for cmd in [cmd1, cmd2, cmd3]:
subprocess.call(["/bin/bash", "-c", cmd])
開いているウィンドウの数が異なる場合の例を以下に示します。
特定のウィンドウを見つける
コマンド:
wmctrl -lp
次の形式ですべてのウィンドウをリストします。
0x19c00085 0 14838 jacob-System-Product-Name *Niet-opgeslagen document 1 - gedit
ここで、最初の列はウィンドウの一意のIDで、3番目の列はウィンドウを所有するアプリケーションのPIDです。
コマンド:
ps -e
次の形式ですべてのプロセスをリストします。
14838 ? 00:00:02 gedit
ここで、最初の列はアプリケーションのpid、最後の列はプロセス名です。
これらの2つのリストを比較することにより、特定のアプリケーション(スクリプトの17/18行目の結果としてw_list
と呼ばれる)に属するすべてのウィンドウ(id-)を見つけることができます。
pids = [p.split()[0] for p in get("ps -e").splitlines() if sys.argv[1] in p]
w_list = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if p in w] for p in pids], [])
行/列の数の計算
これは、列と行の数の両方が、再配置するウィンドウの数の切り上げられた平方根に等しいことを意味します。これは20行目で行われます。
cols = math.ceil(math.sqrt(len(w_list))); rows = cols
ウィンドウのサイズと位置の計算
列数を取得したら、使用可能な領域(画面解像度-左マージン/上部マージン)を列/行に分割するだけで、ターゲットウィンドウサイズが得られます。次に、スクリプトのヘッドに設定されているpadding
によって減少します。
w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
水平(x)位置は、水平ウィンドウサイズ(パディングを含む)×列番号の積の結果です。列。たとえば、300ピクセルの列が3つある場合、結果のx位置は次のようになります。
[0, 300, 600]
垂直(y)位置も同様に計算されます。次に、両方のリストが座標のリストに結合され、座標のリストでウィンドウが再配置されます。
これは、スクリプトの26〜28行目で行われます。
x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
実際の再配置は、最終的に(おそらく最大化されたウィンドウの最大化を解除した後)33行目以降から行われます。
以下のスクリプトは、任意の数のchromeまたはNx2グリッド(N行、2列)のクロムウィンドウをタイル表示します。Nは開いているウィンドウの数に依存します。ウィンドウが1つしかない場合、そのウィンドウは最大化されます(既に最大化されている場合は非最大化されます)。
#!/usr/bin/env bash
#################################################
# Exit if there are no running chrome processes #
#################################################
pgrep "chrom[e|ium]" &>/dev/null ||
echo "No Chrom[e|ium] processes are running" 1>&2 && exit
#########################
# Get screen dimensions #
#########################
read width x height < <(xrandr | grep -Po 'current\s*\K.*?(?=,)' )
###################################################################
# Get the names of all Chrome windows. I am using PIDs because #
# searching by name will match anything with chrome/chromium in #
# the title, not only chromium windows. It also matches a firefox #
# window open on this AU question, for example. #
###################################################################
mapfile -t windows <
<(wmctrl -pl | grep -f <(pgrep "chrom[e|ium]") |
cut -d' ' -f1)
####################################
# Get the number of Chrome windows #
####################################
numofwins=${#windows[@]}
#########################################
# Initialize the x and y positions to 0 #
#########################################
x=0
y=0
#############################################
# Get 1/2 the number of windows, rounded up #
#############################################
halfwins=$(printf "%.f" "$(echo $numofwins/2 | bc -l |
awk '{print int($1+0.5)}')")
######################################################
# If there's only one window, maximize/unmaximize it #
######################################################
[[ $numofwins -eq 1 ]] &&
wmctrl -i -r "${windows[@]}" -b toggle,maximized_vert,maximized_horz &&
exit;
##########################################################################
# The height of each window will be the height of the display divided by #
# half the number of windows #
##########################################################################
winheight=$(printf "%.f" "$(echo $height/$halfwins | bc -l)")
##################################################################
# The width of each window will be half the width of the display #
##################################################################
winwidth=$(($width/2))
##################################
# Iterate over each window found #
##################################
for winID in "${windows[@]}"
do
########################################
# Increment a counter. This is used to #
# know when we should change rows. #
########################################
let c++
###############################
# Position the current window #
###############################
wmctrl -i -r "$winID" -e 0,$x,$y,$winwidth,$winheight
##################################################
# If the counter is a multiple of 2, change rows #
##################################################
if [[ $((c % 2)) -eq 0 ]]
then
y=$((y+$winheight+2))
x=0
#######################################
# If it isn't, move to the right only #
#######################################
else
x=$((x+$winwidth+2))
fi
done