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”将调用一个简单的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所述

EDIT2:给系统一个假窗口是更好的解决方案,如下面的Jacob所述。


嗨,Cosmin,我添加了另一个我认为很干净的解决方案。
Jacob Vlijm '16

谢谢雅各。我当时在考虑那种解决方案,但不知道如何解决。存在解决方案真是太好了。
Cosmin Saveanu

Answers:


18

很好的问题。

原因

通常,从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-)窗口,从而使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

好主意-给一个假窗口。我喜欢
Sergiy Kolodyazhnyy,2016年

@Serg欺骗和欺骗,但有效:)
Jacob Vlijm '16年

4

只是想添加一个替代的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()

真好!直到现在为止都没有注意到这一增加:)
Jacob Vlijm '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.