web-dev-qa-db-ja.com

テキストのAlt-Tab機能を使用できますか?

むかしむかし、「啓蒙」と呼ばれる素晴らしいウィンドウマネージャーがいました。

あなたがそれを使用し、あなたがヒットした場合 Alt+Tab 次に、ウィンドウタイトルの小さなリストがお互いの下に表示されました。

このような:

  • user @ remote-Host
  • foo @ db-server
  • emacs
  • ...

またはこのように:

window-switcher-simple-and-beautiful

私はそれがとても好きでした。

返して欲しい。アプリではなく機能を意味します。

Ubuntu 18.04を使用しています

次のようなアプリケーションのアイコンを見たくありません。

alt-tab-is-useless-at-the-moment

最大5つのターミナルを開いています。 Windowsキーを押すと、ほぼ同じ画像(大きな端末の小さなバージョン)が5回表示されます。

window-key-icons

適切なターミナルを見つけるには、時間と精神的エネルギーが必要です。マウスを使わずにキーボードだけで切り替えたいです。

端末の背後にある魔法:

xtermset -title foo

これは、ssh経由でログインした場合に実行されるbashスクリプトです。

これにより、複数の端末を簡単に区別できます。

1998年に機能したこの機能を取得するにはどうすればよいですか?

(Enlightenmentウィンドウマネージャーをインストールするように言わないでください。この質問は、アプリではなく単純な機能に関するものです)

ユーザー「DK Bose」は、次のコマンドの出力を表示するように要求しました。

===> wmctrl -m
Name: GNOME Shell
Class: N/A
PID: N/A
Window manager's "showing the desktop" mode: N/A
tguettler@aptguettler:~
===> 


tguettler@aptguettler:~
===> wmctrl -lx
0x0200000a  0 desktop_window.Nautilus  aptguettler Schreibtisch
0x01c00178  0 Pidgin.Pidgin         aptguettler tbz
0x02600010  0 Navigator.Firefox     aptguettler command line - List of window names on ALT-Tab - Ask Ubuntu - Mozilla Firefox
0x02200010  0 Mail.Thunderbird      aptguettler Posteingang - [email protected] (IMAP) - Mozilla Thunderbird
0x04400006  0 gnome-terminal-server.Gnome-terminal  aptguettler foooooo
0x044000ce  0 gnome-terminal-server.Gnome-terminal  aptguettler tguettler@aptguettler

文字列 "foooooo"はxtermset -title fooooooを介して設定されました。タイトルは、リモートサーバーでsshを実行していたシェルに設定されました。

6
guettli

Ubuntu 18.04でウィンドウマネージャーを変更しようとするのが賢明かどうかはわかりません。ウィンドウマネージャーはGNOME Shellに統合されています。

Rofi は、システムのデフォルトをそのままにして、説明した目的に適している場合があります。

Rofi in window switcher mode

  • Rofiは、ユニバースセクションで使用できます。

  • インストールされているサイズは524 kBで、依存関係がほとんどないため、apt show rofiを実行するか、apt install -s rofiを使用してインストールをシミュレーションすることで確認できます。

  • Rofiにはいくつかの機能がありますが、ここで興味深いのはウィンドウスイッチャーです。

Rofiがインストールされたら:

  • rofi -dump-config > ~/.config/rofi/config.rasiを実行して、必要に応じて変更できるローカルconfigファイルを生成します。

  • rofi-theme-selectorを実行して、使用するテーマをプレビューします。テーマをさらに微調整する場合は、テーマを/ usr/share/rofi/themesから〜/ .local/shareにコピーします。/rofi/themesそして、混乱を避けるために新しい名前を付けます。私はPop-Darkが好きで、ローカルバージョンにmyPop-Darkという名前を付けました。この回答で投稿された画像では、myPop-Darkを使用しています。

用途

Rofiを示すために、システムの代替として Alt+Tab

  • 5つのxtermウィンドウを含むいくつかのウィンドウを開きました。

  • 私が割り当てた Ctrl+Win+R 実行するショートカットキーボードの組み合わせとしてrofi -show window -theme myPop-Dark

上記の画像には、3つの列があります。アプリケーションの名前とウィンドウのタイトルのみが常に必要な場合は、〜/ .config/rofi/config.rasiを編集して、コメント化されたwindow-format

window-format: "{n}    {t}";

rofiウィンドウの幅、高さ、場所を変更することもできます。

目的のウィンドウにフォーカスを移動するには、矢印キーまたはマウスポインターを使用してエントリを強調表示し、次に Enter

ウィンドウのリストが非常に長い場合は、他のすべてのウィンドウを除外するウィンドウに固有のキーを押します。それが不可能な場合は、以下のアニメーションのように入力してエントリをフィルタリングします。 f、 に続く o 文字列「foo」を含むウィンドウにリストを制限します。

