Ein Werkzeug zum Abrufen der Fenstermaße

14

Ich benötige ein Werkzeug, um die Breite und Höhe eines beliebigen Fensters zu ermitteln.

Idealerweise würde dieses Tool die Größe der Ubuntu-Menüleiste reduzieren.

Akronix
quelle

Antworten:

6

Aus Ihrer eigenen Antwort geht hervor, dass Sie nach einem praktischen GUI-Tool suchen.

Kleines GUI-Tool zum Abrufen der Nettogröße und der tatsächlichen Größe eines Fensters (dynamisch aktualisiert)

Wie weiter unten in "Erläuterung" erläutert, geben beide wmctrlund xdotooleine etwas falsche Fenstergröße zurück.

Bildbeschreibung hier eingeben

Das Skript (Indikator) unten zeigt sowohl die "echte" Größe als auch die Nettogröße eines Fensters im Panel an.

Das Drehbuch

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

Wie benutzt man

  1. Für das Skript muss xdotool installiert sein:

    sudo apt-get install xdotool
    
  2. Kopieren Sie das Skript in eine leere Datei und speichern Sie es unter getwindowsize.py

  3. Führen Sie das Skript von einem Terminalfenster aus mit dem folgenden Befehl aus:

    python3 /path/to/getwindowsize.py
    
  4. Das Skript wählt das fokussierte Fenster aus , um die Nettofenstergröße (wie in der Ausgabe von wmctrlund xdotool) und die tatsächliche Fenstergröße einschließlich Dekoratoren usw. dynamisch anzuzeigen.

    Wenn Sie das Zielfenster schließen, zeigt der Indikator eine Meldung an:

    Bildbeschreibung hier eingeben

  5. Wenn alles funktioniert, fügen Sie es einer Tastenkombination hinzu: Wählen Sie: Systemeinstellungen> "Tastatur"> "Tastenkombinationen"> "Benutzerdefinierte Tastenkombinationen". Klicken Sie auf das "+" und fügen Sie den Befehl hinzu:

    python3 /path/to/getwindowsize.py
    

Erläuterung

Die Fenstergröße, wie sie sowohl von wmctrl als auch von xdotool angezeigt wird

... ist etwas falsch

Du erwähnst:

Idealerweise würde dieses Tool die Größe der Ubuntu-Menüleiste reduzieren

Die ganze Geschichte ist, dass beide wmctrl -lGund xdotool getwindowgeometrydie Größe des Fensters ohne Menüleiste zurückgeben, oder, wie es in dieser Antwort erklärt wird :

Was passiert ist, dass wmctrl die Geometrie des Fensters innerhalb der Dekorationen zurückgibt (dh ohne Titelleiste und Rahmen)

So erhalten Sie die richtige "echte" Größe

Um die Informationen korrekt abzurufen, können wir ausführen

xprop -id <window_id> | grep FRAME

Dies wird wie folgt ausgegeben:

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

Hier erhalten wir die Werte, die wir zur Fenstergröße hinzufügen müssen, als Ausgabe von wmctrlund xdotoollinks, rechts, oben und unten im Fenster.

Mit anderen Worten, wenn in diesem Fall a wmctrleine Größe von 200 x 100 anzeigt , ist die tatsächliche Größe 200 x 128.

Hinweis

Wie von OP vorgeschlagen, kann der Benutzer auch nach dem Start des Indikators ein Fenster auswählen , indem er Folgendes ersetzt:

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

durch:

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

In dem Skript kann eine dieser Zeilen nicht kommentiert werden.

Jacob Vlijm
quelle
Prost @ Jacob-vlijm, so eine gute Antwort! Nur zwei Dinge: 1) Ich habe es getactivewindowdurch ersetzt. selectwindowWenn das Skript gestartet wird, wählen Sie mit dem Cursor das Fenster aus, aus dem die Dimensionen abgerufen werden sollen. Ich finde dieses Verhalten viel praktischer. 2) Ich habe den Code zum Einfügen von Ubuntu hochgeladen , damit es einfacher einzurichten ist: Einfach herunterladen und als getwindowsize.py
Akronix 24.12.16
@Akronix Danke! Hört sich nach einer großartigen Idee an. Würde es Ihnen etwas ausmachen, wenn ich sie in die Antwort einarbeite?
Jacob Vlijm
Sicher @ jacob-vljim. Fühlen Sie sich frei;)
Akronix
11

