Как я могу запустить приложение с предопределенным размером окна и положением?

Я задаюсь вопросом, там какой-либо способ достигнуть влияния ярлыков Ctrl-Alt-Keypad в Единице с помощью терминальных команд вместо этого? Я хочу команду, которая устанавливает gui окно на половину размера экрана, любой левый или правый выровненный.

Посредством фона я пишу сценарий, который бежит, входят в систему. Это использует Zenity, чтобы спросить, хочу ли я открыть свою среду разработки (GVim и IPython бок о бок). Я пытался достигнуть двух окон равного размера для этих программ при помощи set lines= columns= в моем .gvimrc и c.IPythonWidget.width = и c.IPythonWidget.height = в моем ipython_qtconsole_config.py. Однако существуют проблемы, связанные с этим подходом.

26
задан 28 April 2015 в 12:15

10 ответов

С чем вы столкнетесь

Если вы хотите сначала вызвать приложение, а затем поместить его окно в определенное положение и размер, время между вызовом приложения и момент, когда окно действительно появляется , непредсказуем. Если ваша система занята, она может быть значительно дольше, чем когда она простаивает.

Вам нужен «умный» способ убедиться, что позиционирование / изменение размера выполняется (сразу) после появления окна .

Скрипт для вызова приложения, ожидания его появления и размещения на экране

С помощью приведенного ниже скрипта вы можете вызвать приложение и установить положение и размер, в которых оно должно отображаться, с помощью команды:

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

Несколько примеров:

  • Чтобы вызвать gnome-terminal , изменить размер его окна до 50% и поместить его в правую половину:

     
    
    
                      

У меня есть создать приложение под названием Worksets (на github ) для Unity, которое позволяет легко делать это через графический интерфейс пользователя - это бесплатно и открытый исходный код.

tTray menu

Это в основном оболочка для решений wmctrl и xdotool, перечисленных здесь в качестве ответов, и предоставляет простой способ быстро создавать и сохранять такие настройки.

3
ответ дан 23 November 2019 в 01:44

У меня нет представителя, который мог бы напрямую прокомментировать отличный пост Джейкоба Влайма, но я изменил скрипт, разрешающий запуск приложения с аргументами (необходимо использовать setwindow с gedit --new-window ). Измените:

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

на:

if app.split()[0] in p and w[2] in p] for w in ws2]
1
ответ дан 23 November 2019 в 01:44

Фактическая команда, которую вы хотите, - это что-то вроде

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

. Это заставит текущее окно занимать половину экрана (измените $ HALF на размеры вашего экрана) и переместитесь в левую сторону. Чтобы сделать привязку вправо, используйте

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

. Вы также можете поиграть с wmctrl , чтобы получить ID интересующих вас окон, вместо использования : ACTIVE: . Я не могу здесь помочь, так как это зависит от рассматриваемых окон. Посмотрите man wmctrl , чтобы узнать больше.


Я написал для этого сценарий. Я не использую Unity, поэтому не могу гарантировать, что он будет работать с ним, но я не вижу причин, почему нет. Требуется установить wmctrl , xdpyinfo и disper :

sudo apt-get install wmctrl x11-utils disper

Затем сохраните приведенный ниже сценарий как ~ / bin / snap_windows.sh , сделайте его исполняемым с помощью chmod a + x ~ / bin / snap_windows.sh , и вы можете запустить

snap_windows.sh r

для привязки к правой стороне. Используйте l для левой стороны и без аргументов, чтобы развернуть окно. Обратите внимание, что он запускается в текущем окне, поэтому вам нужно назначить ему ярлык, если вы хотите, чтобы он запускался на чем-либо, кроме терминала.

Сценарий немного сложнее, чем вы просите, потому что я написал его для работы как с одним, так и с двумя мониторами.

#!/usr/bin/env bash

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

## If a side has been given, continue
side=$1;
## 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
3
ответ дан 23 November 2019 в 01:44

Вы можете сделать это с помощью xdotool .

Чтобы установить xdotool , вы можете запустить:

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

