Fix focus on first relevant element after changing page with navbar #LINQT-2202

This commit is contained in:
Alexandre Jörgensen 2025-12-29 16:21:29 +01:00
parent 1902fe3029
commit 5cc331ceb3
6 changed files with 82 additions and 0 deletions

View file

@ -18,6 +18,9 @@ Control.TabBar {
property AccountGui defaultAccount
property int visibleCount: 0
signal enterPressed()
signal spacePressed()
// Call it after model is ready. If done before, Repeater will not be updated
function initButtons(){
@ -97,6 +100,8 @@ Control.TabBar {
onVisibleChanged: mainItem.updateVisibleCount()
text: modelData.accessibilityLabel
property bool keyboardFocus: FocusHelper.keyboardFocus
focusPolicy: Qt.StrongFocus
activeFocusOnTab: true
UnreadNotification {
unread: !defaultAccount
? -1
@ -165,6 +170,13 @@ Control.TabBar {
mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize)
}
}
Keys.onPressed: event => {
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
mainItem.enterPressed()
} else if(event.key === Qt.Key_Space){
mainItem.spacePressed()
}
}
onClicked: {
mainItem.setCurrentIndex(TabBar.index)
}

View file

@ -14,6 +14,7 @@ Item {
id: mainItem
property var callObj
property var contextualMenuOpenedComponent: undefined
property bool focusPageOnNextLoad: false // Focus the page on next load - usefull cause of loader
signal addAccountRequest
signal openNewCallRequest
@ -185,6 +186,18 @@ Item {
mainStackView.currentItem.forceActiveFocus();
}
}
/**
* Focus the page when user select the page with keyboard.
* Do not add this behavior on the arrows
*/
onEnterPressed: {
focusPageOnNextLoad = true
}
onSpacePressed: {
focusPageOnNextLoad = true
}
Component.onCompleted: {
if (SettingsCpp.shortcutCount > 0) {
var shortcuts = SettingsCpp.shortcuts;
@ -616,6 +629,10 @@ Item {
openContextualMenuComponent(page);
}
}
onLoaded: {
if(focusPageOnNextLoad) item.forceActiveFocus(Qt.TabFocusReason)
focusPageOnNextLoad = false
}
}
Loader {
active: mainStackLayout.currentIndex === 1
@ -631,6 +648,10 @@ Item {
}
}
}
onLoaded: {
if(focusPageOnNextLoad) item.forceActiveFocus(Qt.TabFocusReason)
focusPageOnNextLoad = false
}
}
Loader {
active: mainStackLayout.currentIndex === 2
@ -649,6 +670,10 @@ Item {
}
}
}
onLoaded: {
if(focusPageOnNextLoad) item.forceActiveFocus(Qt.TabFocusReason)
focusPageOnNextLoad = false
}
}
Loader {
@ -665,6 +690,10 @@ Item {
}
}
}
onLoaded: {
if(focusPageOnNextLoad) item.forceActiveFocus(Qt.TabFocusReason)
focusPageOnNextLoad = false
}
}
}

View file

@ -24,6 +24,14 @@ AbstractMainPage {
goToCallHistory()
}
/**
* Focus on the first pertinent element in the page (LINQT-2202)
* @override
*/
function forceActiveFocus(reason = undefined){
listStackView.currentItem?.newCallButton?.forceActiveFocus(reason)
}
//Group call properties
property ConferenceInfoGui confInfoGui
property AccountProxy accounts: AccountProxy {
@ -135,6 +143,8 @@ AbstractMainPage {
FocusScope {
objectName: "historyListItem"
property alias listView: historyListView
property alias newCallButton: newCallButton
ColumnLayout {
anchors.fill: parent
spacing: 0
@ -187,6 +197,7 @@ AbstractMainPage {
}
Button {
id: newCallButton
focus: true
style: ButtonStyle.noBackground
icon.source: AppIcons.newCall
Layout.preferredWidth: Utils.getSizeWithScreenRatio(34)

View file

@ -16,6 +16,14 @@ AbstractMainPage {
emptyListText: qsTr("chat_empty_title")
newItemIconSource: AppIcons.plusCircle
/**
* Focus on the first pertinent element in the page (LINQT-2202)
* @override
*/
function forceActiveFocus(reason = undefined){
listStackView.currentItem?.newChatButton?.forceActiveFocus(reason)
}
property AccountProxy accounts: AccountProxy {
id: accountProxy
sourceModel: AppCpp.accounts
@ -117,6 +125,7 @@ AbstractMainPage {
FocusScope {
objectName: "chatListItem"
property alias listView: chatListView
property alias newChatButton: newChatButton
ColumnLayout {
anchors.fill: parent
spacing: 0
@ -158,6 +167,7 @@ AbstractMainPage {
}
Button {
id: newChatButton
focus: true
style: ButtonStyle.noBackground
icon.source: AppIcons.plusCircle
Layout.preferredWidth: Utils.getSizeWithScreenRatio(28)

View file

@ -17,6 +17,14 @@ AbstractMainPage {
emptyListText: qsTr("contacts_list_empty")
newItemIconSource: AppIcons.plusCircle
/**
* Focus on the first pertinent element in the page (LINQT-2202)
* @override
*/
function forceActiveFocus(reason = undefined){
createContactButton.forceActiveFocus(reason)
}
// disable left panel contact list interaction while a contact is being edited
property bool leftPanelEnabled: !rightPanelStackView.currentItem
|| rightPanelStackView.currentItem.objectName
@ -242,6 +250,7 @@ AbstractMainPage {
visible: !rightPanelStackView.currentItem
|| rightPanelStackView.currentItem.objectName !== "contactEdition"
style: ButtonStyle.noBackground
focus: true
icon.source: AppIcons.plusCircle
Layout.preferredWidth: Utils.getSizeWithScreenRatio(28)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(28)

View file

@ -26,6 +26,15 @@ AbstractMainPage {
rightPanelStackTopMargin: Utils.getSizeWithScreenRatio(45)
rightPanelStackBottomMargin: Utils.getSizeWithScreenRatio(30)
/**
* Focus on the first pertinent element in the page (LINQT-2202)
* @override
*/
function forceActiveFocus(reason = undefined){
leftPanelStackView.currentItem?.newConfButton?.forceActiveFocus(reason)
}
function createPreFilledMeeting(subject, addresses) {
mainItem.selectedConference = Qt.createQmlObject('import Linphone
ConferenceInfoGui{
@ -136,6 +145,7 @@ AbstractMainPage {
id: listLayout
FocusScope{
property string objectName: "listLayout"
property alias newConfButton: newConfButton
Control.StackView.onDeactivated: {
mainItem.selectedConference = null
}
@ -164,6 +174,7 @@ AbstractMainPage {
}
Button {
id: newConfButton
focus: true
style: ButtonStyle.noBackground
icon.source: AppIcons.plusCircle
Layout.preferredWidth: Utils.getSizeWithScreenRatio(28)