アプリケーションのすべてのウィンドウを表示(表示)する方法は?


21

複数のウィンドウを使用するアプリケーションがあります。そのアプリケーションのすべてのウィンドウをすばやく前面に表示するにはどうすればよいですか?

スクロールホイールでアプリケーションをスクロールすると、1つのウィンドウしか表示されません。次のウィンドウに移動すると、最後のウィンドウが再びバックグラウンドになります。

アプリケーションアイコンをクリックすると、すべてのウィンドウの概要が全画面表示されます。各ウィンドウを手動で選択し、マウスを画面の半分に数回移動する必要があります。

これまでの私の最善の解決策は、すべてのウィンドウを最小化し(Ctrl+ Super+ D)、スクロールホイールを使用してアプリケーションのウィンドウを表示することです。

より良い解決策はありますか?


@Joschuaアプリケーションのすべてのウィンドウを前面に表示するのはそれほど難しくありませんが、アプリケーションをどのように定義しますか?キーの組み合わせ+アプリケーションのウィンドウをクリックするとどうなりますか?
ジェイコブVlijm

@ジョシュアまたはメイビーよりエレガントな、キーコンボ+アプリケーション名の最初の文字?
ジェイコブVlijm

動作はすべてのアプリケーションで同じだと思います。私は、ターミナルウィンドウでこの機能を最もよく見落とします。ターミナルウィンドウでは、2つ以上のウィンドウが並んで開いていることがよくあります。次に、フルスクリーンウィンドウ(Firefoxなど)に切り替えます。2つのターミナルウィンドウに切り替えたいときは、少し難しいです。これまでに見つけた最良の方法は、Firefoxアプリケーションバーをマウスで中クリックすることです。これにより、Firefoxがバックグラウンドになり、前面に2つの端末が再び表示されます。しかし、これは上に積み上げられたアプリケーションがあまり多くない場合にのみうまく機能します:D
peq

@Joschuaまた、アプリケーションウィンドウグループを前面に表示するためのキーの組み合わせを持つことも可能です。一度押す->すべてのFirefoxウィンドウが表示され、再びプレス->すべてのターミナルウィンドウが表示されるなど。面白い。それに取り組んでいます。ただし、少し手間がかかります。
ジェイコブVlijm

@JacobVlijm正しい方向のように聞こえます。:)私にとって最も重要だと思われるのは、キーの組み合わせに加えてアイコンをクリックすると、そのアプリケーションのすべてのウィンドウ(たとえば、peqのような多くの端末)が前面に移動し、できれば広がることです重複しないように..(たぶん、このようなものがUnityの一部になる可能性があります!?)
ジョシュア

回答:


21

編集-新しい回答-

以下の答えはまだ完全に有効であるため、推奨されるオプションです。しかし、継続的な洞察により、このオプションを追加して以下のインジケーターを使用することができました。これはおそらく最もエレガントなソリューションです。

そのため、おそらくオプション5を置き換える必要があります(.desktopファイルを使用)。

リストからアプリケーションを選択するだけで、対応するアプリケーション(現在のビューポートに存在する)のすべてのウィンドウが表示されます:

ここに画像の説明を入力してください

使い方

PPAから:

sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront

...または手動で:

#!/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()
  • インジケーターのニーズ wmctrl

    sudo apt-get wmctrl
    
  • インジケーターを空のファイルにコピーし、名前を付けて保存します raise_apps.py

  • 以下の画像をコピーし、インディケーターと同じディレクトリ正確に名前を付けて 保存します。raise.png

    ここに画像の説明を入力してください

  • 次に、次のコマンドで実行します。

    python3 /path/to/raise_apps.py

  • スタートアップアプリケーションに追加する場合:

    /bin/bash -c "sleep 10 && python3 /path/to/raise_apps.py" 
    

古い回答:

質問について

適切なツールを使用すると、アプリケーションのすべてのウィンドウを「ジャスト」に上げることはそれほど複雑ではありません。確認するのはもう少し複雑です現在のビューポートのウィンドウが表示さです。ただし、実際の課題は、ユーザーがアクションを利用できるようにする便利な方法を見つけることです。

