Как может я окна группы, которые будут повышены как один?

У меня есть два окна, A и B. Действительно ли возможно так или иначе соединить два окна, такие, что переключение на также повышения B или переключение на B также повышают A?

Я понимаю, что использование нескольких рабочих областей является альтернативной опцией, но задавалось вопросом, возможно ли это также?

10
задан 2 August 2016 в 06:37

2 ответа

Введение

Следующий сценарий позволяет выбирать два окна, и в то время как оба окна открыты, он повысит оба окна, когда пользователь сфокусирует любой. Например, если Вы связываете висячие строки A, и B, околдовывая или к A или к B сделает оба повышения выше других висячих строк.

Для остановки сценария, можно использовать killall link_windows.py в терминале, или близко и вновь открыли одно из окон. Можно также отменить выполнение путем сурово обращения с кнопкой X на любом из всплывающих диалоговых окон выбора окна.

Потенциальные тонкие настройки:

  • несколько экземпляров сценария могут привыкнуть к парам группы двух окон. Например, если у нас есть окна A, B, C, и D, мы можем связать A и B вместе, и связать C и D вместе.
  • несколько окон могут быть сгруппированы под одним единственным окном. Например, если я связываю окно B to A, C к A и D к A, который означает, переключаюсь ли я всегда на A, я могу повысить все 4 окна одновременно.

Использование

Запустите скрипт как:

python link_windows.py

Сценарий совместим с Python 3, таким образом, он может также работать как

python3 link_windows.py

Существует два параметра командной строки:

  • --quiet или -q , позволяет заставлять замолчать вниз окна GUI. При использовании этой опции можно просто нажать мышью на любых двух окнах, и сценарий начнет связывать их.
  • --help или -h, печатает информация об описании и использование.

-h опция производит следующую информацию:

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

Дополнительная техническая информация может быть просмотрена через pydoc ./link_windows.py , где ./ показывает, что необходимо быть в том же каталоге как сценарий.

Простой процесс использования для двух окон:

  1. Всплывающее окно будет казаться спрашивающим Вас, чтобы выбрать окно № 1, нажать OK или совершить нападки, Входят. Указатель мыши зайдет к кресту. Нажмите на одно из окон, которые Вы хотите связать.

  2. Второе всплывающее окно будет казаться спрашивающим Вас, чтобы выбрать окно № 2, нажать OK или совершить нападки, Входят. Снова, указатель мыши превратится в крест. Нажмите на другое окно, которое Вы хотите связать. После того, как то выполнение начнется.

  3. Каждый раз, когда Вы фокусируете любое окно, сценарий поднимет другое окно, но возвратит фокус тому, первоначально выбранному (примечание - с четвертью второй задержки лучшей производительности), таким образом создавая чувство, что окна соединены.

При выборе того же окна оба раза сценарий выйдет. В любой момент при нажатии близкой кнопки всплывающего диалогового окна сценарий выйдет.

Источник сценария

Также доступный как Суть GitHub

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

Notes:

9
ответ дан 23 November 2019 в 04:27

Увеличьте произвольное число окон как один

Решение ниже позволит Вам выбрать любую комбинацию два, три или больше окна, которые будут объединены и повышены как один с сочетанием клавиш.

Сценарий делает свою работу с тремя аргументами:

add

добавить активное окно к группе

raise

повысить группу набора

clear

очистить группу, готовую определить новую группу

Сценарий

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

Как использовать

  1. Потребности сценария wmctrl и xdotool:

    sudo apt-get install wmctrl xdotool
    
  2. Скопируйте сценарий выше в пустой файл, сохраните его как groupwindows.py
  3. Тестовый прогон сценарий: откройте два окна терминала, выполните команду:

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

    в них обоих. Покройте их другими окнами (или минимизируйте их). Откройте третье окно терминала, выполните команду:

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

    Первые два окна будут повышены как один.

  4. Если все хорошо работает, создайте три пользовательских сочетания клавиш: Выберите: Параметры настройки системы> "Клавиатура"> "Ярлыки"> "Пользовательские Ярлыки". Нажмите "+" и добавьте команды ниже к трем отдельным ярлыкам:

    в моей системе я использовал:

    Alt+A, выполняя команду:

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

    ... добавить окно к группе.

    Alt+R, выполняя команду:

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

    ... повысить группу.

    Alt+C, выполняя команду:

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

    ... очистить группу

Объяснение

Сценарий работает вполне просто:

  • Когда выполнено с аргументом add, сценарий хранит/добавляет окно активного окна - идентификатор в скрытый файл ~/.windowlist
  • Когда выполнено с аргументом raise, сценарий читает файл, повышает окна в списке с командой:

    wmctrl -ia <window_id>
    
  • Когда выполнено с аргументом clear, сценарий удаляет скрытый файл ~/.windowlist.

Примечания

  • Сценарий будет также работать над минимизированными окнами, он будет не-минимизировать возможно минимизированные окна
  • Если набор окон будет на другой области просмотра, то сценарий переключится на соответствующую область просмотра
  • Набор гибок, можно всегда добавлять другие окна к текущему набору.

Больше гибкости?

Как упомянуто, сценарий выше позволяет добавлять окна в любое время к сгруппированным окнам. Версия ниже также позволяет удалять любое из окон (в любое время) из сгруппированного списка:

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

Дополнительный аргумент для запущения скрипта delete, так:

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

удаляет активное окно из сгруппированных окон. Для выполнения этой команды, в моей системе, я установил Alt+D как ярлык.

6
ответ дан 23 November 2019 в 04:27

Другие вопросы по тегам:

Похожие вопросы: