Un clic droit personnalisé dans Unity Launcher maintient le curseur occupé pendant 20 secondes


14

Pour avoir une option "réduire la fenêtre" par un clic droit sur une icône dans le lanceur Unity (Ubuntu 14.04), j'ai suivi les instructions détaillées ici sur la modification d'un .desktopfichier et créé un Firefoxlanceur personnalisé dans un ~/.local/share/applications/dossier. La partie pertinente du fichier .desktop est:

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;

L'action de bureau "Réduire" appelle un script shell simple, minimize.shqui a le contenu suivant:

#/bin/bash
name=$1
for i in $(xdotool search --class "$name"); do
    xdotool windowminimize $i
done

Le script utilise xdotool, qui peut être installé à partir des référentiels officiels, pour trouver toutes les firefoxfenêtres, les parcourir et les minimiser.

Le script fonctionne et l'option du menu droit du lanceur "Minimiser Windows" fonctionne également, mais dès que les fenêtres sont réduites, le pointeur de la souris passe en mode "occupé" et reste ainsi pendant environ 20 secondes (bien que les actions de la souris soient toujours sensible).

Est-ce que quelqu'un sait pourquoi le démarrage d'un script shell à partir d'une option de menu de droite dans Unity pourrait conduire à ce comportement?

EDIT : Apparemment, la période d'attente est inévitable, comme expliqué dans la réponse de Jacob Vlijm. Puisque la souris reste sensible, éviter la transformation du pointeur dans la roue qui tourne est une solution de contournement esthétique partielle, comme expliqué sur askubuntu .

EDIT2 : donner au système une fausse fenêtre est une meilleure solution, comme expliqué par Jacob ci-dessous.


Salut Cosmin, j'ai ajouté une autre solution assez propre, je pense.
Jacob Vlijm

Merci Jacob. Je réfléchissais à ce type de solution mais je ne savais pas comment cela pouvait être fait. C'est formidable qu'une solution existe.
Cosmin Saveanu

Réponses:


18

Excellente question.

La cause

Normalement, lors du démarrage d'applications GUI à partir du lanceur Unity, le lanceur attend qu'une fenêtre s'affiche. En attendant, il montre le "rouet". Cela n'attendra pas pour toujours cependant; après environ 20 secondes, le lanceur suppose que la fenêtre n'apparaîtra pas et abandonne l'attente.

1. La commande principale du lanceur d'une application

Dans un .desktopfichier, concernant la première Exec=ligne (la commande principale), vous pouvez dire au lanceur d'attendre ou non, dans une ligne:

StartupNotify=true

pour le faire attendre, ou

StartupNotify=false

pour ne pas attendre.

2. Liste rapide des éléments d'un lanceur

Pour les éventuels éléments de liste rapide (clic droit) d'un lanceur, la valeur par défaut est StartupNotify=true. Malheureusement, cette valeur est fixe et ne peut être modifiée par rien.

Cela signifie que si vous lancez une commande en cliquant avec le bouton droit sur une icône de lanceur dans le lanceur Unity, le lanceur attend une fenêtre et l'attend, montrant la roue qui tourne.

L'essentiel est que, bien que cela puisse être expliqué, il ne semble pas y avoir de solution au problème pour le moment, autre que la création d'un lanceur dédié pour votre script et l'ajout de la ligne StartupNotify=falseau fichier.

La preuve

Vous pouvez tester le comportement vous-même. Créez deux lanceurs:

[Desktop Entry]
Name=Test
Exec=sh /home/myusername/Documents/xdotool_sh/minimize.sh firefox
Type=Application
StartupNotify=true

et:

[Desktop Entry]
Name=Test
Exec=sh /home/myusername/Documents/xdotool_sh/minimize.sh firefox
Type=Application
StartupNotify=false

Enregistrez-les sous test1.desktopet test2.desktopfaites glisser les deux lanceurs sur le lanceur Unity. Cliquez dessus et voyez la différence de comportement.


Éditer; si cela vous dérange vraiment , donnez à Unity une fausse fenêtre

Si vous avez de nombreux scripts dans les listes rapides et / ou que cela vous dérange vraiment, il existe une autre solution cosmétique; nous pouvons simuler , invisible (entièrement transparent) pour afficher une fenêtre, à inclure dans votre script. votre script serait alors (par exemple)

#/bin/bash
name=$1
for i in $(xdotool search --class "$name"); do
    xdotool windowminimize $i
done
fake_window

où la commande fake_windowappellera notre (fausse) fenêtre, ce qui fera que Unity mettra fin à la roue qui tourne.

Comment installer

  1. Créer, s'il n'existe pas encore, le répertoire ~/bin
  2. Copiez le script ci-dessous dans un fichier vide, enregistrez-le sous fake_window(sans extension) ~/bin et rendez-le exécutable

    #!/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. Ajoutez à la fin de votre script la commande:

    fake_window
  4. Déconnectez-vous et reconnectez-vous (ou exécutezsource ~/.profile)

Ça y est, la roue ne tourne désormais que tant que le script s'exécute.

Explication

Le script fait créer une fenêtre minimaliste. La fenêtre est cependant entièrement transparente et a une taille de 0x0 pixels et est donc invisible. Il se détruira instantanément une fois qu'il existera.

En appelant la fenêtre à la fin de votre script, vous satisferez le souhait d'Unity pour une fenêtre, en arrêtant la roue de tourner.


Merci pour l'explication détaillée et les modifications apportées à la question. Donne des idées sur les solutions de contournement potentielles.
Cosmin Saveanu

Excellente idée - donner une fausse fenêtre. J'aime ça
Sergiy Kolodyazhnyy

@Serg tromperie et tromperie, mais ça marche :)
Jacob Vlijm

4

Je voulais juste ajouter une implémentation alternative de fake_window qui est un peu plus simple et ne déclenche pas d'avertissements python sur un système 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()

Agréable! n'a jamais remarqué cet ajout jusqu'à présent :)
Jacob Vlijm
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.