Bir uygulamanın tüm pencereleri nasıl gösterilir (yükseltilir)?


21

Birden fazla pencere kullanan bir uygulamam var. Bu uygulamanın tüm pencerelerini hızlı bir şekilde ön plana nasıl getirebilirim?

Kaydırma tekerleği ile uygulamalar arasında gezindiğimde sadece bir pencere görüntüleniyor. Bir sonraki pencereye giderken, son pencere tekrar arka plana getirilir.

Uygulama simgesine tıkladığımda, tüm pencerelere tam ekran genel bir bakış elde ediyorum. Her pencereyi manuel olarak seçmem ve faremi ekranın yarısı boyunca birkaç kez hareket ettirmem gerekiyor.

Şimdiye kadarki en iyi çözüm, tüm pencereleri ( Ctrl+ Super+ D) küçültmek ve daha sonra kaydırma tekerleğini kullanarak uygulamamın pencerelerini göstermek.

Daha iyi bir çözüm var mı?


@Joschua Bir uygulamanın tüm pencerelerini öne getirmek çok zor değil, ancak uygulamayı nasıl tanımlamak istersiniz? Bir tuş kombinasyonunu + bir uygulamanın penceresini tıklatarak ne yaparsınız?
Jacob Vlijm

@Joschua veya mayby ​​daha şık, uygulama adının anahtar bir açılan + 1. karakteri?
Jacob Vlijm

Davranışın tüm uygulamalarla aynı olduğunu düşünüyorum. Bu özelliği sık sık yan yana açık iki ya da daha fazla pencerenin olduğu terminal pencerelerinde özlüyorum. Sonra tam ekran penceresine (örn. Firefox) geçiyorum ve iki terminal penceresine geri dönmek istediğimde biraz zor. Şimdiye kadar bulduğum en iyi yol, arkadaki Firefox'u ön plana çıkaran Firefox uygulama çubuğuna farenin orta tuşuyla tıklamak. Bununla birlikte, bu sadece çok işe
yarar

ayrıca @Joschua Ön uygulama penceresi gruplarına getirmek için bir tuş kombinasyonuna sahip olmak mümkün olacaktır ; bir kez basın -> tüm firefox pencereleri görünür, tekrar basın -> tüm terminal pencereleri görünür vb. gerçekten pürüzsüz hale getirilebilir. ilginç. üzerinde çalışıyorum. olsa biraz çalışacağım.
Jacob Vlijm

@JacobVlijm Doğru yöne benziyor .. :) Benim için en önemli görünen şey, bir tuş kombinasyonunun ve simgeye tıklamanın, o uygulamanın tüm pencerelerini (örneğin, belirtilen peq olarak birçok terminal) öne, tercihen yaymaya getirmesidir. dışarı, böylece üst üste
gelmemeleri için

Yanıtlar:


21

EDIT - yeni cevap

Aşağıdaki cevap (lar) hala tamamen geçerlidir ve bu nedenle önerilen seçenekler. Devam eden içgörü ise, muhtemelen en şık çözüm olan aşağıdaki göstergeyi kullanmak için bu seçeneği eklememi sağladı.

Bu nedenle, muhtemelen seçenek 5'i (.desktop dosyası kullanarak) değiştirmelidir.

Listeden uygulamayı seçmeniz yeterlidir; ilgili uygulamanın tüm pencereleri (geçerli görünüm alanında bulunur) açılır:

görüntü tanımını buraya girin

Nasıl kullanılır

ppa'dan:

sudo add-apt-repository ppa:vlijm/upfront
sudo apt-get update
sudo apt-get install upfront

... veya elle:

