Narzędzie do uzyskiwania wymiarów okna

14

Potrzebuję narzędzia, aby uzyskać szerokość i wysokość dowolnego okna.

Idealnie, to narzędzie odliczy rozmiar paska menu Ubuntu.

Akronix
źródło

Odpowiedzi:

6

Z Twojej odpowiedzi rozumiem, że szukasz wygodnego narzędzia graficznego, więc:

Małe narzędzie GUI, aby uzyskać zarówno rozmiar netto, jak i rzeczywisty rozmiar okna (dynamicznie aktualizowany)

Jak wyjaśniono poniżej w „wyjaśnienie”, zarówno wmctrli xdotoolpowrócić nieco niepoprawne windowsize.

wprowadź opis zdjęcia tutaj

Poniższy skrypt (wskaźnik) pokaże zarówno „rzeczywisty” rozmiar, jak i rozmiar netto okna w panelu.

Scenariusz

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

Jak używać

  1. Skrypt wymaga zainstalowania xdotool:

    sudo apt-get install xdotool
    
  2. Skopiuj skrypt do pustego pliku i zapisz go jako getwindowsize.py

  3. Testuj - uruchom skrypt z okna terminala za pomocą polecenia:

    python3 /path/to/getwindowsize.py
    
  4. Skrypt wybiera zogniskowane okno, aby dynamicznie wyświetlać rozmiar okna netto (jak na wyjściu zarówno wmctrli xdotool), jak i rzeczywisty rozmiar okna, w tym dekoratorów itp.

    Po zamknięciu docelowego okna wskaźnik pokazuje komunikat:

    wprowadź opis zdjęcia tutaj

  5. Jeśli wszystko działa poprawnie, dodaj go do klawisza skrótu: wybierz: Ustawienia systemu> „Klawiatura”> „Skróty”> „Skróty niestandardowe”. Kliknij „+” i dodaj polecenie:

    python3 /path/to/getwindowsize.py
    

Wyjaśnienie

Rozmiar okna, ponieważ jest wyświetlany zarówno przez wmctrl, jak i xdotool

... jest nieco niepoprawny

Wspominasz:

Idealnie, to narzędzie odliczy rozmiar paska menu Ubuntu

Pełna historia jest taka, że zarówno wmctrl -lGi xdotool getwindowgeometryzwróci rozmiar okna bez paska menu, lub, jak to wyjaśniono w tej odpowiedzi :

To, co się dzieje, polega na tym, że wmctrl zwraca geometrię okna wewnątrz dekoracji (tj. Bez paska tytułu i obramowań)

Jak uzyskać właściwy „prawdziwy” rozmiar

Aby poprawnie uzyskać informacje, możemy uruchomić

xprop -id <window_id> | grep FRAME

To da wynik:

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

Tutaj otrzymujemy wartości, które musimy dodać do rozmiaru okna, jako dane wyjściowe z wmctrloraz xdotool, po lewej, prawej, górnej i dolnej części okna.

Innymi słowy, w tym przypadku, jeśli a wmctrlpokazuje rozmiar 200 x 100, rzeczywisty rozmiar to 200 x 128.

Uwaga

Jak sugeruje OP, użytkownik może również wybrać okno po uruchomieniu wskaźnika, zastępując:

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

przez:

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

W skrypcie jedną z tych linii można odkomentować.

Jacob Vlijm
źródło
Pozdrawiam @ Jacob-vlijm, taka dobra odpowiedź! Tylko dwie rzeczy: 1) Mam zastąpiona getactivewindowprzez selectwindow, więc gdy skrypt zostanie uruchomiony wybrać kursorem okna, by otrzymać od wymiarów. Uważam to zachowanie za znacznie wygodniejsze. 2) Przesłałem kod, aby wkleić ubuntu , więc łatwiej jest go skonfigurować: Wystarczy pobrać i zapisać jako getwindowsize.py
Akronix,
@Akronix Thanks! brzmi jak świetny pomysł, czy miałbyś coś przeciwko, jeśli zmienię go w odpowiedź?
Jacob Vlijm,
Jasne @ jacob-vljim. Zapraszam;)
Akronix,
11

Możesz użyć, wmctrl -lGaby uzyskać listę wszystkich otwartych okien, w tabeli o formacie:

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

Przykładowe dane wyjściowe mogą wyglądać następująco:

$ 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
Bajt Dowódca
źródło
2

Można spróbować:

xdotool search --name gnome-panel getwindowgeometry

Zakładając, że gnome-panel jest nazwą procesu na pasku narzędzi Ubuntu, ale kto wie.

(może wymagać sudo apt-get install xdotool)

W przypadku improwizowanego interfejsu GUI, który można chcieć dalej doskonalić, aby wyświetlić tylko podstawowe rzeczy:

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

Zmieni on wskaźnik na krzyżyk xprop, a następnie klikniesz okno i wydrukuje informacje xprop w oknie dialogowym GTK.

El Guesto
źródło
2

xwininfo i jego zalety

Duży problem z wmctrli xdotooljest to, że te narzędzia muszą być zainstalowane - nie są one na Ubuntu domyślnie . Jednak Ubuntu jest dostarczane z xwininfo. Jest to proste narzędzie, które dostarcza informacji o oknie wybranym przez użytkownika.

Prostym zastosowaniem byłoby wpisanie xwininfo | awk '/Width/||/Height/'(zauważ, że awkjest używane do filtrowania danych wyjściowych) w terminalu, a gdy kursor zmieni się, xwybierz dowolne okno GUI, które Ci się podoba, i wyświetli jego informacje. Na przykład:

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

Więc zalety to:

  • to jest proste
  • jest instalowany domyślnie
  • to tylko tekst - nic szczególnego i możesz go filtrować i poprawiać w razie potrzeby

Idąc dalej o xwininfo - wyświetlanie właściwości aktywnego okna

Oczywiście, jeśli masz otwarty terminal 24/7, tak jak ja, xwininfowystarczy. Niektórzy użytkownicy mogą preferować skrót klawiaturowy. Poniższy skrypt (który ma być powiązany ze skrótem klawiaturowym) pozwala wyświetlić graficzne okno podręczne z informacją o aktualnie aktywnym oknie. Jak widać na zrzucie ekranu, wyświetla informacje o tytule, szerokości i wysokości okna.

wprowadź opis zdjęcia tutaj

Pod maską nie robi to nic szczególnie spektakularnego. Wykorzystuje informacje z dbususługi xwininfoi umieszcza je w prostym wyskakującym okienku. Kod źródłowy jest poniżej. Pamiętaj, że obowiązują standardowe reguły skryptów: upewnij się, że ma uprawnienia do wykonywania za pomocą, chmod +xa podczas wiązania ze skrótem klawiaturowym podajesz pełną ścieżkę do pliku skryptu jako komendę.

#!/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 $@

Używanie wskaźnika górnego panelu Unity w celach informacyjnych.

Pisząc odpowiedź, zdałem sobie sprawę, że byłaby to bardzo przydatna funkcja do włączenia w jeden z moich istniejących projektów - Wskaźnik Ayatana. Ten wskaźnik pozwala pokazać cały zakres informacji o oknach GUI. Obecnie jest ciągle w fazie rozwoju. Funkcja informacji o geometrii została dodana do repozytorium github i jest w drodze do mojego osobistego PPA . I oczywiście używa, xwininfochoć w nieco inny sposób.

wprowadź opis zdjęcia tutaj

Sergiy Kolodyazhnyy
źródło