5つのオプションは、そのの世話をするために、次の、それがどのように表示することができます行われます。すべてのオプションを使用する準備ができました。ただし、最後のオプションは実験的なものです。正常に機能しますが、オプションの説明で説明されているように、いくつかの小さな見た目の欠点があります。それでもコンセプトとして追加しました。

コメントで示唆されているように、重複しない方法でウィンドウを自動的に広げることは、私にとって実用的な考えではありません。(アプリケーションごとに)グループ化されたウィンドウ設定で作業する場合、スクリプトはウィンドウを不必要に再配置する可能性があります。

使い方

すべてのオプションについて、以下を行う必要があります。

  • wmctrlシステムにまだインストールされていない場合はインストールします。

    sudo apt-get install wmctrl
    
  • ディレクトリがまだ存在しない場合は作成します:

    ~/bin
    

    (説明:ディレクトリ~/binは$ PATHにあるため、名前で実行可能ファイルを実行できます)

  • オプションに対応するスクリプトをコピーし、空のファイルに貼り付けてraise_app(拡張子なし)として保存し、~/bin実行可能にします。

別のオプションでは、可能な追加の手順が説明されます。

オプション1:1つ以上の文字を入力してアプリケーションを選択します

  • キーの組み合わせを押すと、zenityウィンドウが表示されます
  • 入力ボックスにアプリケーション名の1つ以上の文字を入力します
  • Enterを押す

これにより、(現在のビューポート上の)一致するアプリケーションのすべてのウィンドウが前面に表示されます。

gnome-terminal現在のビューポート上のすべてのウィンドウを上げます:

ここに画像の説明を入力してください

ここに画像の説明を入力してください

使い方:

  • 「使用方法」の説明に従ってセットアップを行います
  • 次のコマンドでテスト実行します。

    raise_app
    
  • すべてが正常に機能する場合は、選択したショートカットキーの組み合わせに追加します。[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]を選択します。「+」をクリックして、コマンドを追加します

スクリプト:

#!/usr/bin/env python3
import subprocess
import getpass

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])
# 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()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
           for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# ask user for first characters
try:
    arg = get('zenity --entry --text "first characters" --title "application"').strip()
except subprocess.CalledProcessError:
    pass
# raise matching windows
try:
    [execute("wmctrl -ia "+item[1]) for item in windows if item[0].startswith(arg)]
except (subprocess.CalledProcessError, NameError):
    pass



オプション2:アプリケーションを切り替えて、キーの組み合わせでウィンドウを上げます:

キーの組み合わせAlt+の下に以下のスクリプトがあるとします1。私はいくつかのウィンドウを開いています:

  • fox
  • gnome-terminal
  • ノーチラス

現在の状態:

ここに画像の説明を入力してください

Alt+を1回押すと1、すべてのnautilusウィンドウが表示されます。

<画像>

もう一度Alt+ を押すと1、すべてのfirefoxウィンドウが表示されます。

<画像>

もう一度Alt+ を押すと1、すべてのgnome-terminalウィンドウが再び表示され、サイクルが始まります:

<画像>

使い方

  • 「使用方法」の説明に従ってセットアップを行います
  • 選択したショートカットキーの組み合わせに追加します。選択:[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]。「+」をクリックして、コマンドを追加します

    raise_app
    

次に、キーの組み合わせでグループ化されたアプリケーションウィンドウを使用してアプリケーションを切り替えます。

スクリプト:

#!/usr/bin/env python3
import subprocess
import getpass

include_single = True # set to False if you only want to cycle through apps with multiple windows

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])

