LINUX.ORG.RU

Как сделать, чтобы приложение открывалось в fullscreen?

 


1

3

Через контекстное меню файла выбираю Open with other application, в поле Use a custome command ввожу /usr/bin/название-приложения — файл открывается и просматривается. Всё в норме.

Вопрос же возник такой: какую команду добавить к /usr/bin/название-приложения, чтобы открывать файл сразу на весь экран?

На англоязычных форумах встречала упоминание wmctrl и эмуляцию нажатия клавиш Ctrl+F, но конкретного объяснения так и не нашла. Везде вода на уровне диванных теоретиков.

Как решить задачу с fullscreen? Поделитесь знанием, кто умеет.


Ответ на: комментарий от futurama

Открыла приложение и нашла ID открытого окна:

xdotool search --name 'Adobe Flash Player'
33554435

Подставила значение:

xdotool key --window 33554435 ctrl+f

Запускаю игру и отдаю команду в терминале

xdotool key --window 33554435 ctrl+f

Приложение переходит в fullscreen без элементов интерфейса.

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

Joanna
() автор топика
Ответ на: комментарий от futurama

xdotool search --classname Flashplayer key 'ctrl+f'

Это, скорее всего, может не заработать, так как метод XSendEvent работает не всегда. В GTK3 вообще не работает. Они теперь фильтруют клинетские сообщения. Типа безопасность. В GTK2 еще работает. Можешь сам проверить на своих приложениях (я не знаю, какой тулкит использует flashplayer - 2 или 3.

Когда ты указываешь search --classname, то работает XSendEvent.

Zubok ★★★★★
()
Ответ на: комментарий от Joanna

Ха., заработало. Значит, еще на GTK2, наверное сидят. Сейчас правило перепишу.

Zubok ★★★★★
()
Ответ на: комментарий от Joanna

Замечу, что у меня это на некоторых приложениях не проходит. По той же вот причине, о которой я упомянул. Об этом упоминается также в документации xdotool. Но попробуйте.

(if (is (window_class) "Flashplayer") 
    (spawn_sync (str "/usr/bin/xdotool sleep 1 key --window "
		     (str (hex (window_xid))) " ctrl+f")))
SENDEVENT NOTES
       If you are trying to send key input to a specific window, and it does
       not appear to be working, then it's likely your application is ignoring
       the events xdotool is generating. This is fairly common.

       Sending keystrokes to a specific window uses a different API than
       simply typing to the active window. If you specify 'xdotool type
       --window 12345 hello' xdotool will generate key events and send them
       directly to window 12345.  However, X11 servers will set a special flag
       on all events generated in this way (see XEvent.xany.send_event in
       X11's manual). Many programs observe this flag and reject these events.

       It is important to note that for key and mouse events, we only use
       XSendEvent when a specific window is targeted. Otherwise, we use XTEST.

       Some programs can be configured to accept events even if they are
       generated by xdotool. Seek the documentation of your application for
       help.

Поэтому первое правило активирует окно и посылает активному окну комбинацию (используется XTEST, который всегда работает, но только для окна, имеющего фокус в данный момент), а второе правило - конкретному окну (используется XSendEvent, работает уже не всегда).

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Joanna

ой, там регистр может быть важен. Вместо F надо f, наверное. ctlr+f вместо Ctrl+F (хотя, наверное, к Ctrl это не относится).

Ну и без паузы можешь попробовать. Быть может. ctrl+f он поймает сразу как появится и назад не уменьшится в дефолтные размеры игры.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok
(if (is (window_class) "Flashplayer") 
    (spawn_sync (str "/usr/bin/xdotool sleep 1 key --window "
		     (str (hex (window_xid))) " ctrl+f")))

Работает великолепно! Сразу видно — вы настоящий знаток дела. Спасибо вам огромное за труд и уделённое время.

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

Успехов вам во всех делах и начинаниях. Благодарю за помощь.

Joanna
() автор топика
Ответ на: комментарий от Joanna

1. Можно попробовать без паузы sleep. Может, сразу поймает.

2. Можно упростить строчку. str все преобразует:

(if (is (window_class) "Flashplayer") 
    (spawn_sync (str "/usr/bin/xdotool sleep 1 key --window "
		     (window_xid) " ctrl+f")))
Zubok ★★★★★
()
Ответ на: комментарий от Zubok

1. Без паузы sleep приложение ненадолго переходит в fullscreen, но возвращается к дефолтному размеру окна. Получается без паузы никак.
2. Упрощённая строчка тоже замечательно работает. Здорово.

Всегда можно остановиться на достигнутом, но приложение бросило мне новый вызов. Те немногочисленные игры, которые изначально запускаются в fullscreen, c предложенным вами кодом демонстрируют обратное поведение — уменьшаются в размере. Неплохо бы и их как-нибудь «победить».

Joanna
() автор топика
Ответ на: комментарий от Joanna

Те немногочисленные игры, которые изначально запускаются в fullscreen, c предложенным вами кодом демонстрируют обратное поведение — уменьшаются в размере. Неплохо бы и их как-нибудь «победить».

А я как-то не понимаю, как это правило может на это влиять. Оно только ctrl+f посылает. А если убить devilspie, запустить игру и нажать ctfl+f, то что? А если отдельно вызвать в терминале xdotool c ctfl+f, то тоже уменьшаются или все нормально?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Хотя я понял, кажется. Когда игра запускается в полноэкране, то повторное нажатие Ctrl-F ее уменьшает. Работает как toggle. Так получается? То есть если нажать в изначально полноэкранной игре опять Ctrl-f, то она уменьшится?

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Нет. Повторное нажатие Сtrl+F в полноэкранном режиме ничего не делает. Выход из fullscreen в приложении сделан через Esc.

Joanna
() автор топика
Ответ на: комментарий от Joanna

Когда же запускаю полноэкранную игру и пробую в терминале вызвать xdotool c ctfl+f — приложение почему-то уменьшается.

Joanna
() автор топика
Ответ на: комментарий от Joanna

Нет. Повторное нажатие Сtrl+F в полноэкранном режиме ничего не делает. Выход из fullscreen в приложении сделан через Esc.

Очень странно тогда. Мы только ctrl+f пересылаем.

Когда же запускаю полноэкранную игру и пробую в терминале вызвать xdotool c ctfl+f — приложение почему-то уменьшается.

Еще страннее. Ладно, предположим, что игра реагирует на передачу Ctrl+f при помощи XSendEvent. Для начала попробуйте тогда первый вариант правила, который работает через другой механизм (через XTEST), но только исправьте Ctrl+F на ctrl+f: Как сделать, чтобы приложение открывалось в fullscreen? (комментарий)

Что в этом случае?

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Со старым вариантом всё равно полноэкран уменьшается.

Быть может есть вариант как-то добавлять конкретные файлы в исключения из правила, чтобы на них оно не распространялось.

Joanna
() автор топика
Ответ на: комментарий от Joanna

Со старым вариантом всё равно полноэкран уменьшается.

devilspie перезапускался точно? Лучше его прибить 100% и запустить заново, он все правила перечитает.

Быть может есть вариант как-то добавлять конкретные файлы в исключения из правила, чтобы на них оно не распространялось.

Я думаю над этим.

Но поведение предельно странное. Что-то тут не так, а что - я понять пока не могу. Если я правильно понимаю ситуацию (уточню):

Открываем игру, которая изначально полноэкранная и нажимаем Ctrl+f. Она и остается полноэкранной, сколько бы не нажимали.

Если в эту игру передать Ctrl+f с xdotool, то она вдруг уменьшается. Так? Тоже самое произойдет, если нажать Esc?

Zubok ★★★★★
()
Ответ на: комментарий от Joanna

Вот вероятное быстрорешение, которое я придумал без понимания сути происходящего пока. ctrl+f не выдаем, если окно имеет статус полноэкранного:

(if (and (is (window_class) "Flashplayer")
	 (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN")))
    (spawn_sync (str "/usr/bin/xdotool sleep 1 key --window "
		     (window_xid) " ctrl+f")))

Но это без понимания сути происходящего. Пробуй.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Хотя я уже вижу проблему. Окно может получить статус полноэкранного не сразу. Если не заработает, то надо бы паузу врубить перед проверкой полноэкранности. И еще потом сделай xprop на полноэкранное окно игры, которая сразу полноэкранная, и выложи на pastebin.com

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Если я правильно понимаю ситуацию (уточню):
Открываем игру, которая изначально полноэкранная и нажимаем Ctrl+f. Она и остается полноэкранной, сколько бы не нажимали.

Не совсем так. Запускаю полноэкран, выполняю в терминале xdotool c ctfl+f — Сtrl+F работает как toggle. Но после того, как закрываю игру и терминал, а потом заново запускаю игру (без терминала с xdotool) — Сtrl+F ничего не делает.

Только после запуска devilspie в терминале — Ctrl+F начинает вести себя как обычно.

Если в эту игру передать Ctrl+f с xdotool, то она вдруг уменьшается. Так? Тоже самое произойдет, если нажать Esc?

Да.

Joanna
() автор топика
Ответ на: комментарий от Zubok

С этим кодом

(if (and (is (window_class) "Flashplayer")
	 (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN")))
    (spawn_sync (str "/usr/bin/xdotool sleep 1 key --window "
		     (window_xid) " ctrl+f")))

по-прежнему всё работает за исключением полноэкраной игры.

Вывод xprop для полноэкранной игры — https://pastebin.com/qJEAPC45

Joanna
() автор топика
Ответ на: комментарий от Zubok

Если не заработает, то надо бы паузу врубить перед проверкой полноэкранности.

Вот исправленный вариант с паузой. Делаем паузу 1 сек, проверяем полноэкранность. Если неполноэкранная, то посылаем окну ctrl+f. В xdotool пауза убрана, так как она уже перед проверкой полноэкранности сделана. Может быть, ее нужно увеличить. Я полагаю, что признак полноэкранности окно получает только после запуска игры. Узнает, что она говорит плееру по поводу геометрии своей и уже потом полноэкраннится. То есть не сразу все происходит. Признаков готовности игры никаких нет, поэтому таймауты.

(if (is (window_class) "Flashplayer")
    (begin
     (spawn_sync "/bin/sleep 1")
     (if (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN"))
	 (spawn_sync (str "/usr/bin/xdotool key --window "
			  (window_xid) " ctrl+f")))))

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Joanna

Вывод xprop для полноэкранной игры — https://pastebin.com/qJEAPC45

Ага, верно, _NET_WM_STATE_FULLSCREEN стоит. Значит, пробуй последнее правило. Оно не будет ctrl+f посылать полноэкранному.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Все flash-игры теперь переходят в fullscreen без проблем и изначально полноэкранные остаются без изменения размеров. Отлично.

(if (is (window_class) "Flashplayer")
    (begin
     (spawn_sync "/bin/sleep 1")
     (if (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN"))
	 (spawn_sync (str "/usr/bin/xdotool key --window "
			  (window_xid) " ctrl+f")))))

Шах и мат Adobe :)

Joanna
() автор топика
Ответ на: комментарий от Joanna

Но это без понимания сути происходящего, с которым надо разбираться. Если вручную нажимать, то из полноэкранного не выходит, а если xdotool передавать, то выходит, а это вызывает вопросы. Но несколько сложно разобраться дистанционно, надо много спрашивать всякого. Может, завтра дойдет, но пока какое-то решение есть. может, потом что-нибудь снова всплывет.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Joanna

Шах и мат Adobe :)

Кстати, предвижу небольшие проблемы. Если у плеера еще есть другие окна (я не знаю точно, но по меню видно, что есть). Например, окно открытия файлов, то у этих окон вполне может быть тоже класс Flashplayer и сработает это правило при появлении этих окон и может сделать их полноэкранными. Поэтому надо будет понять, чем они отличаются и вписать доплнительное условие. Например, если только у главного в названии есть «Adobe Flash Player», то можно добавить условие:

(if (and (is (window_class) "Flashplayer")
         (contains (window_name) "Adobe Flash Player"))
...

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

то у этих окон вполне может быть тоже класс Flashplayer и сработает это правило при появлении этих окон и может сделать их полноэкранными.

Хотя в твоем случае по правилу в окно класса Flashplayer пошлется ctrl+f. Главное выходит в fullscreen, а вот во второстепенных по этой комбинации может что-то свое сделаться, либо ничего не сделают, но что-то там моргнет через секунду, будто что-то не то нажал.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Неудобств не заметила. Ваш код превосходно решает задачу.

И хотелось бы немного ещё «волшебства», если можно:

Как в этом правиле

(if (is (window_class) "Flashplayer")
    (begin
     (spawn_sync "/bin/sleep 1")
     (if (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN"))
	 (spawn_sync (str "/usr/bin/xdotool key --window "
			  (window_xid) " ctrl+f")))))

заставить это событие

/usr/bin/xdotool click 2

вызывать это событие

/usr/bin/wmctrl -c 'Adobe Flash Player'

Не нашла примеров в интернете.

Joanna
() автор топика
Ответ на: комментарий от Joanna

Неудобств не заметила. Ваш код превосходно решает задачу.

А это и не изменение логики. Это предотвращение возможного ошибочного срабатывания правила на окна, к которым оно не должно быть применено, то есть такое правило лучше вписать:

(if (and (is (window_class) "Flashplayer")
         (contains (window_name) "Adobe Flash Player"))
    (begin
     (spawn_sync "/bin/sleep 1")
     (if (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN"))
	 (spawn_sync (str "/usr/bin/xdotool key --window "
			  (window_xid) " ctrl+f")))))

И хотелось бы немного ещё «волшебства», если можно:

Не совсем понял задачу, если честно. Нужны пояснения, что надо сделать.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok

Не совсем понял задачу, если честно. Нужны пояснения, что надо сделать.

При нажатии на колесо прокрутки мыши закрывать приложение Adobe Flash Player.

Joanna
() автор топика
Ответ на: комментарий от Joanna

При нажатии на колесо прокрутки мыши закрывать приложение Adobe Flash Player.

Лучше перехотеть. :) Есть, наверное, ложное ощущение, что раз Линукс, то все можно гладко настроить и автоматизировать. То что вы хотите, тоже можно, в общем-то, хотя костылики такого же уровня будут, как и с fullscreen. Просто не получится никакого улучшения в жизни, а только попытка найти себе дополнительные сложности, чтобы решить, а положительный эффект - пшик.

В том, что вы хотите, есть особенность: подмена действия кнопки 2 должна работать только в приложении (окне) плеера, а вне его кнопка 2 должна работать по умолчанию.

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

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Joanna

1. Устанавливаешь xbindkeys

2. Создаешь файл ~/.xbindkeysrc и в нем добавлешь праавило:

"sh -c 'wmctrl -x -c flashplayer.Flashplayer && killall -q xbindkeys'"
  b:2

3. Новое правило для devilspie:

(if (and (is (window_class) "Flashplayer")
         (contains (window_name) "Adobe Flash Player"))
    (begin
     (spawn_sync "/bin/sleep 1")
     (if (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN"))
	 (begin
	  (spawn_sync (str "/usr/bin/xdotool key --window "
			   (window_xid) " ctrl+f"))
	  (spawn_sync "/usr/bin/xbindkeys -n")))))

Плохо тут то, что некрасиво убивается xbindkeys (совершает [Роскомнадзор] в своем же файле), но надо же как-то освободить Button 2.

Button 2 глобально получает действие на закрывание Flash Player, где бы указатель не находился, но это только на одно нажатие. В следующее нажатие уже будет просто умолчательное действие.

Закрыть окно можно и xdotool, но почему-то xdotool не закрывает окно gracefully (не буду расшифровывать).

Насчет исправления недостатков надо подумать, но если и так сойдет, то и ок.

Zubok ★★★★★
()
Ответ на: комментарий от Zubok
(if (and (is (window_class) "Flashplayer")
         (contains (window_name) "Adobe Flash Player"))
    (begin
     (spawn_sync "/bin/sleep 1")
     (if (not (contains (window_property "_NET_WM_STATE")
			"_NET_WM_STATE_FULLSCREEN"))
	 (begin
	  (spawn_sync (str "/usr/bin/xdotool key --window "
			   (window_xid) " ctrl+f"))
	  (spawn_sync "/usr/bin/xbindkeys -n")))))

Код, к сожалению, не закрывает приложение по middle click мыши. Как же тогда его можно отладить?

Joanna
() автор топика
Ответ на: комментарий от Joanna

Быть может затруднение как-то связано с моим терминалом? У меня rxvt-unicode.

"sh -c 'wmctrl -x -c flashplayer.Flashplayer && killall -q xbindkeys'"
  b:2
Joanna
() автор топика
Ответ на: комментарий от Joanna

'wmctrl -x -c flashplayer.Flashplayer

Вот тут может быть проблема. Надо заменить либо на Flashplayer или на flashplayer. Я, к сожалению, не могу проверить дистанционно, как отзовется приложение. Отладить так: запустить игру, в терминале набрать

$ wmctrl -x -c flashplayer.Flashplayer
$ wmctrl -x -c flashplayer
$ wmctrl -x -c Flashplayer

Какой закроет, тот и использовать, заменить в ~/.xbindkeysrc

xbindkey установлен? Файл ~/.xbindkeysrc создан? (проверить название по буквам). Отлаживаем его. Из терминала запускаем

$ xbindkeys -n

Запускаем игру, нажимаем Button 2. Закрылось - ок. Не закрылось - рассказываем.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

рассказываем

Ваш код работает безупречно: и в fullscreen запускает, и по middle click закрывает. Здорово.

Я неправильно скопировала этот код в ~/.xbindkeysrc:

"sh -c 'wmctrl -x -c flashplayer.Flashplayer && killall -q xbindkeys'"
  b:2

Из-за этого не получалось закрывать приложение по middle click.

Через свои знания вы показали мне возможности devilspie, xdotool и xbindkeys. И меня заинтересовала эта тема. Буду перелопачивать интернет и пробовать учиться на примерах. Ваша помощь — вдохновила.

Joanna
() автор топика
Ответ на: комментарий от Joanna

Мне кажется, что можно сделать и покрасивее в части перехвата Button 2, чтобы глобально не менять ее поведение на время появления окна игры, но я что-то не припомнил нужного инструмента для этого. Поэтому сделал, чтобы быстро и чтобы без программазма. Если вспомню внезапно, то дополню.

Я рекомендую сделать какую-нибудь диреаторию типа ~/.config/automation или что-то в этом роде и собрать в ней симлинки на файлы и каталоги, которые участвуют в автоматизации. Потом забудете, где и что меняли и будете удивляться каким-то странным вещам. Сделать в этой директории что-то типа

$ ln -s ~/.xbindkeysrc xbindkeysrc
$ ln -s ~/.devilspie devilspie

и т. д. Чтобы не забыть, какие файлы участвуют во всем этом и чтобы они были в одном месте.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 1)
Ответ на: комментарий от Zubok

Скорее всего полноэкранная игра перехватывает нажатия клавиш и не даёт выйти из полного экрана по нажатию ctrl+f. Но это так, гадание на кофейной гуще

FireFighter ★★★
()
Последнее исправление: FireFighter (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.