Le transfert de la queue de lecture entre renderers était corrompu car le binding de playlist était réinitialisé, effaçant les items transférés. Correction en transférant directement le binding sans déclencher de rafraîchissement, préservant ainsi le current_index et la position de lecture. - Fichiers modifiés : pmocontrol/src/control_point.rs - Version mise à jour : 0.3.7
3.4 KiB
Bug: Transfert de Queue entre Renderers
Date: 2026-01-17
Fichier principal: pmocontrol/src/control_point.rs
Fonction affectée: transfer_queue()
Symptôme
Le transfert de la queue de lecture d'un renderer vers un autre ne fonctionnait plus correctement, avec des comportements erratiques. La queue transférée était écrasée et le current_index perdu.
Cause Racine
Dans transfer_queue() (lignes 1192-1291), lorsqu'un binding de playlist existait sur le renderer source, le code appelait attach_queue_to_playlist() sur la destination après avoir rempli la queue.
Problème: attach_queue_to_playlist_internal() effectue les opérations suivantes:
clear_for_playlist_attach()- efface la queue du rendererclear_queue()- efface la queue localerefresh_attached_queue_for()- browse le serveur et remplace la queue
Cela écrasait complètement les items qu'on venait de transférer avec replace_queue().
Séquence problématique (avant correction)
1. source_snapshot = get_renderer_queue_snapshot(source) // items + current_index
2. clear_renderer_queue(dest)
3. dest.replace_queue(source_snapshot.items, current_index) // Queue remplie ✓
4. attach_queue_to_playlist(dest, server, container) // ÉCRASE TOUT ✗
└─> clear_for_playlist_attach()
└─> clear_queue()
└─> refresh_attached_queue_for() → browse serveur → replace queue
5. play() sur destination avec mauvaise queue
Correction Appliquée
Remplacement de l'appel attach_queue_to_playlist() par un transfert direct du binding sans déclencher de refresh:
// AVANT (problématique)
if let Some((server_id, container_id, _)) = source_binding {
self.attach_queue_to_playlist(dest_renderer_id, server_id, container_id)?;
}
// APRÈS (corrigé)
if let Some((server_id, container_id, has_seen_update)) = source_binding.clone() {
let binding = PlaylistBinding {
server_id,
container_id,
has_seen_update,
pending_refresh: false, // Pas de refresh immédiat
auto_play_on_refresh: false,
};
dest_renderer.set_playlist_binding(Some(binding));
}
Séquence corrigée
1. source_snapshot = get_renderer_queue_snapshot(source)
2. clear_renderer_queue(dest)
3. dest.replace_queue(source_snapshot.items, current_index) // Queue remplie ✓
4. dest.set_playlist_binding(binding avec pending_refresh=false) // Binding transféré ✓
5. play() sur destination avec bonne queue ✓
Événements
L'analyse a également confirmé que les émissions d'événements sont correctes:
| Méthode | Événement émis |
|---|---|
replace_queue() |
QueueUpdated ✓ |
enqueue_items() |
QueueUpdated ✓ |
clear_queue() |
QueueUpdated ✓ |
set_playlist_binding() |
BindingChanged ✓ |
clear_playlist_binding() |
BindingChanged ✓ |
Le problème de lenteur UI mentionné était probablement lié au fait que la queue était écrasée puis re-remplie, causant plusieurs événements successifs et une confusion dans l'état affiché.
Impact
- Transfert de queue fonctionnel à nouveau
- Préservation du current_index lors du transfert
- Binding de playlist correctement transféré sans perte de synchronisation
- UI réactive car un seul cycle d'événements cohérent
Fichiers Modifiés
pmocontrol/src/control_point.rs: Modification detransfer_queue()lignes 1223-1244