Інструмент для отримання розмірів вікна


14

Мені потрібен інструмент для отримання ширини та висоти довільного вікна.

В ідеалі цей інструмент мав би вирахувати розмір панелі меню Ubuntu.

Відповіді:


6

З вашої власної відповіді я розумію, що ви шукаєте зручний інструмент GUI, так що:

Невеликий інструмент графічного інтерфейсу, щоб отримати як розмір нетто, так і реальний розмір вікна (динамічно оновлюється)

Як пояснено далі в "Пояснення", і те, wmctrlі xdotoolповернути трохи неправильний розмір вікна.

введіть тут опис зображення

Сценарій (індикатор) нижче покаже як "реальний" розмір, так і чистий розмір вікна на панелі.

Сценарій

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

Як користуватись

  1. Сценарій потребує встановлення xdotool:

    sudo apt-get install xdotool
    
  2. Скопіюйте скрипт у порожній файл, збережіть його як getwindowsize.py

  3. Тест - запустіть скрипт із вікна терміналу командою:

    python3 /path/to/getwindowsize.py
    
  4. Сценарій вибирає сфокусоване вікно, щоб динамічно показувати чистий розмір вікна (як у висновку обох wmctrlі xdotool) та реальний розмір вікна, включаючи декоратори тощо.

    Якщо ви закриєте цільове вікно, індикатор показує повідомлення:

    введіть тут опис зображення

  5. Якщо все працює добре, додайте його до клавіші швидкого доступу: виберіть: Налаштування системи> "Клавіатура"> "Ярлики"> "Спеціальні ярлики". Клацніть "+" і додайте команду:

    python3 /path/to/getwindowsize.py
    

Пояснення

Розмір вікна, як він відображається як wmctrl, так і xdotool

... трохи неправильно

Ви згадуєте:

В ідеалі цей інструмент мав би вирахувати розмір панелі меню Ubuntu

Повна історія полягає в тому, що обидва wmctrl -lGі xdotool getwindowgeometryповертають розмір вікна без рядка меню, або, як пояснено у цій відповіді :

Що відбувається, це те, що wmctrl повертає геометрію вікна всередині прикрас (тобто не включає заголовка та рамки)

Як отримати правильний, "реальний" розмір

Щоб правильно отримати інформацію, ми можемо запустити

xprop -id <window_id> | grep FRAME

Це виведе так:

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

Тут ми отримуємо значення, які нам потрібно додати до розміру вікна, як виведення з wmctrlі xdotool, зліва, праворуч, вгорі та внизу вікна.

Іншими словами, у цьому випадку, якщо wmctrlпоказ показує розмір 200x100, реальний розмір - 200x128.

Примітка

За пропозицією ОП, користувач також може вибрати вікно після запуску індикатора, замінивши:

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

автор:

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

У сценарії будь-який із цих рядків може коментуватися.


Привіт @ Jacob-vlijm, така гарна відповідь! Тільки дві речі: 1) Я замінив getactivewindowна selectwindow, тому , коли скрипт запускається ви вибираєте за допомогою курсору в вікно , щоб отримати розміри від. Я вважаю таку поведінку набагато зручнішою. 2) Я завантажив код, щоб вставити ubuntu , тому його простіше налаштувати: Просто завантажте та збережіть як getwindowsize.py
Akronix

@Akronix Дякую! звучить як чудова ідея, ви б не заперечували, якщо я редагую її у відповідь?
Яків Влійм

Звичайно @ jacob-vljim. Відчувайте себе вільно;)
Akronix

11

Можна використовувати wmctrl -lG для отримання списку всіх відкритих вікон у таблиці з форматом:

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

Приклад результату може виглядати так:

$ 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

9

Я дізнався xwininfo -allз /unix/14159/how-do-i-find-the-window-dimensions-and-position-accurely-including-decoration .

Це працює, але я все ще відкритий для більш зручних рішень => інструмент графічного інтерфейсу в реальному часі.


Я опублікував відповідь, але не помітив, що ви вже знайшли xwininfo. Можливо, вас зацікавить сценарій, який я написав - він використовує, xwininfoале із спливаючим графічним інтерфейсом, будь ласка, перегляньте його нижче.
Сергій Колодяжний

2

Можна спробувати:

xdotool search --name gnome-panel getwindowgeometry

Припустимо, що gnome-панель - це ім'я процесу в панелі інструментів ubuntu, але хто знає.

(може знадобитися sudo apt-get install xdotool )

Імпровізований графічний інтерфейс, який, можливо, захочеться вдосконалити, щоб відобразити лише основні речі:

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

Він змінить вказівник на хрест xprop, потім ви натиснете вікно, і воно надрукує інформацію xprop у діалоговому вікні GTK.


2

xwininfo та його переваги

Велика проблема з wmctrlі в xdotoolтому , що ці кошти повинні бути встановлені - вони не на Ubuntu за замовчуванням . Однак Ubuntu поставляється зxwininfo . Це простий інструмент, який надає інформацію про вибране користувачем вікно.

Просте використання буде вводити xwininfo | awk '/Width/||/Height/'(повідомлення, яке awkвикористовується для фільтрації виводу) в термінал, і коли ваш курсор змінюється, щоб xвибрати будь-яке вікно графічного інтерфейсу, яке вам подобається, і воно відображатиме його інформацію. Наприклад:

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

Таким чином, переваги:

  • це просто
  • він встановлений за замовчуванням
  • це просто текст - нічого фантазійного, і ви можете його відфільтрувати та налаштувати

Зробити xwininfo ще на крок - відображення властивостей активного вікна

Звичайно, якщо у вас відкритий термінал 24/7, як я, xwininfo- це все, що вам потрібно. Деякі користувачі можуть скористатися комбінацією клавіш. Сценарій нижче (який повинен бути прив’язаний до комбінації клавіш) дозволяє відображати графічне спливаюче вікно з інформацією про поточне активне вікно. Як видно на скріншоті, він відображає назву вікна, інформацію про ширину та висоту.

введіть тут опис зображення

Під кришкою це не робить нічого особливо вражаючого. Він використовує інформацію з dbusсервісу xwininfoта розміщує її у простому спливаючому вікні. Нижній вихідний код. Пам'ятайте, що застосовуються стандартні правила сценаріїв: переконайтеся, що вони мають дозволені права на виконання chmod +xі при прив'язці до ярлика клавіатури ви надаєте повний шлях до файлу сценарію як команди.

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

Використання індикатора верхньої панелі Unity для отримання інформації.

Пишучи свою відповідь, я зрозумів, що це було б дуже корисною функцією для включення в один із моїх існуючих проектів - показник «Айатана». Цей показник дозволяє показувати весь спектр інформації про вікна GUI. В даний час все ще знаходиться в активному розвитку. Інформація про геометрію була додана до сховища github і переходить до мого особистого PPA . І звичайно, він використовує, xwininfoхоча дещо інакше.

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.