web-dev-qa-db-ja.com

2番目のモニターでファイルを開くためのBashプログラム

ファイルを開いてから5分後に閉じるスクリプトをbashで作成しました。この手順を繰り返し繰り返します。

問題は、マウスをどこに向けてもプログラムが開くので、ファイルを表示するのに最適なサイズである2番目のモニターで開くことを望んでいることです。

次の方法で表示変数を使用してみました(コマンドラインで)export DISPLAY =:0.1。ただし、この後にCLIから呼び出すプログラムはすべてエラーを返します。 (エラー:ディスプレイを開くことができません:0.1)

誰か提案がありますか?

編集:

5分ごとにthesis.pdfというファイルを開くスクリプトです

#! /bin/bash

while true; do
    evince /home/adam/Desktop/Thesis.pdf &
    sleep 5m
    ps -ef | grep "Thesis.pdf" | awk '{print $2}' | xargs kill
done

exit 0
3
Adam

ウィンドウを配置するには、xdotoolwmctrlなどのXイベントを操作するツールを使用できます。たとえば、wmctrlでは、-eを使用できます。

   -e <MVARG>
          Resize  and  move  a  window  that  has been specified with a -r
          action according to the <MVARG> argument.
   <MVARG>
          A move and resize argument has the format 'g,x,y,w,h'.  All five
          components are integers. The first value, g, is the  gravity  of
          the  window,  with  0  being  the most common value (the default
          value for the window). Please see  the  EWMH  specification  for
          other values.

          The four remaining values are a standard geometry specification:
          x,y is the position of the top left corner of  the  window,  and
          w,h  is  the  width and height of the window, with the exception
          that the value of -1 in any position is interpreted to mean that
          the current geometry value should not be modified.

通常、重力は無視できます。そのため、画面の左上隅にウィンドウを配置し、1200 x 700ピクセルにするには、次を実行します。

wmctrl -r :ACTIVE: -e 1,1,1,1200,700

-rではウィンドウを選択でき、:ACTIVE:は現在フォーカスされているウィンドウを意味します。

スクリプトを簡素化することもできます。 psを解析する理由はありません。特殊変数$!は、最後にバックグラウンドに置かれたジョブのPIDを保持します。いずれにせよ、Thesis.pdfに一致するプロセスが複数ある可能性があるため、psの解析は失敗することがよくあります。常に2つあります:実行したevincegrep Thesis.pdfです。

したがって、すべてを念頭に置いて、次のことができます。

#! /bin/bash
while true; do
    ## Open the pdf
    evince ~/doc/a.pdf &
    ## Save the PID of evince
    pid="$!"
    ## Wait for a 1.5 seconds. This is to give the window time to
    ## appear. Change it to a higher value if your system is slower. 
    sleep 1.5
    ## Get the X name of the evince window
    name=$(wmctrl -lp | awk -vpid="$pid" '$3==pid{print $1}')
    ## Position the window
    wmctrl -ir "$name" -e 1,1,1,1200,700
    ## Wait
    sleep 5m
    ## Close it
    kill "$pid"
done

exit 0を削除したことに注意してください。なぜなら、あなたのwhile trueのせいで、到達できず、意味がないからです。位置引数を使用して、ウィンドウを配置する場所を特定できます。

最後に、DISPLAYに関するメモ。この変数はXディスプレイを指します。これは画面ではなく、アクティブなXサーバーです。多くのユーザーは、単一のマシンで並列Xサーバーを実行している可能性があります。これにより、ウィンドウを表示するユーザーを選択できます。各画面が個別のXセッションを実行していない限り、接続されている物理画面の数とはまったく関係ありません。

5
terdon

この回答は、Unityを使用していることを前提としています。

特定の画面または位置でアプリケーションを開くためのスクリプトを作成するときに実行すること

アプリケーションを呼び出し、その後、そのウィンドウを特定の位置とサイズに配置する場合は、callingとウィンドウの瞬間の間の時間実際にはが表示されます。これは必須ですが、予測できません。システムが占有されている場合、アイドル状態の場合よりも大幅に長くなる可能性があります。

ウィンドウが表示された後、(すぐに)位置決め/サイズ変更が行われることを確認する(できれば「スマート」)方法が必要です。

