EDIT -new answer-
Jawaban di bawah ini masih benar-benar valid, dan demikianlah opsi yang disarankan. Namun wawasan yang sedang berlangsung membuat saya menambahkan opsi ini untuk menggunakan indikator di bawah ini, yang mungkin merupakan solusi paling elegan.
Karena itu, mungkin harus mengganti opsi 5 (menggunakan file .desktop).
Cukup pilih aplikasi dari daftar, dan semua jendela aplikasi yang sesuai (ada pada viewport saat ini) akan menaikkan:
Bagaimana cara menggunakan
dari ppa:
sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront
... atau secara manual:
#!/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()
Kebutuhan indikator wmctrl
sudo apt-get wmctrl
Salin indikator ke file kosong, simpan sebagai raise_apps.py
Salin gambar di bawah ini, simpan persis namanya raise.png
dalam satu dan direktori yang sama dengan indikator.
Maka jalankan saja dengan perintah:
python3 /path/to/raise_apps.py
Tambah jika Anda ingin Aplikasi Permulaan:
/bin/bash -c "sleep 10 && python3 /path/to/raise_apps.py"
JAWABAN TUA:
Tentang pertanyaan itu
Dengan alat yang tepat, tidak terlalu rumit untuk "hanya" menaikkan semua jendela aplikasi. Ini sedikit lebih rumit untuk memastikan hanya jendela viewport saat ini yang dinaikkan. Namun tantangan sebenarnya adalah menemukan cara yang nyaman untuk membuat tindakan tersedia bagi pengguna.
Di bawah lima opsi untuk mengatasinya, untuk menunjukkan bagaimana hal itu bisa dilakukan. Semua opsi siap digunakan. Namun opsi terakhir adalah jenis eksperimental; itu berfungsi dengan baik tetapi memiliki beberapa kerugian kosmetik kecil, seperti yang dijelaskan dalam deskripsi opsi. Saya menambahkannya sebagai konsep .
Menyebarkan jendela secara otomatis dengan cara yang tidak tumpang tindih, seperti yang disarankan dalam komentar, tampaknya bukan ide yang praktis bagi saya; jika Anda bekerja dalam pengaturan jendela grup (aplikasi-bijaksana), skrip mungkin akan mengatur ulang windows yang tidak diinginkan.
Bagaimana cara menggunakan
Untuk semua opsi, Anda perlu:
instal wmctrl
jika belum ada di sistem Anda:
sudo apt-get install wmctrl
buat, jika belum ada, direktori:
~/bin
(penjelasan: direktori ~/bin
dalam $ PATH, sehingga Anda dapat menjalankan executable dengan namanya)
Salin skrip, sesuai dengan opsi, tempel ke file kosong, simpan sebagai raise_app
(tanpa ekstensi) ~/bin
dan buat itu dapat dieksekusi
Dalam opsi terpisah, langkah-langkah tambahan yang mungkin akan dijelaskan.
Opsi 1: pilih aplikasi dengan memasukkan satu atau lebih karakter
- Tekan kombinasi tombol, sebuah
zenity
jendela akan muncul
- Masukkan satu atau lebih karakter dari nama aplikasi di kotak entri
- Tekan enter
Ini akan membuat semua jendela aplikasi yang cocok (pada viewport saat ini ) tampil ke depan.
naikkan semua gnome-terminal
jendela di viewport saat ini:
Bagaimana cara menggunakan:
- Lakukan pengaturan seperti yang dijelaskan dalam "Cara menggunakan"
Tes-jalankan dengan perintah:
raise_app
Jika semuanya berfungsi dengan baik, tambahkan ke kombinasi tombol pintas pilihan Anda: Pilih: Pengaturan Sistem> "Keyboard"> "Pintasan"> "Pintasan Khusus". Klik "+" dan tambahkan perintah
Naskah:
#!/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
Opsi 2: menelusuri aplikasi dan meningkatkan windows mereka dengan kombinasi tombol:
Katakanlah saya memiliki skrip di bawah ini di bawah kombinasi kunci Alt+ 1. Saya memiliki beberapa jendela terbuka:
- firefox
- terminal gnome
- nautilus
Keadaan saat ini:
Saya menekan sekali Alt+ 1, semua nautilus
jendela dinaikkan:
Saya menekan lagi Alt+ 1, semua firefox
jendela dinaikkan:
Saya menekan lagi Alt+ 1, semua gnome-terminal
jendela dinaikkan lagi, siklus dimulai lagi:
Bagaimana cara menggunakan
Kemudian putar aplikasi Anda dengan jendela aplikasi yang dikelompokkan dengan kombinasi tombol Anda.
Naskah:
#!/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
Opsi 3: tekan kombinasi tombol + klik ikon peluncur - atau - jendela aplikasi untuk menaikkan semua jendela pada viewport saat ini
Ini mungkin opsi yang paling dekat dengan apa yang dijelaskan dalam pertanyaan / komentar.
Katakanlah saya memiliki desktop yang berantakan dengan tiga nautilus
jendela terkubur di bawah jendela lain.
Untuk menaikkan semua jendela nautilus (contoh pintasan: Alt+ 1):
Bagaimana cara menggunakan:
- Lakukan pengaturan seperti yang dijelaskan dalam "Cara menggunakan"
Tes-jalankan dengan perintah:
raise_app
Jika semuanya berfungsi dengan baik, tambahkan ke kombinasi tombol pintas pilihan Anda: Pilih: Pengaturan Sistem> "Keyboard"> "Pintasan"> "Pintasan Khusus". Klik "+" dan tambahkan perintah
Kemudian:
Naskah
#!/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
Opsi 4: kombinasi tombol memanggil daftar opsi, menunjukkan jumlah jendela per aplikasi pada viewport saat ini
Yang ini ternyata lebih nyaman daripada yang saya duga:
Menekan kombinasi tombol (lagi contoh-) Alt+ 1memanggil zenity
jendela, mendaftar semua aplikasi dan jumlah windows mereka pada viewport saat ini:
Cukup dengan menekan ▴atau ▾panah akan membawa Anda ke opsi yang tepat. Tekan Enterdan semua jendela aplikasi yang dipilih dinaikkan.
Bagaimana cara menggunakan:
- Lakukan pengaturan seperti yang dijelaskan dalam "Cara menggunakan"
Tes-jalankan dengan perintah:
raise_app
Jika semuanya berfungsi dengan baik, tambahkan ke kombinasi tombol pintas pilihan Anda: Pilih: Pengaturan Sistem> "Keyboard"> "Pintasan"> "Pintasan Khusus". Klik "+" dan tambahkan perintah
Naskah
#!/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"')
Opsi 5: meningkatkan windows menjalankan aplikasi dari ikon peluncur
Opsi ini ada dari ikon peluncur, dengan aplikasi yang sedang berjalan dalam daftar cepat. Pilih satu, dan semua jendela aplikasi akan dinaikkan.
Peluncur diperbarui secara otomatis ketika daftar aplikasi yang berjalan (pada viewport saat ini) berubah. Daftar cepat menunjukkan daftar yang berbeda pada viewports lain, di mana jendela aplikasi lain dibuka (akan memakan waktu 1-2 detik untuk beradaptasi).
Sebagaimana disebutkan, meskipun berfungsi penuh, opsi ini dimaksudkan sebagai konsep . Ini memiliki beberapa kerugian kecil kosmetik seperti itu. Yang paling penting:
- "Roda" kursor terus berputar selama beberapa detik setelah suatu tindakan. Meskipun tidak memengaruhi fungsionalitas, ini adalah kerugian kosmetik.
- Diperlukan 1-2 detik untuk daftar aplikasi dalam ikon peluncur untuk diperbarui setelah daftar aplikasi yang berjalan berubah.
Selanjutnya pengaturannya sedikit lebih rumit (meskipun dijelaskan secara rinci di bawah):
Bagaimana cara menggunakan
Di bawah ini Anda akan menemukan:
dua skrip / ikon / .desktop
file
- Siapkan pengaturan seperti pada "Cara menggunakan", simpan skrip pertama (utama) seperti
raise_app
pada~/bin
Simpan ikon di bawah ini (klik kanan, simpan sebagai) sebagai raise.png
Salin .desktop
file ke file kosong, edit baris
Icon=/path/to/raise.png
ke jalan nyata untuk ikon (jalur dengan spasi antara tanda kutip)
Simpan sebagai raise.desktop
di~/.local/share/applications
Seret .desktop
file ke peluncur untuk menambahkannya
- salin script kedua, paste ke file kosong, simpan sebagai
update_apps
di ~/bin
, membuatnya menjadi executable.
Tambahkan perintah berikut ke aplikasi startup Anda (Dash> Startup Applications> Add):
update_apps
- Logout dan kembali untuk membuatnya berfungsi.
Script pertama
#!/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
Naskah kedua
#!/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)
File .desktop
[Desktop Entry]
Name=Raise application windows
Comment=Raise groups of windows
Icon=/path/to/raise.png
Terminal=false
Type=Application
Version=1.0
Actions=
Penjelasan singkat
Semua solusi di atas digunakan wmctrl
untuk membuat daftar jendela, menggunakan wmctrl -lpG
perintah. Perintah ini menghasilkan baris, seperti:
0x044000b3 0 3429 65 24 1615 1026 jacob-System-Product-Name unity - How to show all windows of an application? - Ask Ubuntu - Mozilla Firefox
Garis-garis ini termasuk:
- Kolom 1: id jendela (yang bisa kita gunakan untuk menaikkannya)
- Kolom ke-3: pid yang memiliki jendela.
- Kolom 4/5: geometri jendela xy (yang kita gunakan untuk melihat apakah jendela tersebut ada di viewport saat ini, icw
xrandr
)
Pid itu mencari dalam output ps -u <username>
untuk mendapatkan identifikasi (nama) aplikasi yang "dapat dibaca pengguna".
Dengan demikian kita dapat mengalokasikan windows ke aplikasi. Selanjutnya kita dapat menaikkan jendela aplikasi yang diberikan dalam satu for
lingkaran dengan perintah wmctrl -ia
.
Dalam opsi 3
, skrip memulai loop "menunggu" selama 3 detik, menggunakan xprop -root
perintah berulang kali untuk melihat apakah ada perubahan pada apa yang merupakan jendela paling depan; ini akan terjadi jika pengguna mengklik ikon peluncur untuk menaikkan jendela aplikasi, atau mengklik jendela secara langsung. Jika demikian, loop sementara memecah dan mencari aplikasi paling depan "baru", dan kemudian memunculkan semua jendela lain dari aplikasi itu.