Пользовательское действие по щелчку правой кнопкой мыши в Unity Launcher удерживает курсор занятым в течение 20 секунд
Чтобы использовать параметр "свернуть окно", щелкнув правой кнопкой мыши значок в панели запуска Unity (Ubuntu 14.04), я следовал приведенным здесь подробным инструкциям по изменению .desktop
файл и сделал кастом Firefox
пусковая установка в ~/.local/share/applications/
папка. Соответствующая часть файла.desktop:
Actions=NewWindow;NewPrivateWindow;Minimize
[Desktop Action NewWindow]
Name=Open a New Window
Exec=firefox -new-window
OnlyShowIn=Unity;
[Desktop Action NewPrivateWindow]
Name=Open a New Private Window
Exec=firefox -private-window
OnlyShowIn=Unity;
[Desktop Action Minimize]
Name=Minimize Windows
Exec=sh /home/myusername/Documents/xdotool_sh/minimize.sh firefox
OnlyShowIn=Unity;
Действие рабочего стола "Свернуть" вызывает простой сценарий оболочки, minimize.sh
который имеет следующее содержание:
#/bin/bash
name=$1
for i in $(xdotool search --class "$name"); do
xdotool windowminimize $i
done
Скрипт использует xdotool
, которые можно установить из официальных репозиториев, чтобы найти все firefox
окна, переберите их и сверните их.
Сценарий работает, и в правом меню панели запуска "Свернуть Windows" также работает, но как только окна свернуты, указатель мыши переходит в режим "занят" и остается примерно в течение 20 секунд (хотя действия мыши все еще остаются отзывчивый).
Кто-нибудь знает, почему запуск сценария оболочки из правильной опции меню в Unity может привести к такому поведению?
РЕДАКТИРОВАТЬ: Очевидно, период ожидания неизбежен, как объяснено в ответе Якоба Влиима. Так как мышь остается отзывчивой, избегание преобразования указателя в вращающемся колесе является частичным эстетическим обходным путем, как объясняется в Askubuntu.
РЕДАКТИРОВАТЬ 2: дать системе поддельное окно - лучшее решение, как объяснил Джейкоб ниже.
2 ответа
Отличный вопрос.
Причина
Обычно, когда запускаются приложения с графическим интерфейсом из Unity Launcher, программа запуска ожидает появления окна. В ожидании показывает "вращающееся колесо". Это не будет ждать вечно однако; примерно через 20 секунд программа запуска предполагает, что окно не появится, и перестает ждать.
1. Основная команда запуска приложения
В .desktop
файл, касающийся первого Exec=
line (основная команда), вы можете указать программе запуска ждать или нет, в строке:
StartupNotify=true
чтобы подождать, или
StartupNotify=false
чтобы не ждать.
2. Быстрый список предметов лаунчера
Однако для возможных элементов списка быстрого запуска (щелчка правой кнопкой мыши) значением по умолчанию является StartupNotify=true
, К сожалению, это значение является фиксированным и не может быть изменено ничем.
Это означает, что если вы запустите любую команду, щелкнув правой кнопкой мыши значок запуска в Unity Launcher, программа запуска ожидает окно и ожидает его, показывая вращающееся колесо.
Суть в том, что, хотя это и можно объяснить, в данный момент, похоже, нет решения этой проблемы, кроме создания выделенного модуля запуска для вашего сценария и добавления строки StartupNotify=false
в файл.
Доказательство
Вы можете проверить поведение самостоятельно. Создайте две пусковые установки:
[Desktop Entry]
Name=Test
Exec=sh /home/myusername/Documents/xdotool_sh/minimize.sh firefox
Type=Application
StartupNotify=true
а также:
[Desktop Entry]
Name=Test
Exec=sh /home/myusername/Documents/xdotool_sh/minimize.sh firefox
Type=Application
StartupNotify=false
Сохранить их как test1.desktop
а также test2.desktop
Перетащите оба модуля запуска на модуль запуска Unity. Нажмите на них и увидите разницу в поведении.
Редактировать; если это действительно беспокоит вас, накормите Unity поддельным окном
Если у вас есть много сценариев в быстрых списках, и / или это действительно беспокоит вас, есть другое косметическое решение; мы можем подделать, невидимую (полностью прозрачную), чтобы показать окно, которое будет включено в ваш скрипт. ваш сценарий будет (например)
#/bin/bash
name=$1
for i in $(xdotool search --class "$name"); do
xdotool windowminimize $i
done
fake_window
где команда fake_window
вызовет наше (поддельное) окно, заставив Unity прекратить вращающееся колесо.
Как настроить
- Создайте, если он еще не существует, каталог
~/bin
Скопируйте приведенный ниже скрипт в пустой файл и сохраните его как
fake_window
(без расширения) в~/bin
и сделать его исполняемым#!/usr/bin/env python3 from gi.repository import Gtk from threading import Thread import time import subprocess """ This is a self-destroying window, to "feed" Unity a fake-window, preventing the launcher to show a spinning wheel, waiting for a window to appear. Include the command to run this script at the end of the (your) script. """ class FakeWin(Gtk.Window): def __init__(self): Gtk.Window.__init__(self, title="1526closeme") Thread(target = self.close).start() def close(self): t = 0 while t < 150: time.sleep(0.2) try: pid = subprocess.check_output(["pgrep", "-f", "fake_window"])\ .decode("utf-8").strip() subprocess.Popen(["kill", pid]) break except subprocess.CalledProcessError: pass t += 1 def fakewindow(): window = FakeWin() # make our window transparent window.set_opacity(0) window.set_default_size(0,0) window.show_all() Gtk.main() fakewindow()
Добавьте в самый конец вашего скрипта команду:
fake_window
Выйти и вернуться (или запустить
source ~/.profile
)
Вот и все, колесо будет вращаться только до тех пор, пока работает сценарий.
объяснение
Скрипт создает минималистичное окно. Однако окно полностью прозрачно, имеет размер 0x0 пикселей и поэтому невидимо. Он уничтожит себя мгновенно, как только он будет существовать.
Вызывая окно в конце вашего скрипта, вы удовлетворите желание Unity открыть окно, останавливая вращение колеса.
Просто хотел добавить альтернативную реализацию fake_window, которая немного проще и не вызывает предупреждений python в системе Ubuntu 16.04.
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import GLib
"""
This is a self-destroying window, to "feed" Unity a fake-window, preventing
the launcher to show a spinning wheel, waiting for a window to appear.
Include the command to run this script at the end of the (your) script.
"""
def timer_cb():
Gtk.main_quit()
return False
def show_cb(widget, data=None):
GLib.timeout_add(500, timer_cb)
def fakewindow():
window = Gtk.Window()
# make our window transparent
window.set_opacity(0)
window.set_default_size(0,0)
window.connect("show", show_cb)
window.show_all()
Gtk.main()
fakewindow()