OpenWave 0.1.1
Refactoring realizado sobre
app.py(versão 0.1).
Bugs corrigidos
1. Gst.init(None) chamado duas vezes
Arquivo: app.py — bloco if __name__ == "__main__"
O GStreamer era inicializado em _init_gstreamer() e novamente no ponto de entrada. A segunda chamada é um no-op silencioso, mas pode causar avisos em certas versões do GStreamer e indica descuido na ordem de inicialização.
Fix: removida a chamada redundante do bloco __main__.
2. stop_playback deixava o pipeline GStreamer em estado inconsistente
Arquivo: app.py — método stop_playback
O método usava Gst.State.PAUSED para "parar" a reprodução. Isso mantinha o pipeline alocado (decodificadores, buffers, handle de arquivo), consumindo recursos desnecessariamente e causando comportamento imprevisível ao retomar outra faixa.
Fix: trocado para Gst.State.NULL, que libera o pipeline completamente. Adicionados reset visual da barra de progresso e do tempo atual.
3. Timer de progresso acumulava instâncias a cada faixa
Arquivo: app.py — método play_track
O timer criado com GLib.timeout_add(1000, update_progress) nunca era cancelado antes de iniciar uma nova faixa. Após tocar N faixas, N timers rodavam em paralelo, todos chamando update_progress a cada segundo — causando contenção, glitches de UI e uso de CPU crescente.
Fix: adicionado helper _cancel_progress_timer() chamado no início de play_track, em stop_playback e em on_error.
4. on_error não limpava o estado de reprodução
Arquivo: app.py — método on_error
Ao receber um erro do GStreamer, o método atualizava o ícone play/pause mas não cancelava o timer de progresso, não resetava current_track_path e não resetava a barra de progresso. A UI ficava mostrando a última posição conhecida e novos cliques em "próxima" podiam tentar retomar a faixa com erro.
Fix: on_error agora chama _cancel_progress_timer(), zera current_track_path, reseta progresso e tempo para 00:00.
5. empty_label sempre visível após inicialização com biblioteca carregada
Arquivo: app.py — método __init__
A sequência era: _apply_track_view() (que define empty_label.set_visible(False) quando há faixas) → show_all() (que força todos os widgets para visíveis) → empty_label.set_visible(True) (hardcoded). O resultado: o label "Abra uma pasta para ver suas músicas" aparecia sobreposto à lista mesmo com a biblioteca carregada.
Fix: a última linha foi substituída por set_visible(not has_tracks), baseado no estado real da biblioteca.
6. on_artists_tree_selection_changed referenciada mas nunca definida
Arquivo: app.py — método _sidebar_tree_section
O método conectava o sinal changed da seleção de um TreeView ao handler self.on_artists_tree_selection_changed, que não existe em lugar nenhum na classe. Qualquer código que chegasse a instanciar esse widget resultaria em AttributeError em runtime.
Fix: _sidebar_tree_section (e _build_artist_tree_model, que a alimentava) eram código completamente morto — nunca chamados. Ambos foram removidos.
Redundâncias eliminadas
| Elemento removido | Motivo |
|---|---|
| pretty_album_name() | Sempre retornava o argumento album sem transformação real; inlinado em read_audio_metadata |
| format_time(ns) | Wrapper de 2 linhas sobre format_time_from_seconds; callers atualizados para pos / Gst.SECOND |
| _set_cover_from_tag_bytes() | Wrapper de 2 linhas sobre _load_cover_from_bytes, nunca chamada em lugar nenhum |
| _build_artist_tree_model() | 50 linhas de código morto (nunca chamada) |
| _sidebar_tree_section() | 45 linhas de código morto (nunca chamada) |
| show_all() em main | Redundante; OpenWave.init já chama self.show_all() |
| Chamada dupla a _refresh_album_browser em _apply_track_view | Já era feita por _select_sidebar_row_for_view na mesma sequência de chamadas |
| 4× hasattr(self, "album_selector") | Widget sempre existe após _build_ui; guards mascaravam bugs em vez de proteger |
| Linhas em branco duplicadas em vários métodos | Estilo |