it-swarm.com.de

Wie kann ich einem Skript im Unity-Launcher ein eigenes Symbol zuweisen?

Wenn Sie unter Ubuntu 16.04 einen Launcher (Desktop-Datei in ~/.local/share/applications) mit einem benutzerdefinierten Symbol für eine Terminal-Anwendung (also mit Terminal=true) erstellen, wird beim Starten ein neues Standard-Terminal-Symbol erstellt und Ihr benutzerdefiniertes Symbol blinkt und verschwindet innerhalb weniger Sekunden.

In 14.04 hat es einfach wie erwartet funktioniert. (Es würde kein neues Standard-Terminal-Symbol starten.).

Irgendeine Idee, was zu tun ist, um dieses Verhalten zu ändern? Ich habe ein paar Terminal-Apps, die ich von Unity aus starten möchte, und das neue Verhalten ist problematisch (ich verliere die Spur dessen, was ist, da sie alle mit dem Standard-Terminal-Symbol enden) ...

5
Se6

Warum es nicht so funktioniert wie du?

Wie im Kommentar erwähnt, kann eine Anwendung grundsätzlich immer nur durch ein Symbol im Launcher dargestellt werden . Das war schon immer so.

Damit ist wahrscheinlich gemeint, dass Unity "klüger" geworden ist, um zu bestimmen, welche der .desktop-Dateien der beste Vertreter für das Anwendungsfenster ist. Daher wird Ihr Skript, das ein Terminalfenster ausführt, durch das Symbol gnome-terminal dargestellt:

enter image description here

Daher täuscht das, was in der Vergangenheit in Ihrem Setup funktioniert hat, einfach ein Startprogramm zu erstellen, Ihr Skript zu starten, Unity nicht mehr vor und wählt das vorhandene Startprogramm gnome-terminal aus, um Ihr Fenster darzustellen.

Die schlechte Lösung

... setzt Unitys Wahl außer Kraft, indem Sie Ihrem Launcher eine Zeile hinzufügen (für 16.04):

StartupWMClass=gnome-terminal-server

enter image description here

... aber dann werden alle Terminalfenster, egal ob sie Ihr Skript ausführen oder nicht, unter diesem Symbol gruppiert.

Darüber hinaus ist das Aufrufen derselben Anwendung im Hauptbefehl bei mehreren .desktop-Dateien im Allgemeinen eine schlechte und unsaubere Praxis.


BEARBEITEN

Wie man (ein) Symbol (e) für ein laufendes Skript (e) hat

Es ist ein bisschen trickreich und trügerisch, aber es ist möglich, ein separates Symbol für mehrere Skripte in verschiedenen Terminalfenstern auszuführen.

Wie es in der Praxis funktioniert

  • Angenommen, Sie haben ein Skript, somscript.sh, das Sie in einem Terminalfenster ausführen möchten und das während der Ausführung im Unity Launcher das zugehörige Symbol anzeigt.
  • Führen Sie den Befehl aus:

    showicon somescript.sh someicon.png
    

    und das Skript wird in einem neu geöffneten gnome-terminal-Fenster ausgeführt, in dem das folgende Symbol angezeigt wird: someicon.png

  • Wenn das Fenster geschlossen ist, wird das Symbol wieder aus dem Launcher entfernt.

Ein Beispiel

  • Ich möchte ein Skript namens /home/jacob/Bureaublad/script.sh ausführen, das im Unity-Launcher mit dem folgenden Symbol angezeigt wird: /home/jacob/Thema/icon/ubu.png Führen Sie den folgenden Befehl aus:

    showicon '/home/jacob/Bureaublad/script.sh' '/home/jacob/Thema/icon/ubu.png'
    

    wird das machen:

    enter image description here

    Nun fügen wir noch einen hinzu:

    showicon '/home/jacob/Bureaublad/script2.sh' '/home/jacob/Thema/icon/banaan.png'
    

    Das Ergebnis:

    enter image description here

    Sobald die Fenster geschlossen sind, werden die Symbole wieder entfernt.

