it-swarm-es.com

La acción personalizada de hacer clic con el botón derecho en Unity Launcher mantiene el cursor ocupado durante 20 segundos

Para tener una opción de "minimizar ventana" haciendo clic derecho en un icono en el lanzador de Unity (Ubuntu 14.04), seguí las instrucciones detalladas aquí sobre cambiar un archivo .desktop e hice un Firefox personalizado lanzador en la carpeta ~/.local/share/applications/. La parte relevante del archivo .desktop es:

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;

La acción de escritorio "Minimizar" invoca un script simple de Shell, minimize.sh que tiene el siguiente contenido:

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

El script usa xdotool, que se puede instalar desde los repositorios oficiales, para encontrar todas las ventanas firefox, iterar sobre ellas y minimizarlas.

El script funciona y la opción del menú derecho del iniciador "Minimizar Windows" también funciona, pero tan pronto como las ventanas se minimizan, el puntero del mouse se pone en modo "ocupado" y permanece así durante unos 20 segundos (aunque las acciones del mouse siguen sensible).

¿Alguien sabe por qué iniciar un script de Shell desde una opción de menú correcta en Unity podría conducir a este comportamiento?

EDIT: Aparentemente, el período de espera es inevitable, como se explica en la respuesta de Jacob Vlijm. Dado que el mouse permanece receptivo, evitar la transformación del puntero en la rueda giratoria es una solución estética parcial, como se explica en askubunt .

EDIT2 : dar al sistema una ventana falsa es una mejor solución, como explica Jacob a continuación.

14
Cosmin Saveanu

Excelente pregunta.

La causa

Normalmente, al iniciar aplicaciones GUI desde el Lanzador de Unity, el iniciador espera a que aparezca una ventana. Mientras espera, muestra la "rueca". Sin embargo, no esperará para siempre; Después de unos 20 segundos, el lanzador supone que la ventana no aparecerá y deja de esperar.

1. El comando principal del iniciador de una aplicación

En un archivo .desktop, relativo a la primera línea Exec= (el comando principal), puede decirle al iniciador que espere o no, en una línea:

StartupNotify=true

para hacerla esperar, o

StartupNotify=false

para hacerlo no espera.

2. Elementos de la lista rápida de un lanzador

Sin embargo, para posibles elementos de lista rápida (clic derecho) de un lanzador, el valor predeterminado es StartupNotify=true. Desafortunadamente, este valor es fijo y no puede ser cambiado por nada.

Eso significa que si inicia cualquier comando al hacer clic con el botón derecho en el ícono del iniciador en el Iniciador de Unity, el iniciador espera una ventana y lo espera, mostrando La rueca.

La conclusión es que, aunque puede explicarse, parece que no hay solución al problema en este momento, aparte de crear un iniciador dedicado para su script y agregar la línea StartupNotify=false al archivo.

La prueba

Puede probar el comportamiento usted mismo. Crea dos lanzadores:

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

y:

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

Guárdelos como test1.desktop y test2.desktop, arrastre ambos lanzadores al iniciador de Unity. Haga clic en ellos y vea la diferencia en el comportamiento.


Editar; si realmente te molesta, dale a Unity una ventana falsa

Si tiene muchos guiones en listas rápidas, y/o realmente le molesta, hay otra solución cosmética; podemos falso , invisible (totalmente transparente) para mostrar una ventana, que se incluirá en su secuencia de comandos. su script sería entonces (por ejemplo)

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

donde el comando fake_window llamará a nuestra ventana (falso), haciendo que Unity termine la rueda giratoria.

Como instalar

  1. Cree, si aún no existe, el directorio ~/bin
  2. Copie el script a continuación en un archivo vacío, guárdelo como fake_window (sin extensión) en ~/bin y hágalo ejecutable

    #!/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. Agregue al final de su script el comando:

    fake_window
    
  4. Cerrar sesión y volver a iniciarla (o ejecutar source ~/.profile)

Eso es todo, la rueda ahora solo girará mientras se ejecute el script.

Explicación

El script crea una ventana minimalista. Sin embargo, la ventana es totalmente transparente y tiene un tamaño de 0x0 píxeles y, por lo tanto, es invisible. Se destruirá instantáneamente una vez que exista.

Llamando a la ventana al final de su secuencia de comandos, satisfará el deseo de Unity de una ventana, deteniendo la rueda para girar.

18
Jacob Vlijm

Solo quería agregar una implementación alternativa de fake_window que sea un poco más simple y no active python advertencias en un sistema 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()
4
Digikata