Затем отправить Ctrl + Alt + нажатие клавиши на терминале X окно, которое вы можете запустить:

xdotool key Ctrl+Alt+<keypad_key_value>

* = значение клавиши клавиатуры в список ниже

Чтобы запустить программу с графическим интерфейсом пользователя и отправить нажатие клавиши в ее окно X (которое в данном случае является активным окном во время выполнения команды xdotool ), вы можете запустите:

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

* = команда, которая открывает окно, в которое вы хотите отправить нажатие клавиши; = время ожидания в миллисекундах перед отправкой нажатия клавиши; = значение клавиши клавиатуры в списке ниже

Обратите внимание, что в большинстве случаев вам нужно будет запустить команду, которую вы вводите, как автономный процесс (например, запустив nohup & вместо в примере выше), в противном случае xdotool не будет запущен до тех пор, пока выполнение не будет завершено.

] Также вам необходимо установить некоторую задержку, иначе нажатие клавиши будет отправлено до того, как целевое окно будет полностью загружено в X (подойдет задержка около 500 мс ).

Возможные значения для :

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

как thum Правило b: чтобы узнать значение любой клавиши на клавиатуре в среде X , можно запустить xev и нажать клавишу, чтобы вывести ее значение в терминал.

]
3
ответ дан 23 November 2019 в 01:44

Я поигрался с скриптом Тердона сверху и добавил кое-что новое (возможность выбора монитора и установки высоты для каждый монитор). Думаю, его можно было бы расширить, добавив больше мониторов. Надеюсь, другие сочтут это полезным.

Базовый синтаксис:

prog_name monitor l/r/m window_name (optional)

Где prog_name - это то, как вы сохранили этот код; монитор - это номер монитора, например 1 или 2; l / r / m - левое или правое или максимальное; а window_name - это имя (или часть его имени) целевого окна.

Например:

setwindow 1 m chrome

Bash-скрипт

#!/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 [ ! ${3} ]; then
    WIN=":ACTIVE:"
else
    WIN=${3}
fi
case ${1} 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 ${2} 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
0
ответ дан 23 November 2019 в 01:44

Скрипт оболочки, который можно превратить в файл « ~ / Desktop / Terminals.desktop » со значком ТЕРМИНАЛ на рабочем столе, чтобы запустить его с помощью:

/ usr / bin / gnome-terminal --window-with-profile = Красный --geometry = 100x52 + 200 + 0

/ usr / bin / gnome-terminal -окно-с-профилем = Бирюзовый --geometry = 100x52 + 400 + 0

/ usr / bin / gnome-terminal --window-with-profile = Зеленый --geometry = 100x52 + 600 + 0

/ usr / bin / gnome-terminal --window-with-profile = Синий --geometry = 100x52 + 800 + 0

/ usr / bin / gnome-terminal --window-with-profile = Cyan --geometry = 100x52 + 1100 + 0

$ cat /home/$USER/Desktop/Terminals.desktop

[Desktop Entry]
Encoding=UTF-8
Version=1.0
Type=Application
Exec=/home/$USER/.terminals
TryExec=
Icon=/usr/share/pixmaps/blueprint-config-xfree.png
X-GNOME-DocPath=
Terminal=false
Name=Terminal
GenericName=
Comment=
0
ответ дан 5 January 2021 в 22:55

Я изменил сценарий Джейкоба Влайма, чтобы разрешить добавление дополнительных аргументов / параметров к приложению .

Например, если вы хотите запустить Firefox с двумя вкладками в сценарии bash:

command = "firefox -new-tab -url https://duckduckgo.com -new-tab -url https://www.google.com"
path_to_your_setwindow_script/setwindow 0 0 32 100 $command

Затем модифицированный сценарий Джейкоба Влайма, приведенный ниже, примет первые 4 аргумента для настроек положения и размера, а затем остальные аргументы для запуска приложения

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

print('inside setwindow')
print(sys.argv)
print(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])

commandCore = sys.argv[5]

command= sys.argv[5:];
commandStr = " ".join(command)