def get_frontmost():
    cmd = "xprop -root"
    frontmost = [l for l in get(cmd).splitlines() if\
                 "ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
    return frontmost[:2]+"0"+frontmost[2:]
# 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()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
           for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# create application list to cycle through
if include_single == False:
    pre = [it[0] for it in windows]
    apps = sorted(list(set([it for it in pre if pre.count(it) > 1])))
else:
    apps = sorted(list(set([it[0] for it in windows])))
if len(apps) == 0:
    pass
else:
    # get the frontmost window as a last itm in the cycle
    front = get_frontmost()
    front_pid = [l.split()[2] for l in get("wmctrl -lp").splitlines() if front in l][0]
    last_infront = get("ps -u "+getpass.getuser()+" | grep "+front_pid).split()[-1]
    # determine next apllication to raise
    if not last_infront in apps or last_infront == apps[-1]:
        arg = apps[0]
        print(arg)
    else:
        arg = apps[apps.index(last_infront)+1]
    # raise matching windows
    try:
        [execute("wmctrl -ia "+item[1]) for item in windows if item[0] == arg]
    except (subprocess.CalledProcessError, NameError):
        pass



オプション3:キーの組み合わせを押す+ランチャーアイコンをクリックする-または-アプリケーションウィンドウをクリックして、現在のビューポート上のすべてのウィンドウを表示する

これはおそらく、質問/コメントで説明されている内容に最も近いオプションです。

nautilus他のウィンドウの下に3つのウィンドウが埋め込まれた乱雑なデスクトップがあるとしましょう。

<画像>

すべてのnautilusウィンドウを表示するには(ショートカットの例:Alt+ 1):

  • Alt+を押して1、リリース(!)
  • 3秒以内に、次のいずれか:

    ランチャーでアプリケーションのアイコンをクリックします

    <画像>

    または:

    アプリケーションのウィンドウのいずれかをクリックします

    <画像>

    結果:

    <画像>


使い方:

  • 「使用方法」の説明に従ってセットアップを行います
  • 次のコマンドでテスト実行します。

    raise_app
    
  • すべてが正常に機能する場合は、選択したショートカットキーの組み合わせに追加します。[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]を選択します。「+」をクリックして、コマンドを追加します

次に:

  • キーの組み合わせを押して、3秒以内に次のいずれかを実行します。

    • ランチャーでアプリケーションのアイコンをクリックします
    • アプリケーションのウィンドウのいずれかをクリックします

スクリプト

#!/usr/bin/env python3
import subprocess
import getpass
import time

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])

def get_frontmost():
    cmd = "xprop -root"
    frontmost = [l for l in get(cmd).splitlines() if\
                 "ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
    return frontmost[:2]+"0"+frontmost[2:]

# 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(",", "")))
# get window data for various purposes
w_data = get("wmctrl -lpG").splitlines()
non_windows = sum([[l.split()[0] for l in w_data if it in l]\
               for it in ("unity-launcher", "unity-panel", "unity-dash", "Hud")], [])
# get id of current window
curr_window = get_frontmost()
# user gets 3 seconds to pick an application window (or launcher icon)
t = 0
while t < 4:
    w_id1 = get_frontmost()
    time.sleep(1)
    w_id2 = get_frontmost()
    if w_id1 == w_id2 or w_id2 in non_windows+[curr_window]:
        t = t+1
    else:
        new_frontmost = w_id2
        break
# raise
try:
    pid = [l.split()[2] for l in w_data if new_frontmost in l]
    wl_data = [l.split() for l in w_data]
    raise_windows = [l[0] for l in wl_data if pid[0] == l[2] and\
                     0 < int(l[3]) < res[0] and 0 < int(l[4]) < res[1]]
    [execute("wmctrl -ia "+item) for item in raise_windows]
except NameError:
    pass


オプション4:キーの組み合わせは、現在のビューポート上のアプリケーションごとのウィンドウの数を示すオプションリストを呼び出します

これは私が想定したよりも便利であることが判明しました。

(もう一度例)キーの組み合わせAlt+を押す1と、zenityウィンドウが呼び出され、現在のビューポート上のすべてのアプリケーションとそのウィンドウの数が一覧表示されます。

ここに画像の説明を入力してください

または矢印を押すだけで適切なオプションが表示されます。を押すEnterと、選択したアプリケーションのすべてのウィンドウが表示されます。

使い方:

  • 「使用方法」の説明に従ってセットアップを行います
  • 次のコマンドでテスト実行します。

    raise_app
    
  • すべてが正常に機能する場合は、選択したショートカットキーの組み合わせに追加します。[システム設定]> [キーボード]> [ショートカット]> [カスタムショートカット]を選択します。「+」をクリックして、コマンドを追加します

スクリプト

#!/usr/bin/env python3
import subprocess
import getpass

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])
# 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()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
           for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# preparing zenity optionlist
apps = [item[0] for item in windows]
# prevent multiple zenity windows
if apps.count("zenity") > 1:
    pass
elif apps.count("zenity") > 0:
    execute('zenity --info --text "Another Zenity window is open already"')
