Yükseltilecek pencereleri nasıl gruplandırabilirim?


10

İki pencerem var, A ve B. Bir şekilde iki pencereyi birbirine bağlamak mümkün mü, öyle ki A'ya geçiş de B'yi yükseltiyor veya B'ye geçiş de A'yı yükseltiyor mu?

Birden fazla çalışma alanı kullanmanın alternatif bir seçenek olduğunu anlıyorum ama bunun da mümkün olup olmadığını merak ediyor muydunuz?


z-order süper önemli değil ama mümkünse bu harika olurdu
Simon Tong

Bence birden fazla işyeri açık ara en basit çözüm. Aralarında geçiş yapmak için tuş kombinasyonlarını biliyor musunuz?
thomasrutter

1
Hızlı bir kabul edersiniz :) Yine de, cevabımla ilgili yorumda bulunursanız seviniriz.
Jacob Vlijm

Yanıtlar:


9

Giriş

Aşağıdaki komut dosyası iki pencere seçmeye izin verir ve her iki pencere açıkken, kullanıcı her ikisini de odakladığında her iki pencereyi de yükseltir. Örneğin, eğer A ve B dulları birbirine bağlarsa, ya A ya da B'ye geçmek her ikisini de diğer dulların üzerine çıkarır.

Komut dosyasını durdurmak için killall link_windows.pyterminalde kullanabilir veya pencerelerden birini kapatıp yeniden açabilirsiniz . Ayrıca X, pencere seçimi açılır iletişim kutularından herhangi birinde kapat düğmesine basarak yürütmeyi iptal edebilirsiniz .

Potansiyel ayarlamalar:

  • iki pencerenin çiftlerini gruplandırmak için betiğin birden çok örneği kullanılabilir. Örneğin, A, B, C ve D pencerelerimiz varsa, A ve B'yi birbirine bağlayabilir ve C ve D'yi birbirine bağlayabiliriz.
  • birden çok pencere tek bir pencere altında gruplandırılabilir. Örneğin, B penceresini A, C'den A'ya ve D'yi A'ya bağlarsam, her zaman A'ya geçersem, aynı anda 4 pencereyi de kaldırabilirim.

kullanım

Komut dosyasını şu şekilde çalıştırın:

python link_windows.py

Komut dosyası Python 3 ile uyumlu olduğundan,

python3 link_windows.py

İki komut satırı seçeneği vardır:

  • --quietveya -q, GUI pencerelerinin sessizleştirilmesine izin verir. Bu seçenekle herhangi bir pencerede fare ile tıklayabilirsiniz ve komut dosyası bunları bağlamaya başlayacaktır.
  • --helpveya -hkullanım ve açıklama bilgilerini yazdırır.

-hSeçenek aşağıdaki bilgileri üretir:

$ python3 link_windows.py  -h                                                                                            
usage: link_windows.py [-h] [--quiet]

Linker for two X11 windows.Allows raising two user selected windows together

optional arguments:
  -h, --help  show this help message and exit
  -q, --quiet  Blocks GUI dialogs.

Ek teknik bilgiler aracılığıyla görülebilir pydoc ./link_windows.py, nereye ./komut dosyası ile aynı dizinde olmalıdır anlamına hangi.

İki pencere için basit kullanım süreci:

  1. Bir pencere # seçmenizi, basın OKveya vurmanızı isteyen bir açılır pencere görünecektir Enter. Fare işaretçisi çarpı işaretine dönüşür. Bağlamak istediğiniz pencerelerden birini tıklayın.

  2. 2. pencereyi seçmenizi, basın OKveya vurmanızı isteyen ikinci bir açılır pencere görüntülenir Enter. Fare işaretçisi bir çarpı işaretine dönüşecektir. Bağlamak istediğiniz diğer pencereye tıklayın. Bundan sonra icra başlayacak.

  3. Her iki pencereden birine odaklandığınızda, komut dosyası diğer pencereyi yukarı kaldırır, ancak odağı orijinal olarak seçilen pencereye döndürür (not - en iyi performans için ikinci bir gecikmenin çeyreği ile), böylece pencerelerin birbirine bağlı olduğu hissini yaratır.

Aynı pencereyi iki kez seçerseniz, komut dosyası kapanır. Herhangi bir anda açılır iletişim kutusunun kapat düğmesini tıklarsanız, komut dosyası kapanır.

Komut dosyası kaynağı

