diff --git a/TODO.md b/TODO.md index e8478ae7..7a0e4319 100644 --- a/TODO.md +++ b/TODO.md @@ -48,13 +48,13 @@ ## Issues -- invisible uploaded mxc images? -- first undecryptable message -- Join button 502 -- Leave box button focus +- `EventImage`s for `m.image` sometimes appear broken, can be made normal + by switching to another room and coming back +- First sent message in E2E room is sometimes undecryptable +- Handle matrix errors for accept/decline invite buttons and other +- Pause upload, switch to other room, then come back → wrong state displayed - Pausing uploads doesn't work well, servers end up dropping the connection -- Pause upload, switch to other room, then come back, wrong state displayed - In the "Leave me" room, "join > Hi > left" aren't combined - When selecting text and scrolling up, selection stops working after a while diff --git a/src/gui/Base/HMenu.qml b/src/gui/Base/HMenu.qml index 06cfebbd..1a816a08 100644 --- a/src/gui/Base/HMenu.qml +++ b/src/gui/Base/HMenu.qml @@ -25,9 +25,17 @@ Menu { border.width: theme.controls.menu.borderWidth } - onAboutToShow: previouslyFocused = window.activeFocusItem - onClosed: if (previouslyFocused) previouslyFocused.forceActiveFocus() + onAboutToShow: { + previouslyFocused = window.activeFocusItem + focusOnClosed = Qt.binding(() => previouslyFocused) + } + onClosed: if (focusOnClosed) focusOnClosed.forceActiveFocus() property var previouslyFocused: null + + // MenuItems that open popups (or other elements taking focus when opened) + // should set this to null. It will be reset to previouslyFocus when + // the Menu is closed and opened again. + property Item focusOnClosed: previouslyFocused } diff --git a/src/gui/Base/HMenuItem.qml b/src/gui/Base/HMenuItem.qml index 7b29ee44..b730467d 100644 --- a/src/gui/Base/HMenuItem.qml +++ b/src/gui/Base/HMenuItem.qml @@ -12,11 +12,6 @@ MenuItem { bottomPadding: topPadding height: visible ? implicitHeight : 0 - - readonly property alias iconItem: contentItem.icon - readonly property alias label: contentItem.label - - background: HButtonBackground { button: menuItem buttonTheme: theme.controls.menuItem @@ -28,4 +23,8 @@ MenuItem { buttonTheme: theme.controls.menuItem label.horizontalAlignment: Label.AlignLeft } + + + readonly property alias iconItem: contentItem.icon + readonly property alias label: contentItem.label } diff --git a/src/gui/Base/HMenuItemPopupSpawner.qml b/src/gui/Base/HMenuItemPopupSpawner.qml new file mode 100644 index 00000000..9511daaa --- /dev/null +++ b/src/gui/Base/HMenuItemPopupSpawner.qml @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +HMenuItem { + onTriggered: { + print( parent.parent.parent) + menu.focusOnClosed = null + + utils.makePopup( + popup, + popupParent, + utils.objectUpdate( + { focusOnClosed: menu.previouslyFocused }, properties, + ), + null, + autoDestruct, + ) + } + + + property var popup // url or HPopup Component + property QtObject popupParent: window + property bool autoDestruct: true + property var properties: ({}) +} diff --git a/src/gui/Base/HPopup.qml b/src/gui/Base/HPopup.qml index f4ad110b..2874425b 100644 --- a/src/gui/Base/HPopup.qml +++ b/src/gui/Base/HPopup.qml @@ -24,10 +24,11 @@ Popup { } onAboutToShow: previouslyFocused = window.activeFocusItem - onClosed: if (previouslyFocused) previouslyFocused.forceActiveFocus() + onClosed: if (focusOnClosed) focusOnClosed.forceActiveFocus() property var previouslyFocused: null + property Item focusOnClosed: previouslyFocused readonly property int maximumPreferredWidth: window.width - leftMargin - rightMargin - leftInset - rightInset diff --git a/src/gui/MainPane/AccountDelegate.qml b/src/gui/MainPane/AccountDelegate.qml index c78c6d54..7ec080de 100644 --- a/src/gui/MainPane/AccountDelegate.qml +++ b/src/gui/MainPane/AccountDelegate.qml @@ -110,15 +110,13 @@ HTileDelegate { onTriggered: Clipboard.text = model.data.user_id } - HMenuItem { + HMenuItemPopupSpawner { icon.name: "sign-out" icon.color: theme.colors.negativeBackground text: qsTr("Sign out") - onTriggered: utils.makePopup( - "Popups/SignOutPopup.qml", - window, - { "userId": model.data.user_id }, - ) + + popup: "Popups/SignOutPopup.qml" + properties: { "userId": model.data.user_id } } } } diff --git a/src/gui/MainPane/RoomDelegate.qml b/src/gui/MainPane/RoomDelegate.qml index dea42e88..0fa9d659 100644 --- a/src/gui/MainPane/RoomDelegate.qml +++ b/src/gui/MainPane/RoomDelegate.qml @@ -91,22 +91,19 @@ HTileDelegate { } contextMenu: HMenu { - HMenuItem { + HMenuItemPopupSpawner { visible: joined enabled: model.data.can_invite icon.name: "room-send-invite" text: qsTr("Invite members") - onTriggered: utils.makePopup( - "Popups/InviteToRoomPopup.qml", - window, - { - userId: model.user_id, - roomId: model.data.room_id, - roomName: model.data.display_name, - invitingAllowed: Qt.binding(() => model.data.can_invite) - } - ) + popup: "Popups/InviteToRoomPopup.qml" + properties: ({ + userId: model.user_id, + roomId: model.data.room_id, + roomName: model.data.display_name, + invitingAllowed: Qt.binding(() => model.data.can_invite) + }) } HMenuItem { @@ -129,39 +126,32 @@ HTileDelegate { ) } - HMenuItem { + HMenuItemPopupSpawner { visible: invited || joined icon.name: invited ? "invite-decline" : "room-leave" icon.color: theme.colors.negativeBackground text: invited ? qsTr("Decline invite") : qsTr("Leave") - onTriggered: utils.makePopup( - "Popups/LeaveRoomPopup.qml", - window, - { - userId: model.user_id, - roomId: model.data.room_id, - roomName: model.data.display_name, - } - ) + popup: "Popups/LeaveRoomPopup.qml" + properties: ({ + userId: model.user_id, + roomId: model.data.room_id, + roomName: model.data.display_name, + }) } - HMenuItem { + HMenuItemPopupSpawner { icon.name: "room-forget" icon.color: theme.colors.negativeBackground text: qsTr("Forget") - onTriggered: utils.makePopup( - "Popups/ForgetRoomPopup.qml", - window, - { - userId: model.user_id, - roomId: model.data.room_id, - roomName: model.data.display_name, - }, - null, - false, - ) + popup: "Popups/ForgetRoomPopup.qml" + autoDestruct: false + properties: ({ + userId: model.user_id, + roomId: model.data.room_id, + roomName: model.data.display_name, + }) } } } diff --git a/src/gui/Pages/Chat/Timeline/EventDelegate.qml b/src/gui/Pages/Chat/Timeline/EventDelegate.qml index 1f8aa963..5fc18483 100644 --- a/src/gui/Pages/Chat/Timeline/EventDelegate.qml +++ b/src/gui/Pages/Chat/Timeline/EventDelegate.qml @@ -170,14 +170,13 @@ HColumnLayout { Clipboard.text = selectableLabelContainer.joinedSelection } - HMenuItem { + HMenuItemPopupSpawner { icon.name: "clear-messages" text: qsTr("Clear messages") - onTriggered: utils.makePopup( - "Popups/ClearMessagesPopup.qml", - chat, - {userId: chat.userId, roomId: chat.roomId}, - ) + + popup: "Popups/ClearMessagesPopup.qml" + popupParent: chat + properties: ({userId: chat.userId, roomId: chat.roomId}) } } } diff --git a/src/gui/Utils.qml b/src/gui/Utils.qml index 394ff6aa..629fb148 100644 --- a/src/gui/Utils.qml +++ b/src/gui/Utils.qml @@ -68,6 +68,11 @@ QtObject { } + function objectUpdate(current, update) { + return Object.assign({}, current, update) + } + + function objectUpdateRecursive(current, update) { for (const key of Object.keys(update)) { if ((key in current) && typeof(current[key]) === "object" &&