Mit können wmctrl -lGSie eine Liste aller geöffneten Fenster in einer Tabelle im folgenden Format abrufen:

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

Eine Beispielausgabe könnte folgendermaßen aussehen:

$ 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
Byte Commander
quelle
2

Man könnte versuchen:

xdotool search --name gnome-panel getwindowgeometry

Angenommen, Gnome-Panel ist der Prozessname der Ubuntu-Symbolleiste, aber wer weiß.

(erfordert möglicherweise a sudo apt-get install xdotool)

Für eine improvisierte GUI-Sache, die man weiter verbessern möchte, um nur das Nötigste anzuzeigen:

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

Es ändert den Zeiger auf das Kreuz von xprop, dann klicken Sie auf das Fenster und es werden die Informationen von xprop in einem GTK-Dialogfeld gedruckt.

El Guesto
quelle
2

xwininfo und seine Vorteile

Das große Problem mit wmctrlund xdotoolist, dass diese Tools installiert werden müssen - sie sind standardmäßig nicht auf Ubuntu . Ubuntu wird jedoch mit ausgeliefert xwininfo. Es ist ein einfaches Tool, das Informationen zum vom Benutzer ausgewählten Fenster bereitstellt.

Die einfache Verwendung wäre, im Terminal einzugeben xwininfo | awk '/Width/||/Height/'(Hinweis, awkder zum Filtern der Ausgabe verwendet wird), und wenn sich Ihr Cursor ändert, xum ein beliebiges GUI-Fenster auszuwählen, das Ihnen gefällt, werden dessen Informationen angezeigt. Beispielsweise:

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

Die Vorteile sind also:

  • es ist einfach
  • es wird standardmäßig installiert
  • Es ist nur Text - nichts Besonderes, und Sie können ihn nach Bedarf filtern und optimieren

Xwininfo noch einen Schritt weiter - Eigenschaften eines aktiven Fensters anzeigen

Natürlich xwininfoist alles, was Sie brauchen, wenn Sie ein Terminal haben, das wie ich rund um die Uhr geöffnet ist. Einige Benutzer bevorzugen möglicherweise eine Tastenkombination. Mit dem folgenden Skript (das an eine Tastenkombination gebunden sein soll) können Sie ein grafisches Popup mit Informationen zu Ihrem derzeit aktiven Fenster anzeigen. Wie auf dem Screenshot zu sehen ist, werden Fenstertitel, Breiten- und Höheninformationen angezeigt.

Bildbeschreibung hier eingeben

Unter der Haube macht das nichts besonders Spektakuläres. Es verwendet Informationen aus dem dbusService xwininfound fügt sie in ein einfaches Popup ein. Der Quellcode ist unten. Denken Sie daran, dass die Standardregeln für die Skripterstellung gelten: Stellen Sie sicher, dass sie über ausführbare Berechtigungen verfügen chmod +xund dass Sie beim Binden an eine Tastenkombination den vollständigen Pfad zur Skriptdatei als Befehl angeben.

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

Informationen finden Sie in der Anzeige auf der Oberseite von Unity.

Als ich meine Antwort schrieb, wurde mir klar, dass dies eine sehr nützliche Funktion ist, die ich in eines meiner bestehenden Projekte integrieren kann - den Ayatana-Indikator. Dieser Indikator ermöglicht die Anzeige einer ganzen Reihe von Informationen zu GUI-Fenstern. Derzeit ist noch in der aktiven Entwicklung. Die Geometrie-Info-Funktion wurde dem Github-Repository hinzugefügt und ist auf dem Weg in meine persönliche PPA . Und natürlich wird es xwininfozwar auf etwas andere Art und Weise verwendet.

Bildbeschreibung hier eingeben

Sergiy Kolodyazhnyy
quelle