Önceden tanımlanmış bir pencere boyutu ve konumu olan bir uygulamayı nasıl başlatabilirim?

19

Unutmayın, Unity'deki Ctrl-Alt-Keypad kısayollarının, bunun yerine terminal komutlarını kullanarak ulaşması için bir yol var mı? Ekranın yarısı, sol veya sağ hizalı bir gui penceresi ayarlayan bir komut istiyorum.

Arka plan sayesinde, oturum açtıktan sonra çalışan bir komut dosyası yazıyorum. Geliştirme ortamımı (GVim ve IPython yan yana) açmak isteyip istemediğimi sormak için Zeniteyi kullanıyor. % Co_de% ve set lines= columns= ve .gvimrc c.IPythonWidget.width = c.IPythonWidget.height = kullanarak bu programlar için iki eşit boyutlu pencere elde etmeye çalışıyorum. Ancak, bu yaklaşımla ilgili problemler var.

    
sordu STim 25.04.2015 19:48

6 cevap

15

Ne koşacaksınız

İlk önce bir uygulamayı çağırmak ve daha sonra penceresini belirli bir konum ve boyuta yerleştirmek için uygulamayı çağırmak ve pencerenin gerçekte göründüğü an arasındaki süre , öngörülemez. Sisteminiz meşgulse, boşta olduğundan önemli ölçüde daha uzun olabilir.

Pencerenin görünmesinden sonra konumlandırmanın / yeniden boyutlandırmanın (hemen) yapıldığından emin olmak için "akıllı" bir yönteme ihtiyacınız vardır.

Bir uygulamayı çağırmak için Komut Dosyası, görünmesini ve ekranda görünmesini bekleyin

Aşağıdaki komutla, bir uygulamayı çağırabilir ve komutla birlikte görünmesi gereken konumu ve boyutu ayarlayabilirsiniz:

<script> <application> <x-position> <y-position> <h-size> <v-size>

Birkaç örnek:

  • gnome-terminal öğesini çağırıp penceresini% 50 olarak yeniden boyutlandırın ve sağ tarafa yerleştirin:

    <script> gnome-terminal 840 0 50 100
    

  • gedit öğesini çağırmak için penceresini soldaki ve çağırın gnome-terminal dizinine koyun, sağ tarafa yerleştirin ( v-size 46 ayarını pencerelerin arasında biraz boşluk bırakmak için) ):

    <script> gedit 0 0 46 100&&<script> gnome-terminal 860 0 46 100
    

  • Inkscape'i çağırmak için penceresini ekranın sol / üst çeyreğine yerleştirin:

    <script> inkscape 0 0 50 50
    

Komut dosyası ve nasıl kullanılır?

  1. hem xdotool hem de wmctrl değerini yükleyin. % Co_de% ile yeniden boyutlandırılması, bazı özelliklerin (özellikle wmctrl ) olmasına neden olabileceğinden her ikisini de kullandım.

    sudo apt-get install wmctrl
    sudo apt-get install xdotool
    
  2. Aşağıdaki komut dosyasını boş bir dosyaya kopyalayın, Unity olarak setwindow (uzantı yok) olarak kaydedin; gerekirse dizini oluşturun.
  3. Komut dosyasını çalıştırılabilir (!)
  4. ~/bin az önce oluşturduysanız, şunu çalıştırın: ~bin
  5. Komut dosyasını komutla sınayın (ör.)

    setwindow gnome-terminal 0 0 50 100
    

    Başka bir deyişle:

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

Her şey yolunda gidiyorsa, ihtiyacınız olan yerde komutu kullanın.

Komut dosyası

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

app = sys.argv[1]

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[4]+"% "+sys.argv[5]+"%"
        cmd4 = "xdotool windowmove "+procs[0][0][1]+" "+sys.argv[2]+" "+sys.argv[3]
        for cmd in [cmd1, cmd2, cmd3, cmd4]:   
            subprocess.call(["/bin/bash", "-c", cmd])
        break
    time.sleep(0.5)
    t = t+1

Ne yapar?

Komut çağrıldığında, bu:

  1. uygulamayı başlatır
  2. pencere listesine göz atıyor ( source ~/.profile kullanarak)
  3. yeni bir pencere açılırsa, yeni pencerenin çağrılan uygulamaya ait olup olmadığını ( wmctrl -lp kullanarak, pencerenin pidini uygulamanın pidiyle karşılaştırarak) kontrol eder.
  4. öyleyse, argümanlarınıza göre boyutu ve konumu ayarlar. Bir uygulama appr içinde "görünmüyor" durumunda. 15 saniye, komut dosyası, bir hata nedeniyle uygulamanın çalışmayacağını varsayar. Komut daha sonra yeni pencerenin sonsuza kadar beklemesini önlemek için sonlanır.

Küçük sorun

