Posso ter uma janela mostrando uma pequena visualização ao vivo de outro espaço de trabalho?

22

É possível espelhar uma seção viva de um espaço de trabalho para que fique visível no espaço de trabalho atual como uma janela que pode ser movida?

Outro dia, eu tinha uma VM do Windows 10 em execução no meu host Ubuntu 16.04 que demorava muito tempo para concluir a atualização. Eu continuei checando seu progresso através da Expo ( Super + S ) no Ubuntu. Isso me fez pensar que esse problema provavelmente já foi resolvido, já que ferramentas como o simplescreenrecorder podem ser configuradas para gravar apenas uma parte da tela. No entanto, não conheço a terminologia correta para usar na minha pesquisa no Google.

Gostaria de ver a captura de tela de 300 x 150 abaixo, na forma de uma janela flutuante (com atualizações ao vivo), no canto superior direito da área de trabalho que estiver por vir.

    
por AnthonyK 12.07.2016 / 06:12

1 resposta

21

EDITAR

(Nova resposta)

FEITO.
A resposta abaixo está agora disponível em uma forma polida, como um indicador, como um ppa para Trusty, Xenial, Yakkety e Zesty:

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

O indicador Th (incluindo a janela de pré-visualização) agora está bem baixo em suco. As opções incluem uma janela de configurações, configuração do tamanho / cor da borda da janela, tamanho da janela.

Nesse meio tempo, achei útil ficar de olho na janela do AU; ver se há alguma mensagem:)

RESPOSTA ANTIGA

( primeiro segundo conceito aproximado)

Tenha uma representação minimizada de uma janela em outro espaço de trabalho

Para minha surpresa (grande), pode ser efetivamente feito, seja com truque e engano; ter uma representação atualizada de uma janela em outro espaço de trabalho. Não apto para assistir a um filme, definitivamente bom o suficiente para ficar de olho em uma janela em outro lugar (exemplo: minha janela de cartão de TV):

Como funciona na prática

  1. Com a janela à frente, pressione uma tecla de atalho:

    (a janela irá minimizar)

  2. Mover para outro espaço de trabalho, pressione a tecla de atalho novamente, uma pequena representação da janela aparecerá, atualizada a cada 4 segundos:

    A janela sempre aparece no topo de outras janelas. Do jeito que está, a janela tem 300px (largura), mas pode ser definida para qualquer tamanho.

  3. Para finalizar, pressione (novamente) a tecla de atalho. A pequena janela se fechará, você se moverá para a janela de visualização da janela original, que aparecerá novamente, unminimizada.

Os scripts

  1. O script de controle

    #!/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. A representação da janela

    #!/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()
    

Como usar

  1. Instale python3-pil , xdotool e wmctrl

    sudo apt-get install xdotool wmctrl python3-pil
    
  2. Crie, se ainda não existir, o diretório ~/bin .

  3. Copie o script 1, ele controla o script, como (exatamente) showcase_control (sem extensão) em ~/bin e torne-o executável .
  4. Copie o script 2, o script da mini- janela, como (exatamente) showmin (sem extensão) em ~/bin e torne-o executável .
  5. Faça logout e volte, e adicione o seguinte comando a um atalho de sua escolha:

    showcase_control
    

    Escolha: Configurações do sistema & gt; "Teclado" & gt; "Atalhos" & gt; "Atalhos personalizados". Clique no botão "+" e adicione o comando:

    showcase_control
    

    e deve funcionar!

    • Pressione a tecla uma vez para pegar a janela atual
    • mova-se para a outra área de trabalho em que você deseja a minivisina
    • Pressione novamente para mostrar a mini-janela
    • Pressione novamente para voltar ao espaço de trabalho original, (automaticamente) minimizar a janela original e fechar o mini-one.

Desvantagens?

  • A configuração, como é atualmente, adiciona algum trabalho para o seu processador. No meu (antigo) sistema, no entanto, ele adiciona (em média) aprox. 4-5% Eu acho, que eu não notei em qualquer caminho.

    Atualização: Acontece que import pode redimensionar a imagem em uma única etapa, junto com buscar a imagem da janela. Isso significa uma redução substancial na carga do processador. Ao mesmo tempo, o tempo de atualização é menor (3 segundos agora), ainda com "custos" mais baixos.

Explicação

  • Meu ponto de partida foi o modo como OP mencionou que queria usar a opção de ficar de olho em uma janela em outro espaço de trabalho, esperando que alguma coisa terminasse.
  • Enquanto literalmente tendo uma cópia (mini) exata de uma janela em outro espaço de trabalho parece impossível, podemos criar uma imagem de uma janela existente com import - comando, uma vez que temos o id da janela. Embora isso funcione em janelas ou janelas minimizadas sem foco, há um problema: a janela precisa estar na área de trabalho atual .
  • O truque é então temporariamente (enquanto a mini-janela é usada) tornar a janela "pegajosa" (estar virtualmente disponível em todos os espaços de trabalho) com wmctrl , mas minimizada ao mesmo tempo.
  • Como tudo é feito automaticamente, a diferença efetivamente é nenhuma, já que também retornar à janela de visualização inicial, "não" manter a janela original e minimizá-la é feito automaticamente.

Resumindo:

  1. Pressionando o atalho uma vez: a janela segmentada fica fixa, mas minimizada
  2. Pressionando novamente (presumivelmente em outro espaço de trabalho): uma pequena mini-versão da janela aparece no canto superior esquerdo, atualizada uma vez a cada quatro segundos.
  3. Pressionando novamente: a mini-janela é fechada, a área de trabalho se move para a área de trabalho inicial da janela, a janela é restaurada e não é minimizada.

Especificamente para o VirtualBox

Quando a janela do VBox está na frente, acontece que as teclas de atalho do Ubuntu estão desativadas (!), então o script de controle precisa ser lançado de outra maneira. Abaixo alguns breves.

Opção 1

Eu editei o script de controle. Agora somente no caso do VirtualBox:

  • Clique em qualquer lugar na área de trabalho, Então pressione sua tecla de atalho. Depois disso, basta usar a tecla de atalho para mostrar a janela e sair.

    Explicação: O script de controle foi criado para sair se a janela fosse do tipo "desktop", já que você não desejaria minimizar a área de trabalho. Agora, o script primeiro procura por janelas do VirtualBox possivelmente existentes para serem direcionadas, se a janela ativa no momento for a área de trabalho.

Opção 2

  • Copie o ícone abaixo (clique com o botão direito do mouse - & gt; salve como), salve-o como minwinicon.png

  • Copie as linhas abaixo em um arquivo vazio, salve-o como minwin.desktop in ~/.local/share/applications :

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

    Você precisa sair e voltar para o lançador para "encontrar" o local ~/bin caminho!
    Arraste o ícone para o lançador para usá-lo.

A segunda solução tem uma desvantagem importante: depois de usá-la a partir do lançador, ela continuará piscando por alguns segundos, esperando que uma janela apareça. Durante esse período, clicar novamente não terá nenhum efeito. Isso pode ser resolvido, como descrito aqui , mas incluindo que nesta resposta seria realmente torná-lo demasiado longo. Se você quiser usar a opção dois, por favor, olhe no link.

    
por Jacob Vlijm 07.11.2016 / 15:29