#!/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 ihtiyacı wmctrl

    sudo apt-get wmctrl
    
  • Göstergeyi boş bir dosyaya kopyalayın, raise_apps.py

  • O kaydetme, aşağıdaki resme Kopya tam olarak adlandırılmış raise.png içinde tek ve aynı dizine göstergesi olarak.

    görüntü tanımını buraya girin

  • Sonra sadece komutla çalıştırın:

    python3 /path/to/raise_apps.py

  • Uygulamaları başlatmak istiyorsanız ekleyin:

    /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. Geçerli görünüm penceresinin yalnızca pencerelerinin kaldırıldığından emin olmak biraz daha karmaşıktır . Ancak asıl zorluk, eylemi kullanıcıya ulaştırmak için uygun bir yol bulmaktır.

Beş seçenek olduğunu bakmak Aşağıda, nasıl göstermek için olabilir yapılabilir. Tüm seçenekler kullanıma hazır. Ancak son seçenek deneysel bir tür; iyi çalışıyor ancak seçeneğin açıklamasında açıklandığı gibi birkaç küçük kozmetik dezavantajı var. Yine de bir konsept olarak ekledim .

Pencereleri otomatik olarak üst üste gelmeyecek şekilde yaymak, bir yorumda önerildiği gibi, benim için pratik bir fikir değil; (uygulama açısından) gruplandırılmış bir pencere kurulumunda çalışıyorsanız, komut dosyası muhtemelen istenmeyen bir şekilde pencereleri yeniden düzenler.

Nasıl kullanılır

Tüm seçenekler için yapmanız gerekenler:

  • yüklemek wmctrlsisteminize henüz değilse:

    sudo apt-get install wmctrl
    
  • henüz mevcut değilse, dizini yaratın:

    ~/bin
    

    (açıklama: dizin ~/bin$ PATH konumunda, bu nedenle çalıştırılabilir dosyaları isimlerine göre çalıştırabilirsiniz)

  • Seçeneğe karşılık gelen betiği kopyalayın, boş bir dosyaya yapıştırın, raise_app(uzantısız) olarak kaydedin ~/binve çalıştırılabilir hale getirin

Ayrı seçeneklerde, olası ilave adımlar açıklanacaktır.

Seçenek 1: Bir veya daha fazla karakter girerek uygulamayı seçin

  • Bir tuş bileşimine basın, bir zenitypencere görünecektir
  • Giriş kutusuna uygulamanın adının bir veya daha fazla karakterini girin
  • Enter tuşuna basın

Bu, eşleşen uygulamanın tüm pencerelerini ( geçerli görünüm alanında) öne çıkarır.

gnome-terminalGeçerli vitrindeki tüm pencereleri kaldır :

görüntü tanımını buraya girin

görüntü tanımını buraya girin

Nasıl kullanılır:

  • Kurulumu "Nasıl kullanılır" bölümünde açıklandığı şekilde yapın.
  • Komut tarafından test çalıştırması yapın:

    raise_app
    
  • Her şey yolunda giderse, onu istediğiniz bir kısayol tuş kombinasyonuna ekleyin: Seçin: Sistem Ayarları> "Klavye"> "Kısayollar"> "Özel Kısayollar". "+" İşaretini tıklayın ve komutu ekleyin

Senaryo:

#!/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 dolaşın ve pencereleri bir tuş kombinasyonu ile yükseltin:

Diyelim ki aşağıdaki komut dosyasını Alt+ tuş kombinasyonu altında tutuyorum 1. Birkaç pencerem açık:

  • firefox
  • gnome-terminal
  • nautilus

Şu anki durum:

görüntü tanımını buraya girin

Bir kere basar Alt+ 1, tüm nautiluspencereler açılır:

<Görüntü>

Tekrar basıyorum Alt+ 1, tüm firefoxpencereler açıldı:

<Görüntü>

Tekrar basıyorum Alt+ 1, tüm gnome-terminalcamlar tekrar açılıyor, döngü başlıyor:

<Görüntü>

Nasıl kullanılır

  • Kurulumu "Nasıl kullanılır" bölümünde açıklandığı şekilde yapın.
  • Seçtiğiniz bir kısayol tuşu kombinasyonuna ekleyin: Seçin: Sistem Ayarları> "Klavye"> "Kısayollar"> "Özel Kısayollar". "+" İşaretini tıklayın ve komutu ekleyin

    raise_app
    

