EDIT - yeni cevap -
Aşağıdaki cevaplar hala tamamen geçerli ve önerilen seçenekler. Bununla birlikte, devam eden içgörü, bu seçimi muhtemelen en şık çözüm olan aşağıdaki göstergeyi kullanmamı sağladı.
Bu nedenle, muhtemelen seçenek 5'i (.desktop dosyası kullanarak) değiştirmeniz gerekir.
Uygulamayı listeden seçmeniz yeterlidir ve ilgili uygulamanın tüm pencereleri (geçerli görünümde bulunur):
Nasıl kullanılır?
ppa'dan:
sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront
... veya el ile:
#!/usr/bin/env python3
import signal
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject
import time
from threading import Thread
import os
import subprocess
import getpass
currpath = os.path.dirname(os.path.realpath(__file__))
class Indicator():
def __init__(self):
self.app = 'raise_apps'
iconpath = os.path.join(currpath, "raise.png")
self.indicator = AppIndicator3.Indicator.new(
self.app, iconpath,
AppIndicator3.IndicatorCategory.OTHER)
self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
self.indicator.set_menu(self.create_menu())
# the thread:
self.update = Thread(target=self.check_recent)
# daemonize the thread to make the indicator stopable
self.update.setDaemon(True)
self.update.start()
def create_menu(self):
# creates the (initial) menu
self.menu = Gtk.Menu()
# separator
initial = Gtk.MenuItem("Fetching list...")
menu_sep = Gtk.SeparatorMenuItem()
self.menu.append(initial)
self.menu.append(menu_sep)
# item_quit.show()
self.menu.show_all()
return self.menu
def raise_wins(self, *args):
index = self.menu.get_children().index(self.menu.get_active())
selection = self.menu_items2[index][1]
for w in selection:
execute(["wmctrl", "-ia", w])
def set_new(self):
# update the list, appearing in the menu
for i in self.menu.get_children():
self.menu.remove(i)
for app in self.menu_items2:
sub = Gtk.MenuItem(app[0])
self.menu.append(sub)
sub.connect('activate', self.raise_wins)
# separator
menu_sep = Gtk.SeparatorMenuItem()
self.menu.append(menu_sep)
# quit
item_quit = Gtk.MenuItem('Quit')
item_quit.connect('activate', self.stop)
self.menu.append(item_quit)
self.menu.show_all()
def get_apps(self):
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split() for l in get(["wmctrl", "-lpG"]).splitlines()]
# windows on current viewport
relevant = [w for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# pids
pids = [l.split() for l in get(["ps", "-u", getpass.getuser()]).splitlines()]
matches = [[p[-1], [w[0] for w in relevant if w[2] == p[0]]] for p in pids]
return [m for m in matches if m[1]]
def check_recent(self):
self.menu_items1 = []
while True:
time.sleep(4)
self.menu_items2 = self.get_apps()
for app in self.menu_items2:
app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
if self.menu_items2 != self.menu_items1:
GObject.idle_add(
self.set_new,
priority=GObject.PRIORITY_DEFAULT
)
self.menu_items1 = self.menu_items2
def stop(self, source):
Gtk.main_quit()
def get(command):
return subprocess.check_output(command).decode("utf-8")
def execute(command):
subprocess.Popen(command)
Indicator()
GObject.threads_init()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
-
Gösterge wmctrl
gerektiriyor
sudo apt-get wmctrl
-
Göstergeyi boş bir dosyaya kopyalayın, raise_apps.py
olarak kaydedin
-
Aşağıdaki resmi kopyalayın, tam olarak adlandırılmış raise.png
değerini bir ve aynı dizinde olarak kaydedin gösterge.
-
Ardından, şu komutu kullanarak çalıştırın:
python3 /path/to/raise_apps.py
-
Başlangıç Uygulamaları İsterseniz Ekle:
/bin/bash -c "sleep 10 && python3 /path/to/raise_apps.py"
ESKİ CEVAP:
Soru hakkında
Doğru araçlarla, bir uygulamanın tüm pencerelerini "sadece" yükseltmek çok karmaşık değildir. Mevcut görünümün pencerelerinin olduğundan emin olmak biraz daha karmaşıktır. Ancak asıl zorluk, eylemi kullanıcıya sunmak için uygun bir yol bulmaktır.
Bunun için beş seçeneğin altında, nasıl yapılabileceğini göstermek için . Tüm seçenekler kullanıma hazırdır. Son seçenek, ancak deneysel bir çeşittir; iyi çalışıyor ama seçeneğin açıklamasında açıklandığı gibi birkaç küçük kozmetik downsides vardır. Yine de kavram olarak ekledim.
Bir yorumda önerildiği gibi, pencereleri otomatik olarak örtüşmeyen bir şekilde yaymak bana pratik bir fikir gibi gelmiyor; (uygulama-bilge) gruplandırılmış bir pencere kurulumunda çalışıyorsanız, betik muhtemelen pencereleri istenmeyen şekilde yeniden düzenleyecektir.
Nasıl kullanılır?
Yapmanız gereken tüm seçenekler için:
-
Henüz sisteminizde değilse wmctrl
yükleyin:
sudo apt-get install wmctrl
-
, henüz mevcut değilse, dizin oluşturun:
~/bin
(açıklama: dizin ~/bin
$ PATH, bu nedenle çalıştırılabilirleri adlarına göre çalıştırabilirsiniz)
-
Seçeneğe karşılık gelen komut dosyasını kopyalayın, boş bir dosyaya yapıştırın, raise_app
olarak (uzantı yok) ~/bin
olarak kaydedin ve yürütülebilir hale getirin
Ayrı seçeneklerde, olası ek adımlar açıklanacaktır.
Seçenek 1: bir veya daha fazla karakter girerek uygulamayı seçin
- Bir tuş kombinasyonuna basın,
zenity
pencere görünecektir
- Giriş adında uygulamanın adının bir veya daha fazla karakterini girin
- Girişe basın
Bu, eşleşen uygulamanın tüm pencerelerini ( geçerli görüntülemede) öne çıkaracaktır.
Mevcut% view_düz pencerelerinin% sini yükselt:
Nasıl kullanılır?
Komut dosyası:
#!/usr/bin/env python3
import subprocess
import getpass
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# ask user for first characters
try:
arg = get('zenity --entry --text "first characters" --title "application"').strip()
except subprocess.CalledProcessError:
pass
# raise matching windows
try:
[execute("wmctrl -ia "+item[1]) for item in windows if item[0].startswith(arg)]
except (subprocess.CalledProcessError, NameError):
pass
Seçenek 2: uygulamalar arasında geçiş yapın ve pencerelerini bir tuş kombinasyonu ile kaldırın:
Diyelim ki alt + 1 tuş bileşimi altında aşağıdaki betiğe sahibim. Açık birkaç pencerem var:
- firefox
- gnome-terminal
- Nautilus
Mevcut durum:
Bir kere Alt + 1 tuşlarına basıyorum, tüm gnome-terminal
pencereleri kaldırıldı:
Tekrar basıyorum Alt + 1 , tüm nautilus
pencereleri kaldırıldı:
Tekrar basıyorum Alt + 1 , firefox
penceresi tekrar yükseltilir, döngü başlar:
Nasıl kullanılır?
Ardından, anahtarlı kombinasyonunuzla gruplandırılmış uygulama pencereleriyle uygulamalarınız arasında geçiş yapın.
Komut dosyası:
#!/usr/bin/env python3
import subprocess
import getpass
include_single = True # set to False if you only want to cycle through apps with multiple windows
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
def get_frontmost():
cmd = "xprop -root"
frontmost = [l for l in get(cmd).splitlines() if\
"ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
return frontmost[:2]+"0"+frontmost[2:]
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# create application list to cycle through
if include_single == False:
pre = [it[0] for it in windows]
apps = sorted(list(set([it for it in pre if pre.count(it) > 1])))
else:
apps = sorted(list(set([it[0] for it in windows])))
if len(apps) == 0:
pass
else:
# get the frontmost window as a last itm in the cycle
front = get_frontmost()
front_pid = [l.split()[2] for l in get("wmctrl -lp").splitlines() if front in l][0]
last_infront = get("ps -u "+getpass.getuser()+" | grep "+front_pid).split()[-1]
# determine next apllication to raise
if not last_infront in apps or last_infront == apps[-1]:
arg = apps[0]
print(arg)
else:
arg = apps[apps.index(last_infront)+1]
# raise matching windows
try:
[execute("wmctrl -ia "+item[1]) for item in windows if item[0] == arg]
except (subprocess.CalledProcessError, NameError):
pass
Seçenek 3: tuş kombinasyonuna basın + geçerli görünümdeki tüm pencereleri yükseltmek için -or - uygulama penceresinin başlatıcısı
Bu, muhtemelen, soru / yorum bölümünde açıklananlara en yakın olan seçenektir.
Diğer pencerelerin altında gömülü% 3 co_de% pencereleri olan dağınık bir masaüstüm olduğunu varsayalım.
Tüm nautilus pencerelerini yükseltmek için (örnek kısayol: Alt + 1 ):
Nasıl kullanılır?
Ardından:
Komut dosyası
#!/usr/bin/env python3
import subprocess
import getpass
import time
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
def get_frontmost():
cmd = "xprop -root"
frontmost = [l for l in get(cmd).splitlines() if\
"ACTIVE_WINDOW(WINDOW)" in l][0].split()[-1]
return frontmost[:2]+"0"+frontmost[2:]
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# get window data for various purposes
w_data = get("wmctrl -lpG").splitlines()
non_windows = sum([[l.split()[0] for l in w_data if it in l]\
for it in ("unity-launcher", "unity-panel", "unity-dash", "Hud")], [])
# get id of current window
curr_window = get_frontmost()
# user gets 3 seconds to pick an application window (or launcher icon)
t = 0
while t < 4:
w_id1 = get_frontmost()
time.sleep(1)
w_id2 = get_frontmost()
if w_id1 == w_id2 or w_id2 in non_windows+[curr_window]:
t = t+1
else:
new_frontmost = w_id2
break
# raise
try:
pid = [l.split()[2] for l in w_data if new_frontmost in l]
wl_data = [l.split() for l in w_data]
raise_windows = [l[0] for l in wl_data if pid[0] == l[2] and\
0 < int(l[3]) < res[0] and 0 < int(l[4]) < res[1]]
[execute("wmctrl -ia "+item) for item in raise_windows]
except NameError:
pass
Seçenek 4: tuş kombinasyonu, geçerli görünümde uygulama başına pencere sayısını gösteren bir seçenek listesi çağırır
Bu daha uygun olduğu ortaya çıktı. Sonra düşündüm:
+ 1 tuş bileşimine basıldığında, tüm uygulamaların ve geçerli görünüm penceresindeki pencerelerinin sayısının listelenmesi için gnome-terminal
penceresi çağrılır:
▴ veya ▾ tuşlarına basmak, sizi doğru seçeneğe getirecektir. Enter tuşuna basın ve seçilen uygulamanın tüm pencereleri kaldırılır.
Nasıl kullanılır?
Komut dosyası
#!/usr/bin/env python3
import subprocess
import getpass
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
# preparing zenity optionlist
apps = [item[0] for item in windows]
# prevent multiple zenity windows
if apps.count("zenity") > 1:
pass
elif apps.count("zenity") > 0:
execute('zenity --info --text "Another Zenity window is open already"')
# preventing empty windowlist
elif len(apps) > 0:
applist = [[app, str(apps.count(app))] for app in set(apps)]
applist.sort(key=lambda x: x[1])
# calling zenity window
try:
arg = get('zenity --list --text "Choose an application" '+\
'--title "Current windows" '+\
'--column "application" '+\
'--column "windows" '+\
'--height 250 '+\
'--width 250 '+\
(" ").join(sum(applist, [])))
except subprocess.CalledProcessError:
pass
# raise matching windows
try:
[execute("wmctrl -ia "+item[1]) \
for item in windows if arg.startswith(item[0])]
except (subprocess.CalledProcessError, NameError):
pass
else:
execute('zenity --info --text "No windows to list"')
Seçenek 5: çalışan uygulamaların pencerelerini bir başlatıcı simgesinden kaldırın
Bu seçenek, şu anda çalışan uygulamaları bir hızlı listede bulunan bir başlatıcı simgesinden oluşur. Birini seçin ve uygulamaların tüm pencereleri yükseltilecektir.
Çalışan uygulamalar (geçerli görünümde) değiştiğinde başlatıcı otomatik olarak güncellenir. Hızlı liste, diğer uygulama pencerelerinin açıldığı diğer görünüm pencerelerinde farklı bir liste gösterir (uyarlamanın 1-2 saniye sürmesi gerekir.)
Belirtildiği gibi, tamamen işlevsel olmasına rağmen, bu seçenek bir kavram anlamına gelir. Olduğu gibi birkaç küçük kozmetik downsides vardır. En önemlisi:
- İmleç "tekerleği", bir eylemden sonra birkaç saniye dönmeye devam eder. İşlevselliği etkilemese de, kozmetik bir dezavantajdır.
- Çalışan uygulama değişiklikleri listesinden sonra, başlatıcı simgesindeki uygulama listesinin güncellenmesi 1-2 saniye sürer.
Ayrıca, kurulum biraz daha karmaşıktır (aşağıda ayrıntılı olarak açıklanmasına rağmen):
Nasıl kullanılır?
Aşağıda bulacaksınız:
iki komut dosyası / simge / nautilus
dosyası
- Kurulumu "Nasıl kullanılır?" bölümünde olduğu gibi hazırlayın, ilk (main-) komut dosyasını
zenity
olarak% co_de olarak kaydedin.
-
Aşağıdaki simgeyi (sağ tıklayın, farklı kaydet) .desktop
olarak kaydedin
-
raise_app
dosyasını boş bir dosyaya kopyalayın, satırı düzenleyin
Icon=/path/to/raise.png
simgenin gerçek yoluna (tırnak işaretleri arasındaki boşluklara sahip yollar)
% Co_de% olarak ~/bin
olarak kaydetme
-
Eklemek için raise.png
dosyasını başlatıcıya sürükleyin
- ikinci komut dosyasını kopyalayın, boş bir dosyaya yapıştırın,
.desktop
olarak raise.desktop
olarak kaydedin, yürütülebilir hale getirin.
-
Başlangıç uygulamalarınıza aşağıdaki komutu ekleyin (Dash & gt; Startup Applications & gt; Add):
update_apps
- Çalıştırmak için oturumu kapatıp tekrar açın.
İlk komut
#!/usr/bin/env python3
import subprocess
import getpass
import sys
arg = sys.argv[1]
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
try:
[execute("wmctrl -ia "+item[1]) for item in windows if item[0].startswith(arg)]
except (subprocess.CalledProcessError, NameError):
pass
İkinci komut dosyası
#!/usr/bin/env python3
import subprocess
import getpass
import time
import os
dtfile = os.environ["HOME"]+"/.local/share/applications/raise.desktop"
def get(command):
return subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
def execute(command):
subprocess.Popen(["/bin/bash", "-c", command])
# calculate screen resolution
res_output = get("xrandr").split(); idf = res_output.index("current")
res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
# creating window list on current viewport / id's / application names
def applist():
try:
w_data = [l.split()[0:7] for l in get("wmctrl -lpG").splitlines()]
windows = [[get("ps -u "+getpass.getuser()+" | grep "+w[2]).split()[-1], w[0]]
for w in w_data if 0 < int(w[3]) < res[0] and 0 < int(w[4]) < res[1]]
except subprocess.CalledProcessError:
return []
else:
return set([app[0] for app in windows])
def update_dtfile(applications, text):
actionline = "Actions="+(";").join(applications)+";\n"
with open(dtfile) as src:
lines = src.readlines()
lines = lines[:[i for i in range(len(lines)) \
if lines[i].startswith("Actions=")][0]]+[actionline]
for item in text:
for it in item:
lines.append(it)
with open(dtfile, "wt") as out:
for line in lines:
out.write(line)
while True:
apps1 = applist()
time.sleep(1)
apps2 = applist()
if apps1 != apps2:
text = [["[Desktop Action "+it+"]\n", "Name="+it+"\n",
"Exec=raise_app "+it+"\n", "OnlyShowIn=Unity;\n\n",
]for it in apps2]
update_dtfile(apps2, text)
.desktop dosyası
[Desktop Entry]
Name=Raise application windows
Comment=Raise groups of windows
Icon=/path/to/raise.png
Terminal=false
Type=Application
Version=1.0
Actions=
Kısa Açıklama
Yukarıdaki tüm çözümler ~/.local/share/applications
komutunu kullanarak bir pencere listesi oluşturmak için .desktop
kullanmaktadır.Bu komut, aşağıdaki gibi görünen çizgiler üretir:
0x044000b3 0 3429 65 24 1615 1026 jacob-System-Product-Name unity - How to show all windows of an application? - Ask Ubuntu - Mozilla Firefox
Bu satırlar şunları içerir:
- 1. sütun: pencerenin kimliği (yükseltmek için kullanabiliriz)
- 3. sütun: pencerenin sahibi olan pid.
- 4. / 5. sütun: pencerenin geometrisi x-y (pencerenin geçerli görünümde olup olmadığını görmek için kullandığımız, i.c.w
update_apps
)
Uygulamanın "kullanıcı tarafından okunabilir" bir tanımını (adı) almak için pid ~/bin
çıktısına baktı.
Böylece pencereleri uygulamalara ayırabiliriz. Ardından, wmctrl
komutuyla, wmctrl -lpG
döngüsünde belirli bir uygulamanın pencerelerini kaldırabiliriz.
Seçenek 3'te
komut dosyası, en ön pencerede herhangi bir değişiklik olup olmadığını görmek için art arda xrandr
komutunu kullanarak 3 saniyelik bir "bekleme" döngüsü başlatır; Bu, kullanıcının bir uygulamanın penceresini yükseltmek için bir başlatıcı simgesine veya doğrudan bir pencereye tıklanması durumunda gerçekleşir. Eğer öyleyse, while döngüsü "yeni" en üstteki uygulamayı kırıyor ve daha sonra bu uygulamanın tüm diğer pencerelerini yükseltir.