# preventing empty windowlist
elif len(apps) > 0:
    applist = [[app, str(apps.count(app))] for app in set(apps)]
    applist.sort(key=lambda x: x[1])
    # calling zenity window
    try:
        arg = get('zenity  --list  --text "Choose an application" '+\
               '--title "Current windows" '+\
               '--column "application" '+\
               '--column "windows" '+\
               '--height 250 '+\
               '--width 250 '+\
               (" ").join(sum(applist, [])))
    except subprocess.CalledProcessError:
        pass
    # raise matching windows
    try:
        [execute("wmctrl -ia "+item[1]) \
         for item in windows if arg.startswith(item[0])]
    except (subprocess.CalledProcessError, NameError):
        pass
else:
    execute('zenity --info --text "No windows to list"')



オプション5:ランチャーアイコンから実行中のアプリケーションのウィンドウを上げる

このオプションにはランチャーアイコンがあり、現在実行中のアプリケーションがクイックリストにあります。いずれかを選択すると、アプリケーションのすべてのウィンドウが表示されます。

ここに画像の説明を入力してください

(現在のビューポートで)実行中のアプリケーションのリストが変更されると、ランチャーが自動的に更新されます。クイックリストには、他のアプリケーションのウィンドウが開いている他のビューポートの別のリストが表示されます(適応するのに1〜2秒かかります)。

前述のように、このオプションは完全に機能しますが、概念として意味があります。いくつかのマイナーな化粧品の欠点がそのままあります。最も重要な:

  • カーソルの「ホイール」は、アクション後数秒間回転し続けます。機能には影響しませんが、見た目の欠点です。
  • 実行中のアプリケーションのリストが変更された後、ランチャーアイコンのapplicationlistが更新されるまでに1〜2秒かかります。

さらに、セットアップは少し複雑です(ただし、以下で詳しく説明します)。

使い方

以下にあります:

2つのスクリプト/アイコン/ .desktopファイル

  1. 最初の(メーン)スクリプトの保存、「使い方」のようにセットアップを準備raise_app~/bin
  2. 下のアイコンを右クリックして名前を付けて保存します raise.png

    <アイコン>

  3. .desktopファイルを空のファイルにコピーし、行を編集します

        Icon=/path/to/raise.png
    

    アイコンへの実際のパスに(引用符の間にスペースを含むパス)
    、それを保存としてraise.desktop~/.local/share/applications

  4. .desktopファイルをランチャーにドラッグして追加します

  5. 2番目のスクリプトをコピーし、空のファイルに貼り付け、として保存update_apps~/bin、実行可能にします。
  6. 次のコマンドをスタートアップアプリケーションに追加します([ダッシュ]> [スタートアップアプリケーション]> [追加])。

    update_apps
    
  7. ログアウトしてから再度ログインすると、機能します。

最初のスクリプト

#!/usr/bin/env python3
import subprocess
import getpass
import sys

arg = sys.argv[1]

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])
# 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()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
           for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
try:
    [execute("wmctrl -ia "+item[1]) for item in windows if item[0].startswith(arg)]
except (subprocess.CalledProcessError, NameError):
    pass

2番目のスクリプト

#!/usr/bin/env python3
import subprocess
import getpass
import time
import os

dtfile = os.environ["HOME"]+"/.local/share/applications/raise.desktop"

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def execute(command):
    subprocess.Popen(["/bin/bash", "-c", command])
# 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
def applist():
    try:
        w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
        windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
                   for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
    except subprocess.CalledProcessError:
        return []
    else:
        return set([app[0] for app in windows])

def update_dtfile(applications, text):
    actionline = "Actions="+(";").join(applications)+";\n"
    with open(dtfile) as src:
        lines = src.readlines()
    lines = lines[:[i for i in range(len(lines)) \
                 if lines[i].startswith("Actions=")][0]]+[actionline]
    for item in text:
        for it in item:
            lines.append(it)
    with open(dtfile, "wt") as out:
        for line in lines:
            out.write(line)

while True:
    apps1 = applist()
    time.sleep(1)
    apps2 = applist()
    if apps1 != apps2: 
        text = [["[Desktop Action "+it+"]\n", "Name="+it+"\n",
            "Exec=raise_app "+it+"\n", "OnlyShowIn=Unity;\n\n",
            ]for it in apps2]
        update_dtfile(apps2, text)

