- Add ComboBox for ringtone selection in Call Settings - Convert MKV ringtones to WAV format (Linphone only supports WAV) - Fix ComboSetting to support dialPlan type for international prefix - Disable account devices feature to prevent API errors - Disable automatic update check on startup - Add ringtone fallback to default when custom file not found - Fix ringtone dropdown to not override setting on initialization Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
9.9 KiB
Executable file
Bugfix: Doppelte Buttons in der Anrufdetailansicht
Problem
In der Anrufdetailansicht (CallHistoryLayout) wurden die drei Aktionsbuttons "Anrufen", "Nachricht" und "Videoanruf" nach mehrmaligem Wechseln zwischen Tabs doppelt angezeigt. Sowohl die Icons als auch die Labels erschienen zweimal untereinander.
Symptome
- Buttons erscheinen normal beim ersten Besuch der Anrufe-Seite
- Nach Navigation zu einem anderen Tab (z.B. Kontakte) und Rückkehr zu Anrufe: noch OK
- Nach erneutem Wechsel (2-3 mal): Buttons werden doppelt angezeigt
- Besuch der Einstellungen (als Overlay) und Rückkehr behob das Problem temporär
Betroffene Dateien
Linphone/view/Page/Main/Call/CallPage.qmlLinphone/view/Control/Container/Call/CallHistoryLayout.qmlLinphone/view/Control/Button/LabelButton.qml
Ursachen
1. Nicht bereinigter StackView-Zustand
Die CallPage wird bei Tab-Wechseln durch einen Loader zerstört und neu erstellt. Der rightPanelStackView wurde bei der Neuerstellung nicht bereinigt, was zu Zustandsproblemen führte.
2. Fehlerhafte Größenangaben bei LabelButtons
Die LabelButtons hatten explizite width: 56 und height: 56 Angaben, obwohl der tatsächliche Inhalt (Button 56x56 + Spacing 8 + Text ~20) größer war. Dies führte zu Layout-Inkonsistenzen bei der Neuberechnung.
3. Fehlende Layout-Ausrichtung
Nach Entfernung der expliziten Größen fehlte eine konsistente vertikale Ausrichtung, was zu Verschiebungen des Videoanruf-Buttons führte.
Lösung
CallPage.qml
Component.onCompleted: {
console.log("[CallPage] Created, rightPanelStackView.depth:", rightPanelStackView.depth)
// Ensure clean state on creation
rightPanelStackView.clear()
}
Erklärung: Bei jeder Neuerstellung der CallPage wird der StackView geleert, um einen sauberen Zustand sicherzustellen.
CallHistoryLayout.qml
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72)
visible: !mainItem.isConference
LabelButton {
Layout.alignment: Qt.AlignTop // Hinzugefügt
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.phone
label: qsTr("contact_call_action")
// ... onClick handler
}
// Gleiche Änderung für alle drei LabelButtons
}
Änderungen:
- Entfernt:
width: Utils.getSizeWithScreenRatio(56)undheight: Utils.getSizeWithScreenRatio(56)von allen LabelButtons - Entfernt:
Layout.fillWidth: trueundLayout.preferredHeight: childrenRect.heightvom RowLayout - Hinzugefügt:
Layout.alignment: Qt.AlignTopfür konsistente vertikale Ausrichtung
Technischer Hintergrund
Navigation und Loader-Verhalten
Die CallPage befindet sich in einem Loader mit active: mainStackLayout.currentIndex === 0. Bei Tab-Wechseln:
currentIndexändert sich- Loader wird inaktiv → CallPage wird zerstört
- Bei Rückkehr wird Loader aktiv → Neue CallPage wird erstellt
Im Gegensatz dazu öffnen die Einstellungen als Overlay (contextual menu), ohne die CallPage zu zerstören.
StackView-Verhalten
Der rightPanelStackView verwendet replace() für Übergänge. Bei schneller Neuerstellung und property-Änderungen (durch onSelectedRowHistoryGuiChanged) konnte es zu Race-Conditions kommen, die zu doppelten Einträgen führten.
Test-Szenario
- App starten
- Zu "Anrufe" navigieren
- Einen Anruf in der Liste anklicken (Details werden rechts angezeigt)
- Zu "Kontakte" wechseln
- Zurück zu "Anrufe" wechseln
- Schritte 4-5 mehrmals wiederholen
- Erwartetes Ergebnis: Buttons bleiben korrekt (nicht doppelt, korrekt ausgerichtet)
Datum
2026-02-08
Weitere Bugfixes (2026-02-08)
1. ComboSetting zeigt gespeicherte Werte nicht an
Problem
Die Dropdown-Menüs für Sprache und Akzentfarbe in den Anzeigeeinstellungen zeigten den gespeicherten Wert nicht an. Das erste Element wurde immer angezeigt, auch wenn ein anderer Wert gespeichert war.
Ursache
Die currentIndex-Berechnung verglich das gesamte Model-Entry-Objekt (z.B. {text: "English", value: "en"}) mit dem gespeicherten String-Wert ("en") mit Utils.equalObject(). Dies ergab immer false, da die Typen nicht übereinstimmen.
Lösung
Datei: Linphone/view/Control/Button/Settings/ComboSetting.qml
ComboBox {
id: comboBox
// ...
valueRole: "value"
textRole: "text"
currentIndex: Utils.findIndex(model, function (entry) {
var currentVal = propertyOwnerGui
? propertyOwnerGui.core[mainItem.propertyName]
: propertyOwner[mainItem.propertyName]
// Compare entry.value with the stored value (both are simple strings)
return entry.value === currentVal
})
onCurrentValueChanged: {
var storedVal = propertyOwnerGui
? propertyOwnerGui.core[mainItem.propertyName]
: propertyOwner[mainItem.propertyName]
// currentValue is now just the value string
binding.when = currentValue !== storedVal
}
2. CardDAV Benutzername und Realm werden nicht angezeigt
Problem
In den CardDAV-Einstellungen wurden gespeicherte Werte für Benutzername und Realm nicht in den Textfeldern angezeigt.
Ursache
Das TextField.qml hat einen Windows-Workaround im Component.onCompleted:
Component.onCompleted: {
text = "workaround"
resetText()
}
Die imperative Zuweisung text = "workaround" bricht den deklarativen Binding zu initialText. Wenn der Core-Wert erst nach der Komponentenerstellung verfügbar ist, wird er nicht angezeigt.
Lösung
Datei: Linphone/view/Control/Input/TextField.qml
Component.onCompleted: {
text = "workaround"
// Re-establish binding to initialText after workaround
text = Qt.binding(function() { return initialText })
}
3. Dark Mode Probleme
3a. ComboBox-Popup ist weiß im Dark Mode
Problem: Das Dropdown-Popup der ComboBox hatte einen weißen Hintergrund im Dark Mode.
Ursache: Das Rectangle im Popup-Hintergrund hatte keine color-Eigenschaft.
Lösung:
Datei: Linphone/view/Control/Button/ComboBox.qml
background: Item {
// ...
Rectangle {
id: cboxBg
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(15)
color: DefaultStyle.grey_100 // Hinzugefügt - passt sich Dark Mode an
}
3b. Beschreibungstext schwarz im Dark Mode
Problem: Hinweistexte in den Anzeigeeinstellungen waren schwarz und kaum lesbar im Dark Mode.
Ursache: Tippfehler: main2_500main statt main2_500_main
Lösung:
Datei: Linphone/view/Page/Layout/Settings/DisplaySettingsLayout.qml
color: DefaultStyle.main2_500_main // Korrigiert von main2_500main
3c. Anruffenster hell im Dark Mode
Problem: Das Anruffenster hatte einen weißen Hintergrund im Dark Mode.
Ursache: Die color-Eigenschaft wurde nicht gesetzt (fehlt im Gegensatz zu MainWindow.qml).
Lösung:
Datei: Linphone/view/Page/Window/Call/CallsWindow.qml
AbstractWindow {
id: mainWindow
flags: Qt.Window
color: DefaultStyle.grey_0 // Hinzugefügt
// ...
}
4. ComboSetting unterstützt verschiedene Model-Typen
Problem
Die ComboSetting-Komponente konnte nur mit einem Model-Typ umgehen. Es gibt aber drei verschiedene Typen:
- Audio-Geräte:
QVariantListmit Objekten{id: "...", display_name: "..."} - Einfache Einträge:
QVariantListmit Objekten{text: "...", value: "..."} - Video-Geräte:
QStringListmit einfachen Strings
Symptome
- Audio-Geräte (Lautsprecher, Mikrofon, Klingel) wurden nach Neustart nicht korrekt angezeigt
- Kamera-Dropdown zeigte keine Gerätenamen an (nur leere Einträge)
Lösung
Datei: Linphone/view/Control/Button/Settings/ComboSetting.qml
Die currentIndex-Berechnung, onCurrentIndexChanged und Binding.value wurden erweitert, um alle drei Typen zu erkennen und korrekt zu verarbeiten:
currentIndex: Utils.findIndex(model, function (entry) {
var currentVal = propertyOwnerGui
? propertyOwnerGui.core[mainItem.propertyName]
: propertyOwner[mainItem.propertyName]
// Handle different entry types
if (typeof entry === 'string') {
// QStringList (video devices): compare strings directly
return entry === currentVal
} else if (entry.id !== undefined) {
// Audio devices: compare by id
return currentVal && entry.id === currentVal.id
} else if (entry.value !== undefined) {
// Simple entries (language, color): compare by value
return entry.value === currentVal
}
return false
})
Datei: Linphone/view/Control/Form/Settings/MultimediaSettings.qml
Für die Kamera-ComboBox wurde textRole: "" gesetzt, da QStringList-Models keine Properties haben:
ComboSetting {
id: videoDevicesCbox
entries: SettingsCpp.videoDevices
propertyName: "videoDevice"
propertyOwner: SettingsCpp
textRole: "" // Empty for QStringList models
// ...
}
Technischer Hintergrund
| Model-Typ | Beispiel | Vergleich | Rückgabewert |
|---|---|---|---|
| QStringList | "V4L2: /dev/video0" |
entry === currentVal |
entry (String) |
| Audio-Geräte | {id: "pulse:0", display_name: "Speaker"} |
entry.id === currentVal.id |
entry (Objekt) |
| Einfache Einträge | {text: "English", value: "en"} |
entry.value === currentVal |
entry.value (String) |
Zusammenfassung der geänderten Dateien
| Datei | Änderung |
|---|---|
ComboSetting.qml |
Unterstützung für drei Model-Typen (QStringList, Audio-Geräte, einfache Einträge) |
MultimediaSettings.qml |
textRole: "" für Kamera-ComboBox |
TextField.qml |
Binding nach Windows-Workaround wiederherstellen |
ComboBox.qml |
Popup-Hintergrundfarbe für Dark Mode |
DisplaySettingsLayout.qml |
Tippfehler bei Farbname korrigiert |
CallsWindow.qml |
Window-Hintergrundfarbe für Dark Mode |