मैं एक अदृश्य व्यूपोर्ट से विंडो को चालू कैसे कर सकता हूं, बिना व्यूपोर्ट को स्विच किए


3

मैं 15.04 यूनिटी और 4 वर्चुअल डेस्कटॉप के साथ उपयोग करता हूं।

जब मैंने डेस्कटॉप 1 पर एक विंडो खोली है और डेस्कटॉप 2 (उदाहरण के लिए) देख रहा हूं, क्या डेस्कटॉप 1 से दृश्य को स्विच किए बिना डेस्कटॉप 2 पर दिखाने के लिए आसानी से डेस्कटॉप 1 से विंडो प्राप्त करने का एक तरीका है?

इसलिए मैं अदृश्य डेस्कटॉप को देखे बिना अपने सक्रिय डेस्कटॉप के लिए वर्तमान में अदृश्य डेस्कटॉप से ​​एक खिड़की प्राप्त करना चाहता हूं (और अंततः एक पर अन्य खुली हुई खिड़कियां)।

क्या इसे प्राप्त करने का एक आसान तरीका है?


बहुत स्वागत किया जा सकता है। अगर किसी ने पहले जवाब नहीं दिया, तो मैं घर
पहुंचूंगा

हाय बाइट कमांडर, मेरा जवाब पोस्ट किया। कृपया मुझे बताएं कि क्या कुछ स्पष्ट नहीं है।
जैकब व्लिजम

जवाबों:


4

खिड़कियों को सूचीबद्ध करें, वर्तमान कार्यक्षेत्र में जाने के लिए एक चुनें

जब नीचे दी गई स्क्रिप्ट को कहा जाता है, तो यह सभी कार्यस्थानों पर सभी खिड़कियों को सूचीबद्ध करेगी। एक को चुनें और OKविंडो को वर्तमान कार्यक्षेत्र में स्थानांतरित करने के लिए दबाएं और इसे बढ़ाएं। डिफ़ॉल्ट रूप से, यह विंडो को स्थिति 100(x), 100(y) में ले जाता है

दोनों के उपयोग के परिणामस्वरूप स्क्रिप्ट अपेक्षाकृत सरल है wmctrlऔर xdotool। जबकि wmctrlसभी विंडो को सूचीबद्ध करने के लिए उपयोग किया जाता है, xdotoolबस उन्हें विंडो के आकार (विपरीत wmctrl) और एक दूसरे के दोनों कार्यक्षेत्रों के सापेक्ष पदों पर "बिना सवाल पूछे" वर्तमान कार्यक्षेत्र पर पूर्वनिर्धारित स्थिति में ले जाता है ।
अपने मूल कार्यक्षेत्र पर स्थिति के अनुसार, खिड़की की एक अधिक सटीक स्थिति बहुत अच्छी तरह से संभव होगी, लेकिन आवश्यक कोड को भी गुणा करेगी (जैसे कि यहां )। मैं ज्यादातर स्थितियों में मानता हूं, यह होगा।

एक उदाहरण :

मैं कार्यक्षेत्र 8 पर हूं, जबकि मेरे पास geditकार्यक्षेत्र पर एक खिड़की है। स्क्रिप्ट को कॉल करने से विंडोज़ सूचीबद्ध होती है:

यहाँ छवि विवरण दर्ज करें

गेडिट विंडो चुनने से यह वर्तमान कार्यक्षेत्र में चला जाएगा:

यहाँ छवि विवरण दर्ज करें

लिपी

#!/usr/bin/env python3
import subprocess
import socket
import time

def get(command):
    return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")

def check_window(w_id):
    w_type = get("xprop -id "+w_id)
    if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
        return True
    else:
        return False

# split wmctrl output by machine name
wlist = [l.split(socket.gethostname()) for l in get("wmctrl -l").splitlines()]
# extract window -id from first section
wlist = [[wlist[i][0].split()[0], wlist[i][-1].strip()] for i, l in enumerate(wlist)]
# filter only "real, normal" windows
wlist = [w for w in wlist if check_window(w[0]) == True]
# create columns for zenity list
cols = (" ").join(['"'+w[1]+'" '+'"'+w[0]+'"' for w in wlist])
# calculate height and width for the zenity window, according to window names and list length
h = str(140+(len(wlist)*23))
w = str((max([len(w[-1]) for w in wlist])*8))
# define the zenity window
cmd = "zenity --list --hide-column=2 --print-column=2 "+\
      "--title='Window list' --column='Current windowlist' "+\
      "--column='wid' --height="+h+" --width="+w+" "+cols

try:
    # call the window
    w_id = get(cmd).split("|")[-1].strip()
    # move the selected window to the current workspace
    subprocess.Popen(["xdotool", "windowmove", "--sync", w_id, "100", "100"])
    # raise it (the command below alone should do the job, but sometimes fails
    # on firefox windows without first moving the window).
    subprocess.Popen(["wmctrl", "-iR", w_id])