以下のアニメーションはそれを示しています。

filtering windows

ハイライトされたウィンドウを閉じるには、 Shift+Delete

7
DK Bose

18.04を含むUbuntuは現在GNOMEに基づいており、いくつかの追加機能は GNOME Shell Extensions で利用できるようになります。ウェブサイトにアクセスして検索:キーワードとして「ウィンドウスイッチャー」を使用すると、関連する拡張子が検索結果の最初のページに表示される場合があります。

これ は関連性があり、維持されているようです:

Switcherby dlandau

switcher by dlandau in action

入力してウィンドウを切り替えるか、アプリケーションをすばやく起動します

構成されたグローバルホットキー(デフォルトではSuper + w)を使用して、現在のウィンドウのリストを開きます。アクティブ化するアプリケーションウィンドウの名前またはタイトルの一部を入力し、Enterキーを押すか、アクティブ化するアイテムをクリックします。矢印キーを使用して、フィルタリングされた選択項目間を移動し、スペースで区切られた複数の検索語を入力して、さらにフィルタリングできます。 Escを使用するか、スイッチャーの外側をクリックしてキャンセルします。

設定されたグローバルホットキー(デフォルトではSuper + x)を使用して、アプリケーションランチャーを開きます。起動するアプリケーションの名前の一部を入力して、Enterキーを押します。 Ctrl + SpaceまたはCtrl + Tabを使用して、スイッチャーとランチャーを切り替えることができます。または、名前に一致する開いているウィンドウがなく、アプリが存在する場合、モードは自動的に切り替えられます。

環境設定でルックアンドフィールと機能をカスタマイズできます。

拡張機能のホームページ: https://github.com/daniellandau/switcher

シェルバージョン:3.303.283.263.243.223.203.183.16.33.163.14

共通のキーボードショートカットをバインドするには Alt+Tab または Super+Tab この拡張機能では、回避策を使用する必要がある場合があります。 GitHubユーザーPHLAKが GitHubのこの問題#6 を提出し、いくつかのコメントで回避策について説明しました。

スイッチャーをSuper + Tabにバインドしたいのですが、バインドできません。 Alt + Tabにもバインドできないことにも気づきました。


dconfで値を直接設定することで、これを回避することができました。

dconf write /org/gnome/Shell/extensions/switcher/show-switcher "['<Super>tab']"

dconf-config GUIを使用して同じことを行うこともできます。


また、そのキーの組み合わせを使用して、事前設定されたショートカットのバインドを解除する必要がある場合もあります。具体的には、「アプリケーションの切り替え」はGnomeのSuper+Tabにバインドされています。

これを変更するには、設定を開いてDevices > Keyboardに移動します。次に、Super+Tabを検索し、このバインディングを変更または削除します。

免責事項:私はUbuntu 18.04またはGNOME Shellを使用しないので、私はこの拡張をテストしませんでした。私は単にウェブ上で見つかった最も信頼できると思われるリソースを引用しただけです。元のスクリーンショットとアニメーション画像が大きすぎる(500kB、7MB)ため、代わりにGIMPでスクリーンショットをやり直して最適化(122kB)しました。

TL; DRGNOME Shell Extensions Webサイトにアクセスして、選択した拡張機能をインストールします: Switcher by dlanda 。シェルバージョンとの互換性が必要です。

6
clearkimura

XFCEのウィンドウマネージャーの微調整->サイクリングで利用できる「リスト内のウィンドウを循環する」機能を具体的に探していると思います。

リスト内のALT-TABサイクリング

enter image description here

4
BarBar1234

テキスト代替タブ

後期の家庭料理:

動作中

enter image description here

設定方法

セットアップは2つの小さなスクリプトで構成されており、同じディレクトリに保存されます。

スクリプト1

#!/usr/bin/env python3
import gi
gi.require_version("Gtk", "3.0")
gi.require_version('Wnck', '3.0')
from gi.repository import Gtk, Wnck, Gdk
import subprocess

css_data = """
.activestyle {
  background-color: grey;
  color: white;
  border-width: 1px;
  border-radius: 0px;
  border-color: white;
}
.defaultstyle {
  border-width: 0px;
  color: black;
  background-color: white;
}
"""