Daha sonra, tuş kombinasyonunuzla birlikte gruplanmış uygulama pencereleriyle uygulamalarınız arasında dolaşın.

Senaryo:

#!/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: geçerli vitrindeki tüm pencereleri kaldırmak için tuş kombinasyonuna basın + başlatıcı simgesine veya uygulama penceresine tıklayın

Bu, muhtemelen soru / yorumda açıklananlara en yakın seçenektir.

Diyelim ki nautilusdiğer pencerelerin altına gömülmüş üç pencereli dağınık bir masaüstüm var .

<Görüntü>

Tüm nautilus pencerelerini yükseltmek için (örnek kısayol: Alt+ 1):

  • Alt+ 1Tuşlarına basın , bırakın (!)
  • 3 saniye içinde ya:

    Başlatıcıdaki uygulamanın simgesine tıklayın

    <Görüntü>

    veya:

    uygulamanın pencerelerinden birine tıklayın

    <Görüntü>

    sonuç:

    <Görüntü>


Nasıl kullanılır:

  • Kurulumu "Nasıl kullanılır" bölümünde açıklandığı şekilde yapın.
  • Komut tarafından test çalıştırması yapın:

    raise_app
    
  • Her şey yolunda giderse, onu istediğiniz bir kısayol tuş kombinasyonuna ekleyin: Seçin: Sistem Ayarları> "Klavye"> "Kısayollar"> "Özel Kısayollar". "+" İşaretini tıklayın ve komutu ekleyin

Sonra:

  • Tuş kombinasyonunuza basın ve 3 saniye içinde:

    • Başlatıcıdaki uygulamanın simgesine tıklayın
    • uygulamanın pencerelerinden birine tıklayın

Senaryo

#!/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: Bir tuş kombinasyonu, geçerli görünüm alanında uygulama başına pencere sayısını gösteren seçenek listesini çağırır.

Bu daha uygun olduğu ortaya çıktı sonra kabul ettim:

(Tekrar örnek-) tuş birleşimine basmak Alt+ 1, bir zenitypencereyi çağırır , tüm uygulamaları ve pencerelerin sayısını geçerli görünüm penceresinde listeler:

görüntü tanımını buraya girin

Basitçe veya oklarına basmak sizi doğru seçime getirecektir. Tuşuna basın Enterve seçilen uygulamanın tüm pencereleri açılır.

Nasıl kullanılır:

  • Kurulumu "Nasıl kullanılır" bölümünde açıklandığı şekilde yapın.
  • Komut tarafından test çalıştırması yapın:

    raise_app
    
  • Her şey yolunda giderse, onu istediğiniz bir kısayol tuş kombinasyonuna ekleyin: Seçin: Sistem Ayarları> "Klavye"> "Kısayollar"> "Özel Kısayollar". "+" İşaretini tıklayın ve komutu ekleyin

Senaryo

#!/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 başlatıcı simgesinden kaldırın

Bu seçenek, halihazırda çalışan uygulamaların hızlı listesindeki bir başlatıcı simgesinden oluşur. Birini seçin, uygulamaların tüm pencereleri kaldırılacaktır.

görüntü tanımını buraya girin

Çalışan uygulamaların listesi (geçerli görünüm alanında) değiştiğinde, başlatıcı otomatik olarak güncellenir. Hızlı liste, diğer uygulamaların pencerelerinde, diğer uygulamaların pencerelerinin açıldığı farklı bir liste gösterir (uyum sağlaması 1-2 saniye sürer).

Belirtildiği gibi, tamamen işlevsel olmasına rağmen, bu seçenek bir kavram olarak ifade edilir . Olduğu gibi birkaç küçük kozmetik dezavantajı vardır. En önemli:

  • İmleç "tekerlek" bir işlemden sonra birkaç saniye dönmeye devam eder. İşlevselliği etkilemese de, kozmetik bir olumsuz taraftır.
  • Çalışan uygulama listesi değiştikten 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 bulabilirsiniz:

iki komut dosyası / bir simge / bir .desktopdosya

  1. Kurulumu "Nasıl kullanılır" gibi hazırlayın, ilk (ana) betiği olduğu gibi kaydedin raise_app.~/bin
  2. Aşağıdaki simgeyi kaydedin (sağ tıklayın, farklı kaydet) raise.png

    <Simgesi>

  3. .desktopDosyayı boş bir dosyaya kopyalayın , satırı düzenleyin

        Icon=/path/to/raise.png
    

    simgeye gerçek yoluna (tırnaklar arasındaki boşluklarla yolları)
    o kaydet raise.desktopde~/.local/share/applications

  4. .desktopDosyayı eklemek için başlatıcıya sürükleyin

  5. İkinci senaryo kopyalamak boş bir dosyaya yapıştırın olarak kaydedin update_appsiçinde ~/binçalıştırılabilir hale.
  6. Başlangıç ​​uygulamalarınıza aşağıdaki komutu ekleyin (Dash> Başlangıç ​​Uygulamaları> Ekle):

    update_apps
    
  7. Çalışması için oturumu kapatıp tekrar açın.

İlk senaryo

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

#!/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 wmctrl, wmctrl -lpGkomutu kullanarak bir pencere listesi oluşturmak için kullanılı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 kullanabileceğimiz)
  • 3. sütun: pencerenin sahibi olan pid.
  • 4. / 5. sütun: pencerenin geometrisi xy (pencerenin geçerli görünüm alanında olup olmadığını görmek için kullanıyoruz, icw xrandr)

Uygulamanın ps -u <username>bir "kullanıcı tarafından okunabilir" kimliğini (adı) elde etmek için Pid çıktıya bakılır .
Böylece pencereleri uygulamalara tahsis edebiliriz. Daha sonra verilen bir uygulamanın pencerelerini forkomut ile bir döngü içinde yükseltebiliriz wmctrl -ia.

Seçenek 3'te
komut dosyası xprop -root, en öndeki pencerede herhangi bir değişiklik olup olmadığını görmek için komutu tekrar tekrar kullanarak 3 saniyelik "bekleme" döngüsünü başlatır ; kullanıcı bir uygulamanın penceresini yükseltmek için başlatıcı simgesini tıklatırsa veya doğrudan bir pencereye tıklarsa bu olur. Öyleyse, while döngüsü en öndeki "yeni" uygulamayı keser ve arar ve ardından o uygulamanın diğer tüm pencerelerini yükseltir.


Katılıyorum ve tüm çabalarınız için tekrar teşekkürler! :) || Daha önce farketmediğim tuhaf bir şey var. Bazen Option 2betiği kullandıktan sonra , bir uygulama penceresi odaklandığında (maksimize değil) ve "aşağıda" görünen başka bir pencereye tıklarsam, aşağıdaki uygulama odağı elde edemez.
Joschua

@Joschua bu sorunun OP'si: askubuntu.com/questions/575830/… bana en son "özellik" güncellemesinde tanıtılan bir hataya katıldı. Doğru / Yanlış karışık, hiçbir uygulamada birden fazla pencere olmadığında komut dosyasının çökmesine neden oldu. Seçenek2 kullanıyorsanız, lütfen en son sürüme güncelleyin.
Jacob Vlijm

Seçenek 1 ubuntu xenial'da benim için çalışmıyor. bir şey @ bir şey: ~ / bin $ ./raise_app Gtk-Mesaj: geçici bir ebeveyn olmadan eşlenen GtkDialog. Bu önerilmez. Terminal pencerelerini açmaya çalışıyordum. Hiçbir şey olmadı.
xtrinch 17:16

@Nirri hangi uygulama adını kullandınız? Bir zenci penceresi bir Gtk ebeveyni olmadan çalışırsa, mesaj oldukça normaldir. "Cesareti kırılmış" bir hata değildir.
Jacob Vlijm