.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=



簡単な説明

上記のすべてのソリューション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

これらの行は次のとおりです。

  • 1列目:ウィンドウのID(それを上げるために使用できます)
  • 3列目:ウィンドウを所有するPID。
  • 4番目/ 5番目の列:ウィンドウのジオメトリxy(ウィンドウが現在のビューポートicw上にあるかどうかを確認するために使用するxrandr

pidはの出力で検索されps -u <username>、アプリケーションの「ユーザーが読み取り可能な」識別(名前)を取得します。
したがって、ウィンドウをアプリケーションに割り当てることができます。その後for、コマンドを使用して、特定のアプリケーションのウィンドウをループで上げることができますwmctrl -ia

オプション3
では、スクリプトは3秒間の「待機」ループを開始し、xprop -rootコマンドを繰り返し使用して、最前面のウィンドウに変更があるかどうかを確認します。これは、ユーザーがランチャーアイコンをクリックしてアプリケーションのウィンドウを表示するか、ウィンドウを直接クリックすると発生します。その場合、whileループは中断して「新しい」最前面のアプリケーションを検索し、その後、そのアプリケーションの他のすべてのウィンドウを表示します。


私は同意します、そしてあなたのすべての努力に再び感謝します!:) || 以前に気づかなかった奇妙なことがあります。Option 2スクリプトを使用した後、アプリケーションウィンドウがフォーカスされている(最大化されていない)ときに「下」に表示される別のウィンドウをクリックすると、以下のアプリケーションがフォーカスを取得しません。
ジョシュア

@Joschuaこの質問のOP:askubuntu.com/questions/575830 / ...は、最新の「機能」アップデートで導入されたバグに参加しました。True / Falseが混同され、複数のウィンドウを持つアプリケーションがない場合にスクリプトがクラッシュしました。オプション2を使用する場合は、最新バージョンに更新してください。
ジェイコブVlijm

オプション1は、ubuntu xenialで動作しません。something @ something:〜/ bin $ ./raise_app Gtk-Message:一時的な親なしでマップされたGtkDialog。これは推奨されません。ターミナルウィンドウを開こうとしていました。何も起こらなかった。
xtrinch

@Nirri使用したアプリケーション名は何ですか?zenityウィンドウがGtk親なしで実行される場合、メッセージは非常に正常です。「ディスコレージド」はエラーではありません。
ジェイコブVlijm

端末の最初の文字。それは動作します-種類-それはすべてのアプリのウィンドウを表示します-しかし、それらのうちの1つだけ、予想どおりすべてではありません@ user72216
xtrinch

1

他のアプリケーションが含まれますが、現在開いているすべてのウィンドウのエキスポを表示するSuper+ Wショートカットがあります。これはデフォルトで提供されており、変更を必要としないため、おそらく最も簡単なオプションです。

とりわけ、Ctrl+ Super+ Left/ Rightボタンを使用して画面の右半分と左半分にウィンドウを配置し、Alt +〜(チルダ、ナンバーワンキーの隣のボタン)でウィンドウを切り替えることができます。


ただし、アプリケーションのすべてのウィンドウが一番上に表示されるわけではありません。それらを見ることができますが、たくさんクリックすることなくそれらを使用することはできません。
ジョシュア

1

Altキーを押しながらTabキーを押してアプリケーションを切り替え、複数のウィンドウが表示されている場合は、Altキーを押し続けると、約1秒後にアイコンがそのアプリケーションのすべてのウィンドウのビューに置き換えられます。

それはあなたが探しているものかもしれないし、そうでないかもしれないが、それは私のために機能し、非常に簡単ですので、私はオプションを共有すると思いました!


1
下矢印キーを押して、アプリケーションウィンドウをすぐに表示することもできます。
クリス

1

@JacobVlijmのraise_apps.pyスクリプトを使用して、より堅牢にするなど、いくつかの機能強化を行いました。

具体的には、1、2日後に@JacobVlijmのスクリプトが機能しなくなることを発見し、スクリプトを手動で再起動して、再び機能させる必要がありました。振り返ってみると、xrandrへの多数の呼び出しが最終的に問題を引き起こすというのが私の最良の推測です。

