如何显示(提升)应用程序的所有窗口?

Pet*_*ler 21 window-manager unity

我有一个使用多个窗口的应用程序。如何快速将该应用程序的所有窗口置于前台?

当我用滚轮滚动应用程序时,它只显示一个窗口。当转到下一个窗口时,最后一个窗口再次回到后台。

当我单击应用程序图标时,我会看到所有窗口的全屏概览。我必须手动选择每个窗口并在屏幕的一半上移动鼠标几次。

我最好的解决办法,到目前为止是最小化所有窗口(Ctrl+ Super+ D),然后使用滚轮显示我的应用程序的窗口。

有更好的解决方案吗?

Jac*_*ijm 21

编辑 - 新答案 -

下面的答案仍然完全有效,因此建议的选项也是如此。然而,持续的洞察力让我添加了这个选项来使用下面的指标,这可能是最优雅的解决方案。

因此,它可能应该替换选项 5(使用 .desktop 文件)。

只需从列表中选择应用程序,相应应用程序的所有窗口(出现在当前视口上)都会出现:

在此处输入图片说明

如何使用

来自ppa:

sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront
Run Code Online (Sandbox Code Playgroud)

...或手动:

sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront
Run Code Online (Sandbox Code Playgroud)
  • 指标需要 wmctrl

    sudo apt-get wmctrl
    
    Run Code Online (Sandbox Code Playgroud)
  • 将指标复制到一个空文件中,将其另存为 raise_apps.py

  • 复制下面的图像,将其准确命名 保存raise.png指标相同的目录中。

    在此处输入图片说明

  • 然后只需通过以下命令运行它:

    python3 /path/to/raise_apps.py

  • 如果要启动应用程序,请添加:

    /bin/bash -c "sleep 10 && python3 /path/to/raise_apps.py" 
    
    Run Code Online (Sandbox Code Playgroud)

旧答案:

关于问题

使用正确的工具,“只是”提升应用程序的所有窗口并不是很复杂。确保提升当前视口的窗口要复杂一些。然而,真正的挑战是找到一种方便的方法来使用户可以使用该操作。

下面五个选项的照顾,为了显示它如何做到。所有选项都可以使用。然而,最后一个选项是实验性的;如选项说明中所述,它工作正常,但有一些小的外观缺点。尽管如此,我还是将其添加为一个概念

正如评论中所建议的那样,以不重叠的方式自动展开窗口对我来说似乎不是一个实用的想法;如果您在(应用程序方面的)分组窗口设置中工作,脚本可能会意外地重新排列窗口。

如何使用

对于所有选项,您需要:

  • wmctrl如果您的系统上还没有安装,请安装:

    sudo apt-get install wmctrl
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建(如果尚不存在)目录:

    ~/bin
    
    Run Code Online (Sandbox Code Playgroud)

    (说明:该目录~/bin在 $PATH 中,因此您可以按名称运行可执行文件)

  • 复制该选项对应的脚本,粘贴到一个空文件中,另存为raise_app(无扩展名)~/bin并使其可执行

在单独的选项中,将解释可能的附加步骤。

选项 1:通过输入一个或多个字符来选择应用程序

  • 按组合键,zenity会出现一个窗口
  • 在输入框中输入应用程序名称的一个或多个字符
  • 按回车

这将使匹配应用程序的所有窗口(在当前视口上)出现在前面。

提升gnome-terminal当前视口上的所有窗口:

在此处输入图片说明

在此处输入图片说明

如何使用:

  • 按照“如何使用”中的描述进行设置
  • 通过以下命令测试运行它:

    raise_app
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果一切正常,请将其添加到您选择的快捷键组合中:选择:系统设置 > “键盘” > “快捷方式” > “自定义快捷方式”。单击“+”并添加命令

剧本:

#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread
import os
import subprocess
import getpass

currpath = os.path.dirname(os.path.realpath(__file__))

