linux.x86.linphone/BUGFIX_DOUBLE_BUTTONS.md
data ae94b325b1 Fix: Multiple UI bugs - settings display, dark mode, double buttons
- ComboSetting: Fix saved values not showing for language/accent color
  - Add valueRole/textRole and fix comparison logic

- TextField: Fix CardDAV username/realm not displaying when saved
  - Re-establish Qt.binding after Windows password workaround

- Dark Mode fixes:
  - ComboBox popup: Add background color for dark mode
  - DisplaySettingsLayout: Fix typo main2_500main -> main2_500_main
  - CallsWindow: Add window background color for dark mode

- Double buttons fix:
  - CallPage: Clear rightPanelStackView on component creation
  - CallHistoryLayout: Remove explicit sizes, add Layout.alignment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-08 07:19:07 +01:00

213 lines
7.5 KiB
Markdown

# 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.qml`
- `Linphone/view/Control/Container/Call/CallHistoryLayout.qml`
- `Linphone/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
```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
```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)` und `height: Utils.getSizeWithScreenRatio(56)` von allen LabelButtons
- Entfernt: `Layout.fillWidth: true` und `Layout.preferredHeight: childrenRect.height` vom RowLayout
- Hinzugefügt: `Layout.alignment: Qt.AlignTop` fü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:
1. `currentIndex` ändert sich
2. Loader wird inaktiv → CallPage wird zerstört
3. 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
1. App starten
2. Zu "Anrufe" navigieren
3. Einen Anruf in der Liste anklicken (Details werden rechts angezeigt)
4. Zu "Kontakte" wechseln
5. Zurück zu "Anrufe" wechseln
6. Schritte 4-5 mehrmals wiederholen
7. **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`
```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`:
```qml
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`
```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`
```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`
```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`
```qml
AbstractWindow {
id: mainWindow
flags: Qt.Window
color: DefaultStyle.grey_0 // Hinzugefügt
// ...
}
```
## Zusammenfassung der geänderten Dateien
| Datei | Änderung |
|-------|----------|
| `ComboSetting.qml` | valueRole/textRole und korrekter Wertvergleich |
| `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 |