とにかく、私は彼のコードを修正し、ポーリング頻度を5秒から1秒ごとに増やしました。とにかくCPUをあまり使用しないので、より堅牢になりました。通常、問題なく数日間/数週間実行できます。

1つの注意点は、画面解像度の寸法を取得するために、起動時にxrandrを1回だけ呼び出すことです。したがって、画面の解像度を変更する場合(たとえば、1920x1080から他の解像度に変更する場合)、おそらくraise-apps.pyを手動で再起動して、新しい解像度を取得する必要があります。個人的に、画面の解像度を変更することはありませんので、これは私にとっては問題ではありません。さらに、xrandrへの呼び出しが多すぎると、@ JacobVlijmのバージョンのスクリプトが1日か2日後に動作しなくなると信じる強い理由があります。

ところで、raise.pngイメージを/ usr / local / icons /ディレクトリに配置する必要があります。または、raise.pngを別のディレクトリに配置する場合は、スクリプトが画像ファイルを見つけられるように、スクリプトに適切な変更を加えます。

Ubuntuがこのタイプの「すべてのウィンドウを上げる」機能をシステムに統合することは、非常に役立つことを願っています。

#!/usr/bin/python2
#
# Note to self:
# You need to add raise.png to /usr/local/icons/ directory.
#
# This script was taken from: /ubuntu/446521/how-to-show-raise-all-windows-of-an-application, 
# (@JacobVlijm's answer), and then improved to fix some
# issues, that were causing it to stop working after a day or two.
#
#
from __future__ import print_function

from sys import stderr, exit
import signal
import gi

gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject, GLib

import logging
import logging.handlers

import time
import os
import subprocess
import getpass

logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)

log_handler = logging.handlers.SysLogHandler(address='/dev/log')

logger.addHandler(log_handler)


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

class Indicator():
    def __init__(self):
        self.app = 'raise-apps'
        iconpath = '/usr/local/icons/raise.png'
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        self.prev_menu_item_names = []
        self.menu_items = []

        res_output = get("xrandr").split()
        if (len(res_output) == 0):
            logger.error("raise-apps.py: invocation of xrandr failed! Unable to continue..")
            exit(-1)

        idf = res_output.index("current")
        res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
        (self.screen_width, self.screen_height) = res
        logger.info("raise-apps.py: screen resolution is %s x %s" % (self.screen_width, self.screen_height))

        self.indicator.set_menu(self.create_menu())

        GLib.timeout_add_seconds(1.0, self.check_recent)

    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)

        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_items[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_items:

            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):
        # 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]) < self.screen_width and 0 < int(w[4]) < self.screen_height]
        # 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):
        # print("in check_recent()", file=stderr)
        self.menu_items = self.get_apps()
        for app in self.menu_items:
            app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
        # check if menu items have changed:
        has_changed = len(self.menu_items) != len(self.prev_menu_item_names)
        if (not has_changed):
            for i in range(len(self.menu_items)):
                if self.prev_menu_item_names[i] != self.menu_items[i][0]:
                    has_changed = True
                    break

        if has_changed:
            GObject.idle_add(
                self.set_new,
                priority=GObject.PRIORITY_DEFAULT)

            self.prev_menu_item_names = []
            for item in self.menu_items:
                self.prev_menu_item_names.append(item[0])

        GLib.timeout_add_seconds(1.0, self.check_recent)


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


    def recreate_menu(self, *args):
        logger.info("in recreate_menu()")
        self.prev_menu_item_names = []
        self.menu_items = []

        self.menu_items = self.get_apps()
        for app in self.menu_items:
            app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]

        GObject.idle_add(
            self.set_new,
            priority=GObject.PRIORITY_DEFAULT)

        self.prev_menu_item_names = []
        for item in self.menu_items:
            self.prev_menu_item_names.append(item[0])


def get(command):
    # enable to get a feel for what this app is doing..
    # print("get", command, file=stderr)
    try:
        return subprocess.check_output(command).decode("utf-8")

    except subprocess.CalledProcessError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
        return ""

    except OSError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
        return ""

def execute(command):
    # enable to get a feel for what this app is doing..
    # print("exec", command, file=stderr)
    try:
        subprocess.call(command)

    except subprocess.CalledProcessError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
        return ""
    except OSError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
    return ""


logger.info("(raise-apps.py is starting up..)")
Indicator()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.