O ícone do indicador de aplicativo não muda até ser clicado

2

Eu tenho um indicador de aplicativo que mostra a fase / orientação da lua como seu ícone (junto com um rótulo de texto). Quando o indicador faz uma atualização (várias vezes por hora), o ícone é recriado (como um arquivo SVG) e, portanto, o ícone muda com o tempo.

Recentemente, o ícone não mostra nenhuma alteração, a menos que eu clique no ícone (ou rótulo). Eu estou no Ubuntu 14.04 64 bit e meu indicador usa Python 3 e Appindicator3.

O código abaixo é representativo do problema e mostra um ícone que deve mudar a cada três segundos (fiz o intervalo de três segundos para ver o problema rapidamente - na realidade, o ícone muda no máximo por hora). O ícone em si é um arquivo SVG e mostra uma contagem numérica, começando do zero e incrementando a cada três segundos.

Eu testei no Ubuntu 12.04 e no Xubuntu 12.04 (via VirtualBox) e o ícone muda a cada três segundos de atualização.

Teste no Ubuntu 14.04, o ícone NÃO muda, A MENOS QUE eu clique nele. Se eu alterar o texto da etiqueta em cada atualização, o ícone também será alterado, mas somente se eu não repetir o mesmo texto da etiqueta.

Alguém pode confirmar isso, por favor? Não consigo encontrar um relatório de bug e a API do Python AppIndicator não está mais disponível, por isso não posso dizer se algo foi alterado ou obsoleto.

#!/usr/bin/env python3


try: from gi.repository import AppIndicator3
except: pass

from gi.repository import GLib, Gtk

import os


class IndicatorTestIcon:

    NAME = "indicator-test-icon"
    SVG_ICON = "." + NAME
    SVG_FILE = os.getenv( "HOME" ) + "/" + SVG_ICON + ".svg"


    def __init__( self ):
        self.count = 0

        self.indicator = AppIndicator3.Indicator.new( IndicatorTestIcon.NAME, "", AppIndicator3.IndicatorCategory.APPLICATION_STATUS )
        self.indicator.set_icon_theme_path( os.getenv( "HOME" ) )
        self.indicator.set_status( AppIndicator3.IndicatorStatus.ACTIVE )


    def main( self ):
        self.update()
        GLib.timeout_add_seconds( 3, self.update )
        Gtk.main()


    def update( self ):
        self.buildMenu()

        self.createIcon()

        self.indicator.set_icon( IndicatorTestIcon.SVG_ICON )

        #        self.indicator.set_label( "static label", "" ) # Using a static label, the icon does not change unless clicked with the mouse.
        self.indicator.set_label( str( self.count ), "" ) # Using a dynamic label (which does not repeat) DOES change the icon.

        self.count += 1

        return True


    def buildMenu( self ):
        menu = Gtk.Menu()

        quitMenuItem = Gtk.ImageMenuItem.new_from_stock( Gtk.STOCK_QUIT, None )
        quitMenuItem.connect( "activate", Gtk.main_quit )
        menu.append( quitMenuItem )

        self.indicator.set_menu( menu )
        menu.show_all()


    def createIcon( self ):
        header = '<?xml version="1.0" standalone="no"?>' \
            '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' \
            '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100">'

        text = '<g>' \
            '<text x="0" y="75" font-family="Verdana" font-size="100" fill="white" >' + str( self.count ) + '</text>' \
            '</g>'

        footer = '</svg>'

        with open( IndicatorTestIcon.SVG_FILE, "w" ) as f:
            f.write( header + text + footer )
            f.close()


if __name__ == "__main__": IndicatorTestIcon().main()

FYI: Enviou um relatório de bug link

    
por Bernmeister 02.07.2014 / 07:09

2 respostas

0

Após testar vários cenários, a solução mais simples (além do próprio bug sendo corrigido, supondo que seja um bug) é alternar a nomeação do arquivo de ícone para frente e para trás ...

#!/usr/bin/env python3


from gi.repository import AppIndicator3, GLib, Gtk

import glob, os