class AltTabStuff(Gtk.Window):
    def __init__(self):
        # css
        self.provider = Gtk.CssProvider.new()
        self.provider.load_from_data(css_data.encode())       
        Gtk.Window.__init__(
            self, title="AltTab replacement"
        )
        self.curr_index = 0
        self.connect('key-press-event', self.get_key)
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.set_decorated(False)
        buttongrid = Gtk.Grid()
        self.add(buttongrid)
        self.connect("delete_event", Gtk.main_quit)

        wins = get_winlist()
        self.buttonindex = 0
        self.buttonsets = []
        index = 0
        for w in wins:
            button = Gtk.Button("\t" + w.get_name())
            button.set_relief(Gtk.ReliefStyle.NONE)
            buttongrid.attach(button, 0, index, 1, 1)
            index = index + 1
            button.connect("clicked", raise_window, w)
            self.buttonsets.append([button, w])
        self.set_focus()
        self.show_all()
        Gtk.main()

    def set_focus(self):
        for b in self.buttonsets:
            button = b[0]
            self.set_style(button, active=False)
        newactive = self.buttonsets[self.buttonindex][0]
        self.set_style(newactive, active=True)
        n_buttons = len(self.buttonsets)
        self.buttonindex = self.buttonindex + 1
        if self.buttonindex >= n_buttons:
            self.buttonindex = 0

    def set_style(self, button, active):
        st_cont = button.get_style_context()
        if active:
            st_cont.add_class("activestyle")
            st_cont.remove_class("defaultstyle")
        else:
            st_cont.remove_class("activestyle")
            st_cont.add_class("defaultstyle")
        Gtk.StyleContext.add_provider(
            st_cont,
            self.provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
        )

    def get_key(self, val1, val2):
        keyname = Gdk.keyval_name(val2.keyval)
        if keyname == "Tab":
            self.set_focus()
        Elif keyname == "Alt_L":
            window = self.buttonsets[self.buttonindex-1][1]
            button = self.buttonsets[self.buttonindex-1][0]
            raise_window(button, window)
        Elif keyname == "Escape":
            Gtk.main_quit()


def raise_window(button, window):
    subprocess.Popen(["wmctrl", "-ia", str(window.get_xid())])
    Gtk.main_quit()

def check_windowtype(window):
    try:
        return "WNCK_WINDOW_NORMAL" in str(
            window.get_window_type()
        )
    except AttributeError:
        pass

def get_winlist(scr=None):
    """

    """
    if not scr:
        scr = Wnck.Screen.get_default()
        scr.force_update()
    windows = [w for w in scr.get_windows() if check_windowtype(w)]
    return windows


AltTabStuff()

スクリプト2

#!/bin/bash

dr=`dirname $0`
f=$dr'/alttab_runner'

if ! pgrep -f $f
then
$f
else
echo "runs"
fi

次の手順を実行します:

  1. Wnckwmctrlの両方がインストールされていることを確認します。

    Sudo apt install python3-gi gir1.2-wnck-3.0 wmctrl
    
  2. (正確に)alttab_runnerとしてスクリプト1を空のファイルに保存し、(正確に)alttab_alternativeとしてスクリプト2を保存します。 両方のスクリプトを実行可能にします

  3. 既存のAlt-Tabを無効にします。

    gsettings set org.gnome.desktop.wm.keybindings switch-applications '[]'
    
  4. ショートカットを(正確に)Alt-Tabに設定してスクリプト2を実行します。

    /path/to/alttab_alternative
    

使用法

押す Alt + Tab (図のように)スイッチャーを呼び出すには、Altキーを離して押します Tab ウィンドウを切り替えるには、 Alt もう一度、リストから選択したウィンドウを選択します。

Escape スイッチャーを閉じます(閉じます)。

オプション

異なる色が必要な場合は、スクリプト1のCSSで遊んで、独自のスタイルを設定できます。

enter image description hereenter image description here

そのためには、このセクションを編集します。ここで、activestyleは明らかに現在選択されているアイテムです。

css_data = """
.activestyle {
  background-color: blue;
  color: white;
  border-width: 1px;
  border-radius: 0px;
  border-color: white;
}
.defaultstyle {
  border-width: 0px;
  color: black;
  background-color: white;
}
"""

フォントとボタンのGtk cssオプション here を参照してください。


編集

そのままにしたい場合 Alt + Tab、通常の正確なキー動作では、スクリプト1の代わりに使用します。

#!/bin/bash

dr=`dirname $0`
user=$USER
f=$dr'/alttab_runner'
trg='/tmp/'$user'_alttab_trigger'

if ! pgrep -f $f
then
$f
else
echo "runs"
touch $trg
fi

そしてスクリプト2の代わりに:

#!/usr/bin/env python3
import gi
gi.require_version("Gtk", "3.0")
gi.require_version('Wnck', '3.0')
from gi.repository import Gtk, Wnck, Gdk
import subprocess
from threading import Thread
import time
import os

trigger = os.path.join("/tmp", os.environ["USER"] + "_alttab_trigger")

css_data = """
.activestyle {
  background-color: grey;
  color: white;
  border-width: 1px;
  border-radius: 0px;
  border-color: white;
}
.defaultstyle {
  border-width: 1px;
  color: black;
  background-color: white;
}
"""