Terminalin ilk karakterleri. Çalışır - tür - herhangi bir uygulamanın penceresini yükseltir - ancak yalnızca bir tanesi, hepsi beklendiği gibi değil @ user72216
xtrinch 17:16

1

Şu anda açık olan tüm pencerelerin fuarını gösterecek Super+ Wkısayol var, ancak diğer uygulamaları da içerecek. Bu, varsayılan olarak gelir ve herhangi bir değişiklik gerektirmez, bu yüzden belki de mevcut en basit seçenek.

Diğer şeylerin yanı sıra, pencereleri ekranın sağ ve sol yarısına Ctrl+ Super+ Left/ Rightdüğmeleri ile konumlandırabilir ve aralarında Alt + ~ ile (bir tuşun yanındaki tuş) arasında geçiş yapabilirsiniz.


Bu olsa da bir uygulamanın tüm pencerelerini en üste getirmiyor. Onları görebilirsiniz, ancak çok fazla tıklatmadan kullanamazsınız.
Joschua

1

Uygulamalar arasında gezinmek için Alt + Tab tuşlarına basarsanız ve birden çok pencereli bir pencereye ulaşırsanız, alt tuşunu basılı tutmaya devam edin ve yaklaşık 1 saniye sonra, simge o uygulamanın tüm pencerelerinin manzarasını değiştirir.

Bu, aradığın şey olabilir veya olmayabilir, ama benim için çalışıyor ve ton daha basit, bu yüzden seçeneği paylaşacağımı düşündüm!


1
Uygulama pencerelerinin hemen görünmesini sağlamak için aşağı ok tuşuna da basabilirsiniz.
Kris

1

@ JacobVlijm'in raise_apps.py betiğini aldım ve daha sağlam hale getirmek dahil bazı geliştirmeler yaptım.

Spesifik olarak, bir ya da iki gün sonra @ JacobVlijm'in senaryosunun çalışmayı durduracağını ve yeniden çalışmasını sağlamak için komut dosyasını manuel olarak yeniden başlatmam gerektiğini keşfettim. Geçmişe baktığımda, en iyi tahminim xrandr'a yapılan çağrıların sonunda sorunlara yol açtığı yönünde.

Her neyse, kodunu uyarladım, oy kullanma sıklığını 5 saniyeden 5 saniyeye çıkardım, çünkü zaten CPU kullanmıyor ve daha da sağlamlaştırıyordu. Genellikle sorun olmadan günlerce / haftalarca çalışmasını sağlayabilirim.