以下のスクリプト( this one の編集バージョン)は、デスクトップ上の任意の場所(同様に2番目のモニター)で、おそらくファイルを引数としてアプリケーションを開きます。ウィンドウが表示されるのを待ってから、ウィンドウをその位置とサイズに移動するため、システムが遅い(または占有されている)かどうかにかかわらず、正しく実行されます。

スクリプト

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

app = (" ").join(sys.argv[5:])

get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
ws1 = get("wmctrl -lp"); t = 0
subprocess.Popen(["/bin/bash", "-c", app])

while t < 30:      
    ws2 = [w.split()[0:3] for w in get("wmctrl -lp").splitlines() if not w in ws1]
    procs = [[(p, w[0]) for p in get("ps -e ww").splitlines() \
              if app in p and w[2] in p] for w in ws2]
    if len(procs) > 0:
        w_id = procs[0][0][1]
        cmd1 = "wmctrl -ir "+w_id+" -b remove,maximized_horz"
        cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert"
        cmd3 = "xdotool windowsize --sync "+procs[0][0][1]+" "+sys.argv[3]+"% "+sys.argv[4]+"%"
        cmd4 = "xdotool windowmove "+procs[0][0][1]+" "+sys.argv[1]+" "+sys.argv[2]
        for cmd in [cmd1, cmd2, cmd3, cmd4]:   
            subprocess.call(["/bin/bash", "-c", cmd])
        break
    time.sleep(0.5)
    t = t+1


それを使用する方法

  1. xdotoolwmctrlの両方をインストールします。 bothを使用しました。wmctrlでサイズ変更すると、(具体的に)Unityにいくつかの特異性が生じる可能性があるためです。

    Sudo apt-get install wmctrl
    Sudo apt-get install xdotool
    
  2. 以下のスクリプトを空のファイルにコピーし、~/binsetwindow(拡張子なし)として保存します。必要に応じてディレクトリを作成します。

  3. スクリプトを実行可能にします(!)
  4. ~binを作成したばかりの場合は、source ~/.profileを実行します
  5. 次のようなコマンドを使用してスクリプトをテスト実行します

    setwindow 0 0 50 100 gedit /path/to/file.txt
    

    言い換えると:

    setwindow <horizontal-position> <vertical-position> <horizontal-size (%)> <vertical-size (%)> <application> <file_to_open>
    

すべてが正常に機能する場合は、必要な場所でコマンドを使用します。

右側のモニターでアプリケーションを開くには

2台目のモニターを接続している場合は、下の例のように、結合された画面を1つの大きな仮想デスクトップと考える必要があります。

enter image description here

この例では、ウィンドウを右画面に配置するには、そのx位置を左画面のx解像度より大きくするだけです。 (この場合> 1680)。

アプリケーションでファイルを最大化して開くには、<horizontal-size (%)><vertical-size (%)>の両方を100に設定します。

軽微な問題

Unityでは、wmctrlまたはxdotoolのいずれかでウィンドウを(再)配置および(再)サイズ変更すると、設定しない限り、ウィンドウは常に画面の境界に小さなマージを保持します。それを100%にします。上記の画像(3)で確認できます。 inkscapeウィンドウがx位置0に配置されている間、Unityランチャーとinkscapeウィンドウの間に小さなマージが見られます。

1
Jacob Vlijm

ここでは絶対的な暗闇での撮影を行っていますが、現在の回避策は次のスクリプトです。

#!/bin/bash
# Author: Andrew Martin
# Credit: http://ubuntuforums.org/showthread.php?t=1309247
echo "Enter the primary display from the following:"            # Prompt for the display
xrandr --prop | grep "[^dis]connected" | cut --delimiter=" " -f1    # query connected monitors
read choice                             # read the users's choice of monitor
xrandr --output $choice --primary                   # set the primary monitor

これは、ラップトップモニターの代わりに中間モニターを「メインモニター」に設定するのに有効だったと思います。これは、理論的には、メインモニターでプログラムを開きますか?-マウスがある場所で開くと言ったのは知っていますが、これはちょっとしたショットです...

あなたがそれを解決することを願っています:)

0
Patrick