Bagaimana saya bisa mengelompokkan jendela yang akan dinaikkan menjadi satu?

10

Saya memiliki dua jendela, A dan B. Apakah mungkin untuk menghubungkan dua jendela bersama-sama, sehingga beralih ke A juga meningkatkan B, atau beralih ke B juga menimbulkan A?

Saya mengerti bahwa menggunakan banyak ruang kerja adalah pilihan alternatif tetapi bertanya-tanya apakah ini juga mungkin?

Simon Tong
sumber
z-order tidak super penting tetapi jika mungkin itu akan menjadi hebat
Simon Tong
Saya pikir beberapa tempat kerja sejauh ini merupakan solusi paling sederhana. Anda tahu kombinasi tombol untuk beralih di antara mereka?
thomasrutter
1
Anda adalah akseptor cepat :) Namun, akan sangat menghargai jika Anda memberikan komentar atas jawaban saya.
Jacob Vlijm
5
Kemungkinan duplikat pengelompokan Window?

Jawaban:

9

pengantar

Script berikut memungkinkan memilih dua jendela, dan sementara kedua jendela terbuka, itu akan menaikkan kedua jendela ketika pengguna memfokuskan keduanya. Misalnya, jika seseorang menautkan janda A dan B, mempesonakan ke A atau B akan membuat keduanya naik di atas janda lainnya.

Untuk menghentikan skrip yang dapat Anda gunakan killall link_windows.pydi terminal, atau tutup dan buka kembali salah satu jendela. Anda juga dapat membatalkan eksekusi dengan menekan tombol tutup Xpada salah satu dialog sembulan pilihan jendela.

Potensi tweak:

  • beberapa contoh skrip dapat digunakan untuk mengelompokkan pasangan dua jendela. Misalnya, jika kita memiliki windows A, B, C, dan D kita dapat menghubungkan A dan B bersama-sama, dan menghubungkan C dan D bersama-sama.
  • beberapa jendela dapat dikelompokkan dalam satu jendela tunggal. Misalnya, jika saya menautkan jendela B ke A, C ke A, dan D ke A, itu berarti jika saya selalu beralih ke A, saya dapat menaikkan semua 4 jendela secara bersamaan.

Pemakaian

Jalankan skrip sebagai:

python link_windows.py

Script ini kompatibel dengan Python 3, sehingga dapat juga dijalankan sebagai

python3 link_windows.py

Ada dua opsi baris perintah:

  • --quietatau -q, memungkinkan membungkam jendela GUI. Dengan opsi ini Anda cukup mengklik dengan mouse di dua jendela apa saja, dan skrip akan mulai menghubungkannya.
  • --helpatau -h, mencetak informasi penggunaan dan deskripsi.

The -hpilihan menghasilkan informasi berikut:

$ 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.

Informasi teknis tambahan dapat dilihat melalui pydoc ./link_windows.py, di mana ./menandakan bahwa Anda harus berada di direktori yang sama dengan skrip.

Proses penggunaan sederhana untuk dua jendela:

  1. Munculan akan muncul meminta Anda untuk memilih jendela # 1, tekan OKatau tekan Enter. Pointer mouse akan berubah menjadi tanda silang. Klik salah satu jendela yang ingin Anda tautkan.

  2. Munculan kedua akan muncul meminta Anda untuk memilih jendela # 2, tekan OKatau tekan Enter. Sekali lagi, penunjuk tetikus akan berubah menjadi tanda silang. Klik pada jendela lain yang ingin Anda tautkan. Setelah itu eksekusi akan dimulai.

  3. Setiap kali Anda memfokuskan kedua jendela, skrip akan menaikkan jendela lainnya, tetapi mengembalikan fokus ke jendela yang sebelumnya dipilih (perhatikan - dengan seperempat penundaan kedua untuk kinerja terbaik), sehingga menciptakan kesan bahwa jendela dihubungkan bersama.

Jika Anda memilih jendela yang sama dua kali, skrip akan berhenti. Jika suatu saat Anda mengklik tombol tutup dialog sembulan, skrip akan berhenti.

Sumber skrip

Juga tersedia sebagai GitHub Gist

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Author: Sergiy Kolodyazhnyy
Date:  August 2nd, 2016
Written for: /ubuntu//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()

Catatan:

