Uma ferramenta para obter as dimensões da janela

14

Eu preciso de uma ferramenta para obter a largura e a altura de uma janela arbitrária.

O ideal seria que a ferramenta deduzisse o tamanho da barra de menus do Ubuntu.

    
por Akronix 17.12.2016 / 23:47

5 respostas

6

A partir de sua própria resposta, eu entendo que você está procurando uma ferramenta GUI conveniente, então:

Ferramenta GUI pequena para obter o tamanho da rede e o tamanho real de uma janela (atualizada dinamicamente)

Conforme explicado abaixo em "Explicação", tanto wmctrl quanto xdotool retornam um windowsize ligeiramente incorreto.

Oscript(indicador)abaixomostraráotamanho"real" e o tamanho da rede de uma janela no painel.

O script

#!/usr/bin/env python3
import signal
import gi
gi.require_version('AppIndicator3', '0.1')
gi.require_version('Gtk', '3.0')
import subprocess
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread


def get(cmd):
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

# ---
# uncomment either one of two the lines below; the first one will let the user
# pick a window *after* the indicator started, the second one will pick the 
# currently active window
# ---

window = get(["xdotool", "selectwindow"])
# window = get(["xdotool", "getactivewindow"])

class Indicator():
    def __init__(self):
        self.app = 'test123'
        iconpath = "unity-display-panel"
        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())
        self.indicator.set_label(" ...Starting up", self.app)
        # the thread:
        self.update = Thread(target=self.show_seconds)
        # daemonize the thread to make the indicator stopable
        self.update.setDaemon(True)
        self.update.start()

    def create_menu(self):
        menu = Gtk.Menu()
        # separator
        menu_sep = Gtk.SeparatorMenuItem()
        menu.append(menu_sep)
        # quit
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.stop)
        menu.append(item_quit)
        menu.show_all()
        return menu

    def show_seconds(self):
        sizes1 = None
        while True:
            time.sleep(1)
            sizes2 = self.getsize(window)
            if sizes2 != sizes1:
                GObject.idle_add(
                    self.indicator.set_label,
                    sizes2, self.app,
                    priority=GObject.PRIORITY_DEFAULT
                    )
            sizes1 = sizes2

    def getsize(self, window):
        try:
            nettsize = [int(n) for n in get([
                "xdotool", "getwindowgeometry", window
                ]).splitlines()[-1].split()[-1].split("x")]
        except AttributeError:
            subprocess.Popen(["notify-send", "Missing data", "window "+window+\
                              " does not exist\n(terminating)"])
            self.stop()
        else:
            add = [l for l in get(["xprop", "-id", window]).splitlines() if "FRAME" in l][0].split()
            add = [int(n.replace(",", "")) for n in add[-4:]]
            xadd = add[0]+add[1]; yadd = add[2]+add[3]
            totalsize = [str(s) for s in [nettsize[0]+add[0]+add[1], nettsize[1]+add[2]+add[3]]]
            displ_sizes = ["x".join(geo) for geo in [[str(s) for s in nettsize], totalsize]]
            string = " "+displ_sizes[0]+" / "+displ_sizes[1]
            return string+((25-len(string))*" ")

    def stop(self, *args):
        Gtk.main_quit()

Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()

Como usar

  1. O script precisa do xdotool para ser instalado:

    sudo apt-get install xdotool
    
  2. Copie o script em um arquivo vazio, salve-o como getwindowsize.py

  3. Teste- execute o script a partir de uma janela de terminal pelo comando:

    python3 /path/to/getwindowsize.py
    
  4. O script seleciona a janela focada para mostrar dinamicamente o windowsize da rede (como na saída de wmctrl e xdotool ) e o real tamanho da janela, incluindo decoradores, etc.

    Se você fechar a janela segmentada, o indicador mostrará uma mensagem:

  5. Setudofuncionarbem,adicione-oaumatecladeatalho:escolha:Configuraçõesdosistema>"Teclado" > "Atalhos" > "Atalhos personalizados". Clique no botão "+" e adicione o comando:

    python3 /path/to/getwindowsize.py
    

Explicação

O tamanho da janela, como é exibido por wmctrl e xdotool

... está ligeiramente incorreto

Você menciona:

Idealmente, essa ferramenta deduziria o tamanho da barra de menus do Ubuntu

A história completa é que wmctrl -lG e xdotool getwindowgeometry retornam o tamanho da janela sem a barra de menus, ou, como é explicado em esta resposta :

O que está acontecendo é que o wmctrl está retornando a geometria da janela dentro das decorações (ou seja, sem incluir a barra de título e as bordas)

Como obter o tamanho "real" correto

Para obter as informações corretamente, podemos executar

xprop -id <window_id> | grep FRAME

Isso será exibido como:

_NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 28, 0

Aqui, obtemos os valores que precisamos adicionar ao tamanho da janela, como saída de wmctrl e xdotool , à esquerda, à direita, na parte superior e inferior da janela.

Em outras palavras, nesse caso, se um wmctrl mostrar um tamanho de 200x100, o tamanho real será 200x128.

Nota

Como sugerido por OP, o usuário também pode escolher uma janela após o indicador foi iniciado, substituindo:

