Чи можу я мати вікно із невеликим попереднім попереднім переглядом іншої робочої області?


29

Чи можна відобразити дзеркальний розділ однієї робочої області, щоб він був видимий у поточній робочій області як вікно, яке можна переміщувати?

Днями у мене на хості Ubuntu 16.04 працював Windows 10 VM, який потребував дуже довгого часу для повного оновлення. Я постійно перевіряв його хід через Expo ( Super+ S) на Ubuntu. Це змусило мене думати, що ця проблема, швидше за все, була вирішена вже з тих пір, як такі інструменти, як simplecreenrecorder, можна налаштувати для запису лише частини екрана. Однак я не знаю належної термінології, яку слід використовувати для пошуку в Google.

Я хотів би побачити знімок екрана 300x150 нижче у вигляді плаваючого вікна (з актуальними оновленнями) у правому верхньому куті, залежно від того, яка робоча область буде актуальною.

введіть тут опис зображення


1
@serg тут новий проект для вас
Rinzwind

@Rinzwind ти повинен ненавидіти Серга ... Ми (обидва) раніше дивились на щось подібне, не досягли успіху.
Яків Влійм

1
Я навіть поклав на цей раз щедрості: =) дістатися до нього @JacobVlijm
Rinzwind

Це було б цікавою особливістю :) Це не допоможе у випадку VM, але є рішення для термінальних додатків: використання Konsole. Він має два корисні варіанти: «сповістити про активність» та «сповістити про тишу». Перший надішле вам сповіщення, коли в терміналі відображається новий рядок (корисний при використанні tail -F file | grep patternв журналах, щоб попередити про деякі події), другий надішле вам сповіщення, коли минуло певний рядок з часу останнього написаного рядка (корисно для знати, коли збірка закінчилася).
кік

@ Rinzwind святе лайно, воно спрацює ...
Яків Влійм

Відповіді:


26

EDIT

(Нова відповідь)

Зроблено.
Відповідь нижче доступна у відшліфованому вигляді, як індикатор, як програма для Trusty, Xenial, Yakkety та Zesty:

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

Індикатор (включаючи вікно попереднього попереднього перегляду) зараз сильно низький. Опції включають вікно налаштувань, встановлення розміру / кольору рамки вікна, розміру вікна.

введіть тут опис зображення

Тим часом мені здалося корисним стежити за вікном АС; подивіться, чи є повідомлення :)


СТАРИЙ ВІДПОВІДЬ

( перша друга груба концепція)

Майте мінімізоване представлення вікна на іншій робочій області

На мій власний (великий) подив, це можна зробити ефективно , будь то хитрістю та обманом; мати оновлене подання вікна на іншій робочій області. Не підходить для перегляду фільму, безумовно, досить хороший, щоб стежити за вікном в іншому місці (наприклад: вікно моєї телевізійної картки):

Як це працює на практиці

  1. Маючи вікно спереду, натисніть клавішу швидкого доступу:

    введіть тут опис зображення

    (вікно буде мінімізоване)

  2. Перейдіть до іншої робочої області, знову натисніть клавішу швидкого доступу, з'явиться невелике представлення вікна, оновлене кожні 4 секунди:

    введіть тут опис зображення

    Вікно завжди відображається поверх інших вікон. Як і зараз, вікно становить 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-pil, xdotoolіwmctrl

    sudo apt-get install xdotool wmctrl python3-pil
    
  2. Створіть, якщо він ще не існує, каталог ~/bin.

  3. Скопіюйте сценарій 1, він керує сценарієм, як (саме) showcase_control(без розширення) ~/bin, і зробить його виконуваним .
  4. Скопіюйте сценарій 2, сценарій міні-вікна, як (саме) showmin(без розширення) ~/bin, та зробіть його виконуваним .
  5. Вийдіть із системи та ввійдіть знову та додайте таку команду до ярлика на ваш вибір:

    showcase_control
    

    Виберіть: Налаштування системи> "Клавіатура"> "Ярлики"> "Спеціальні ярлики". Клацніть "+" і додайте команду:

    showcase_control
    

    і це має працювати!

    • Натисніть клавішу один раз, щоб схопити поточне вікно
    • перейдіть до іншої робочої області, де вам потрібно міні-вікно
    • Натисніть ще раз, щоб показати міні-вікно
    • Натисніть ще раз, щоб повернутися до початкової робочої області, (автоматично) скасувати мінімізацію оригінального вікна та закрити міні -он.

Недоліки?

  • Налаштування, як і зараз, додає певної роботи вашому процесору. У моїй (дуже) старій системі вона додає (в середньому) appr. 4-5% я вважаю, що я жодним чином не помічав .

    Оновлення: виявляється, ви importможете змінити розмір зображення за один крок разом із отриманням віконного зображення. Це означає значне зниження навантаження процесора. У той же час час оновлення коротший (зараз 3 секунди), все ще при менших "витратах".

