Uygulamayı yalnızca henüz açık değilse başlat


16

Mac OS X'te Alfred'in kullanımını taklit etmek istiyorum, burada bir uygulamayı aradıktan sonra açmaya çalışırsanız, yalnızca program zaten çalışmıyorsa yeni bir pencere açacaktır, aksi takdirde odağı o uygulamanın çalışan örneği. Yeni bir pencere açmadan önce başlatıcıyı kontrol etmek için varsayılan davranışını değiştirmek için yine de var mı?


Ayrıca @pidge Bunu yapmak zor olmayacaktı, ama sağ tık "ile aç" davranışını da etkileyecekti. Sanırım bu kabul edilemez bir yan etki.
Jacob Vlijm

1
Belirli bir işlemin zaten çalışıp çalışmadığını kontrol edebilecek bir komut dosyası oluşturabilmeniz ve yeni bir işlem başlatmaya veya mevcut pencereye odaklanmaya karar verebilmeniz gerektiğini düşünüyorum. Ne yazık ki, henüz komut dosyasında çok iyi değilim ... Ama @JacobVlijm her amaç için komut dosyası olan bir adam olarak bilinir;) Yine de tüm orijinal başlatıcıları ilgili komut dosyasıyla değiştirmeniz gerekir. Bunu yapmak isteyip istemediğinizden emin değilim
Yapmazdım

2
Komut dosyası rotası ile giderseniz, bu komut dosyasını başlangıç ​​noktası olarak kullanabilirsiniz . Başlangıçta LXDE / Openbox için yazdım, ancak Unity'de de çalışmalı. Komut dosyası ve kullanımı hakkında daha fazla bilgi burada .
Glutanimate

1
@ByteCommander tam da aklımda olan buydu. Hatta .desktopdosyalardaki komutları komut dosyasıyla değiştirebilirsiniz . .desktopBununla birlikte, dosyadaki komutu değiştirirseniz, açık tıklama seçeneği ile sağ tıklama bozulur.
Jacob Vlijm

1
Hangi Masaüstü Ortamı İçin?
j0h

Yanıtlar:


6

Güncelleme 7 Nisan: Farklı bir sürüm eklendi ve Albert bulundu, güncelleme ve Bonus feryat bakınız !!!

Kısa çizgi işlevselliği ile ilgili olarak : " Yeni bir pencere açmadan önce başlatıcısının bunu kontrol etmek için varsayılan davranışını değiştirmek için yine de var mı? " Temel cevap, hayır, normal bir kullanıcı olarak bu davranışı kısa çizgiye eklemenin hiçbir yolu yoktur. Bununla birlikte, bunu uygulamaya istekli bir birlik kapsamı geliştiricisi varsa, çözüme ulaşmaya ve öğrenmeye istekliyseniz onlara yaklaşabilir veya kendiniz geliştirebilirsiniz. Kodlama becerilerim çok mütevazı, bu nedenle kabuk komut dosyası ve komut dosyaları için kullanılabilir grafik ön uç kullanıyorum.

İlgili bilgi

Orijinal yayın:

Ne istediğini elde etmek için zenity diyalog ve wmctrl kullanan bir senaryo yazdım. Bunun grafiksel bir komut dosyası olduğuna dikkat edin, yani GUI'de yalnızca pencerelerle çalışır ve tty'de bir şey başlatmaya çalışırsanız çalışmaz. Ayrıca, anladığım kadarıyla Alfred de aynı şeyi yapıyor. Burada ve burada açıklandığı gibi bir masaüstü kısayolu veya başlatıcı kısayolu oluşturabilirsiniz .

Senaryo:

#!/bin/bash
# Author: Serg Kolo
# Description: A launcher script that checks whether
#       or not a window of a particular program already exists
#       If a window of such program is open, bring it to focus
#       Otherwise - launch a new window
#       Written for /ubuntu//q/440142/295286
# Date: April 6 , 2015
#


MYPROG=$( zenity --entry --title='MY LAUNCHER' --text='Type the name of application to run' )
sleep 0.5
wmctrl -lx | awk '{print $3}' | grep -i "$MYPROG"

