web-dev-qa-db-ja.com

Ubuntu 14.10 Aeroスナップは2つの画面の水平セットアップですか?

私はなんとか Aero snap left and right working in metacity Ubuntu 14.1 を取得し、正しいwinctrlコマンドを考えて、2つのコマンドで同じ効果を模倣できるようにしたいと思います下の画像のように2つの画面が水平方向に隣り合って配置される画面設定。私はこれをMetacity(GNOMEクラシック)で動作させたいので、他のウィンドウマネージャーに移動する気はまったくありません。したがって、これは特にMetacity GNOMEクラシック環境の答えを見つけて見つけるための質問です。

enter image description here

私が欲しいのは、現在のwinctrlコマンドを拡張することです。それらは現在、画面全体の幅の半分を画面全体の長さの左または右に使用することで機能します。 Super_L+leftと入力すると、アクティブウィンドウで左半分が使用され、Super_L+rightと入力すると、アクティブウィンドウで合計水平ピクセルの右半分のサイズが使用されます。

[hpenvy15 ~] $ cat > ~/bin/left.sh
#!/bin/bash
sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,0,0,`xwininfo -root | grep Width | awk '{ print (($2/2))}'`,`xwininfo -root | grep Height | awk '{ print $2 }'`
^C
[hpenvy15 ~] $ cat > ~/bin/right.sh
#!/bin/bash
sleep 0.1 && wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz && wmctrl -r :ACTIVE: -e 0,`xwininfo -root | grep Width | awk '{ print (($2/2)+5) ",0," (($2/2)) }'`,`xwininfo -root | grep Height | awk '{ print $2 }'`
^C

2つの画面を持つ新しいセットアップでは、幅が1920 + 1920ピクセルです。ウィンドウの理想的な幅は1920の半分で、これは1920/2 = 960です。新しいleftおよびrightコマンドで、現在見つかっているウィンドウがどこにあるかを計算し、leftが入力されている場合は、最も近い960幅のピクセルブロックに移動します、2画面、1920 + 1920構成に存在する4つのブロックのいずれかで、1画面1920構成で最も近い960幅のブロックにも機能します。以下に図を示します。

これは、1と2に外部画面があり、3と4にラップトップ画面がある場合の構成です。現在、Super_L+leftをクリックすると、ウィンドウが画面の左半分のTotalWidth/2に移動します。大きすぎて、1 + 2になります。

最初のleftコマンドでペイン3に移動し、次にleftコマンドで2に移動し、次のコマンドで1に移動します。

   +-------------------++-------------------++-------------------++-------------------+
   |                   ||                   ||                   || +------------+    |
   |                   ||                   ||                   || |            |    |
   |                   ||                   ||           <-------++-+            |    |
   |                   ||                   ||                   || |            |    |
   |         1         ||         2         ||         3         || |       4    |    |
   |                   ||                   ||                   || |            |    |
   |                   ||                   ||                   || +------------+    |
   |                   ||                   ||                   ||                   |
   |                   ||                   ||                   ||                   |
   +-------------------++-------------------++-------------------++-------------------+

これは、幅960ピクセルの2つの半分にラップトップ画面のみがある場合の構成です。

現在、Super_L+rightをクリックすると、ウィンドウが画面の右半分のTotalWidth/2(番号4に対応)に移動します。

   +-------------------++-------------------+
   | +------------+    ||                   |
   | |            |    ||                   |
   | |            |    ||                   |
   | |            |----++--->               |
   | |       3    |    ||         4         |
   | |            |    ||                   |
   | |            |    ||                   |
   | +------------+    ||                   |
   |                   ||                   |
   +-------------------++-------------------+

これは、2つの画面がオンになっているときのwmctrlの出力です。

wmctrl -d
0  * DG: 3840x1080  VP: 0,0  WA: 0,0 3840x1080  Workspace 1
1  - DG: 3840x1080  VP: N/A  WA: 0,0 3840x1080  Workspace 2
2  - DG: 3840x1080  VP: N/A  WA: 0,0 3840x1080  Workspace 3
3  - DG: 3840x1080  VP: N/A  WA: 0,0 3840x1080  Workspace 4

そして、これは2つの画面がオンの場合のxrandrの出力です。