Birlik olarak, (%) co_de% veya ps -ef ww ile bir pencereyi (yeniden) konumlandırdığınızda (yeniden) ve pencereyi ayarladığınızda, pencere siz ayarladığınız sürece, ekranınızın kenarlarında küçük bir marj bırakmaya devam edecektir. % 100'e. Yukarıdaki görüntüde (3) görebilirsiniz; wmctrl penceresi xdotool position 0'a yerleştirilirken, Unity Launcher ve inkscape penceresi arasında hala küçük bir marj görebilirsiniz.

    
verilen cevap Jacob Vlijm 26.04.2015 11:20
4

Unity için bir grafik kullanıcı arayüzü aracılığıyla bunu kolayca yapmanızı sağlayan Worksets ( github ) adlı bir uygulama oluşturdum. Özgür ve açık kaynak.

Temel olarak, burada cevap olarak listelenen wmctrl ve xdotool çözümleri için bir sarıcıdır ve bu tür kurulumları hızlı bir şekilde yapmak ve kaydetmek için kolay bir yol sağlar.

    
verilen cevap Tumult 10.07.2017 07:07
3

İstediğiniz gerçek komut

gibi bir şeydir
wmctrl -r :ACTIVE: -b add,maximized_vert && 
wmctrl -r :ACTIVE: -e 0,0,0,$HALF,-1

Geçerli pencere ekranın yarısını kapatacak (ekranın $HALF 'sini ekranınızın boyutlarına getirecek) ve sol tarafa geçecektir. Sağa geçmek için

kullanın
wmctrl -r :ACTIVE: -b add,maximized_vert && 
wmctrl -r :ACTIVE: -e 0,$HALF,0,$HALF,-1 

Ayrıca, wmctrl kullanmak yerine ilgilendiğiniz pencerelerin kimliğini almak için :ACTIVE: ile oynayabilirsiniz. Buna yardım edemem, çünkü söz konusu pencerelere bağlı. Daha fazlası için% co_de yüzdesine bakın.

Bunun için bir senaryo yazdım. Unity'yi kullanmam, onunla çalışacağını garanti edemem, ama neden olmasın diye bir sebep göremiyorum. Yüklenecek man wmctrl , wmctrl ve xdpyinfo gerekir:

sudo apt-get install wmctrl x11-utils disper

Ardından, aşağıdaki komut dosyasını disper olarak kaydedin, ~/bin/snap_windows.sh ile yürütülebilir hale getirin ve çalıştırabilirsiniz

snap_windows.sh r

Sağ tarafa geçmek için. Sol taraf için chmod a+x ~/bin/snap_windows.sh ve pencereyi büyütmek için argüman kullanmayın. Geçerli pencerede çalıştığını unutmayın, böylece terminalden başka bir şey üzerinde çalışmasını istiyorsanız bir kısayol atamanız gerekir.

Komut, sizden beklediğinizden biraz daha karmaşıktır, çünkü hem tek hem de çift monitörlü kurulumlarda çalışmam için yazdım.

#!/usr/bin/env bash

## If no side has been given, maximize the current window and exit
if [ !  ]
then
    wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz
    exit
fi

## If a side has been given, continue
side=;
## How many screens are there?
screens='disper -l | grep -c display'
## Get screen dimensions
WIDTH='xdpyinfo | grep 'dimensions:' | cut -f 2 -d ':' | cut -f 1 -d 'x'';
HALF=$(($WIDTH/2));

## If we are running on one screen, snap to edge of screen
if [ $screens == '1' ]
then
    ## Snap to the left hand side
    if [ $side == 'l' ]
    then
        ## wmctrl format: gravity,posx,posy,width,height
    wmctrl -r :ACTIVE: -b add,maximized_vert && wmctrl -r :ACTIVE: -e 0,0,0,$HALF,-1
    ## Snap to the right hand side
    else
    wmctrl -r :ACTIVE: -b add,maximized_vert && wmctrl -r :ACTIVE: -e 0,$HALF,0,$HALF,-1 
    fi
## If we are running on two screens, snap to edge of right hand screen
## I use 1600 because I know it is the size of my laptop display
## and that it is not the same as that of my 2nd monitor.
else
    LAPTOP=1600; ## Change this as approrpiate for your setup.
    let "WIDTH-=LAPTOP";
    SCREEN=$LAPTOP;
    HALF=$(($WIDTH/2));
    if [ $side == 'l' ]
    then
        wmctrl -r :ACTIVE: -b add,maximized_vert && wmctrl -r :ACTIVE: -e 0,$LAPTOP,0,$HALF,-1
    else
    let "SCREEN += HALF+2";
    wmctrl -r :ACTIVE: -b add,maximized_vert && wmctrl -r :ACTIVE: -e 0,$SCREEN,0,$HALF,-1;
    fi
fi
    
verilen cevap terdon 25.04.2015 20:35
3

Bunu xdotool kullanarak yapabilirsiniz.

xdotool uygulamasını yüklemek için şunları çalıştırabilirsiniz:

sudo apt-get update && sudo apt-get install xdotool

Ardından + Alt + tuş takımını tuşlamak için tuş takımını tuşlar X penceresine çalıştırabilirsiniz:

xdotool key Ctrl+Alt+<keypad_key_value>

* & lt; keypad_key_value & gt; = aşağıdaki listede tuş takımı tuşunun değeri

Bir GUI programını çalıştırmak ve tuş vuruşunu X penceresine göndermek (bu durumda, xdotool komut yürütme sırasındaki etkin pencere):

<command> && window="$(xdotool getactivewindow)" xdotool key --delay <delay> --window "$window" <keypad_key_value>

* & lt; komut ve gt; = tuş vuruşunu göndermek istediğiniz pencereyi açan komut; Ve LT, gecikme ve gt; = tuşa basmadan önce milisaniye cinsinden bekleyeceği süre; & Lt; keypad_key_value & gt; = aşağıdaki listede tuş takımı tuşunun değeri

Çoğu durumda, tek başına işlem olarak verdiğiniz komutu çalıştırmanız gerektiğine dikkat edin (örn. yukarıdaki örnekte nohup <command> & yerine <command> komutu çalıştırarak), aksi halde xdotool kazandı " <command> 'nin çalışması tamamlanana kadar çalıştırılmalıdır.

Ayrıca, biraz gecikme ayarlamanız gerekecek, aksi takdirde, hedef pencere X 'sinde tam olarak yüklenmeden önce tuşa basılacak ( 500ms ' si civarında bir gecikme yapmalıdır).