class AltTabStuff(Gtk.Window):
    def __init__(self):
        # apply css
        self.provider = Gtk.CssProvider.new()
        self.provider.load_from_data(css_data.encode())       
        Gtk.Window.__init__(
            self, title="AltTab replacement"
        )
        self.curr_index = 0
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
        self.set_decorated(False)
        buttongrid = Gtk.Grid()
        self.add(buttongrid)
        self.connect("delete_event", Gtk.main_quit)

        wins = get_winlist()
        self.buttonindex = 0
        self.buttonsets = []
        index = 0
        for w in wins:
            button = Gtk.Button("\t" + w.get_name())
            button.set_relief(Gtk.ReliefStyle.NONE)
            buttongrid.attach(button, 0, index, 1, 1)
            index = index + 1
            button.connect("clicked", raise_window, w)
            self.buttonsets.append([button, w])
        self.set_focus()

        # thread to watch the trigger file
        self.timer = Thread(target=self.wait)
        self.timer.setDaemon(True)
        self.timer.start()

        self.show_all()
        Gtk.main()

    def set_focus(self):
        # rotate the focus + styling
        for b in self.buttonsets:
            button = b[0]
            self.set_style(button, active=False)

        newactive = self.buttonsets[self.buttonindex][0]
        newselected = self.buttonsets[self.buttonindex][1]
        time.sleep(0.03)
        self.set_style(newactive, active=True)
        n_buttons = len(self.buttonsets)
        self.buttonindex = self.buttonindex + 1
        if self.buttonindex >= n_buttons:
            self.buttonindex = 0
        return newselected

    def wait(self):
        """
        wait loop; see if trigger file pops up, or we need to quit on immediate
        key release
        """
        newfocus = self.buttonsets[0][1]
        while True:
            time.sleep(0.05)
            if not self.key_checker():
                # try/except, in case no windows on workspace
                try:
                    self.activate(str(newfocus.get_xid()))
                except TypeError:
                    pass
                Gtk.main_quit()
            if os.path.exists(trigger):
                os.remove(trigger)
                newfocus = self.set_focus()

    def activate(self, arg1, arg2=None):
        # activate the selected window, close preview window
        w = arg2 or arg1
        subprocess.Popen(["wmctrl", "-ia", w])
        Gtk.main_quit()

    def set_style(self, button, active):
        st_cont = button.get_style_context()
        if active:
            # st_cont.add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION)
            st_cont.add_class("activestyle")
            st_cont.remove_class("defaultstyle")
        else:
            st_cont.remove_class("activestyle")
            # st_cont.remove_class("suggested-action")
            st_cont.add_class("defaultstyle")
        Gtk.StyleContext.add_provider(
            st_cont,
            self.provider,
            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
        )


    def key_checker(self):
        # check if keys are in a pressed state
        exclude = ["Button", "Virtual", "pointer"]
        keyboards = [
            k for k in get(["xinput", "--list"]).splitlines()
            if not any([s in k for s in exclude])
        ]
        dev_ids = [[
            s.split("=")[1] for s in k.split() if "id=" in s
        ][0] for k in keyboards]
        pressed = False
        for d in dev_ids:
            if "down" in get(["xinput", "--query-state", d]):
                pressed = True
                break
        return pressed


def get(cmd):
    # just a helper
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except (subprocess.CalledProcessError, TypeError, UnicodeDecodeError):
        pass


def raise_window(button, window):
    subprocess.Popen(["wmctrl", "-ia", str(window.get_xid())])
    Gtk.main_quit()


def check_windowtype(window):
    try:
        return "WNCK_WINDOW_NORMAL" in str(
            window.get_window_type()
        )
    except AttributeError:
        pass


def get_winlist(scr=None):
    if not scr:
        scr = Wnck.Screen.get_default()
        scr.force_update()
    windows = [w for w in scr.get_windows() if check_windowtype(w)]
    return windows


AltTabStuff()

セットアップは最初のバージョンとまったく同じです。

  1. Wnckwmctrlの両方がインストールされていることを確認します。

    Sudo apt install python3-gi gir1.2-wnck-3.0 wmctrl
    
  2. (正確に)alttab_runnerとしてスクリプト1を空のファイルに保存し、(正確に)alttab_alternativeとしてスクリプト2を保存します。 両方のスクリプトを実行可能にします

  3. 既存のAlt-Tabを無効にします。

    gsettings set org.gnome.desktop.wm.keybindings switch-applications '[]'
    
  4. ショートカットを(正確に)Alt-Tabに設定してスクリプト2を実行します。

    /path/to/alttab_alternative
    
4
Jacob Vlijm