except subprocess.CalledProcessError:
    pass

कैसे इस्तेमाल करे

  1. स्क्रिप्ट को दोनों की जरूरत है wmctrlऔरxdotool

    sudo apt-get install wmctrl xdotool
    
  2. एक खाली फ़ाइल में स्क्रिप्ट की प्रतिलिपि बनाएं, इसे इस रूप में देखें move_windows.py

  3. कमांड द्वारा इसे टेस्ट करें:

    python3 /path/to/move_windows.py
    
  4. एक खिड़की दिखाई देनी चाहिए, वर्तमान में खोली गई खिड़कियां सूचीबद्ध हैं:

    यहाँ छवि विवरण दर्ज करें

    यह देखने के लिए कि क्या इसे वर्तमान कार्यक्षेत्र में ले जाया गया है और सही तरीके से उठाया गया है, एक को चुनें।

  5. यदि सभी ठीक काम करते हैं, तो इसे एक शॉर्टकट कुंजी में एड करें: चुनें: सिस्टम सेटिंग्स> "कीबोर्ड"> "शॉर्टकट"> "कस्टम शॉर्टकट"। "+" पर क्लिक करें और कमांड जोड़ें:

    python3 /path/to/move_windows.py
    

ध्यान दें

zenityविंडो का आकार , वर्तमान विंडो को सूचीबद्ध करना, स्वचालित रूप से सेट किया गया है। स्क्रिप्ट सबसे लंबी विंडो नाम और पंक्तियों की संख्या (विंडोज़) की तलाश करती है और तदनुसार आकार निर्धारित करती है।


संपादित करें

जैसा कि एक टिप्पणी में अनुरोध किया गया है, एक संस्करण के नीचे, जिसमें zenityसूची- विंडो में अधिक जानकारी शामिल है: लक्षित विंडो (एस) का डे वर्तमान कार्यक्षेत्र और यह जिस एप्लिकेशन से संबंधित है।

यहाँ छवि विवरण दर्ज करें

जैसा कि ऊपर उल्लेख किया गया है, रिश्तेदार / पूर्ण कार्यक्षेत्र पदों की जानकारी कोड की अधिक "पर्याप्त" मात्रा की ओर ले जाती है, लेकिन सौभाग्य से मैं इस पहले के जवाब को आधार के रूप में उपयोग कर सकता था।

कैसे इस्तेमाल करे

उपयोग स्क्रिप्ट के पहले संस्करण (ऊपर) के रूप में बहुत अधिक है, लेकिन कमांड को पसंदीदा सॉर्टिंग विकल्प शामिल करना होगा। इसे किसी एक कमांड से चलाएं:

python3 /path/to/move_windows.py -app

आवेदन द्वारा सूची को क्रमबद्ध करने के लिए,

python3 /path/to/move_windows.py -ws

कार्यक्षेत्र द्वारा सूची को सॉर्ट करने के लिए, और

python3 /path/to/move_windows.py -win

विंडो नाम से सूची को सॉर्ट करने के लिए।

लिपी:

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

arg = sys.argv[1]
# list (column) header titles and their (data) position in the produced window data list
cols = [["Workspace", -1], ["Application name", -2] , ["Window name", -3]]
# rearrange columns, depending on the chosen option
if arg == "-app":
    cols = [cols[1], cols[2], cols[0]]
elif arg == "-ws":
    cols = [cols[0], cols[2], cols[1]]
elif arg == "-win":
    cols = [cols[2], cols[1], cols[0]]
# extract headers, list positions, to be used in the zenity list
col1 = cols[0][0]; i1 = cols[0][1]
col2 = cols[1][0]; i2 = cols[1][1]
col3 = cols[2][0]; i3 = cols[2][1]
# just a helper function
get = lambda cmd: subprocess.check_output([
    "/bin/bash", "-c", cmd
    ]).decode("utf-8")