class Indicator():
    def __init__(self):
        self.app = 'raise_apps'
        iconpath = os.path.join(currpath, "raise.png")
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)       
        self.indicator.set_menu(self.create_menu())
        # the thread:
        self.update = Thread(target=self.check_recent)
        # daemonize the thread to make the indicator stopable
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        # creates the (initial) menu
        self.menu = Gtk.Menu()
        # separator
        initial = Gtk.MenuItem("Fetching list...")
        menu_sep = Gtk.SeparatorMenuItem()
        self.menu.append(initial)
        self.menu.append(menu_sep)
        # item_quit.show() 
        self.menu.show_all()
        return self.menu

    def raise_wins(self, *args):
        index = self.menu.get_children().index(self.menu.get_active())
        selection = self.menu_items2[index][1]
        for w in selection:
            execute(["wmctrl", "-ia", w])

    def set_new(self):
        # update the list, appearing in the menu
        for i in self.menu.get_children():
            self.menu.remove(i)
        for app in self.menu_items2:

            sub = Gtk.MenuItem(app[0])
            self.menu.append(sub)
            sub.connect('activate', self.raise_wins)
        # separator
        menu_sep = Gtk.SeparatorMenuItem()
        self.menu.append(menu_sep)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        self.menu.append(item_quit)
        self.menu.show_all()

    def get_apps(self):
        # calculate screen resolution
        res_output = get("xrandr").split(); idf = res_output.index("current")
        res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
        # creating window list on current viewport / id's / application names
        w_data = [l.split() for l in get(["wmctrl", "-lpG"]).splitlines()]
        # windows on current viewport
        relevant = [w for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
        # pids
        pids = [l.split() for l in get(["ps", "-u", getpass.getuser()]).splitlines()]
        matches = [[p[-1], [w[0] for w in relevant if w[2] == p[0]]] for p in pids]
        return [m for m in matches if m[1]]

    def check_recent(self):
        self.menu_items1 = []
        while True:
            time.sleep(4)
            self.menu_items2 = self.get_apps()
            for app in self.menu_items2:
                app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
            if self.menu_items2 != self.menu_items1:
                GObject.idle_add(
                    self.set_new, 
                    priority=GObject.PRIORITY_DEFAULT
                    )
            self.menu_items1 = self.menu_items2

    def stop(self, source):
        Gtk.main_quit()

def get(command):
    return subprocess.check_output(command).decode("utf-8")

def execute(command):
    subprocess.Popen(command)

Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
Run Code Online (Sandbox Code Playgroud)



选项 2:循环浏览应用程序并使用组合键升起它们的窗口:

假设我在组合键Alt+下有下面的脚本1。我打开了几个窗口:

  • 火狐
  • 侏儒终端
  • 鹦鹉螺

当前状态:

在此处输入图片说明

我按一次Alt+ 1,所有nautilus窗口都会升起:

<图片>

我再次按下Alt+ 1,所有firefox窗口都被抬起:

<图片>

我再次按下Alt+ 1,所有gnome-terminal窗口再次升起,循环重新开始:

<图片>

如何使用

  • 按照“如何使用”中的描述进行设置
  • 将其添加到您选择的快捷键组合中:选择:系统设置>“键盘”>“快捷方式”>“自定义快捷方式”。单击“+”并添加命令

    raise_app
    
    Run Code Online (Sandbox Code Playgroud)

然后使用组合键通过分组的应用程序窗口循环浏览您的应用程序。

剧本:

sudo apt-get wmctrl
Run Code Online (Sandbox Code Playgroud)



选项 3:按组合键 + 单击启动器图标- 或 -应用程序窗口以提升当前视口上的所有窗口

这可能是最接近问题/评论中描述的选项。

假设我有一个凌乱的桌面,三个nautilus窗口隐藏在其他窗口下。

<图片>

提升所有 nautilus 窗口(示例快捷方式:Alt+ 1):

  • Alt+ 1,松开 (!)
  • 在 3 秒内,要么:

    单击启动器中的应用程序图标

    <图片>

    或者:

    单击应用程序的窗口之一

    <图片>

    结果:

    <图片>


如何使用:

  • 按照“如何使用”中的描述进行设置
  • 通过以下命令测试运行它:

    raise_app
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果一切正常,请将其添加到您选择的快捷键组合中:选择:系统设置 > “键盘” > “快捷方式” > “自定义快捷方式”。单击“+”并添加命令

然后:

  • 按您的组合键并在 3 秒内:

    • 单击启动器中的应用程序图标
    • 单击应用程序的窗口之一

剧本

/bin/bash -c "sleep 10 && python3 /path/to/raise_apps.py" 
Run Code Online (Sandbox Code Playgroud)


选项 4:组合键调用选项列表,显示当前视口上每个应用程序的窗口数

结果证明这个比我想象的更方便:

按(再次示例-)组合键Alt+1调用一个zenity窗口,列出当前视口上的所有应用程序及其窗口数:

在此处输入图片说明

只需按??箭头即可找到正确的选项。按Enter,所选应用程序的所有窗口都会出现。

如何使用:

  • 按照“如何使用”中的描述进行设置
  • 通过以下命令测试运行它:

    raise_app
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果一切正常,请将其添加到您选择的快捷键组合中:选择:系统设置 > “键盘” > “快捷方式” > “自定义快捷方式”。单击“+”并添加命令

剧本

sudo apt-get install wmctrl
Run Code Online (Sandbox Code Playgroud)



选项 5:从启动器图标提升运行应用程序的窗口

此选项存在一个启动器图标,当前正在运行的应用程序位于快速列表中。选择一个,应用程序的所有窗口都会被弹出。

在此处输入图片说明

当正在运行的应用程序列表(在当前视口上)发生变化时,启动器会自动更新。快速列表在其他视口上显示不同的列表,其中打开了其他应用程序的窗口(需要 1-2 秒来适应)。

如前所述,虽然功能齐全,但此选项只是一个概念。它有一些小的美容缺点。最重要的:

  • 一个动作后,光标“滚轮”会持续旋转几秒钟。虽然它不会影响功能,但它是一个美容缺点。
  • 正在运行的应用程序列表发生变化后,启动器图标中的应用程序列表需要1-2秒才能更新。

此外,设置稍微复杂一些(尽管在下面详细解释):

如何使用

下面你会发现:

两个脚本/一个图标/一个.desktop文件

  1. 准备安装在“如何使用”,保存第一(main-)脚本raise_app~/bin
  2. 将下面的图标(右键单击,另存为)另存为 raise.png

    <图标>

  3. .desktop文件复制到一个空文件中,编辑该行

        Icon=/path/to/raise.png
    
    Run Code Online (Sandbox Code Playgroud)

    向图标的真实路径(带引号之间的空格路径)
    保存为raise.desktop~/.local/share/applications

  4. .desktop文件拖到启动器以添加它

  5. 复制第二个脚本,将其粘贴到一个空文件,将其保存为update_apps~/bin,使其可执行。
  6. 将以下命令添加到您的启动应用程序(Dash > Startup Applications > Add):

    update_apps
    
    Run Code Online (Sandbox Code Playgroud)
  7. 注销并重新登录以使其工作。

第一个脚本

~/bin
Run Code Online (Sandbox Code Playgroud)

第二个脚本

raise_app
Run Code Online (Sandbox Code Playgroud)

.desktop 文件

[Desktop Entry]
Name=Raise application windows
Comment=Raise groups of windows
Icon=/path/to/raise.png
Terminal=false
Type=Application
Version=1.0

Actions=
Run Code Online (Sandbox Code Playgroud)



简要说明

以上所有解决方案都wmctrl用于创建窗口列表,使用wmctrl -lpG命令。此命令生成行,如下所示:

0x044000b3  0 3429   65   24   1615 1026 jacob-System-Product-Name unity - How to show all windows of an application? - Ask Ubuntu - Mozilla Firefox