Добавьте меняющийся значок на панель Ubuntu

Каким будет самый простой способ добавления и изменения значка на панели Ubuntu (Gnome)? Я ищу что-то столь же простое, как сценарии оболочки, но я не ограничиваюсь этим. Напишу для него программу, если это лучший или более простой подход.

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


person Ilari Kajaste    schedule 18.11.2009    source источник


Ответы (3)


Один из простых способов — сделать это на Python. См., например, этот сообщение в блоге.

person dottedmag    schedule 18.11.2009
comment
Было бы неплохо, если бы пример действительно был включен в пост, а не оставлен во внешней ссылке (которая сейчас мертва). К сожалению, этот ответ сейчас почти бесполезен. :( - person Thor84no; 13.08.2012
comment
Решение Python подробно обсуждается в ответах на этот вопрос. - person Communicative Algebra; 05.12.2015

Я нашел YAD (еще один диалог), чтобы найти самое простое решение. См. краткое описание webupd8. Однако на данный момент интеграция с Unity немного нарушена. Ниже я упоминаю об обходном пути, но если вам действительно небезразлична Unity, вам, вероятно, следует взглянуть на другие ответы.

Примечание. Хотя я считаю, что YAD работает в широком диапазоне сред, я тестировал приведенные ниже инструкции только на Lubuntu 15.10 (рабочий стол LXDE) и Ubuntu 14.04 (рабочий стол Unity).

Установка

Я получил рабочую установку с:

sudo apt-add-repository ppa:webupd8team/y-ppa-manager 
sudo apt-get update
sudo apt-get install yad

(На самом деле мне не нужны были первые две строки в Lubuntu 15.10, но это могло быть совпадением.)
В LXDE вызов

yad --notification --listen

затем появился значок в трее, который я мог изменить, набрав (например): icon:gtk-help. В Unity ничего не появилось, поэтому мне понадобилось следующее…

Обходной путь для Unity: следующие инструкции снова взяты из webupd8. Проблема в том, что «системный трей» больше официально не существует в Unity. Одним из возможных решений для запуска таких программ, как YAD, которые не догнали это изменение, является установка «эмулятора панели задач»:

sudo apt-add-repository ppa:fixnix/indicator-systemtray-unity
sudo apt-get update
sudo apt-get install indicator-systemtray-unity

Для получения иконок прямо в панели Unity я использовал следующие настройки:

gsettings set net.launchpad.indicator.systemtray tray-is-static true
gsettings set net.launchpad.indicator.systemtray show-background-static false

Как только я выходил из системы и снова входил в нее, yad --notification работал, как и ожидалось. (Более того, в «системном трее» отображались некоторые дополнительные значки, которые я ранее тщетно искал.) Положение значков на панели можно изменить с помощью:

gsettings set net.launchpad.indicator.systemtray static-x 1500

(где 1500 можно заменить любым разумным значением). Я не знаю, как сделать так, чтобы значки отображались заподлицо. Если вам когда-нибудь захочется снова удалить «эмулятор системного лотка», webupd8 рекомендует:

sudo apt-get purge indicator-systemtray-unity

Демо

Вот упрощенная демонстрация, которая может помочь проиллюстрировать, как использовать YAD в реальных сценариях. Я предполагаю, что сам YAD уже установлен, как описано выше. Предположим, мы хотим просмотреть вывод какой-либо программы, работающей в командной строке, и соответствующим образом обновить значок в трее. Для целей этой демонстрации давайте просто возьмем эту «программу» как следующий скрипт «dummyprogram.sh»:

#! /bin/bash
i=1
while [ $i -ne 3 ]
do
  let "i=((i+1)%2)"
echo $i
  sleep 1
done

Скопировав приведенные выше строки в файл «dummyprogram.sh», сделав его исполняемым с помощью «chmod +x dummyprogram.sh» и вызвав «./dummyprogram.sh», вы получите следующий результат:

0
1
0
1
...

(одна строка каждую секунду). Теперь о самой задаче. Чтобы получить «иконизированную» версию вышеуказанного вывода в области трея, мы используем следующий скрипт «demo.sh»:

#! /bin/bash
while read x
do
  if  [ $x -eq 0 ]
  then
    echo icon:gtk-home
  else
    echo icon:gtk-help
  fi
done

Снова скопируйте строки в файл "demo.sh" и сделайте его исполняемым. Вызов

./dummyprogram.sh | ./demo.sh | yad --notification --listen

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

Вы можете закончить демонстрацию, набрав Ctrl-C в терминале.

person Communicative Algebra    schedule 04.12.2015

Для тех, кто заботится о Unity, в настоящее время может не существовать простого решения. Так что, возможно, написание пользовательского скрипта Python, использующего AppIndicator-API Unity, — это действительно правильный путь. В Интернете уже есть много примеров этого, но мне все же потребовалось немало усилий, чтобы создать сценарий, который реализует примерно ту же функциональность, что и решение с использованием YAD, описанное в моем другом ответе: скрипт, который будет прослушивать выходные данные программы и соответствующим образом обновлять "значок в трее". Вот мое решение:

#!/usr/bin/python
import os, threading, signal
from subprocess import Popen, PIPE, STDOUT
from gi.repository import Gtk
from gi.repository import AppIndicator3 as AppIndicator

class my_indicator:
    ICON_0 = "gtk-home" 
    ICON_1 = "gtk-help"       

    def __init__(self, wrapper):
        self.ind = AppIndicator.Indicator.new("my-app-indicator", Gtk.STOCK_INFO, AppIndicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind.set_status(AppIndicator.IndicatorStatus.ACTIVE)
        self.wrapper = wrapper
        self.build_menu()

    def build_menu(self):
        item_quit = Gtk.MenuItem('Quit')
        item_quit.connect('activate', self.wrapper.quit)
        menu = Gtk.Menu()
        self.ind.set_menu(menu)
        menu.append(item_quit)
        menu.show_all()

    def update_icon(self,icon):
        self.ind.set_icon(icon)

class dummy_wrapper:
    PROGRAM = "./dummyprogram.sh"

    def __init__(self):
        self.indicator = my_indicator(self)

    def main(self):
        self.process = Popen(self.PROGRAM, stdout=PIPE, stderr=STDOUT, close_fds=True, shell=True, preexec_fn=os.setsid)
        self.thread = threading.Thread(target=self.watch_pipe, args=(self.process.stdout,self.indicator))
        self.thread.daemon = True
        self.thread.start() 
        Gtk.main()

    def quit(self, source):
        if self.process:
            os.killpg(self.process.pid, signal.SIGTERM)               
        if self.thread:
            self.thread.join() 
        Gtk.main_quit()

    @staticmethod
    def watch_pipe(pipe, indicator): 
        while 1:  
            line = pipe.readline().strip() 
            # The thread waits here until a line appears in the pipe.
            if not line: 
                # This happens exactly once, namely when the process ends.
                break
            else:
                print line
                if line=="0": 
                    indicator.update_icon(my_indicator.ICON_0)
                else:
                    indicator.update_icon(my_indicator.ICON_1)  

dummy_wrapper().main()

Несколько кратких замечаний по коду:

Демонстрация: вставьте приведенный выше код в файл my-indicator.py и сделайте его исполняемым с помощью chmod +x my-indicator.py. Сделайте то же самое для файла dummy-programm.sh, описанного в мом ответе, предлагающем YAD. Вызовите ./my-indicator.py, и вы должны увидеть значок на панели Unity, который каждую секунду переключается между двумя разными значками. (Это должно также работать на рабочих столах gnome и KDE, если установлена ​​библиотека индикаторов приложений Ubuntu.)

person Communicative Algebra    schedule 12.12.2015