Bir uyarı, ekran çözünürlüğü boyutlarını elde etmek için başlatma sırasında yalnızca bir kez xrandr çağırmam. Bu nedenle, ekran çözünürlüğünüzü değiştirirseniz (örneğin 1920x1080'den başka bir çözünürlüğe), muhtemelen yeni çözünürlüğü alabilmesi için raise-apps.py dosyasını manuel olarak yeniden başlatmak isteyeceksiniz. Şahsen, ekran çözünürlüğümü asla değiştirmedim, bu yüzden bu benim için sorun değil. Ek olarak, xrandr'a yapılan çok fazla çağrının, JacobVlijm'in betiğinin sürümünün bir veya iki gün sonra çalışmayı bırakmasına neden olan şey olduğuna inanmak için güçlü bir nedenim var, bu yüzden xrandr'a geri aramak için çok sayıda çağrı yapmamanızı şiddetle tavsiye ederim.

BTW, raise.png görüntüsünü / usr / local / icons / dizinine yerleştirmelisiniz. Veya farklı bir dizine raise.png koymak istiyorsanız, komut dosyasında uygun değişiklikleri yapın; böylece komut dosyası görüntü dosyasını bulabilir.

İnşallah Ubuntu, bu tür 'tüm pencereleri yükselt' işlevini, çok kullanışlı olduğu kadar, en kısa sürede sistemlerine dahil edecektir:

#!/usr/bin/python2
#
# Note to self:
# You need to add raise.png to /usr/local/icons/ directory.
#
# This script was taken from: /ubuntu/446521/how-to-show-raise-all-windows-of-an-application, 
# (@JacobVlijm's answer), and then improved to fix some
# issues, that were causing it to stop working after a day or two.
#
#
from __future__ import print_function

from sys import stderr, exit
import signal
import gi

gi.require_version('Gtk', '3.0')
gi.require_version('AppIndicator3', '0.1')
from gi.repository import Gtk, AppIndicator3, GObject, GLib

import logging
import logging.handlers

import time
import os
import subprocess
import getpass

logger = logging.getLogger('MyLogger')
logger.setLevel(logging.DEBUG)

log_handler = logging.handlers.SysLogHandler(address='/dev/log')

logger.addHandler(log_handler)


currpath = os.path.dirname(os.path.realpath(__file__))

class Indicator():
    def __init__(self):
        self.app = 'raise-apps'
        iconpath = '/usr/local/icons/raise.png'
        self.indicator = AppIndicator3.Indicator.new(
            self.app, iconpath,
            AppIndicator3.IndicatorCategory.OTHER)
        self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)

        self.prev_menu_item_names = []
        self.menu_items = []

        res_output = get("xrandr").split()
        if (len(res_output) == 0):
            logger.error("raise-apps.py: invocation of xrandr failed! Unable to continue..")
            exit(-1)

        idf = res_output.index("current")
        res = (int(res_output[idf+1]), int(res_output[idf+3].replace(",", "")))
        (self.screen_width, self.screen_height) = res
        logger.info("raise-apps.py: screen resolution is %s x %s" % (self.screen_width, self.screen_height))

        self.indicator.set_menu(self.create_menu())

        GLib.timeout_add_seconds(1.0, self.check_recent)

    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)

        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_items[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_items:

            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):
        # 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]) < self.screen_width and 0 < int(w[4]) < self.screen_height]
        # 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):
        # print("in check_recent()", file=stderr)
        self.menu_items = self.get_apps()
        for app in self.menu_items:
            app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]
        # check if menu items have changed:
        has_changed = len(self.menu_items) != len(self.prev_menu_item_names)
        if (not has_changed):
            for i in range(len(self.menu_items)):
                if self.prev_menu_item_names[i] != self.menu_items[i][0]:
                    has_changed = True
                    break

        if has_changed:
            GObject.idle_add(
                self.set_new,
                priority=GObject.PRIORITY_DEFAULT)

            self.prev_menu_item_names = []
            for item in self.menu_items:
                self.prev_menu_item_names.append(item[0])

        GLib.timeout_add_seconds(1.0, self.check_recent)


    def stop(self, source):
        Gtk.main_quit()


    def recreate_menu(self, *args):
        logger.info("in recreate_menu()")
        self.prev_menu_item_names = []
        self.menu_items = []

        self.menu_items = self.get_apps()
        for app in self.menu_items:
            app[0] = "gnome-terminal" if "gnome-terminal" in app[0] else app[0]

        GObject.idle_add(
            self.set_new,
            priority=GObject.PRIORITY_DEFAULT)

        self.prev_menu_item_names = []
        for item in self.menu_items:
            self.prev_menu_item_names.append(item[0])


def get(command):
    # enable to get a feel for what this app is doing..
    # print("get", command, file=stderr)
    try:
        return subprocess.check_output(command).decode("utf-8")

    except subprocess.CalledProcessError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
        return ""

    except OSError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
        return ""

def execute(command):
    # enable to get a feel for what this app is doing..
    # print("exec", command, file=stderr)
    try:
        subprocess.call(command)

    except subprocess.CalledProcessError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
        return ""
    except OSError as e:
        logger.error("raise-apps.py error: cmd=%s, error=%s" % (command, e))
    return ""


logger.info("(raise-apps.py is starting up..)")
Indicator()
signal.signal(signal.SIGINT, signal.SIG_DFL)
Gtk.main()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.