if [ $? -eq 0 ]; then
    sleep 1         
    wmctrl -xa $MYPROG
   #as an alternative try the line bellow
   #wmctrl -a $MYPROG
    exit 1
else 
    $MYPROG &
    exit 0
fi

Yan notlar: önceki sürümde, komut dosyası önceki ifadelerin başarıyla çıkıp çıkmadığını test etmek için echo $? Muru'nun önerisine göre (düzenlemeden), kodu biraz daha kompakt bir sürüme değiştirdim, bu yüzden önceki sürüme ve geçerli olana bir göz atmanızı öneririm.

Ayrıca, daha önce wmctrl -a $MYPROGgoogle-chrome veya chrome-browser testleriyle çalışmadı; bazı aptal nedenlerle, bazı programlar WM_CLASS özelliğinin büyük harfle yazılmasını sağlarken, listelenen program dpkg --get-selectionsküçük harflidir (sadece okuyun man wmctrlve çalıştırın wmctrl -lx, bileceksiniz). -Ax eklenmesi bununla ilgilenmelidir. Betik zaten açık olan krom penceresini olması gerektiği gibi getiriyor

Başka bir şey - wmctlr bazen (başka bir komut dosyasında onunla deneyimi vardı) bir gecikme ihtiyacı biraz garip, bu yüzden sleep 1satır eklemek zorunda kaldı . Daha önce firefox ile biraz açık ve kapalı olurdu, ama şimdi yüzerek çalışıyor.

Uygulamadaki komut dosyası

Aşağıdaki animasyonda, komut dosyasının ilk çalıştırılmasında bir tane firefox açık örneği olduğunu ve komut dosyasının odağı bu pencereye değiştirdiğini görebilirsiniz; ikinci testte, daha önce açık olmayan yeni google-chrome örneğini açtım. (Yan not: Bu arada masaüstünden cüret ediyorsanız, bu, cairo dock'lu openbox'tır)

Yorumlardaki öneri başına, gömülü animasyon kaldırıldı, yalnızca yayınlanan bağlantı. Bozuksa bildirin lütfen! http://i.stack.imgur.com/puuPZ.gif

Güncelleme, 7 Nisan

Betiği, zenity'nin açılan giriş kutusunda listelenen tüm programları yapmak için biraz geliştirdim. Artık kullanıcının her programı ezberlemesi gerekmez, ancak ok tuşlarını kullanarak bir listede gezinebilir veya sadece açılır menüyü açabilirsiniz. Ayrıca, bu geliştirilmiş sürüm pencereleri adlarına göre değil, daha iyi performans sağlayan pencere kimliğine göre yükseltir. Not, .desktop dosyalarından geçme şeklim, cut komutunu iki kez kullanarak biraz gereksiz, ancak benim script-fu o kadar iyi olmadığından, yapabileceğim tek şey bu. İyileştirme önerileri bekliyoruz!

#!/bin/bash
# Author: Serg Kolo
# Description: Second version of a launcher script that checks whether
#       or not a window of a particular program already exists
#       If a window of such program is open, bring it to focus
#       Otherwise - launch a new window
#       Written for /ubuntu//q/440142/295286
# Date: April 7 , 2015
#

set -x

