Risposte:
Dalla tua risposta, capisco che stai cercando uno strumento GUI conveniente, quindi:
Come spiegato più avanti in "Spiegazione", entrambi wmctrl
e xdotool
restituiscono un formato di finestra leggermente errato.
Lo script (indicatore) di seguito mostrerà sia la dimensione "reale" che la dimensione netta di una finestra nel pannello.
#!/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()
Lo script richiede l'installazione di xdotool:
sudo apt-get install xdotool
Copia lo script in un file vuoto, salvalo come getwindowsize.py
Prova- esegui lo script da una finestra terminale con il comando:
python3 /path/to/getwindowsize.py
Lo script seleziona la finestra focalizzata per mostrare dinamicamente la dimensione della finestra (come nell'output di entrambi wmctrl
e xdotool
) e la dimensione reale della finestra, inclusi i decoratori ecc.
Se chiudi la finestra target, l'indicatore mostra un messaggio:
Se tutto funziona bene, aggiungilo a un tasto di scelta rapida: scegli: Impostazioni di sistema> "Tastiera"> "Scorciatoie"> "Scorciatoie personalizzate". Fai clic su "+" e aggiungi il comando:
python3 /path/to/getwindowsize.py
... è leggermente errato
Tu citi:
Idealmente, quello strumento dedurrebbe le dimensioni della barra dei menu di Ubuntu
La storia completa è che sia wmctrl -lG
e xdotool getwindowgeometry
restituire la dimensione della finestra senza barra dei menu, o, come si è spiegato in questa risposta :
Quello che sta succedendo è che wmctrl sta restituendo la geometria della finestra all'interno delle decorazioni (cioè non includendo la barra del titolo e i bordi)
Per ottenere correttamente le informazioni, possiamo eseguire
xprop -id <window_id> | grep FRAME
Questo produrrà come:
_NET_FRAME_EXTENTS(CARDINAL) = 0, 0, 28, 0
Qui otteniamo i valori che dobbiamo aggiungere alle dimensioni della finestra, come output da wmctrl
e xdotool
, a sinistra, a destra, in alto e in basso nella finestra.
In altre parole, in questo caso, se a wmctrl
mostra una dimensione di 200x100, la dimensione reale è 200x128.
Come suggerito da OP, l'utente può anche selezionare una finestra dopo l'avvio dell'indicatore, sostituendo:
window = get(["xdotool", "getactivewindow"])
di:
window = get(["xdotool", "selectwindow"])
Nello script, una di queste righe può essere decommentata.
È possibile utilizzare wmctrl -lG
per ottenere un elenco di tutte le finestre aperte, in una tabella con il formato:
<window ID> <desktop ID> <x-coordinate> <y-coordinate> <width> <height> <client machine> <window title>
Un output di esempio potrebbe essere simile al seguente:
$ 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
Ho trovato xwininfo -all
da /unix/14159/how-do-i-find-the-window-dimensions-and-position-accurately-including-decoration .
Funziona ma sono ancora aperto a soluzioni più convenienti => uno strumento GUI in tempo reale.
xwininfo
già trovato . Forse ti interesserebbe lo script che ho scritto - utilizza xwininfo
ma con un popup della GUI, per favore, vedi sotto.
Si potrebbe provare:
xdotool search --name gnome-panel getwindowgeometry
Supponendo che gnome-panel sia il nome del processo della barra degli strumenti di Ubuntu, ma chi lo sa.
(potrebbe richiedere un sudo apt-get install xdotool
)
Per una cosa della GUI improvvisata che si potrebbe desiderare di migliorare ulteriormente in modo da visualizzare solo gli elementi essenziali nudi:
zenity --text-info --filename=<(xprop)
Cambierà il puntatore alla croce di xprop, quindi fai clic sulla finestra e stamperà le informazioni di xprop in una finestra di dialogo GTK.
Il grosso problema con wmctrl
e xdotool
è che quegli strumenti devono essere installati - non sono su Ubuntu per impostazione predefinita . Tuttavia, Ubuntu viene fornito con xwininfo
. È uno strumento semplice che fornisce informazioni sulla finestra selezionata dall'utente.
L'utilizzo semplice sarebbe quello di digitare xwininfo | awk '/Width/||/Height/'
(notare che awk
viene utilizzato per filtrare l'output) nel terminale e quando il cursore cambia per x
selezionare qualsiasi finestra della GUI che ti piace e visualizzerà le sue informazioni. Per esempio:
$ xwininfo | awk '/Width/||/Height/'
Width: 602
Height: 398
Quindi i vantaggi sono:
Ovviamente se hai un terminale aperto 24 ore su 24, 7 giorni su 7, come faccio io, xwininfo
è tutto ciò di cui hai bisogno. Alcuni utenti potrebbero preferire avere una scorciatoia da tastiera. Lo script seguente (che si intende associare a una scorciatoia da tastiera) consente di visualizzare un popup grafico con informazioni sulla finestra attualmente attiva. Come si può vedere nello screenshot, visualizza il titolo della finestra, le informazioni su larghezza e altezza.
Sotto il cofano questo non fa nulla di particolarmente spettacolare. Utilizza le informazioni dal dbus
servizio xwininfo
e le mette in un semplice popup. Il codice sorgente è sotto. Ricorda che si applicano le regole standard di scripting: assicurati che disponga delle autorizzazioni eseguibili con chmod +x
e quando si esegue il collegamento alla scorciatoia da tastiera, si fornisce il percorso completo al file di script come comando.
#!/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 $@
Quando ho scritto la mia risposta, mi sono reso conto che questa sarebbe una caratteristica molto utile da incorporare in uno dei miei progetti esistenti: l'indicatore Ayatana. Questo indicatore consente di mostrare l'intera gamma di informazioni sulle finestre della GUI. Attualmente è ancora in fase di sviluppo attivo. La funzione di informazioni sulla geometria è stata aggiunta al repository github ed è in arrivo nel mio PPA personale . E, naturalmente, usa xwininfo
anche se in modo leggermente diverso.
getactivewindow
daselectwindow
, quindi quando lo script viene lanciato scegli con il cursore la finestra da cui ottenere le dimensioni. Trovo questo comportamento molto più conveniente. 2) Ho caricato il codice per incollare Ubuntu , quindi è più facile da configurare: basta scaricare e salvare come getwindowsize.py