Wie stellt man das ein

  1. Das Skript benötigt wmctrl

    Sudo apt-get install wmctrl
    
  2. Erstellen Sie, falls noch nicht vorhanden, das Verzeichnis ~/bin

  3. Kopieren Sie das folgende Skript in eine leere Datei, speichern Sie es als showicon (keine Erweiterung) in ~/bin und machen Sie es ausführbar
  4. Melden Sie sich ab und wieder an, Ihr Setup sollte funktionieren. Teste es mit dem Befehl

    showicon </path/to/script.sh> </path/to/icon.png>
    

    damit script.sh in einem Terminal ausgeführt wird, wird icon.png im Unity-Launcher angezeigt.

Das Drehbuch

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

terminal = "gnome-terminal"
key = "com.canonical.Unity.Launcher"
script = sys.argv[1]
icon = sys.argv[2]

curr = os.path.dirname(os.path.realpath(__file__))
scriptname = script.split("/")[-1]

def get(command):
    try:
        return subprocess.check_output(command).decode("utf-8")
    except subprocess.CalledProcessError:
        pass

# --- edit Unity launcher section

def current_launcher():
    return eval(get(["gsettings", "get", key, "favorites"]))

def set_launcher(desktopfile, arg):
    curr_launcher = current_launcher()
    last = [i for i, x in enumerate(curr_launcher) if x.startswith("application://")][-1]
    new_icon = "application://"+desktopfile
    if arg == "a":
        if not new_icon in curr_launcher:
            curr_launcher.insert(0, new_icon)
            subprocess.Popen(["gsettings", "set", key,"favorites",str(curr_launcher)])
    Elif arg == "r":
        curr_launcher.remove(new_icon)
        subprocess.Popen(["gsettings", "set", key,"favorites",str(curr_launcher)])

# --- end section

def create_launcher(w, scriptname, icon):
    launcher = ["[Desktop Entry]", "Type=Application",
            "Exec=wmctrl -ia "+w, "Name="+scriptname, "Icon="+icon,
            "StartupNotify=False"]
    with open(l_name, "wt") as newlauncher:
        for l in launcher:
            newlauncher.write(l+"\n")

def getname():
    # create unique launcher name
    n = 1
    while True:
        nm = os.path.join(curr, "scriptlauncher_"+str(n)+".desktop")
        if os.path.exists(nm):
            n += 1
        else:
            break
    return nm    

wlist1 = [l.split()[0] for l in get(["wmctrl", "-l"]).splitlines()]
subprocess.Popen(["gnome-terminal", "-e", script])

while True:
    time.sleep(1)
    wdata = get(["wmctrl", "-l"]).splitlines()
    if wdata:
        try:
            wlist2 = [l.split()[0] for l in wdata]
            w = [w for w in wlist2 if not w in wlist1][0]
        except IndexError:
            pass
        else:
            # check if the new window belongs to the terminal
            if terminal in get(["xprop", "-id", w]):
                # create launcher
                l_name = getname()
                create_launcher(w, scriptname, icon)
                set_launcher(l_name, "a")
                break
    wlist1 = wlist2

while True:
    time.sleep(2)
    wdata = get(["wmctrl", "-l"])
    if wdata:
        if not w in wdata:
            os.remove(l_name)
            set_launcher(l_name, "r")
            break 

Hinweis

  • Was das Symbol bewirkt:

    • Es stellt das Fenster gnome-terminal dar, in dem Ihr Skript ausgeführt wird
    • Wenn Sie darauf klicken, wird das Fenster wie gewohnt geöffnet. Der entsprechende Befehl wird automatisch zum temporären Launcher hinzugefügt:

      wmctrl -ia <window_id>
      
  • Was es macht nicht :

    • Der einzige Nachteil dieser Lösung ist, dass das Symbol links nicht den für das Ausführen von Apps üblichen Pfeil anzeigt, da die Darstellung indirekt ist.

Erläuterung