GitHub Gist olarak da mevcut

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sergiy Kolodyazhnyy
Date:  August 2nd, 2016
Written for: https://askubuntu.com/q/805515/295286
Tested on Ubuntu 16.04 LTS
"""
import gi
gi.require_version('Gdk', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Gdk, Gtk
import time
import subprocess
import sys
import argparse


def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError:
        sys.exit(1)
    else:
        if stdout:
            return stdout


def focus_windows_in_order(first, second, scr):
    """Raise two user-defined windows above others.
       Takes two XID integers and screen object.
       Window with first XID will have the focus"""

    first_obj = None
    second_obj = None

    for window in scr.get_window_stack():
        if window.get_xid() == first:
            first_obj = window
        if window.get_xid() == second:
            second_obj = window

    # When this  function is called first_obj is alread
    # raised. Therefore we must raise second one, and switch
    # back to first
    second_obj.focus(int(time.time()))
    second_obj.get_update_area()
    # time.sleep(0.25)
    first_obj.focus(int(time.time()))
    first_obj.get_update_area()


def get_user_window():
    """Select two windows via mouse. Returns integer value of window's id"""
    window_id = None
    while not window_id:
        for line in run_cmd(['xwininfo', '-int']).decode().split('\n'):
            if 'Window id:' in line:
                window_id = line.split()[3]
    return int(window_id)


def main():
    """ Main function. This is where polling for window stack is done"""

    # Parse command line arguments
    arg_parser = argparse.ArgumentParser(
        description="""Linker for two X11 windows.Allows raising """ +
                    """two user selected windows together""")
    arg_parser.add_argument(
                '-q','--quiet', action='store_true',
                help='Blocks GUI dialogs.',
                required=False)
    args = arg_parser.parse_args()

    # Obtain list of two user windows
    user_windows = [None, None]
    if not args.quiet:
        run_cmd(['zenity', '--info', '--text="select first window"'])
    user_windows[0] = get_user_window()
    if not args.quiet:
        run_cmd(['zenity', '--info', '--text="select second window"'])
    user_windows[1] = get_user_window()

    if user_windows[0] == user_windows[1]:
        run_cmd(
            ['zenity', '--error', '--text="Same window selected. Exiting"'])
        sys.exit(1)

    screen = Gdk.Screen.get_default()
    flag = False

    # begin watching for changes in window stack
    while True:

        window_stack = [window.get_xid()
                        for window in screen.get_window_stack()]

        if user_windows[0] in window_stack and user_windows[1] in window_stack:

            active_xid = screen.get_active_window().get_xid()
            if active_xid not in user_windows:
                flag = True

            if flag and active_xid == user_windows[0]:
                focus_windows_in_order(
                    user_windows[0], user_windows[1], screen)
                flag = False

            elif flag and active_xid == user_windows[1]:
                focus_windows_in_order(
                    user_windows[1], user_windows[0], screen)
                flag = False

        else:
            break

        time.sleep(0.15)


if __name__ == "__main__":
    main()

Notlar:

  • Komut satırından çalıştırıldığında, açılır iletişim kutuları aşağıdaki iletiyi oluşturur: Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.Bunlar yok sayılabilir.
  • Danışmak Unity'deki yeni başlatıcı öğelerini elle nasıl düzenleyebilir / oluşturabilirim? çift ​​tıklatarak başlatmak istiyorsanız, bu komut dosyası için bir başlatıcı veya masaüstü kısayolu oluşturmak için
  • Bu komut dosyasını kolay erişim için bir klavye kısayoluna bağlamak için bkz. Klavye kısayolları nasıl eklenir?

Şerefe Gerçekten etkilendim. time.sleepAnahtarlama arasındaki bit, bunu sıfıra koymak mümkün ben? gecikmenin bir nedeni var mı?
Simon Tong

1
@simontong gibi satır yorum yapmayı deneyebilirsiniz # time.sleep(0.25)ve yürütmek alışkanlık. Bunun nedeni, her pencerenin düzgün bir şekilde kaldırılmasını sağlamaktır. Geçmişteki tecrübelerime göre, pencerelerde çalışmak için gecikmelere ihtiyacım vardı. Çeyrek saniye gecikmenin o kadar da olmadığını düşünürdüm. Aslında betiğe sadece bir satır daha ekleyeyim, bu onu hızlandırabilir. TAMAM ?
Sergiy Kolodyazhnyy

@simontong Tamam, senaryoyu güncelledim. Şimdi dene. Daha hızlı geçiş olmalı
Sergiy Kolodyazhnyy

@simontong Komut dosyasını birkaç ek özellik eklemek için birkaç küçük eklemeyle güncelleyeceğim. Hazır olduğunda size haber vereceğim, lütfen ne düşündüğünüzü bana bildirin
Sergiy Kolodyazhnyy

@simontong betiğe ekstra seçenekler ekledi, lütfen gözden geçirin
Sergiy Kolodyazhnyy

6

İstediğiniz sayıda pencereyi bir tane olarak yükseltin

Aşağıdaki çözüm , bir klavye kısayolu ile birleştirilecek ve yükseltilecek iki, üç veya daha fazla pencerenin herhangi bir kombinasyonunu seçmenize izin verecektir .

Komut dosyası üç argümanla çalışır:

add

etkin pencereyi gruba eklemek için

raise

set grubunu yükseltmek

clear