Sergiy Kolodyazhnyy
sumber
Ceria aku benar-benar terkesan. The time.sleepbit antara switching, aku dapat menempatkan bahwa ke nol? apakah ada alasan penundaan?
Simon Tong
1
@simontong Anda dapat mencoba berkomentar seperti # time.sleep(0.25)itu dan tidak akan dijalankan. Alasannya adalah untuk memastikan bahwa setiap jendela dinaikkan dengan benar. Dalam pengalaman saya di masa lalu, saya perlu memiliki penundaan untuk beroperasi di windows. Saya akan berpikir penundaan seperempat detik tidak banyak. Sebenarnya, izinkan saya menambahkan satu baris lagi ke skrip, yang dapat mempercepatnya. BAIK ?
Sergiy Kolodyazhnyy
@simontong OK, saya sudah memperbarui skrip. Coba sekarang. Seharusnya beralih lebih cepat
Sergiy Kolodyazhnyy
@simontong Saya akan memperbarui skrip dengan beberapa tambahan kecil untuk menambahkan beberapa fitur tambahan. Saya akan memberi tahu Anda setelah siap, tolong beri tahu saya apa yang Anda pikirkan
Sergiy Kolodyazhnyy
@simontong menambahkan opsi tambahan ke skrip, harap tinjau
Sergiy Kolodyazhnyy
6

Naikkan jumlah jendela sembarang sebagai satu

Solusi di bawah ini akan membiarkan Anda memilih salah kombinasi dari dua, tiga atau lebih jendela untuk digabungkan dan dibesarkan sebagai satu dengan shortcut keyboard.

Script bekerja dengan tiga argumen:

add

untuk menambahkan jendela aktif ke grup

raise

untuk meningkatkan grup yang ditetapkan

clear

untuk menghapus grup, siap menentukan grup baru

Naskah

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

Cara Penggunaan

  1. Script membutuhkan wmctrldan xdotool:

    sudo apt-get install wmctrl xdotool
  2. Salin skrip di atas ke dalam file kosong, simpan sebagai groupwindows.py
  3. Tes-jalankan skrip: buka dua terminal windows, jalankan perintah:

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

    di keduanya. Tutupi dengan jendela lain (atau perkecil). Buka jendela terminal ketiga, jalankan perintah:

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

    Dua jendela pertama akan dinaikkan menjadi satu.

  4. Jika semuanya berfungsi dengan baik, buat tiga tombol pintasan khusus: Pilih: Pengaturan Sistem> "Keyboard"> "Pintasan"> "Pintasan Khusus". Klik "+" dan tambahkan perintah di bawah ini ke tiga pintasan terpisah:

    pada sistem saya, saya menggunakan:

    Alt+ A, menjalankan perintah:

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

    ... untuk menambahkan jendela ke grup.

    Alt+ R, menjalankan perintah:

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

    ... untuk membesarkan grup.

    Alt+ C, menjalankan perintah:

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

    ... untuk menghapus grup

Penjelasan

Scriptnya bekerja cukup sederhana:

  • Ketika dijalankan dengan argumen add, skrip menyimpan / menambahkan window-id jendela yang aktif ke dalam file tersembunyi~/.windowlist
  • Ketika dijalankan dengan argumen raise, skrip membaca file, memunculkan jendela dalam daftar dengan perintah:

    wmctrl -ia <window_id>
  • Saat dijalankan dengan argumen clear, skrip menghapus file yang tersembunyi ~/.windowlist.

Catatan

  • Skrip juga akan bekerja pada jendela yang diperkecil, ia akan menghapus kemungkinan jendela yang diperkecil
  • Jika set windows berada di viewport lain, skrip akan beralih ke viewport yang sesuai
  • Set ini fleksibel, Anda selalu dapat menambahkan jendela lain ke set saat ini.

Lebih fleksibel?

Seperti disebutkan, skrip di atas memungkinkan penambahan jendela kapan saja ke jendela yang dikelompokkan. Versi di bawah ini juga memungkinkan menghapus salah satu jendela (kapan saja) dari daftar yang dikelompokkan:

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

Argumen tambahan untuk menjalankan skrip adalah delete, jadi:

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

menghapus jendela aktif dari jendela yang dikelompokkan. Untuk menjalankan perintah ini, di sistem saya, saya menetapkan Alt+ Dsebagai pintasan.

Yakub Vlijm
sumber