두 개의 창 A와 B가 있습니다. 어떻게 든 두 개의 창을 연결하여 A로 전환하면 B가 증가하거나 B로 전환하면 A가 증가합니까?
여러 작업 공간을 사용하는 것이 대체 옵션이라는 것을 알고 있지만 이것이 가능한지 궁금합니다.
두 개의 창 A와 B가 있습니다. 어떻게 든 두 개의 창을 연결하여 A로 전환하면 B가 증가하거나 B로 전환하면 A가 증가합니까?
여러 작업 공간을 사용하는 것이 대체 옵션이라는 것을 알고 있지만 이것이 가능한지 궁금합니다.
답변:
다음 스크립트에서는 두 개의 창을 선택할 수 있으며 두 창이 열려있는 동안 사용자가 둘 중 하나에 초점을 맞출 때 두 창을 모두 띄웁니다. 예를 들어, 하나가 미망인 A와 B를 연결하면 A 나 B로 전환하면 둘 다 다른 미망인보다 높아집니다.
스크립트를 중지하려면 killall link_windows.py
터미널에서 사용하거나 창 중 하나를 닫았다가 다시 열 수 있습니다. X창 선택 팝업 대화 상자에서 닫기 단추 를 눌러 실행을 취소 할 수도 있습니다 .
잠재적 인 조정 :
다음과 같이 스크립트를 실행하십시오.
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를 눌러 지정을 요구 나타납니다 OK또는 히트를 Enter. 마우스 포인터가 십자로 변합니다. 연결하려는 창 중 하나를 클릭하십시오.
창 2를 선택하거나을 누르 OK거나 누르라는 두 번째 팝업이 나타납니다 Enter. 다시 마우스 포인터가 십자로 변합니다. 연결하려는 다른 창을 클릭하십시오. 그 후 실행이 시작됩니다.
두 창 중 하나에 초점을 맞출 때마다 스크립트는 다른 창을 위로 올리지 만 원래 선택한 창으로 초점을 되돌립니다 (최고의 성능을 위해 2 분의 1의 지연으로 노트).
동일한 창을 두 번 선택하면 스크립트가 종료됩니다. 팝업 대화 상자의 닫기 버튼을 클릭하면 스크립트가 종료됩니다.
GitHub Gist로도 사용 가능
#!/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()
Gtk-Message: GtkDialog mapped without a transient parent. This is discouraged.
. 무시할 수 있습니다.time.sleep
전환 사이 의 비트는 0으로 설정할 수 있습니까? 지연 이유가 있습니까?
# time.sleep(0.25)
하고 실행되지 않습니다. 그 이유는 각 창을 올바르게 올리는 것입니다. 과거의 경험에서, 나는 창문에서 작동하기 위해 지연이 필요했습니다. 1/4 초 지연은 그렇게 많지 않다고 생각합니다. 실제로 스크립트에 한 줄만 추가하면 속도가 빨라질 수 있습니다. 확인 ?
이 솔루션은 아래 당신이 선택하게됩니다 어떤 결합과 키보드 단축키 하나로서 제기되는 두 개, 세 개 이상의 창 조합.
이 스크립트는 세 가지 인수로 작동합니다.
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)
스크립트가 필요 wmctrl
하고 xdotool
:
sudo apt-get install wmctrl xdotool
groupwindows.py
스크립트를 테스트 실행하십시오. 두 개의 터미널 창을 열고 다음 명령을 실행하십시오.
python3 /absolute/path/to/groupwindows.py add
둘 다. 다른 창으로 덮거나 최소화하십시오. 세 번째 터미널 창을 열고 다음 명령을 실행하십시오.
python3 /absolute/path/to/groupwindows.py raise
처음 두 개의 창이 하나로 나타납니다.
모두 제대로 작동하면 시스템 설정> "키보드"> "바로 가기"> "사용자 정의 바로 가기"를 선택하십시오. "+"를 클릭하고 아래의 명령을 세 개의 바로 가기에 추가하십시오.
내 시스템에서 다음을 사용했습니다.
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
하면 스크립트는 활성 창의 window-id를 숨겨진 파일에 저장 / 추가합니다.~/.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를 바로 가기로 설정 했습니다.