window = get(["xdotool", "getactivewindow"])

por:

window = get(["xdotool", "selectwindow"])

No script, qualquer uma dessas linhas pode ser descomentada.

    
por Jacob Vlijm 18.12.2016 / 09:47
11

Você pode usar wmctrl -lG para obter uma lista de todas as janelas abertas, em uma tabela com o formato:

<window ID> <desktop ID> <x-coordinate> <y-coordinate> <width> <height> <client machine> <window title>

Um exemplo de saída poderia ser assim:

$ wmctrl -lG
0x02a00002  0 -2020 -1180 1920 1080 MyHostName XdndCollectionWindowImp
0x02a00005  0 0    24   61   1056 MyHostName unity-launcher
0x02a00008  0 0    0    1920 24   MyHostName unity-panel
0x02a0000b  0 -1241 -728 1141 628  MyHostName unity-dash
0x02a0000c  0 -420 -300 320  200  MyHostName Hud
0x03a0000a  0 0    0    1920 1080 MyHostName Desktop
0x0400001d  0 61   24   1859 1056 MyHostName application development - A tool to get window dimensions - Ask Ubuntu - Mozilla Firefox
0x04200084  0 61   52   999  745  MyHostName Untitled Document 1 - gedit
    
por Byte Commander 18.12.2016 / 00:02
9

Encontrei xwininfo -all de link .

Funciona, mas ainda estou aberto a soluções mais convenientes = > uma ferramenta de GUI em tempo real.

    
por Akronix 18.12.2016 / 00:02
2

Pode-se tentar:

xdotool search --name gnome-panel getwindowgeometry

Assumindo que o gnome-panel é o nome do processo da barra de ferramentas do Ubuntu, mas quem sabe.

(pode exigir um sudo apt-get install xdotool )

Para uma coisa GUI improvisada, pode-se querer melhorar ainda mais para exibir apenas o essencial:

zenity --text-info --filename=<(xprop)

Ele mudará o ponteiro para o cruzamento de xprop, então você clicará na janela e imprimirá as informações do xprop em um diálogo do GTK.

    
por El Guesto 18.12.2016 / 04:45
2

xwininfo e suas vantagens

O grande problema com wmctrl e xdotool é que essas ferramentas precisam ser instaladas - elas não estão no Ubuntu por padrão . No entanto, o Ubuntu vem com xwininfo . É uma ferramenta simples que fornece informações sobre a janela selecionada pelo usuário.

O uso simples seria digitar xwininfo | awk '/Width/||/Height/' (observe que awk é usado para filtrar a saída) no terminal e, quando o cursor for alterado para x , selecione qualquer janela da GUI desejada e ela exibirá suas informações . Por exemplo:

$ xwininfo | awk '/Width/||/Height/'                
  Width: 602
  Height: 398

Então as vantagens são:

  • é simples
  • é instalado por padrão
  • é apenas texto - nada sofisticado e você pode filtrar e ajustar conforme necessário

Levando o xwininfo um passo adiante - exibindo propriedades de uma janela ativa

Claro que se você tem um terminal aberto 24 horas por dia, 7 dias por semana, como eu, xwininfo é tudo o que você precisa. Alguns usuários podem preferir ter um atalho de teclado. O script abaixo (que se destina a ser vinculado a um atalho de teclado) permite exibir um pop-up gráfico com informações sobre sua janela ativa no momento. Como pode ser visto na captura de tela, exibe informações de título, largura e altura da janela.

Sobocapôissonãofaznadaparticularmenteespetacular.Eleusainformaçõesdedbusserviceexwininfoeascolocaemumpopupsimples.Ocódigofonteestáabaixo.Lembre-sedequeasregrasdescriptpadrãoseaplicam:certifique-sedequeeletenhapermissõesexecutáveiscomchmod+xe,aovincularaumatalhodeteclado,forneçaocaminhocompletoparaoarquivodescriptcomocomando.

#!/bin/bash get_active_window() { qdbus org.ayatana.bamf \ /org/ayatana/bamf/matcher \ org.ayatana.bamf.matcher.ActiveWindow } get_active_name() { qdbus org.ayatana.bamf $1 \ org.ayatana.bamf.view.Name } main() { active_window=$(get_active_window) active_xid=$( awk -F '/' '{print $NF}' <<< "$active_window" ) echo $active_xid active_title=$(get_active_name $active_window) dimensions=$(xwininfo -id "$active_xid" | awk '/Width/||/Height/') text="$active_title\n""$dimensions" zenity --info --text "$text" --width=200 --height=200 } main $@

Usando o indicador do painel superior do Unity para obter informações.

Ao escrever minha resposta, percebi que isso seria um recurso muito útil para incorporar em um dos meus projetos existentes - o Indicador Ayatana. Este indicador permite mostrar toda a gama de informações sobre janelas GUI. Atualmente ainda está em desenvolvimento ativo. O recurso de informações de geometria foi adicionado ao repositório do github e está a caminho de my PPA pessoal . E, claro, usa xwininfo embora de maneira ligeiramente diferente.

    
por Sergiy Kolodyazhnyy 18.12.2016 / 13:55