grubu temizlemek için yeni bir grup tanımlamaya hazır

Senaryo

#!/usr/bin/env python3
import sys
import os
import subprocess

wlist = os.path.join(os.environ["HOME"], ".windowlist")

arg = sys.argv[1]

if arg == "add":
    active = subprocess.check_output([
        "xdotool", "getactivewindow"
        ]).decode("utf-8").strip()
    try:
        currlist = open(wlist).read()
    except FileNotFoundError:
        currlist = []
    if not active in currlist:
        open(wlist, "a").write(active + "\n")
elif arg == "raise":
    group = [w.strip() for w in open(wlist).readlines()]
    [subprocess.call(["wmctrl", "-ia", w]) for w in group]
elif arg == "clear":
    os.remove(wlist)

Nasıl kullanılır

  1. Betiğin ihtiyacı wmctrlve xdotool:

    sudo apt-get install wmctrl xdotool
  2. Yukarıdaki komut dosyasını boş bir dosyaya kopyalayın, groupwindows.py
  3. Komut dosyasını test edin: iki terminal penceresi açın, komutu çalıştırın:

    python3 /absolute/path/to/groupwindows.py add

    ikisinde de. Bunları diğer pencerelerle örtün (veya simge durumuna küçültün). Üçüncü bir terminal penceresi açın, şu komutu çalıştırın:

    python3 /absolute/path/to/groupwindows.py raise

    İlk iki pencere birer yükseltilecek.

  4. Her şey yolunda giderse, üç özel kısayol tuşu oluşturun: Seçin: Sistem Ayarları> "Klavye"> "Kısayollar"> "Özel Kısayollar". "+" İşaretini tıklayın ve aşağıdaki komutları üç ayrı kısayola ekleyin:

    benim sistemimde kullandım:

    Alt+ A, şu komutu çalıştırır:

    python3 /absolute/path/to/groupwindows.py add

    ... gruba pencere eklemek için.

    Alt+ R, şu komutu çalıştırır:

    python3 /absolute/path/to/groupwindows.py raise

    ... grubu büyütmek için.

    Alt+ C, şu komutu çalıştırır:

    python3 /absolute/path/to/groupwindows.py clear

    ... grubu temizlemek için

açıklama

Betik oldukça basit çalışır:

  • Bağımsız değişkenle çalıştırıldığında add, komut dosyası etkin pencerenin pencere kimliğini gizli bir dosyaya depolar / ekler~/.windowlist
  • Bağımsız değişken ile çalıştırıldığında raise, komut dosyası dosyayı okur, listedeki pencereleri şu komutla kaldırır:

    wmctrl -ia <window_id>
  • Bağımsız değişkenle çalıştırıldığında clear, komut dosyası gizli dosyayı kaldırır ~/.windowlist.

notlar

  • Komut dosyası simge durumuna küçültülmüş pencerelerde de çalışır, simge durumuna küçültülmüş pencereleri en aza indirir
  • Windows kümesi başka bir görünümde ise, komut dosyası ilgili görünüm penceresine geçer
  • Set flexibel'dir, mevcut sete her zaman başka pencereler ekleyebilirsiniz.

Daha fazla esneklik?

Belirtildiği gibi, yukarıdaki komut dosyası gruplandırılmış pencerelere herhangi bir zamanda pencere eklenmesine izin verir. Aşağıdaki sürüm , pencerelerden herhangi birinin (herhangi bir zamanda) gruplandırılmış listeden kaldırılmasına da izin verir :

#!/usr/bin/env python3
import sys
import os
import subprocess

wlist = os.path.join(os.environ["HOME"], ".windowlist")
arg = sys.argv[1]
# add windows to the group
if arg == "add":
    active = subprocess.check_output([
        "xdotool", "getactivewindow"
        ]).decode("utf-8").strip()
    try:
        currlist = open(wlist).read()
    except FileNotFoundError:
        currlist = []
    if not active in currlist:
        open(wlist, "a").write(active + "\n")
# delete window from the group
if arg == "delete":
    try:
        currlist = [w.strip() for w in open(wlist).readlines()]
    except FileNotFoundError:
        pass
    else:
        currlist.remove(subprocess.check_output([
            "xdotool", "getactivewindow"]).decode("utf-8").strip())      
        open(wlist, "w").write("\n".join(currlist)+"\n")
# raise the grouped windows
elif arg == "raise":
    group = [w.strip() for w in open(wlist).readlines()]
    [subprocess.call(["wmctrl", "-ia", w]) for w in group]
# clear the grouped window list
elif arg == "clear":
    os.remove(wlist)

Komut dosyasını çalıştırmak için ek argüman şudur delete:

python3 /absolute/path/to/groupwindows.py delete

etkin pencereyi gruplanmış pencerelerden siler. Bu komutu çalıştırmak için, sistemimde Alt+ Dkısayol olarak ayarladım .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.