<keypad_key_value> için olası değerler:

  • 0 : 90
  • 1 : 87
  • 2 : 88
  • 3 : 89
  • 4 : 83
  • 5 : 84
  • 6 : 85
  • 7 : 79
  • 8 : 80
  • 9 : 81

Bir başparmak kuralı olarak, X ortamındaki klavyedeki herhangi bir tuşun değerini bulmak için, xev komutunu çalıştırabilir ve anahtarın içindeki değeri çıktılamak için tuşa basabilir.

    
verilen cevap kos 25.04.2015 19:55
1

Ben Jacob Vlijm'in mükemmel gönderisine doğrudan yorum yapma hakkım yok, ancak betiği argümanlarla bir uygulamaya başlatabilmem için değiştirdim ( setwindow 'yi gedit --new-window ile kullanmak gerekli). Değişim:

if app in p and w[2] in p] for w in ws2]

için:

if app.split()[0] in p and w[2] in p] for w in ws2]
    
verilen cevap D. Hancock 13.05.2016 19:31
0

Yukarıdan Terdon'un senaryosu ile oynadım ve bazı yeni şeyler ekledim (monitörü seçme ve her monitör için yüksekliği ayarlama). Sanırım daha fazla monitör ekleyerek genişletilebilir. Umarım diğerleri yararlı bulacaktır.

Temel sözdizimi:

prog_name monitor l/r/m window_name (optional)

prog_name bu kodu kaydettiğiniz her neyse; Monitör, monitör numarasıdır örn. 1 yada 2; l / r / m sola veya sağa veya maks; ve window_name, hedef pencerenin adıdır (veya adının bir kısmı).

E.g .:

setwindow 1 m chrome

Bash komut dosyası

#!/usr/bin/env bash
set -e
#######################-    Early Definitions    -#######################

snap () {
    wmctrl -r ${WIN} -b toggle,add,maximized_vert && wmctrl -r ${WIN} -e 0,${WINX},0,${WINWIDTH},${WINHEIGHT}
    }

DISPLAYWIDTH='xdpyinfo | grep 'dimensions:' | cut -f 2 -d ':' | cut -f 1 -d 'x'';       ## Get screen dimensions
LEFTSCREENWIDTH=1024    ## user set
LEFTSCREENHEIGHT=720    ## user set
RIGHTSCREENHEIGHT=960   ## user set
let "RIGHTSCREENWIDTH=(DISPLAYWIDTH-LEFTSCREENWIDTH)"

#############################-    Logic    -#############################

if [ !  ]; then
    WIN=":ACTIVE:"
else
    WIN=
fi
case  in
    1)  # monitor one
        LEFT=0
        WINHEIGHT=${LEFTSCREENHEIGHT}
        let "WINWIDTH=LEFTSCREENWIDTH/2"
    ;;
    2)  # monitor two
        let "LEFT=LEFTSCREENWIDTH"
        WINHEIGHT=${RIGHTSCREENHEIGHT}
        let "WINWIDTH=RIGHTSCREENWIDTH/2"
    ;;
    "") # error please select a monitor
        echo "please select a monitor (1 or 2)"
        exit 0
    ;;
esac
case  in
    l|L)
        WINX=${LEFT}
        snap
    ;;
    r|R)
        let "WINX=LEFT+WINWIDTH"
        snap
    ;;
    ""|m|M)
        WINX=${LEFT}
        let "WINWIDTH=WINWIDTH*2"
        snap
    ;;
esac

exit 0
    
verilen cevap Philosopher Rex 02.07.2018 11:49

Etiketlerdeki diğer soruları oku