Unity Launcher中的自定义右键单击操作可使光标忙碌20秒

要通过右键单击Unity启动器(Ubuntu 14.04)中的图标来获得“最小化窗口”选项,我按照此处有关更改.desktop文件的详细说明,并在~/.local/share/applications/创建了自定义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”调用一个简单的shell脚本,如下所示: minimize.sh具有以下内容:

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

该脚本使用xdotool ,可以从官方存储库安装,以查找所有firefox窗口,迭代它们并最小化它们。

该脚本工作,并且启动器右菜单选项“最小化Windows”也可以工作,但是一旦窗口最小化,鼠标指针就会进入“忙碌”模式并保持这样大约20秒(尽管鼠标操作仍然是响应)。

有谁知道为什么从Unity中的右侧菜单选项启动shell脚本会导致这种行为?

编辑 :显然等待期是不可避免的,正如Jacob Vlijm的回答所解释的那样。 由于鼠标保持响应,避免旋转轮中指针的转换是部分美学解决方法,如askubuntu所述 。

编辑2 :给系统假窗口是一个更好的解决方案,正如雅各布在下面解释的那样。

好问题。

原因

通常,从Unity Launcher启动GUI应用程序时,启动程序会等待出现一个窗口。 在等待时,它显示出“旋转轮”。 然而,它不会永远等待; 大约20秒后,发射器假定窗口不会出现并放弃等待。

1.应用程序启动器的主要命令

.desktop文件中,关于第一个Exec=行(主命令),您可以告诉启动器在一行中等待或不等待:

 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.desktoptest2.desktop ,将两个启动器拖到Unity启动器上。 单击它们并查看行为差异。


编辑; 如果它真的困扰你,给Unity一个虚假的窗口

如果你在快速列表中有很多脚本,和/或它真的困扰你,那么还有另一种美容解决方案; 我们可以伪造 ,不可见(完全透明)来显示一个窗口,包含在你的脚本中。 那么你的脚本就是(例如)

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

命令fake_window将调用我们的( fake_window )窗口,使Unity结束旋转轮。

如何设置

  1. 如果它还不存在,则创建目录~/bin
  2. 将下面的脚本复制到一个空文件中,将其保存为~/bin fake_window (无扩展名) 并使其可执行

     #!/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对窗口的期望,停止旋转。

只是想添加一个更简单的备用fake_window实现,并且不会在Ubuntu 16.04系统上触发python警告。

 #!/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()