From a407fa2c479846d99561e438dfa60625d251aa9a Mon Sep 17 00:00:00 2001 From: pmagnier-slimani Date: Mon, 3 Mar 2025 13:50:26 -0500 Subject: [PATCH] fullscreen: reimplement fullscreen for reliability Reimplement the fullscreen behavior to only work during calls and to make it more consistent. Change-Id: I8fbad30dfcf577f5af7d809073e20105374deb35 --- src/app/LayoutManager.qml | 53 +++++++++++-------- src/app/mainview/MainView.qml | 9 +--- .../components/CallButtonDelegate.qml | 6 ++- src/app/mainview/components/CallStackView.qml | 12 ++++- .../components/KeyboardShortcutTable.qml | 8 +-- src/app/webengine/MediaPreviewBase.qml | 2 +- src/app/webengine/VideoPreview.qml | 2 +- 7 files changed, 52 insertions(+), 40 deletions(-) diff --git a/src/app/LayoutManager.qml b/src/app/LayoutManager.qml index 8f4fa2e4..5d5753b0 100644 --- a/src/app/LayoutManager.qml +++ b/src/app/LayoutManager.qml @@ -17,6 +17,7 @@ import QtQuick import QtQuick.Controls +import QtWebEngine import net.jami.Adapters 1.1 import net.jami.Enums 1.1 @@ -37,9 +38,12 @@ QtObject { readonly property bool isHidden: visibility === Window.Hidden || visibility === Window.Minimized - // Used to store if a OngoingCallPage component is fullscreened. + // Used to store if a CallStackView component is fullscreened. property bool isCallFullscreen: false + // Used to store if a WebEngineView component is fullscreened. + property bool isWebFullscreen: false + // QWK: Provide spacing for widgets that may be occluded by the system buttons. property QtObject qwkSystemButtonSpacing: QtObject { id: qwkSystemButtonSpacing @@ -150,9 +154,8 @@ QtObject { // Adds an item to the fullscreen item stack. Automatically puts // the main window in fullscreen mode if needed. Callbacks should be used // to perform component-specific tasks upon successful transitions. - function pushFullScreenItem(item, prevParent, pushedCb, removedCb) { - if (item === null || item === undefined - || priv.fullScreenItems.length >= 3) { + function pushFullScreenItem(item, removedCb=undefined) { + if (!item || priv.fullScreenItems.length >= 3) { return } @@ -162,15 +165,13 @@ QtObject { // Add the item to our list and reparent it to appContainer. priv.fullScreenItems.push({ "item": item, - "prevParent": prevParent, + "prevParent": item.parent, "prevAnchorsFill": item.anchors.fill, "removedCb": removedCb }) + item.parent = appContainer - item.anchors.fill = item.parent - if (pushedCb) { - pushedCb() - } + item.anchors.fill = appContainer // Reevaluate isCallFullscreen. priv.fullScreenItemsChanged() @@ -178,34 +179,37 @@ QtObject { // Remove an item if specified, or by default, the top item. Automatically // resets the main window to windowed mode if no items remain in the stack. - function popFullScreenItem(obj=null) { + function popFullScreenItem(obj = undefined) { // Remove the item and reparent it to its original parent. - if (obj === null) { - obj = priv.fullScreenItems.pop() + if (obj === undefined) { + obj = priv.fullScreenItems.pop(); } else { const index = priv.fullScreenItems.indexOf(obj); if (index > -1) { priv.fullScreenItems.splice(index, 1); } } - if (obj !== undefined) { + if (obj && typeof obj === 'object') { if (obj.item !== appWindow) { - obj.item.anchors.fill = obj.prevAnchorsFill - obj.item.parent = obj.prevParent - if (obj.removedCb) { - obj.removedCb() + // Clear anchors first, then set parent, then reset anchors. + obj.item.anchors.fill = undefined; + obj.item.parent = obj.prevParent; + obj.item.anchors.fill = obj.prevAnchorsFill; + + // Call removed callback if it's a function. + if (typeof obj.removedCb === 'function') { + obj.removedCb(); } } // Reevaluate isCallFullscreen. - priv.fullScreenItemsChanged() + priv.fullScreenItemsChanged(); } - // Only leave fullscreen mode if our window isn't in fullscreen - // mode already. + // Only leave fullscreen mode if our window isn't in fullscreen mode already. if (priv.fullScreenItems.length === 0 && priv.windowedVisibility !== Window.Hidden) { // Simply recall the last visibility state. - visibility = priv.windowedVisibility + visibility = priv.windowedVisibility; } } @@ -247,7 +251,10 @@ QtObject { // When fullScreenItems is changed, we can recompute isCallFullscreen. onFullScreenItemsChanged: { isCallFullscreen = fullScreenItems - .filter(o => o.item instanceof OngoingCallPage) + .filter(o => o.item.objectName === "callViewLoader") + .length + isWebFullscreen = fullScreenItems + .filter(o => o.item instanceof WebEngineView) .length } @@ -258,7 +265,7 @@ QtObject { function onHasCallChanged() { if (!CallAdapter.hasCall && isCallFullscreen) { priv.fullScreenItems.forEach(o => { - if (o.item instanceof OngoingCallPage) { + if (o.item.objectName === "callViewLoader") { popFullScreenItem(o) return } diff --git a/src/app/mainview/MainView.qml b/src/app/mainview/MainView.qml index 1694e226..2f682925 100644 --- a/src/app/mainview/MainView.qml +++ b/src/app/mainview/MainView.qml @@ -136,17 +136,12 @@ Rectangle { } Shortcut { - sequence: "F11" + sequence: "Esc" context: Qt.ApplicationShortcut - onActivated: layoutManager.toggleWindowFullScreen() - } - - Keys.onPressed: function (keyEvent) { - if (keyEvent.key === Qt.Key_Escape) { + onActivated: { MessagesAdapter.replyToId = ""; MessagesAdapter.editId = ""; layoutManager.popFullScreenItem(); - keyEvent.accepted = true; } } diff --git a/src/app/mainview/components/CallButtonDelegate.qml b/src/app/mainview/components/CallButtonDelegate.qml index 91b302cf..3ae7c0f8 100644 --- a/src/app/mainview/components/CallButtonDelegate.qml +++ b/src/app/mainview/components/CallButtonDelegate.qml @@ -171,8 +171,10 @@ ItemDelegate { Connections { target: menuAction !== undefined ? menuAction : null function onTriggered() { - if (menuAction.popupMode !== CallActionBar.ActionPopupMode.ListElement) - itemListView.currentIndex = menuAction.listModel.getCurrentIndex(); + if (menuAction.popupMode !== CallActionBar.ActionPopupMode.ListElement) { + var index = menuAction.listModel.currentIndex; + itemListView.currentIndex = index !== undefined ? index : 0; + } } } diff --git a/src/app/mainview/components/CallStackView.qml b/src/app/mainview/components/CallStackView.qml index 89c29a34..a7a289cc 100644 --- a/src/app/mainview/components/CallStackView.qml +++ b/src/app/mainview/components/CallStackView.qml @@ -40,6 +40,13 @@ Item { onActivatedAmbiguously: CallAdapter.hangUpThisCall() } + Shortcut { + sequence: "F11" + context: Qt.ApplicationShortcut + enabled: CurrentConversation.hasCall && !layoutManager.isWebFullscreen + onActivated: toggleFullScreen(); + } + Keys.onPressed: { if (LRCInstance.currentAccountType !== Profile.Type.SIP) return; @@ -72,14 +79,15 @@ Item { function toggleFullScreen() { if (!layoutManager.isCallFullscreen) { - layoutManager.pushFullScreenItem(callStackMainView.item, callStackMainView, null, null); + layoutManager.pushFullScreenItem(callStackMainView); } else { - layoutManager.removeFullScreenItem(callStackMainView.item); + layoutManager.removeFullScreenItem(callStackMainView); } } Loader { id: callStackMainView + objectName: "callViewLoader" anchors.fill: parent diff --git a/src/app/mainview/components/KeyboardShortcutTable.qml b/src/app/mainview/components/KeyboardShortcutTable.qml index 91b4ad1a..3120087f 100644 --- a/src/app/mainview/components/KeyboardShortcutTable.qml +++ b/src/app/mainview/components/KeyboardShortcutTable.qml @@ -59,10 +59,6 @@ Window { shortcut: "Ctrl+F" description: qsTr("Search bar") } - ListElement { - shortcut: "F11" - description: qsTr("Full screen") - } ListElement { shortcut: "Ctrl++" description: qsTr("Increase font size") @@ -131,6 +127,10 @@ Window { shortcut: "Ctrl+Shift+D" description: qsTr("Decline call") } + ListElement { + shortcut: "F11" + description: qsTr("Full screen") + } ListElement { shortcut: "M" description: qsTr("Mute microphone") diff --git a/src/app/webengine/MediaPreviewBase.qml b/src/app/webengine/MediaPreviewBase.qml index 26de4d3a..ef8bf9e6 100644 --- a/src/app/webengine/MediaPreviewBase.qml +++ b/src/app/webengine/MediaPreviewBase.qml @@ -53,7 +53,7 @@ WebEngineView { } onFullScreenRequested: function (request) { if (request.toggleOn) { - layoutManager.pushFullScreenItem(this, localMediaCompLoader, null, function () { + layoutManager.pushFullScreenItem(this, function () { wev.fullScreenCancelled(); }); } else if (!request.toggleOn) { diff --git a/src/app/webengine/VideoPreview.qml b/src/app/webengine/VideoPreview.qml index 1cab4b9b..0bb97a60 100644 --- a/src/app/webengine/VideoPreview.qml +++ b/src/app/webengine/VideoPreview.qml @@ -38,7 +38,7 @@ Rectangle { Component.onCompleted: loadHtml(root.html, 'file:///') onFullScreenRequested: function (request) { if (request.toggleOn) { - layoutManager.pushFullScreenItem(this, root, null, function () { + layoutManager.pushFullScreenItem(this, function () { wev.fullScreenCancelled(); }); } else if (!request.toggleOn) {