Пояснення

  • Моєю відправною точкою було те, як ОП згадував, що він хотів використати опцію, щоб стежити за вікном на іншому робочому просторі, чекаючи, коли щось закінчиться.
  • Хоча в буквальному сенсі мати точну (міні) копію вікна на іншій робочій площі здається неможливою, ми можемо створити зображення існуючого вікна за допомогою import-command, як тільки у нас буде ідентифікатор вікна. Хоча це працює як на мінімізованих вікнах, так і на вікнах без фокусу, проте існує одна проблема: вікно має знаходитись у поточному робочому просторі .
  • Підхід полягає в тому, щоб тимчасово (поки використовується міні-вікно) зробити вікно "липким" (бути практично доступним на всіх робочих просторах) за допомогою wmctrl, але при цьому мінімізувати.
  • Оскільки все робиться автоматично, різниці фактично немає, оскільки також повернення до початкового вікна перегляду, "відклеїти" оригінальне вікно та зняти його мінімізацію, робиться автоматично.

Коротко:

  1. Натискання ярлика один раз: цільове вікно стає клейким, але мінімізоване
  2. Повторне натискання на нього (імовірно, на іншому робочому просторі): у верхньому лівому куті з’являється невелика міні-версія вікна, яка оновлюється один раз на чотири секунди.
  3. Повторне натискання на нього: міні-вікно закрито, робочий стіл переміщується на початкову робочу область вікна, вікно відновлюється не липким та мінімізованим.

Спеціально для VirtualBox

Коли вікно VBox передує, виявляється, клавіші швидкого доступу Ubuntu відключені (!), Тому сценарій управління потрібно запустити іншим способом. Нижче декілька коротких.

Варіант 1

Я відредагував сценарій управління. Тепер лише у випадку з VirtualBox:

  • Клацніть будь-де на робочому столі, а потім натисніть клавішу швидкого доступу. Після цього просто використовуйте клавішу швидкого доступу, щоб показати вікно та вийти.

    Пояснення: Сценарій керування був зроблений для виходу, якщо вікно типу "робочий стіл", оскільки ви не хочете мінімізувати робочий стіл. Тепер сценарій спочатку шукає можливі існуючі вікна VirtualBox, щоб націлити їх, якщо поточне активне вікно - це робочий стіл.

Варіант 2

  • Скопіюйте піктограму нижче (клацніть правою кнопкою миші -> зберегти як) і збережіть як minwinicon.png

    введіть тут опис зображення

  • Скопіюйте рядки нижче в порожній файл, збережіть його як minwin.desktopу ~/.local/share/applications:

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

    Вам потрібно буде вийти та повернутися для запуску, щоб "знайти" локальний ~/binшлях!
    Перетягніть піктограму на панель запуску, щоб використовувати її.

Друге рішення має важливий недолік: після використання його з пускового пристрою він буде блимати кілька секунд, чекаючи появи вікна. Під час цього натискання ще раз не матиме жодного ефекту. Це можна вирішити, як описано тут , але включення цього у відповідь справді зробить це занадто довго. Якщо ви хочете скористатися другим варіантом, перейдіть за посиланням.


Отже, добрий старий importможе це зробити, тоді як скріншот гнома не може. Дуже, дуже цікаво. Мені цікаво, яка саме різниця між способом їх роботи
Сергій Колодяжний

@ Серг, так, я був дуже здивований, думав, що це неможливо зробити лише з кухонними інструментами :)
Якоб Влієм

1
@ThatGuy над цим працює :)
Яків Влійм

1
@jymbob Дякую за коментар! Вони не сумніваються в системі, але питання полягає в тому, чи вони доступні ззовні. Якщо розробники не надають опцію cli або API жодним чином, пробиття коду буде завданням зовсім іншого замовлення. Я хотів би мати варіант.
Яків Влійм

1
@JacobVlijm Справедливий пункт. Можливо, більше інформації тут stackoverflow.com/questions/18595951/…, але набагато вище рівня моєї компетентності!
джимбоб

1

Щось таке, що здається завищеним, але цілком працює для цієї мети, - це Open Broadcaster . У вікні списку "Джерела" натисніть плюс, виберіть "Захоплення вікон", а потім дотримуйтесь підказок, щоб вибрати вікно, яке вас цікавить. Немає сенсу записувати запис; просто використовуйте попередній перегляд. Він доступний майже для будь-якої ОС , тут є інструкції для Ubuntu , які я скопіював нижче.

sudo apt-get install ffmpeg
sudo add-apt-repository ppa:obsproject/obs-studio
sudo apt-get update
sudo apt-get install obs-studio

Якщо вам здається, ви можете зайти в меню «Вид» і приховати всі елементи інтерфейсу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.