Как я могу дать скрипту свою собственную иконку в Unity launcher?

5

С Ubuntu 16.04, если вы создаете launcher (файл рабочего стола в ~/.local/share/applications ) с пользовательским значком для приложения терминала (так что с Terminal=true ), то при его запуске он создаст новый значок стандартного терминала, и ваш пользовательский значок будет пульсировать и исчезать в течение нескольких секунд.

В 14.04 он просто работал, как ожидалось. (он не запустит новый стандартный значок терминала).

Любая идея, что делать, чтобы изменить это поведение? У меня есть несколько терминальных приложений, которые я хочу запустить из единства, и новое поведение проблематично (я теряю след, из-за которого все они заканчиваются стандартной иконкой терминала) ...

    
задан Se6 20.06.2016 в 11:44
источник

3 ответа

4

Почему это не работает, как вы делаете

Как указано в комментарии, приложение в принципе может быть представлено только одним значком в панели запуска за раз . Это всегда было так.

Что вы имеете в виду, вероятно, что Unity стал «умнее» в определении того, какой из файлов .desktop является лучшим представителем для окна приложения. Поэтому ваш скрипт, запускающий терминальное окно, будет представлен gnome-terminal -icon:

Следовательно, то, что работало в прошлом в вашей настройке, просто создавая пусковую установку, начиная ваш скрипт, больше не обманывает Unity и выбирает существующую консольную консоль gnome-terminal для представления вашего окна.

Плохое решение

... заключается в том, чтобы отменить выбор Unity, добавив строку в вашу пусковую установку (для 16.04):

StartupWMClass=gnome-terminal-server

... но затем all , независимо от того, запускают ли они ваш скрипт или нет, сгруппированы под этим значком.

Кроме того, в общем случае наличие нескольких файлов .desktop , вызывающих одно и то же приложение в их основной команде, является плохой, нечистой практикой.

ИЗМЕНИТЬ

Как иметь (a) отдельные значки для запуска сценариев

Требуется немного обмана и обмана, но может иметь отдельный значок для нескольких сценариев, работающих в разных терминальных окнах.

Как это работает на практике

  • Скажем, у вас есть скрипт somscript.sh , который вы хотите запустить в окне терминала, показывая его выделенный значок в Unity Launcher во время его запуска.
  • Запустите команду:

    showicon somescript.sh someicon.png
    

    , и скрипт будет запущен внутри вновь открытого окна gnome-terminal , показывая значок: someicon.png

  • Если окно закрыто, значок снова удаляется из панели запуска.

Пример

  • Мне нужен скрипт, /home/jacob/Bureaublad/script.sh , run, показывающий в Unity launcher со значком: /home/jacob/Thema/icon/ubu.png Выполнение команды:

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

    сделает это:

    Теперь добавим еще один:

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

    Результат:

    После закрытия окон значок (и) снова удаляется.

Как настроить

  1. Скрипт нуждается в wmctrl

    sudo apt-get install wmctrl
    
  2. Создайте, если он еще не существует, каталог ~/bin

  3. Скопируйте сценарий ниже в пустой файл, сохраните его как showicon (без расширения) в ~/bin и сделайте его выполнимым
  4. Выйдите из системы и вернитесь, ваша настройка должна работать. Протестируйте его командой

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

    , чтобы script.sh работал в терминале, показывая icon.png в пусковой установке Unity.

Скрипт

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

Примечание

  • Что делает значок:

    • Он представляет окно gnome-terminal , запускающее ваш скрипт
    • При щелчке по нему он поднимает окно, как обычно. Команда для этого автоматически добавляется во временную пусковую установку:

      wmctrl -ia <window_id>
      
  • Что он делает not :

    • Единственным недостатком этого решения является то, что значок не показывает обычную стрелку слева для запуска приложений, поскольку представление является косвенным.

Объяснение

Не вдаваясь в подробности:

  • Скрипт - это оболочка. Если вы запускаете свой скрипт через showicon , экземпляр showicon запускает ваш скрипт в окне gnome-terminal , аналогично Terminal=true .
  • Впоследствии showicon ожидает появления нового окна gnome-terminal и считывает его идентификатор окна.
  • Затем создается временная пусковая установка, используя идентификатор окна, чтобы создать команду для подъема окна в строке Exec= . Значок, который вы задали как аргумент в команде для запуска showicon , автоматически устанавливается как значок этой временной пусковой установки (определен в строке Icon= ).

    пример такого автоматически созданного (временного) запуска:

    [Desktop Entry]
    Type=Application
    Exec=wmctrl -ia 0x04400b7f
    Name=script2.sh
    Icon=/home/jacob/Thema/icon/ubu.png
    StartupNotify=False
    
  • Используя ту же процедуру, что и в этом ответе , временная пусковая установка добавляется в Unity Launcher, в верхней позиции, чтобы представить ваш исполняемый скрипт.

  • Тем временем showicon проверяет существование окна. Если нет (больше), временная пусковая установка удаляется из пусковой установки Unity и вообще удаляется из , а экземпляр showicon завершается.
ответ дан Jacob Vlijm 21.06.2016 в 12:47
источник
1

Другой не ответ, а решение.

Я использую quicklists для создания пусковых установок для моих наиболее часто используемых терминальных сеансов, затем создаю профили для каждого из них в gnome-терминале, чтобы делать что-то вроде изменения их цветов, поэтому очень легко узнать, какой сервер вы используете.

Вы можете сделать это, отредактировав файл gnome-terminal.desktop в ~ / .local / share / applications / gnome-terminal.desktop.

моя выглядит так

[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

Я также написал сценарий некоторое время назад, чтобы автоматизировать добавление записей в ваш быстрый список из файла hosts, поэтому любая команда ssh получает запись быстрого списка. Я написал это, когда списки быстрого доступа не обновлялись автоматически и не сдавались, потому что это сделало его неуклюжим, теперь они мгновенно запускаются через работу cron.

Ссылка

    
ответ дан Amias 21.06.2016 в 13:04
0

Однократное исправление будет заключаться в том, чтобы написать небольшую исполняемую программу, которая запускает ваш скрипт, и присваивать исполняемому файлу уникальный значок запуска.

    
ответ дан Michael Clayton 28.06.2016 в 03:06