class IndicatorTestIcon:

    NAME = "indicator-test-icon"
    ICON_STATE = True


    def __init__( self ):
        self.count = 0

        for file in glob.glob( os.getenv( "HOME" ) + "/." + IndicatorTestIcon.NAME + "*.svg" ):
            print(file)
            os.remove( file )

        self.indicator = AppIndicator3.Indicator.new( IndicatorTestIcon.NAME, "", AppIndicator3.IndicatorCategory.APPLICATION_STATUS )
        self.indicator.set_icon_theme_path( os.getenv( "HOME" ) )
        self.indicator.set_status( AppIndicator3.IndicatorStatus.ACTIVE )


    def main( self ):
        self.update()
        GLib.timeout_add_seconds( 3, self.update )
        Gtk.main()


    def update( self ):

        print( self.count )
        self.buildMenu()

        self.createIcon()

        self.indicator.set_label( "static label", "" )
        self.indicator.set_icon_full( self.getIconName(), "" )

        self.count += 1

        self.toggleIconState()
        return True


    def buildMenu( self ):
        menu = Gtk.Menu()

        quitMenuItem = Gtk.ImageMenuItem.new_from_stock( Gtk.STOCK_QUIT, None )
        quitMenuItem.connect( "activate", Gtk.main_quit )
        menu.append( quitMenuItem )

        self.indicator.set_menu( menu )
        menu.show_all()


    def createIcon( self ):
        header = '<?xml version="1.0" standalone="no"?>' \
            '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' \
            '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100">'

        text = '<g>' \
            '<text x="0" y="75" font-family="Verdana" font-size="100" fill="white" >' + str( self.count ) + '</text>' \
            '</g>'

        footer = '</svg>'

        with open( self.getIconFile(), "w" ) as f:
            f.write( header + text + footer )
            f.close()


    def getIconName( self ):
        if IndicatorTestIcon.ICON_STATE: return "." + IndicatorTestIcon.NAME + "-1"

        return "." + IndicatorTestIcon.NAME + "-2"


    def getIconFile( self ):
        if IndicatorTestIcon.ICON_STATE: return os.getenv( "HOME" ) + "/." + IndicatorTestIcon.NAME + "-1.svg"

        return os.getenv( "HOME" ) + "/." + IndicatorTestIcon.NAME + "-2.svg"


    def toggleIconState( self ): IndicatorTestIcon.ICON_STATE = not IndicatorTestIcon.ICON_STATE


if __name__ == "__main__": IndicatorTestIcon().main()
    
por Bernmeister 06.07.2014 / 10:14
1

Acho que isso é razoável, como caminho do tema & nome do ícone não mudou, não haverá atualização / recarga para o ícone do indicador (por que deve perder alguns ciclos para recarregá-lo? Isso é ótimo, não ?!).

Bem, libappindicator foi projetado para ícones estáticos carregados de arquivos. ( lp bug # 812067: API necessária: suporte ao ajuste de ícones pixbuf ). Você quer fazer uma solução para isso alterando o conteúdo do arquivo de ícone. No seu caso está ok, mas não para uso geral, onde ele precisa de um atraso de atualização mais curto (ex: 120ms), ou seja, solicitações de arquivo io em excesso (abrir, escrever, fechar).

  • Ou você muda o caminho do tema, isso é um truque:

    self.indicator.set_icon_theme_path( os.getenv( "HOME" )+"./"*(self.count % 2) )
    self.indicator.set_icon_full( IndicatorTestIcon.SVG_ICON, str( self.count ) )
    
  • Ou altere o nome (você pode usar o mesmo método anterior, alternando entre 2 nomes):

    SVG_ICON = "." + NAME+ "_{0}"
    ...
    self.indicator.set_icon_full( IndicatorTestIcon.SVG_ICON.format(self.count % 2) , str( self.count ) )
    ...
    with open( IndicatorTestIcon.SVG_FILE.format(self.count % 2), "w" ) as f:
    

BTW, é melhor usar set_icon_full , set_icon está obsoleto. (Testado no Ubuntu 14.04)

    
por user.dz 04.07.2014 / 06:51