Programa Bash para abrir arquivos em um segundo monitor

3

Eu escrevi um pequeno script no bash que abre um arquivo e depois, cinco minutos depois, o fecha. Repete este procedimento e assim por diante.

O problema é que, onde quer que o mouse esteja apontado, o programa abre, eu gostaria que ele fosse aberto no meu segundo monitor, que é o tamanho perfeito para visualizar o arquivo.

Eu tentei usar as variáveis de exibição da seguinte maneira (na linha de comando) export DISPLAY =: 0.1. Mas, então, qualquer programa que eu chame da CLI depois disso, retorne um erro. (Erro: não é possível abrir o display: 0.1)

Alguém tem alguma sugestão?

editar:

Aqui está o script para abrir um arquivo chamado thesis.pdf a cada cinco minutos

#! /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
    
por Adam 10.06.2015 / 11:10

3 respostas

5

Para posicionar uma janela, você pode usar uma ferramenta que manipule eventos X, como xdotool ou wmctrl . Por exemplo, com wmctrl , você pode usar -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.

Normalmente, você pode ignorar a gravidade, portanto, para colocar uma janela no canto superior esquerdo da tela e torná-la 1200 x 700 pixels, execute:

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

O -r permite selecionar uma janela e :ACTIVE: significa a janela atualmente focada.

Você também pode simplificar seu script. Não há razão para analisar ps , a variável especial $! contém o PID do trabalho colocado mais recentemente em segundo plano. Em qualquer caso, a análise ps geralmente falhará, pois pode haver vários processos correspondentes a Thesis.pdf . Sempre haverá dois: o evince e o grep Thesis.pdf que você acabou de executar.

Então, com tudo isso em mente, você poderia fazer:

#! /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

Observe que eu removi o exit 0 porque, devido ao seu while true , ele nunca será alcançado e não faz sentido. Você pode brincar com os argumentos posicionais para descobrir onde deseja colocar a janela.

Por fim, uma observação sobre DISPLAY . Essas variáveis apontam para um display X. Esta não é uma tela, é o servidor X ativo. Muitos usuários podem estar executando servidores X paralelos em uma única máquina, isso permite escolher em qual deles uma janela deve ser exibida. Não tem absolutamente nada a ver com quantas telas físicas estão conectadas, a menos que cada tela esteja executando uma sessão X separada.

    
por terdon 10.06.2015 / 13:58
1

Esta resposta assume que você está usando o Unity:

O que você vai encontrar ao escrever um script para abrir um aplicativo em uma tela ou posição específica

Se você quiser chamar um aplicativo e, posteriormente, colocar sua janela em uma posição e tamanho específicos, o tempo entre chamar o aplicativo e o momento em que a janela aparecer

Você precisa de uma maneira (de preferência "inteligente") para garantir que o posicionamento / redimensionamento seja feito (imediatamente) após a exibição da janela.

O script abaixo (uma versão editada de este ) abre um aplicativo, possivelmente com o arquivo como argumento, em qualquer lugar na sua área de trabalho (no segundo monitor também). Ele espera que a janela apareça antes de mover a janela para sua posição e tamanho, para que ela funcione corretamente, não importa se seu sistema está lento (ou ocupado) ou não.

O script

#!/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


Como usar

  1. instale os dois xdotool e wmctrl . Eu usei ambos pois o redimensionamento com wmctrl pode causar algumas peculiaridades em (especificamente) Unity .

    sudo apt-get install wmctrl
    sudo apt-get install xdotool
    
  2. Copie o script abaixo em um arquivo vazio, salve-o como setwindow (sem extensão) em ~/bin ; crie o diretório, se necessário.

  3. Torne o script executável (!)
  4. Se você acabou de criar ~bin , execute: source ~/.profile
  5. Teste o script com o comando como (por exemplo)

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

    Em outras palavras:

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

Se tudo funcionar bem, use o comando onde você precisar.

Para abrir o aplicativo no monitor à direita

Se você tiver um segundo monitor conectado, pense nas telas combinadas como uma grande área de trabalho virtual, como no exemplo abaixo.

Neste exemplo, para colocar a janela na tela da direita, basta tornar sua posição x maior que a resolução x da tela esquerda. (> 1680 neste caso).

Para abrir o arquivo com seu aplicativo de maneira maximizada, defina ambos <horizontal-size (%)> e <vertical-size (%)> para 100 .

Questão secundária

No Unity, quando você (re) posiciona e (re) dimensiona uma janela com wmctrl ou xdotool , a janela sempre manterá uma pequena margem para as bordas da tela, a menos que você a defina para 100%. Você pode ver isso na imagem (3) acima; Enquanto a janela inkscape foi colocada em x position 0, você ainda pode ver uma pequena diferença entre o Iniciador Unity e a janela inkscape .

    
por Jacob Vlijm 10.06.2015 / 16:02
0

Estou tendo um tiro no escuro absoluto aqui, mas uma solução alternativa por enquanto poderia ser este script:

#!/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

Acredito que isso funcionou, para mim, configurar meu monitor intermediário em vez do monitor do meu laptop para o "monitor principal". Isso, em teoria, vai abrir o seu programa no monitor principal? - Eu sei que você disse que abre onde está o mouse, mas, é um tiro pequeno ...

Espero que você resolva:)

    
por Patrick 10.06.2015 / 12:53