print('commandCore:', commandCore, '\ncommandStr:', commandStr)

#print('exiting now...')
#sys.exit()

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

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 commandCore 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
0
ответ дан 5 January 2021 в 22:55

Для большинства программ есть очень простая опция« -джеметрия »:

xclock -geometry 150x150+20+20

KATE -GEOMEOMETRY 400x400 + 100 + 100

<appname> -geometry <height>x<width>+<posH>+<posV>
0
ответ дан 2 April 2021 в 00:37

Для простых задач можно использовать следующий сценарий bash.

#!/bin/bash

nemo &
sleep 2
LastWID=$(wmctrl -li | awk '{ print $1}' | sort | tail -n1)
wmctrl -ia $LastWID
wmctrl -i -r $LastWID -b remove,maximized_vert,maximized_horz
wmctrl -i -r $LastWID -e 0,900,300,700,700

Для большей гибкости используйте следующий скрипт, который является форком ответа Russo's answer. Удалена зависимость xdotool. Также (на мой взгляд) упрощен код.

Поместите этот скрипт в PATH и используйте его, используя

#!/usr/bin/env python3

import subprocess
import time
import sys

commandCore = sys.argv[5]

command= sys.argv[5:];
commandStr = " ".join(command)

get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")

w_id_pre_value = get("wmctrl -li | awk '{ print $1}' | wc -l").strip()
subprocess.Popen(["/bin/bash", "-c", commandStr],stdout=subprocess.DEVNULL,stderr=subprocess.DEVNULL)

while True:
    time.sleep(0.1)
    if w_id_pre_value < get("wmctrl -li | awk '{ print $1}' |wc -l").strip():
        break

w_id = get("wmctrl -li | awk '{ print $1}' | tail -n1").strip()

cmd1 = "wmctrl -is "+w_id
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert,maximized_horz"
cmd3 = "wmctrl -ir "+w_id+" -e 0,"+sys.argv[1]+","+sys.argv[2]+","+sys.argv[3]+","+sys.argv[4]
for cmd in [cmd1, cmd2, cmd3]:
    subprocess.call(["/bin/bash", "-c", cmd])

Прелесть этого скрипта на питоне в том, что вы можете создать файл оболочки, как

#!/bin/bash

setwindow 0 0 960 1078 firefox
setwindow 960 0 960 1078 nemo
setwindow 1920 0 960 1078 codium

и открыть несколько приложений в назначенных позициях.

Обновление 1:

Если у вас есть Python 3.5+, вы также можете использовать следующий код.

#!/usr/bin/env python3

import subprocess
import time
import sys

commandCore = sys.argv[5]

command= sys.argv[5:];
commandStr = " ".join(command)

w_id_pre_value = subprocess.run("wmctrl -li | awk '{ print $1}' | wc -l", shell=True, capture_output=True, text=True).stdout.strip()

subprocess.run(commandStr, shell=True)

while True:
    time.sleep(0.1)
    if w_id_pre_value < subprocess.run("wmctrl -li | awk '{ print $1}' |wc -l", shell=True, capture_output=True, text=True).stdout.strip():
        break

w_id = subprocess.run("wmctrl -li | awk '{ print $1}' | tail -n1", shell=True, capture_output=True, text=True).stdout.strip()

cmd1 = "wmctrl -is "+w_id
cmd2 = "wmctrl -ir "+w_id+" -b remove,maximized_vert,maximized_horz"
cmd3 = "wmctrl -ir "+w_id+" -e 0,"+sys.argv[1]+","+sys.argv[2]+","+sys.argv[3]+","+sys.argv[4]
for cmd in [cmd1, cmd2, cmd3]:
    subprocess.run(cmd, shell=True)

Однако он имеет некоторые проблемы.

  1. использование shell=True имеет много недостатков, и худшим из них являются возможные утечки безопасности
  2. "открыть несколько приложений в назначенных местах" не работает. Не знаю почему.
0
ответ дан 20 August 2021 в 13:55

Другие вопросы по тегам:

Похожие вопросы: