web-dev-qa-db-ja.com

別のワークスペースの小さなライブプレビューを表示するウィンドウを使用できますか?

1つのワークスペースのライブセクションをミラーリングして、現在のワークスペースで移動可能なウィンドウとして表示することは可能ですか?

先日、Ubuntu 16.04ホストでWindows 10 VMを実行していましたが、更新に非常に長い時間がかかりました。 Expoで進捗状況を確認し続けました(Super+S)Ubuntuで。 simplescreenrecorderなどのツールは画面の一部のみを記録するように構成できるため、この問題はすでに解決されている可能性が高いと考えました。ただし、Google検索に使用する適切な用語がわかりません。

現在のワークスペースの右上隅に、以下の300x150のスクリーンショットをフローティングウィンドウ(ライブ更新あり)の形で表示したいと思います。

enter image description here

28
AnthonyK

編集

(新しい回答)

DONE。
以下の回答は、Trusty、Xenial、Yakkety、ZestyのPPAとして、インジケータとして洗練された形で利用できるようになりました。

Sudo apt-add-repository ppa:vlijm/windowspy
Sudo apt-get update
Sudo apt-get install windowspy

Thインジケーター(プレビューウィンドウを含む)のジュースが少なくなりました。オプションには、設定ウィンドウ、ウィンドウの境界サイズ/色、ウィンドウサイズの設定が含まれます。

enter image description here

それまでの間、私はAUウィンドウに注目するのが便利だと感じました。メッセージがあるかどうかを確認してください:)


古い回答

最初 2番目の大まかな概念)

別のワークスペース上のウィンドウの最小化された表現を持っている

私自身の(大きな)驚いたことに、それは効果的にできます。別のワークスペース上のウィンドウの更新された表現があります。 Not映画を見るのに適していますが、他の場所のウィンドウ(例:私のテレビカードウィンドウ)を監視するのに十分です:

実際の仕組み

  1. ウィンドウが前面にある状態で、ショートカットキーを押します。

    enter image description here

    (ウィンドウは最小化されます)

  2. 別のワークスペースに移動し、ショートカットキーをもう一度押すと、ウィンドウの小さな表現が表示され、4秒ごとに更新されます。

    enter image description here

    ウィンドウは常に他のウィンドウの上に表示されます。現状では、ウィンドウは300ピクセル(幅)ですが、任意のサイズに設定できます。

  3. 終了するには、ショートカットキーを(もう一度)押します。小さなウィンドウが閉じ、元のウィンドウのビューポートに移動します。これは最小化されずに再び表示されます。

スクリプト

  1. 制御スクリプト

    #!/usr/bin/env python3
    import subprocess
    import os
    import sys
    import time
    
    # paths
    imagepath = os.path.join(os.environ["HOME"], ".showcase")
    wfile = os.path.join(imagepath, "currentwindow")
    vpfile = os.path.join(imagepath, "last_vp")
    # setup path
    if not os.path.exists(imagepath):
        os.mkdir(imagepath)
    
    def get(command):
        try:
            return subprocess.check_output(command).decode("utf-8").strip()
        except subprocess.CalledProcessError:
            pass
    
    def get_vp():
        open(vpfile, "wt").write(get(["wmctrl", "-d"]).split()[5])
    
    def run(command):
        subprocess.Popen(command)
    
    def convert_tohex(widxd):
        return widxd[:2]+((10-len(widxd))*"0")+widxd[2:]
    
    def check_windowtype(wid):
        check = get(["xprop", "-id", wid])
        return not any([s in check for s in [
            "_NET_WM_WINDOW_TYPE_DOCK",
            "_NET_WM_WINDOW_TYPE_DESKTOP"]])
    
    def edit_winprops(wid, convert=True):
        run(["xdotool", "windowminimize", wid])
        if convert:
            widxd = convert_tohex(hex(int(wid)))
        else:
            widxd = wid
        run(["wmctrl", "-i", "-r", widxd, "-b", "add,sticky"])
        get_vp()
        open(os.path.join(imagepath, "currentwindow"), "wt").write(widxd)
    
    def initiate_min():
        # if not, minmize window, write the file
        wid = get(["xdotool", "getactivewindow"])
        if check_windowtype(wid):
            edit_winprops(wid)
        else:
            pidinfo = [l.split() for l in wlist.splitlines()]
            match = [l for l in pidinfo if all([
                get(["ps", "-p", l[2], "-o", "comm="]) == "VirtualBox",
                not "Manager" in l])]
            if match:
                edit_winprops(match[0][0], convert=False)
    
    # windowlist
    wlist = get(["wmctrl", "-lp"])
    
    if "Window preview" in wlist:
        # kill the miniwindow
        pid = get(["pgrep", "-f", "showmin"])
        run(["kill", pid])
        window = open(wfile).read().strip()
        viewport = open(vpfile).read().strip()
        run(["wmctrl", "-o", viewport])
        time.sleep(0.3)
        run(["wmctrl", "-i", "-r", window, "-b", "remove,sticky"])
        run(["wmctrl", "-ia", window])
        os.remove(wfile)
    
    else:
        # check if windowfile exists
        wfileexists = os.path.exists(wfile)
        if wfileexists:
            # if file exists, try to run miniwindow
            window = open(wfile).read().strip()
            if window in wlist:
                # if the window exists, run!
                run(["showmin", window])
            else:
                # if not, minmize window, write the file
                initiate_min()
        else:
            # if not, minmize window, write the file
            initiate_min()
    
  2. ウィンドウ表現

    #!/usr/bin/env python3
    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk, GObject
    from PIL import Image
    import os
    import subprocess
    import time
    from threading import Thread
    import sys
    
    wid = sys.argv[1]
    xsize = 300
    
    imagepath = os.path.join(os.environ["HOME"], ".showcase")
    if not os.path.exists(imagepath):
        os.mkdir(imagepath)
    img_in = os.path.join(imagepath, "image.png")
    resized = os.path.join(imagepath, "resized.png")
    
    def get_img():
        subprocess.Popen([
            "import", "-window", wid, "-resize", str(xsize),  resized
            ])
    
    get_img()
    
    class Splash(Gtk.Window):
    
        def __init__(self):
            Gtk.Window.__init__(self, title="Window preview")
            maingrid = Gtk.Grid()
            self.add(maingrid)
            self.image = Gtk.Image()
            # set the path to the image below
            self.resized = resized
            self.image.set_from_file(self.resized)
            maingrid.attach(self.image, 0, 0, 1, 1)
            maingrid.set_border_width(3)
            self.update = Thread(target=self.update_preview)
            self.update.setDaemon(True)
            self.update.start()
    
        def update_preview(self):
            while True:
                get_img()
                time.sleep(3)
                GObject.idle_add(
                    self.image.set_from_file, self.resized,
                    priority=GObject.PRIORITY_DEFAULT
                    )
    
    def miniwindow():
        window = Splash()
        window.set_decorated(False)
        window.set_resizable(False)
        window.set_keep_above(True)
        window.set_wmclass("ShowCase", "showcase")
        window.connect("destroy", Gtk.main_quit)
        GObject.threads_init()
        window.show_all()
        window.move(70, 50)
        Gtk.main()
    
    miniwindow()
    

使い方

  1. python3-pilxdotool、およびwmctrlをインストールします

    Sudo apt-get install xdotool wmctrl python3-pil
    
  2. まだ存在しない場合は、~/binディレクトリを作成します。

  3. showcase_controlの(正確に)~/bin(拡張子なし)、および実行可能にする
  4. スクリプト2、ミニウィンドウスクリプトを(正確に)~/binshowmin(拡張子なし)、および実行可能にする
  5. ログアウトしてから再度ログインし、選択したショートカットに次のコマンドを追加します。

    showcase_control
    

    システム設定>「キーボード」>「ショートカット」>「カスタムショートカット」を選択します。 「+」をクリックして、コマンドを追加します。

    showcase_control
    

    そしてそれは動作するはずです!

    • キーを1回押すと、現在のウィンドウが表示されます
    • ミニウィンドウが必要な他のワークスペースに移動します
    • もう一度押すと、ミニウィンドウが表示されます
    • もう一度押すと元のワークスペースに戻り、(自動的に)元のウィンドウの最小化を解除して、ミニ1を閉じます。

マイナス面?

  • 現在のセットアップでは、プロセッサにsome workが追加されます。しかし、私の(非常に)古いシステムでは、(平均して)承認者が追加されます。 4〜5%気づいていなかったが、anyの方法で。

    Update:importは、fetchingウィンドウ画像と一緒に、1ステップで画像のサイズを変更できます。これにより、プロセッサの負荷が大幅に削減されます。同時に、更新時間は短くなり(現在は3秒)、依然として「コスト」は低くなっています。

説明

  • 私の出発点は、OPが別のワークスペースのウィンドウを監視し、何かが完了するのを待つオプションを使用したいと言った方法でした。
  • literally別のワークスペースにウィンドウの正確な(ミニ)コピーを作成することは不可能に思えますが、canimport-コマンドで既存のウィンドウのイメージを作成します。 、ウィンドウIDを取得したら。これは両方とも最小化されたウィンドウまたはフォーカスなしのウィンドウで機能しますが、1つの問題があります。ウィンドウは現在のワークスペースでである必要があります。
  • トリックは、一時的に(ミニウィンドウの使用中に)wmctrlでウィンドウを「スティッキー」にする(実質的にすべてのワークスペースで使用可能にする)が、同時に最小化することです。
  • すべてが自動的に行われるため、最初のビューポートに戻り、元のウィンドウを「un-」スティッキーし、最小化を解除することも自動的に行われるため、差effectivelyはありません。

要するに:

  1. ショートカットを1回押す:ターゲットウィンドウはスティッキーになりますが、最小化されます
  2. もう一度押すと(おそらく別のワークスペースで):左上隅に小さなミニバージョンのウィンドウが表示され、4秒ごとに更新されます。
  3. もう一度押すと、ミニウィンドウが閉じられ、デスクトップがウィンドウの初期ワークスペースに移動し、ウィンドウが非粘着性かつ最小化されて復元されます。

VirtualBox専用

VBoxウィンドウが前面にある場合、Ubuntuショートカットキーが無効になっていることがわかります(!)。そのため、制御スクリプトを別の方法で起動する必要があります。以下にいくつか簡単なものを示します。

オプション1

制御スクリプトを編集しました。現在、VirtualBoxの場合only

  • デスクトップでanywhereをクリックし、Thenショートカットキーを押します。その後、ショートカットキーを使用してウィンドウを表示し、終了します。

    説明:ウィンドウを「デスクトップ」タイプにした場合、デスクトップを最小化したくないため、制御スクリプトは終了しました。現在アクティブなウィンドウがデスクトップである場合、スクリプトはまず、既存のVirtualBoxウィンドウを探してターゲットにします。

オプション2

  • 下のアイコンをコピーし(右クリック->名前を付けて保存)、minwinicon.pngとして保存します

    enter image description here

  • 以下の行を空のファイルにコピーし、minwin.desktop~/.local/share/applicationsとして保存します。

    [Desktop Entry]
    Type=Application
    Name=Window Spy
    Exec=showcase_control 
    Icon=/path/to/minwinicon.png
    StartupNotify=false
    

    ランチャーがローカル~/binパスを「見つける」ためにログアウトしてからログインする必要があります!
    アイコンをランチャーにドラッグして使用します。

2番目のソリューションには重要な欠点があります。ランチャーから使用した後、数秒間点滅し続け、ウィンドウが表示されるのを待ちます。その間、再度クリックしても効果はありません。 ここ で説明されているようにcanを解決できますが、これをこの回答に含めると、実際には長すぎます。オプション2を使用する場合は、リンクをご覧ください。

25
Jacob Vlijm