Pour avoir une option "réduire la fenêtre" par un clic droit sur une icône du lanceur Unity (Ubuntu 14.04), j'ai suivi les instructions détaillées ici sur la modification d'un fichier .desktop
et créé un lanceur personnalisé Firefox
dans le dossier ~/.local/share/applications/
. 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.sh
, dont le contenu est le suivant:
#/bin/bash
name=$1
for i in $(xdotool search --class "$name"); do
xdotool windowminimize $i
done
Le script utilise xdotool
name__, qui peut être installé à partir des référentiels officiels, pour rechercher toutes les fenêtres firefox
name__, les parcourir et les minimiser.
Le script fonctionne et l'option de menu de droite du lanceur "Réduire Windows" fonctionne également, mais dès que les fenêtres sont réduites au minimum, le pointeur de la souris passe en mode "occupé" et reste ainsi pendant environ 20 secondes (bien que les actions de la souris restent sensible).
Quelqu'un sait-il pourquoi le démarrage d'un script Shell à partir d'une option de menu de droite dans Unity pourrait entraîner 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 le rouet est une solution de contournement esthétique partielle, comme expliqué sur askubunt .
EDIT2 : donner au système une fausse fenêtre est une meilleure solution, comme l'explique Jacob ci-dessous.
Excellente question.
Normalement, lors du démarrage des applications GUI à partir du lanceur Unity, le lanceur attend qu'une fenêtre apparaisse. En attendant, il montre le "rouet". Il 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'application
Dans un fichier .desktop
, concernant la première ligne Exec=
(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 le faire pas attendre.
2. Éléments de liste rapide d'un lanceur
Pour les éléments de liste rapide possibles (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 toute commande en cliquant avec le bouton droit de la souris sur l’icône du lanceur dans le lanceur Unity, le lanceur attend une fenêtre et attend, en indiquant le rouet.
L’essentiel est que, bien que cela puisse être expliqué, il ne semble pas y avoir de solution au problème pour le moment, à part créer un programme de lancement dédié à votre script et ajouter la ligne StartupNotify=false
au fichier.
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 les noms test1.desktop
et test2.desktop
, faites glisser les deux lanceurs sur le lanceur Unity. Cliquez dessus et voyez la différence de comportement.
Si vous avez de nombreux scripts dans des listes rapides et/ou que cela vous dérange vraiment, il existe une autre solution esthétique. nous pouvons simuler , invisible (totalement 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_window
appellera notre (fausse) fenêtre, faisant en sorte que Unity termine la roue en rotation.
~/bin
Copiez le script ci-dessous dans un fichier vide, enregistrez-le sous fake_window
(sans extension) dans ~/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()
Ajoutez à la toute fin de votre script la commande:
fake_window
Déconnectez-vous et reconnectez-vous (ou exécutez source ~/.profile
)
Ça y est, la roue ne tournera que tant que le script fonctionnera.
Le script crée une fenêtre minimaliste. La fenêtre est cependant totalement transparente et a une taille de 0x0 pixels et est donc invisible. Il va se détruire instantanément une fois qu'il existe.
En appelant la fenêtre à la fin de votre script, vous satisferez le souhait de Unity de disposer d’une fenêtre, en arrêtant la roue de tourner.
Je voulais juste ajouter une autre implémentation de fake_window qui est un peu plus simple et ne déclenche pas python avertissements 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()