# analyse viewport data, to be able to calculate relative/absolute position of windows
# and current viewport
def get_spandata():
    xr = get("xrandr").split(); pos = xr.index("current")
    res = [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
    spandata = get("wmctrl -d").split()
    span = [int(n) for n in spandata[3].split("x")]
    cols = int(span[0]/res[0]); rows = int(span[1]/res[1])
    curr_vector = [int(n) for n in spandata[5].split(",")]
    curr_viewport = int((curr_vector[1]/res[1])*cols + (curr_vector[0]/res[0])+1)
    return {"resolution": res, "n_columns": cols, "vector": curr_vector, "current_viewport": curr_viewport}

posdata = get_spandata()
vector = posdata["vector"]; cols = posdata["n_columns"]
res = posdata["resolution"]; currvp = posdata["current_viewport"]
# function to distinguish "normal" windows from other types (like the desktop etc)
def check_window(w_id):
    w_type = get("xprop -id "+w_id)
    if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
        return True
    else:
        return False
# split windowdata by machine name
mach_name = socket.gethostname()
wlist = [[l.strip() for l in w.split(mach_name)] for w in get("wmctrl -lpG").splitlines()]
# split first section of window data
for i, w in enumerate(wlist):
    wlist[i][0] = wlist[i][0].split()
# filter only "real" windows
real_wlist = [w for w in wlist if check_window(w[0][0]) == True]
# adding the viewport to the window's data
for w in real_wlist:
    w.append(get("ps -p "+w[0][2]+" -o comm=").strip())
    loc_rel = [int(n) for n in w[0][3:5]]
    loc_abs = [loc_rel[0]+vector[0], loc_rel[1]+vector[1]]
    abs_viewport = int((loc_abs[1]/res[1])*cols + (loc_abs[0]/res[0])+1)
    abs_viewport = str(abs_viewport)+"*" if abs_viewport == currvp else str(abs_viewport)
    w.append(abs_viewport)
# set sorting rules
if arg == "-app":
    real_wlist.sort(key=lambda x: x[-2])
elif arg == "-ws":
    real_wlist.sort(key=lambda x: x[-1])
elif arg == "-win":
    real_wlist.sort(key=lambda x: x[-3])
# calculate width and height of the zenity window:
# height = 140px + 23px per line
h = str(140+(len(real_wlist)*23))
# width = 250px + 8px per character (of the longest window title)
w = str(250+(max([len(w[-3]) for w in real_wlist])*8))
# define the zenity window's content
cmd = "zenity --list --hide-column=4 --print-column=4 --title='Window list' "\
      "--width="+w+" --height="+h+" --column='"+col1+"' --column='"+col2+"' --column='"+col3+\
      "' --column='w_id' "+(" ").join([(" ").join([
          '"'+w[i1]+'"','"'+w[i2]+'"','"'+w[i3]+'"','"'+w[0][0]+'"'
          ]) for w in real_wlist])
# finally, call the window list
try:
    w_id = subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").split("|")[0]
    subprocess.Popen(["xdotool", "windowmove", "--sync", w_id, "100", "100"])
    subprocess.Popen(["wmctrl", "-iR", w_id])
except subprocess.CalledProcessError:
    pass

EDIT 2: 15.04 विशिष्ट

प्रयुक्त psकमांड का आउटपुट gnome-terminal15.04 में बदल गया है । इसलिए, 15.04 में, gnome-terminalउपरोक्त स्क्रिप्ट में एप्लिकेशन का नाम सही ढंग से प्रदर्शित नहीं किया गया था। नीचे दिया गया संस्करण कमांड WM_CLASSके आउटपुट के अनुसार, एप्लिकेशन नाम को व्युत्पन्न करता है xprop:

यहाँ छवि विवरण दर्ज करें

उपयोग ठीक उसी तरह है जैसे ऊपर (दूसरी) लिपि में है:

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

arg = sys.argv[1]
# list (column) header titles and their (data) position in the produced window data list
cols = [["Workspace", -1], ["Application name", -2] , ["Window name", -3]]
# rearrange columns, depending on the chosen option
if arg == "-app":
    cols = [cols[1], cols[2], cols[0]]
elif arg == "-ws":
    cols = [cols[0], cols[2], cols[1]]
elif arg == "-win":
    cols = [cols[2], cols[1], cols[0]]
# extract headers, list positions, to be used in the zenity list
col1 = cols[0][0]; i1 = cols[0][1]
col2 = cols[1][0]; i2 = cols[1][1]
col3 = cols[2][0]; i3 = cols[2][1]
# just a helper function
get = lambda cmd: subprocess.check_output([
    "/bin/bash", "-c", cmd
    ]).decode("utf-8")
# analyse viewport data, to be able to calculate relative/absolute position of windows
# and current viewport
def get_spandata():
    xr = get("xrandr").split(); pos = xr.index("current")
    res = [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
    spandata = get("wmctrl -d").split()
    span = [int(n) for n in spandata[3].split("x")]
    cols = int(span[0]/res[0]); rows = int(span[1]/res[1])
    curr_vector = [int(n) for n in spandata[5].split(",")]
    curr_viewport = int((curr_vector[1]/res[1])*cols + (curr_vector[0]/res[0])+1)
    return {"resolution": res, "n_columns": cols, "vector": curr_vector, "current_viewport": curr_viewport}

posdata = get_spandata()
vector = posdata["vector"]; cols = posdata["n_columns"]
res = posdata["resolution"]; currvp = posdata["current_viewport"]
# function to distinguish "normal" windows from other types (like the desktop etc)
def check_window(w_id):
    w_type = get("xprop -id "+w_id)
    if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
        cl = [l.replace('"', '').split(",")[-1].strip()\
              for l in w_type.splitlines() if "WM_CLASS(STRING)" in l][0]
        return (True, cl)
    else:
        return (False, "")
# split windowdata by machine name
mach_name = socket.gethostname()
wlist = [[l.strip() for l in w.split(mach_name)] for w in get("wmctrl -lpG").splitlines()]
# split first section of window data
for i, w in enumerate(wlist):
    wlist[i][0] = wlist[i][0].split()
# filter only "real" windows   
real_wlist = [w+[check_window(w[0][0])[1]] for w in wlist if check_window(w[0][0])[0] == True]
# adding the viewport to the window's data
for w in real_wlist:
    loc_rel = [int(n) for n in w[0][3:5]]
    loc_abs = [loc_rel[0]+vector[0], loc_rel[1]+vector[1]]
    abs_viewport = int((loc_abs[1]/res[1])*cols + (loc_abs[0]/res[0])+1)
    abs_viewport = str(abs_viewport)+"*" if abs_viewport == currvp else str(abs_viewport)
    w.append(abs_viewport)
# set sorting rules
if arg == "-app":
    real_wlist.sort(key=lambda x: x[-2])
elif arg == "-ws":
    real_wlist.sort(key=lambda x: x[-1])
elif arg == "-win":
    real_wlist.sort(key=lambda x: x[-3])
# calculate width and height of the zenity window:
# height = 140px + 23px per line
h = str(140+(len(real_wlist)*23))
# width = 250px + 8px per character (of the longest window title)
w = str(250+(max([len(w[-3]) for w in real_wlist])*8))
# define the zenity window's content
cmd = "zenity --list --hide-column=4 --print-column=4 --title='Window list' "\
      "--width="+w+" --height="+h+" --column='"+col1+"' --column='"+col2+"' --column='"+col3+\
      "' --column='w_id' "+(" ").join([(" ").join([
          '"'+w[i1]+'"','"'+w[i2]+'"','"'+w[i3]+'"','"'+w[0][0]+'"'
          ]) for w in real_wlist])
# finally, call the window list
try:
    w_id = subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8").split("|")[0]
    subprocess.Popen(["xdotool", "windowmove", "--sync", w_id, "100", "100"])
    subprocess.Popen(["wmctrl", "-iR", w_id])
except subprocess.CalledProcessError:
    pass

क्या आप हमेशा एक साथ हैक अद्भुत! : मैं प्रभावित हूँ। एक सवाल: आउटपुट विंडो के शीर्षक - क्या उन्हें उदाहरण के लिए डेस्कटॉप नंबर पर दिखाने के लिए और अनुप्रयोग नाम (जैसे टर्मिनल के लिए) में सुधार किया जा सकता है?
बाइट कमांडर

@ByteCommander मुझे लगता था कि तुम पूछोगे :)। सौभाग्य से, मैं आधार के रूप में लिंक किए गए उत्तर (स्क्रिप्ट) का उपयोग कर सकता हूं, लेकिन इसकी कार्यक्षमता को बदल सकता हूं।
जैकब वलीजम

मैं संशोधित elif arg == "-ws": cols = [cols[0], cols[2], cols[1]]करने के लिए elif arg == "-ws": cols = [cols[0], cols[1], cols[2]]स्तंभ क्रम बदलने के लिए। एक बात जो मैंने देखी, हालांकि: i.imgur.com/wBSTi8f.png से पता चलता है कि यह किसी भी तरह लंबे एप्लिकेशन नामों को काट देता है। ऐसा लगता है कि आपके स्क्रीन शॉट पर ऐसा नहीं है। किसी भी विचार क्या वहाँ अलग हो सकता है? कॉलम ऑर्डर को संशोधित करने से पहले ही यह एक समस्या थी।
बाइट कमांडर

मुझे लाइन बदलने के बाद कोई बदलाव नहीं दिखाई दे रहा है। और दूसरी बात: मेरा मॉनिटर हर बार आपके स्क्रिप्ट के उस दूसरे संस्करण को लॉन्च करता है, लेकिन यह कई अनुप्रयोगों के साथ होता है, जैसे कि एकता-नियंत्रण-केंद्र, क्यूटॉक्स या inxi भी। मैं तुम्हें ठीक नहीं कर सकते लगता है सिवाय इसके कि पहले स्क्रिप्ट संस्करण में वापस जाकर ...
बाइट कमांडर

@ByteCommander मेरे पास इसके लिए कोई स्पष्टीकरण नहीं है, केवल यह कि यह मेरे सिस्टम पर नहीं है। ग्राफिक्स ड्राइवर की संभवतः कुछ प्रकार की छोटी असंगतता।
जैकब वलिज्म
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.