[hpenvy15 ~] $ xrandr
Screen 0: minimum 8 x 8, current 3840 x 1080, maximum 32767 x 32767
eDP1 connected primary 1920x1080+1920+0 (normal left inverted right x axis y axis) 344mm x 193mm
   1920x1080      60.1*+   59.9     40.0  
   1680x1050      60.0     59.9  
   1600x1024      60.2  
   1400x1050      60.0  
   1280x1024      60.0  
   1440x900       59.9  
   1280x960       60.0  
   1360x768       59.8     60.0  
   1152x864       60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 connected 1920x1080+0+0 (normal left inverted right x axis y axis) 521mm x 293mm
   1920x1080      60.0*+   50.0     59.9     30.0     25.0     24.0     30.0     24.0  
   1920x1080i     60.1     50.0     60.0  
   1680x1050      59.9  
   1600x900       60.0  
   1280x1024      75.0     60.0  
   1440x900       59.9  
   1366x768       59.8  
   1280x800       59.9  
   1152x864       75.0  
   1280x720       60.0     50.0     59.9  
   1440x576i      50.1  
   1024x768       75.1     70.1     60.0  
   1440x480i      60.1     60.1  
   832x624        74.6  
   800x600        72.2     75.0     60.3  
   720x576        50.0  
   720x480        60.0     59.9  
   640x480        75.0     72.8     66.7     60.0     59.9  
   720x400        70.1  
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
1
719016

Ubuntu(Gnome)ClassicおよびGnome Flashback(Metacity)14.04で以下のスクリプトをテストしました。 Metacity用のスクリプトを作成する際にいくつかの特殊性があったため、xdotoolwmctrlの「混合」アプリケーションが必要でした。

ソリューション

スクリプトに次のことを要求した結果、

  • 左/右の画面を決定
  • 両方のモニターの解像度を計算する
  • 2つの画面の解像度が異なる場合も正常に機能します(ウィンドウの位置とターゲットサイズの両方を計算します)
  • セカンドスクリーンが接続されているかどうかに関係なく正常に動作する

-スクリプトは、私が予見したよりも少し広範囲になりました。

それがすること:

2台目のモニターが接続されている場合:
説明したとおりに機能します。

  • 2つの画面を4つの領域に分割します。各領域は、配置されている画面の半分のサイズです(前述のように、解像度も異なります)。
  • オプション「左」または「右」で実行:
    • ウィンドウをウィンドウの左/右の領域に移動します
    • targeted画面の半分のサイズに水平方向にサイズ変更します
    • ウィンドウを垂直に最大化します

2台目のモニターが接続されていない場合:
従来の方法で機能します。

  • オプション「左」で実行すると、画面の左半分で最前面のウィンドウが最大化されます。
  • 「右」オプションで実行すると、画面の右半分で最前面のウィンドウが最大化されます。

どうやって使うのですか

  • xdotoolwmctrlの両方をインストールします。

    Sudo apt-get install wmctrl
    Sudo apt-get install xdotool
    
  • スクリプトを空のファイルにコピーし、aero.pyとして保存し、コマンドで実行します。

    python3 /path/to/aero.py left
    python3 /path/to/aero.py right
    

スクリプト

#!/usr/bin/env python3
import subprocess
import sys

move = sys.argv[1]

def get(cmd):
    return subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
def execute(cmd):
    subprocess.call(["/bin/bash", "-c", cmd])

# screen resolutions ("raw")  
wds = [s for s in get("xrandr").split() if s.endswith("+0")]
# x-res left/right)
left = [scr.split("x")[0] for scr in wds if scr.endswith("+0+0")]
right = [scr.split("x")[0] for scr in wds if not scr.endswith("+0+0")]
# x-positions areas
left_pos = [0, int(int(left[0])/2), int(left[0])]
right_pos = [int(int(left[0])+int(right[0])/2)] if len(right) != 0 else []
x_positions = left_pos+right_pos
# frontmost window pos
frontmost =get("printf 0x%x "+get("xdotool getwindowfocus").strip())
frontmost = frontmost[:2]+"0"+frontmost[2:]
f_data = [l.split() for l in get("wmctrl -lG").splitlines() if frontmost in l][0][:6]
curr_pos = int(f_data[2])
area = len([x for x in x_positions if x <= curr_pos])
if move == "left":
    i = area-2; target_pos = x_positions[i] if i >= 0 else 0 
Elif move == "right":
    i = area; target_pos = x_positions[area] if area < len(x_positions) else x_positions[-1]
if i >= 2:
    perc = int((100*(x_positions[-1]-x_positions[-2])/sum([int(it) for it in left+right])))
else:
    perc = int((100*(x_positions[1]-x_positions[0])/sum([int(it) for it in left+right])))
# execute actions
cmd1 = "wmctrl -r :ACTIVE: -b remove,maximized_vert,maximized_horz"
cmd2 = "wmctrl -ir "+f_data[0]+" -e 0,"+str(target_pos)+","+"30,300,300"
cmd3 = "xdotool windowsize $(xdotool getactivewindow) "+str(perc)+"% 100%"
for cmd in [cmd1, cmd2, cmd3]:
    execute(cmd)

Gist.gisthub (最新バージョン)にも投稿されています

3
Jacob Vlijm