วิธีรับรายการแอพพลิเคชั่น GUI ใน Unity Launcher


8

ฉันต้องการรายการที่มีเฉพาะแอพที่เปิด / ทำงานใน Dash เท่านั้นในขณะนี้แอปที่มีลูกศรสีขาวเล็ก ๆ ทางด้านซ้ายของไอคอน

มีวิธีการรับหรือไม่

เส้นประพร้อมหน้าจอลูกศร


1
บริบทคืออะไรและคุณต้องการให้รายการพร้อมใช้งาน (ในรูปแบบใด)
Jacob Vlijm

รายการของหน้าต่างที่เปิดอยู่? สามารถทำได้อย่างง่ายดาย แต่อย่างที่จาค็อบพูดเราอาจต้องทราบข้อมูลเพิ่มเติม
Sergiy Kolodyazhnyy

ที่เกี่ยวข้องและมีแนวโน้มมากที่ซ้ำกัน: askubuntu.com/q/483554/295286
Sergiy Kolodyazhnyy

คำตอบ:


4

วิธีที่จะทำกับqdbusและorg.ayatana.bamfอินเตอร์เฟซ

รายการแอปพลิเคชันที่เปิดตาม.desktopไฟล์:

$ qdbus org.ayatana.bamf /org/ayatana/bamf/matcher \                           
> org.ayatana.bamf.matcher.RunningApplicationsDesktopFiles
/usr/share/applications/compiz.desktop
/usr/share/applications/firefox.desktop
/usr/share/applications/x-terminal-emulator.desktop

การใช้org.ayatana.bamf.matcher.RunningApplicationsและ org.ayatana.bamf.view.Nameวิธีการ

$ qdbus org.ayatana.bamf /org/ayatana/bamf/matcher  \                          
> org.ayatana.bamf.matcher.RunningApplications | \                             
> xargs -I {} qdbus org.ayatana.bamf {} org.ayatana.bamf.view.Name
Firefox Web Browser
MY CUSTOM TERMINAL
Compiz

ตอนนี้มันน่าประทับใจ!
Jacob Vlijm

@JacobVlijm มีรูปแบบที่หลากหลายมากขึ้น แต่มีวัตถุประสงค์เฉพาะและต้องการรหัสเพิ่มเติมและการแยกวิเคราะห์ ฉันเพิ่งวางสิ่งที่ง่ายที่สุดที่นี่ แต่ขอบคุณ :)
Sergiy Kolodyazhnyy

5

คำถามที่น่าสนใจ

เช่นเคยมีวิธีที่แตกต่างกันในการรับรายการแอปพลิเคชันเหล่านี้ซึ่งแต่ละแอปพลิเคชันนั้นมีโฆษณาและข้อเสียเฉพาะ

การรับรายการกระบวนการแสดงใน Launcher โดยใช้รายการหน้าต่าง

เนื่องจากมีเฉพาะแอปพลิเคชันที่มีหน้าต่าง (แมป) ปรากฏใน Launcher โดยใช้:

wmctrl -lp 

( wmctrlไม่ได้ติดตั้งโดยค่าเริ่มต้น) เราสามารถรับรายการของหน้าต่างที่เปิดอยู่และกระบวนการที่เป็นของ windows รูปแบบของผลลัพธ์คือ:

0x05204641  0 12618  jacob-System-Product-Name verhaal (~) - gedit

ข้อมูลที่สำคัญที่สุดสำหรับเราอยู่ที่:

  • สตริงแรก ( 0x05204641); นี่คือหน้าต่าง -id
  • สตริงที่สาม ( 12618); นี่คือรหัสกระบวนการ (pid) ที่หน้าต่างเป็นของและ
  • ส่วนสุดท้าย ( verhaal (~) - gedit); นี้เป็นหน้าต่างชื่อ

เมื่อเรามี pid เราสามารถค้นหาชื่อกระบวนการที่สอดคล้องกันโดยคำสั่ง:

ps -p <pid> -o comm=

เราสามารถสคริปต์ขั้นตอนข้างต้นและรายการผลลัพธ์สำหรับหน้าต่างที่มีอยู่ดูเหมือน (ใช้python):

