Спеціальна дія правої кнопки миші в програмі Unity Launcher утримує курсор протягом 20 секунд


14

Щоб мати опцію «мінімізувати вікно» через праву кнопку миші на іконці в панелі запуску 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 може призвести до такої поведінки?

EDIT : Мабуть, термін очікування неминучий, як пояснено у відповіді Якова Влійма. Оскільки миша залишається чуйною, уникнення трансформації вказівника у спінінг - це часткове естетичне вирішення, як пояснено на askubuntu .

EDIT2 : надання системи підробленого вікна - краще рішення, як пояснив Яків нижче.


Привіт Cosmin, я додав ще одне, досить чисте рішення, я думаю.
Яків Влійм

Дякую, Яково. Я думав про таке рішення, але не знав, як це можна зробити. Чудово, що рішення існує.
Cosmin Saveanu

Відповіді:


18

Відмінне запитання.

Причина

Зазвичай, при запуску програм GUI від Unity Launcher, пускач чекає появи вікна. Поки чекає, на ній видно "прядильне колесо". Однак це не чекатиме вічно; приблизно через 20 секунд пускова установка припускає, що вікно не з’явиться, і відмовляється від очікування.

1. Основна команда запуску програми

У .desktopфайлі, що стосується першого Exec=рядка (основна команда), ви можете сказати запуску, чекати чи ні, у рядку:

StartupNotify=true

змусити його почекати, або

StartupNotify=false

щоб не чекати.

2. Елементи швидкого списку запуску

Однак для можливих елементів швидкого списку (клацання правою кнопкою миші) пускового пристрою значенням за замовчуванням є StartupNotify=true. На жаль, це значення є фіксованим і його неможливо змінити будь-чим.

Це означає, що якщо ви запускаєте будь-яку команду з клацання правою кнопкою миші на значку запуску в пусковій панелі Unity, пусковий апарат очікує вікна і чекає його, показуючи спінінг.

Суть полягає в тому, що, хоча це можна пояснити, наразі проблеми не існує, інакше, ніж створити спеціальний запуск для вашого сценарію та додати рядок 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 закінчити спінінг.

Як налаштувати

  1. Створіть, якщо він ще не існує, каталог ~/bin
  2. Скопіюйте нижче скрипт у порожній файл, збережіть його як 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()
  3. Додайте команду до самого кінця сценарію:

    fake_window
  4. Вийти та повернутися (або запуститиsource ~/.profile)

Ось так, колесо тепер буде крутитися лише до тих пір, поки працює сценарій.

Пояснення

Сценарій дійсно створює мінімалістичне вікно. Однак вікно є повністю прозорим і має розмір 0x0 пікселів, і тому невидиме. Він знищить себе миттєво, коли існує.

Зателефонувавши до вікна в кінці сценарію, ви задоволите бажання Unity у вікні, зупинивши кручення колеса.


Дякуємо за детальне пояснення та правки в питанні. Дає уявлення про потенційні шляхи вирішення.
Cosmin Saveanu

Відмінна ідея - надання підробленого вікна. Мені це подобається
Сергій Колодяжний

@Serg хитрість і обман, але це працює :)
Яків Влійм

4

Просто хотів додати альтернативну реалізацію fake_window, яка дещо простіша і не запускає попередження пітона в системі 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()

Приємно! ніколи не помічав цього доповнення досі :)
Яків Влійм
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.