MYPROG=$(zenity --entry --text 'Select program from list' --entry-text $(ls /usr/share/applications/*.desktop | cut -d'/' -f5 | cut -d'.' -f1 | xargs echo))
sleep 0.5
# Do we have a window of such program ?
wmctrl -lx| awk '{print $3}'  | grep -i $MYPROG

if [ $? -eq 0 ]; then
    sleep 0.5 # if yes, find that window id, and raise it
    WINID=$(wmctrl -lx | grep -i $MYPROG | awk 'NR==1{print $1}')
    wmctrl -ia $WINID &
 #  exit 0  
else
    echo $MYPROG | grep -i libreoffice
    if [ $? -eq 0  ]
    then
        MYPROG=$(echo $MYPROG | sed 's/-/ --/g')
    fi
    $MYPROG &

#  exit 0 
fi

resim açıklamasını buraya girin

Bonus:

Aslında Alfred'in Linux versiyonu olan Albert'i buldum , ama kendim denemedim. Yine de kontrol değer. Ancak, Jacob'un daha önce de belirttiği gibi, hala buggy.

Grafiksel olarak Alfred'e benzeyen Gnome-Do adlı bir uygulama var, ancak bu komut dosyasıyla aynı işlevselliğe sahip değil.

resim açıklamasını buraya girin

Bu komut dosyasını beğendiyseniz, düzeltilmesi gereken bir şey varsa bana bildirin ve yararlı bulursanız cevabı yükseltmeyi unutmayın.


Bu arada, programların adlarını nasıl yazdığımı fark et - tam olarak listelendiği gibi dpkg --get-selectons. "Writer" yazarak libreoffice yazarı başlatmak işe yaramaz, ancak ~ / bin, / bin veya / usr / bin klasörünüzde bir symlink yapabilir veya .bashrc veya .profile içinde takma ad kullanabilirsiniz.
Sergiy Kolodyazhnyy

Ayrıca dikkat, yüklü wmctl ihtiyacınız olacak, varsayılan olarak gelmiyor, ama oldukça kullanışlı. Ben de yapmak için kullandım bu
Sergiy Kolodyazhnyy

Annimasyona, annasyona bağlantı veren bir görüntü koyabilir misiniz? Tarayıcım sayfayı "yüklemeye" devam ettiğinden sayfayı yenileyemiyorum. (ve
iptal

Teşekkürler! Bağlantı, Firefox'ta değil Chrome'da iyi çalışıyor.
Jacob Vlijm

@JacobVlijm Ugh, öyle. Firefox'un neden oynamayı reddettiğinden emin değilim. Bu aslında yüklediğim şey için imgur link
Sergiy Kolodyazhnyy

5

1. İkinci Çizgi

Sorunuzda açıklandığı gibi uygulamaların çalıştırılması söz konusu olduğunda Dash'e alternatif olarak kullanılabilecek bir komut dosyasının altında.

Dash ile aynı işlevselliğe sahip bir pencere vardır; uygulamanın bir veya daha fazla karakterini yazın, uygulama listede görünür. EnterUygulamanın çalışıp çalışmadığına bağlı olarak uygulamayı başlatmak veya yükseltmek için basın .

Bir kısayol tuşu bileşiminden arayabilir veya başlatıcıdaki bir simgeyi Dash'e (aşağıya bakın) veya her ikisine benzer şekilde kullanacak şekilde ayarlayabilirsiniz.

resim açıklamasını buraya girin

Senaryo

#!/usr/bin/env python3
import subprocess
import os
import getpass
import time

user = getpass.getuser()
get = lambda x: subprocess.check_output(["/bin/bash", "-c", x]).decode("utf-8")
skip = ["%F", "%U", "%f", "%u"]; trim = ["chrome", "chromium", "nautilus"]

def apply(command):
    if "libreoffice" in command:
        proc = [l.split()[0] for l in get("ps -u "+user).splitlines() if "soffice.bin" in l]
        module = command.split("--")[-1]
        time.sleep(0.1)
        try:
            ws = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if process in w and module in w.lower()] for process in proc], [])[0]
            subprocess.call(["wmctrl", "-ia", ws])
        except IndexError:
            subprocess.Popen(["/bin/bash", "-c", command+"&"])
    else:
        check = command.split("/")[-1][:14]
        proc = [p.split()[0] for p in get("ps -u "+user).splitlines() if check in p]
        time.sleep(0.5)
        try:
            ws = sum([[w.split()[0] for w in get("wmctrl -lp").splitlines() if process in w] for process in proc], [])
            if command == "nautilus":
                real_window = [w for w in ws if "_NET_WM_WINDOW_TYPE_NORMAL" in get("xprop -id "+w)][0]
            else:
                real_window = ws[0]
            subprocess.call(["wmctrl", "-ia", real_window])
        except IndexError:
            subprocess.Popen(["/bin/bash", "-c", command+"&"])
# default directories of .desktop files; globally, locally, LibreOffice- specific when separately installed
globally = "/usr/share/applications"; locally = os.environ["HOME"]+"/.local/share/applications"; lo_dir = "/opt/libreoffice4.4/share/xdg"
# create list of .desktop files; local ones have preference
local_files = [it for it in os.listdir(locally) if it.endswith(".desktop")]
global_files = [it for it in os.listdir(globally) if it.endswith(".desktop")]
lo_spec = [it for it in os.listdir(lo_dir) if it.endswith(".desktop")] if os.path.exists(lo_dir) else []
for f in [f for f in local_files if f in global_files]:
    global_files.remove(f)
for f in [f for f in local_files if f in lo_spec]:
    lo_spec.remove(f)
dtfiles = [globally+"/"+f for f in global_files]+[locally+"/"+f for f in local_files]+[lo_dir+"/"+f for f in lo_spec]
# create list of application names / commands
valid = []
for f in dtfiles:
    content = open(f).read()
    if all(["NoDisplay=true" not in content,"Exec=" in content]):
        lines = content.splitlines()
        name = [l.replace("Name=", "") for l in lines if "Name=" in l][0]
        command = [l.replace("Exec=", "") for l in lines if all(["Exec=" in l, not "TryExec=" in l])][0]
        valid.append((name, command))
valid.sort(key=lambda x: x[0])
# create zenity list + window
list_items = '"'+'" "'.join([f[0] for f in valid])+'"'
proposed = 'zenity --list --text "Type one or more characters... " --column="Application List" '+\
           '--title="Dash the Second" --height 450 --width 300 '+list_items
try:
    choice = subprocess.check_output(["/bin/bash", "-c", proposed]).decode("utf-8").strip().split("|")[0]
    command = [r[1] for r in valid if r[0] == choice][0]
    # command fixes:
    for s in skip:
        command = command.replace(" "+s, "")
    for t in trim:
        if t in command:
            command = t
    apply(command)
except subprocess.CalledProcessError:
    pass

Nasıl kullanılır

Komut dosyasının wmctrlyüklenmesi gerekiyor :

sudo apt-get install wmctrl

Sonra:

  1. Yukarıdaki komut dosyasını boş bir dosyaya yapıştırın, dash_alternative.py
  2. Kısayol tuşu bileşimine ekleyin: Seçin: Sistem Ayarları> "Klavye"> "Kısayollar"> "Özel Kısayollar". "+" İşaretini tıklayın ve şu komutu ekleyin:

    python3 /path/to/dash_alternative.py
    

açıklama

Komut dosyası çalıştırıldığında, içinde temsil edilen tüm uygulamaları listeler /usr/share/applications. .dektopTüm uygulama adlarının bir listesini (ilk "Ad =" satırından) ve uygulamayı çalıştırma komutunu (ilk "Exec =" satırından) oluşturarak dosyaları arar .

Daha sonra, tüm uygulamaları sıralı bir şekilde sunan bir Zenity listesi oluşturulur.

Bir uygulama seçildiğinde, komut dosyası uygulama çalışıyorsa çalışan işlemler listesine bakar. Eğer öyleyse, ilgili pencere kaldırılır. Değilse, yeni bir örnek açılır.

notlar

  1. Komut dosyasını 12.04'te çalıştırmak için (orijinal soru etiketlendiğinden, 12.04basitçe kodu değiştirin #!/usr/bin/env pythonve komutla çalıştırın

    python /path/to/dash_alternative.py
    
  2. Test ettiğim kadarıyla, senaryo iyi çalışıyor. Komutlar ve bunlara karşılık gelen işlem adları (örn. LibreOffice<> soffice.bin), Farklı pencere türleri ( nautilus"gerçek" pencerelerin yanı sıra birkaç farklı pencere türü vardır), uygulama başına birden çok pids ( Chromium, Google-chrome), örneklerde düzelttiğim istisnalara neden olabilir yukarıda. Herhangi bir sorunla karşılaşırsanız, lütfen sorun.

2. Ek: çalışan uygulamalar için "gerçek" Dash'e alternatif olarak ayarlama

  1. Komut dosyasını yukarıda belirtildiği gibi kopyalayın ve güvenli hale getirin
  2. Aşağıdaki simgeyi kaydedin (sağ tıklayın> güvenli) dash_alternative.png

    resim açıklamasını buraya girin

  3. Boş bir dosya içine aşağıdaki kodu kopyalayın kaydetmek ~/.local/share/applicationsolarak dash_thesecond.desktop. /path/to/dash_alternative.py(Kod) ve /path/to/dash_alternative.png(simge) için doğru yolları ayarlayın

    [Desktop Entry]
    Name=Dash the Second
    Exec=python3 /path/to/dash_alternative.py
    Icon=/path/to/dash_alternative.png
    Type=Application
    Hidden=false
    
  4. .desktopDosyayı başlatıcıya sürükleyin :


1
.Desktop dosyalarının bir klasörü olduğunu bilmek güzel! Yerel ve uygun yüklü uygulamaların komutlar yerine ada göre nasıl listelendiğini merak ediyordum. Orada iyi iş çıkardın!
Sergiy Kolodyazhnyy

@Serg Teşekkürler! ve sizin için aynı :). İçin yerel dizin de vardır .desktopdosyalar: ~/.local/share/applications. Aramayı global olarak yüklenen uygulamalarla sınırlayacağımı düşündüm.
Jacob Vlijm

Jacob, python bilmiyorum, ama belki bu senaryoyu bir birlik kapsamına dönüştürerek geliştirmeniz için yararlı olacaktır. Benim anlayış bu OP tam olarak istediği çizgi işlevselliğini değiştirmek için tek yol olduğunu
Sergiy Kolodyazhnyy

@Serg Teşekkürler! bu ilginç bir yazı, kesinlikle iyi bir göz alacak!
Jacob Vlijm

0

İçin fırlatıcı o görev anahtarlama arayüzü olduğu gibi (ekranın sol tarafında dikey panel), bu, zaten varsayılan davranıştır.

Kısa çizgi için (Ubuntu logosunu tıkladığınızda açılan büyük bit), kaynak kodun kendisinde muhtemelen önemli bir değişiklik yapmadan davranışı bu şekilde değiştirmenin bir yolu yoktur.

Bununla birlikte, bazı uygulamalar bu şekilde davranacak şekilde tasarlandıkları için bunu zaten yapabilir. Bununla birlikte, tüm uygulamalar böyle bir şekilde uygulanmaz ve uygulanması gerekmez.

Yine başka bir özellik olarak, pencere formasını Super+ ile açar Wve bir uygulama adı yazmaya başlarsanız, o uygulamanın pencereleri gösterilenler olacaktır.


Aslında OP'nin istediğinin Linux sürümünü buldum, yazıma, bonus bölümüne bakın. Görünüşe göre başkası Alfred Linux'a getirmek için bir fikri vardı
Sergiy Kolodyazhnyy

1
@ Lütfen Albert'i deneyin; Albert'in hala "LibreOffice hatası", "Chromium hatası" ve "Chrome hatası" var. "Dosyalar hatası" bile ... Albert her zaman bu uygulamaların yeni bir örneğini açar. LibreOffice hiç çalışmıyor. Ayrıca, bağlantınızın altındaki yorumlarda bir dizi sorun bulabilirsiniz.
Jacob Vlijm

@Serg No, arka planda çalışan ve tamamen farklı bir kullanıcı deneyimi sağlayan ve uygulamaların nasıl bulunacağını yeniden eğitmeyi gerektiren ek bir yazılım parçası ekleyerek bir çözüm buldunuz. Sorulan soru, bu çalışmayı Birlik çizgisinde nasıl ele alacağınızdı. Benzer bir özelliği Unity'nin dışında elde edebilirsiniz, ancak Unity'yi bunu yapmak için değiştirmenin tek yolu kaynak kodunu değiştirmektir.
dobey

@dobey Evet, bu doğru; çizgi işlevselliğini değiştirmek erişimimizin ötesindedir, yani. . ... vailable'ımızla ne yapacağız, değil mi? Böyle bir işlevsellik ile birlik kapsamını kodlamak isteyen bir geliştirici olmadığı sürece. . .
Sergiy Kolodyazhnyy
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.