{'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'thunderbird', 'soffice.bin'}

ภาวะแทรกซ้อน

ดูเหมือนจะตรงไปตรงมา อย่างไรก็ตามเช่นเคยความเป็นจริงค่อนข้างซับซ้อนกว่าเล็กน้อย มีข้อยกเว้นและภาวะแทรกซ้อนบางประการที่เราต้องดูแล:

  1. บางหน้าต่างจะเป็นของpid 0ซึ่งจะทำให้เกิดข้อผิดพลาดเมื่อพยายามรับคุณสมบัติ Windows ของIdle( pythonIDE) หรือtkinterเป็นหน้าต่างดังกล่าว
  2. หน้าต่างบางบานไม่มี "ของจริง" หรือหน้าต่างเช่นหน้าต่างชั่วคราว (หน้าต่างซึ่งเรียกจากและเป็นของหน้าต่างอื่น) หรือตัวอย่างเช่นเดสก์ท็อปเอง windows เหล่านี้ถูกแสดงรายการเป็น windows ในผลลัพธ์ของwmctrlแต่ไม่ปรากฏแยกต่างหากใน Dash
  3. ในบางกรณีชื่อโปรแกรมที่ค่อนข้างแตกต่างจากชื่อกระบวนการเช่นในกรณีของที่โมดูลทั้งหมดมีชื่อกระบวนการของLibreOffice soffice.binในเวลาเดียวกันการรันคำสั่ง soffice.binจะไม่ทำงาน ในกรณีที่คุณต้องระบุโมดูล ( Calc, Writerฯลฯ ) แยกกันคุณจะต้องได้รับข้อมูลเพิ่มเติมจากหน้าต่างของชื่อเช่น
  4. อีกตัวอย่างหนึ่งคือชื่อกระบวนการของตามที่ปรากฏในรายการกระบวนการในขณะที่การส่งออกของgnome-terminal ps -e wwใน 14.04, gnome-terminalปรากฏเป็นgnome-terminalอย่างไรก็ตามใน 15.04 / 15.10 /usr/lib/gnome-terminal/gnome-terminal-serverมันแสดงให้เห็น:

สิ่งที่เราต้องแก้ไขอย่างน้อย

ในการแก้ไขปัญหาที่สำคัญที่สุดข้างต้นคุณต้อง:

  • เพิ่มการตรวจสอบว่าหน้าต่างเป็นหน้าต่าง "จริง" หรือ "ปกติ" การตรวจสอบด้วย

    xprop -id <window_id>
    

    หากเอาต์พุตรวมบรรทัด:

    _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_NORMAL
    

    หน้าต่างเป็นหน้าต่างที่ถูกต้องในความหมายของ Unity Launcher

  • ในการแก้ไขชื่อกระบวนการgnome-terminalใน15.x(สมมติว่าคุณต้องการชื่อกระบวนการที่นำเสนอgnome-terminal) เราจำเป็นต้องเพิ่มข้อยกเว้นเพื่อเปลี่ยนชื่อกระบวนการเป็นgnome-terminalถ้ามันปรากฏเป็น /usr/lib/gnome-terminal/gnome-terminal-server

ต้นฉบับ

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

try:
    listed = sys.argv[1]
except IndexError:
    listed = []

get = lambda cmd: subprocess.check_output(cmd).decode("utf-8").strip()

def check_wtype(w_id):
    # check the type of window; only list "NORMAL" windows
    return "_NET_WM_WINDOW_TYPE_NORMAL" in get(["xprop", "-id", w_id])

def get_process(w_id):
    # get the name of the process, owning the window
    proc = get(["ps", "-p", w_id, "-o", "comm="])
    proc = "gnome-terminal" if "gnome-terminal" in proc else proc
    return proc

wlist = [l.split() for l in subprocess.check_output(["wmctrl", "-lp"])\
         .decode("utf-8").splitlines()]

validprocs = set([get_process(w[2]) for w in wlist if check_wtype(w[0]) == True])

if listed == "-list":
    for p in validprocs:
        print(p)
else:
    print(validprocs)

วิธีใช้

  1. สคริปต์ต้องการwmctrl:

    sudo apt-get install wmctrl
    
  2. คัดลอกสคริปต์ด้านบนเป็นไฟล์เปล่าบันทึกเป็น get_running.py

  3. เรียกใช้โดยคำสั่ง:

    python3 /path/to/get_running.py
    

    มันจะออกเช่น:

    {'gnome-terminal', 'nautilus', 'gedit', 'GuitarPro.exe', 'firefox', 'thunderbird', 'soffice.bin'}
    

    หรือเรียกใช้ด้วยอาร์กิวเมนต์-list:

    thunderbird
    nautilus
    gnome-terminal
    firefox
    gedit
    GuitarPro.exe
    soffice.bin
    

หมายเหตุ

จากคำถามของคุณไม่ชัดเจนว่าอะไรคือจุดประสงค์ของรายการที่พบ หากคุณต้องการชื่อของแอปพลิเคชันดังที่ปรากฏในอินเทอร์เฟซ (ชื่อ "อ่านได้") อาจมีวิธีการที่แตกต่างกันโดยสิ้นเชิง:

  • ทุกโปรแกรมที่ติดตั้งทั่วโลกจะมีแฟ้มใน.desktop /usr/share/applicationsในกรณีส่วนใหญ่เราสามารถสรุปชื่อกระบวนการและชื่ออินเตอร์เฟสของแอปพลิเคชันจาก.desktopไฟล์ การใช้ข้อมูลนี้เราสามารถสร้างรายการแอพพลิเคชั่น GUI ที่ใช้งานง่ายซึ่งแสดงโดยชื่อ "ที่อ่านได้"

นอกจากนี้ในกรณีนี้ แต่ความเป็นจริงก็ยังมีความซับซ้อนมากขึ้นแล้วทฤษฎีตามที่อธิบายไว้ที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.