Ohne zu viel ins Detail zu gehen:

  • Das Skript ist ein Wrapper. Wenn Sie Ihr Skript über showicon starten, führt eine Instanz von showicon Ihr Skript in einem gnome-terminal-Fenster aus, ähnlich wie Terminal=true.
  • Anschließend wartet showicon auf das Erscheinen des neuen Fensters gnome-terminal und liest dessen Fenster-ID.
  • Anschließend wird ein temporärer Starter erstellt, der die Fenster-ID verwendet, um den Befehl zum Aufrufen des Fensters in der Zeile Exec= zu erstellen. Das Symbol, das Sie im Befehl zum Ausführen von showicon als Argument festgelegt haben, wird automatisch als Symbol für diesen temporären Starter festgelegt (in der Zeile Icon= definiert).

    Ein Beispiel für einen solchen automatisch erstellten (temporären) Launcher:

    [Desktop Entry]
    Type=Application
    Exec=wmctrl -ia 0x04400b7f
    Name=script2.sh
    Icon=/home/jacob/Thema/icon/ubu.png
    StartupNotify=False
    
  • Mit dem gleichen Verfahren wie in diese Antwort wird der temporäre Launcher an der obersten Position zum Unity Launcher hinzugefügt, um das ausgeführte Skript darzustellen.

  • In der Zwischenzeit prüft showicon, ob das Fenster vorhanden ist. Wenn nicht (mehr), wird der temporäre Launcher aus dem Unity-Launcher entfernt und überhaupt nicht mehr vorhanden , und die Instanz showicon wird beendet.
5
Jacob Vlijm

Eine andere nicht beantworten, aber Lösung.

Ich verwende Quicklists, um Startprogramme für meine am häufigsten verwendeten Terminalsitzungen zu erstellen. Anschließend erstelle ich Profile für jedes einzelne in gnome-terminal, um beispielsweise die Farben zu ändern. Auf diese Weise lässt sich ganz einfach ermitteln, welchen Server Sie verwenden.

Sie können dies tun, indem Sie Ihre Datei gnome-terminal.desktop in ~/.local/share/applications/gnome-terminal.desktop bearbeiten.

meins sieht so aus

[Desktop Entry]
Name=Terminal
Comment=Use the command line
Keywords=Shell;Prompt;command;commandline;
TryExec=gnome-terminal
Exec=gnome-terminal
Icon=utilities-terminal
Type=Application
X-GNOME-DocPath=gnome-terminal/index.html
X-GNOME-Bugzilla-Bugzilla=GNOME
X-GNOME-Bugzilla-Product=gnome-terminal
X-GNOME-Bugzilla-Component=BugBuddyBugs
X-GNOME-Bugzilla-Version=3.16.2
Categories=GNOME;GTK;System;TerminalEmulator;
StartupNotify=true
X-GNOME-SingleWindow=false
OnlyShowIn=GNOME;Unity;
Actions=New;Item1;Item2
X-Ubuntu-Gettext-Domain=gnome-terminal

[Desktop Action New]
Name=New Terminal
Exec=gnome-terminal
OnlyShowIn=Unity

[Desktop Action Item1]
Name=SSH Shell type 1
Exec=gnome-terminal -e 'ssh item1' --profile 'Item1'
OnlyShowIn=Unity


[Desktop Action Item2]
Name=SSH Shell type 2
Exec=gnome-terminal -e 'ssh item2' --profile 'Item2'
OnlyShowIn=Unity

Ich habe vor einiger Zeit auch ein Skript geschrieben, um das Hinzufügen von Einträgen aus der Hosts-Datei zu Ihrer Quicklist zu automatisieren, damit jeder ssh-Befehl einen Quicklist-Eintrag erhält. Ich habe es geschrieben, als Quicklists nicht automatisch aktualisiert und aufgegeben wurden, weil es dadurch unhandlich wurde. Jetzt können sie sofort über einen Cron-Job ausgeführt werden.

http://blog.amias.net/articles/114

1
Amias

Eine einmalige Korrektur wäre, ein kleines ausführbares Programm zu schreiben, das Ihr Skript ausführt, und der ausführbaren Datei ein eindeutiges Startsymbol zuzuweisen.

0
Michael Clayton