fullscreen: reimplement fullscreen for reliability

Reimplement the fullscreen behavior to only work during calls
and to make it more consistent.

Change-Id: I8fbad30dfcf577f5af7d809073e20105374deb35
This commit is contained in:
pmagnier-slimani
2025-03-03 13:50:26 -05:00
committed by Page Magnier-Slimani
parent 3143d60760
commit a407fa2c47
7 changed files with 52 additions and 40 deletions

View File

@@ -17,6 +17,7 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtWebEngine
import net.jami.Adapters 1.1 import net.jami.Adapters 1.1
import net.jami.Enums 1.1 import net.jami.Enums 1.1
@@ -37,9 +38,12 @@ QtObject {
readonly property bool isHidden: visibility === Window.Hidden || readonly property bool isHidden: visibility === Window.Hidden ||
visibility === Window.Minimized 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 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. // QWK: Provide spacing for widgets that may be occluded by the system buttons.
property QtObject qwkSystemButtonSpacing: QtObject { property QtObject qwkSystemButtonSpacing: QtObject {
id: qwkSystemButtonSpacing id: qwkSystemButtonSpacing
@@ -150,9 +154,8 @@ QtObject {
// Adds an item to the fullscreen item stack. Automatically puts // Adds an item to the fullscreen item stack. Automatically puts
// the main window in fullscreen mode if needed. Callbacks should be used // the main window in fullscreen mode if needed. Callbacks should be used
// to perform component-specific tasks upon successful transitions. // to perform component-specific tasks upon successful transitions.
function pushFullScreenItem(item, prevParent, pushedCb, removedCb) { function pushFullScreenItem(item, removedCb=undefined) {
if (item === null || item === undefined if (!item || priv.fullScreenItems.length >= 3) {
|| priv.fullScreenItems.length >= 3) {
return return
} }
@@ -162,15 +165,13 @@ QtObject {
// Add the item to our list and reparent it to appContainer. // Add the item to our list and reparent it to appContainer.
priv.fullScreenItems.push({ priv.fullScreenItems.push({
"item": item, "item": item,
"prevParent": prevParent, "prevParent": item.parent,
"prevAnchorsFill": item.anchors.fill, "prevAnchorsFill": item.anchors.fill,
"removedCb": removedCb "removedCb": removedCb
}) })
item.parent = appContainer item.parent = appContainer
item.anchors.fill = item.parent item.anchors.fill = appContainer
if (pushedCb) {
pushedCb()
}
// Reevaluate isCallFullscreen. // Reevaluate isCallFullscreen.
priv.fullScreenItemsChanged() priv.fullScreenItemsChanged()
@@ -178,34 +179,37 @@ QtObject {
// Remove an item if specified, or by default, the top item. Automatically // 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. // 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. // Remove the item and reparent it to its original parent.
if (obj === null) { if (obj === undefined) {
obj = priv.fullScreenItems.pop() obj = priv.fullScreenItems.pop();
} else { } else {
const index = priv.fullScreenItems.indexOf(obj); const index = priv.fullScreenItems.indexOf(obj);
if (index > -1) { if (index > -1) {
priv.fullScreenItems.splice(index, 1); priv.fullScreenItems.splice(index, 1);
} }
} }
if (obj !== undefined) { if (obj && typeof obj === 'object') {
if (obj.item !== appWindow) { if (obj.item !== appWindow) {
obj.item.anchors.fill = obj.prevAnchorsFill // Clear anchors first, then set parent, then reset anchors.
obj.item.parent = obj.prevParent obj.item.anchors.fill = undefined;
if (obj.removedCb) { obj.item.parent = obj.prevParent;
obj.removedCb() obj.item.anchors.fill = obj.prevAnchorsFill;
// Call removed callback if it's a function.
if (typeof obj.removedCb === 'function') {
obj.removedCb();
} }
} }
// Reevaluate isCallFullscreen. // Reevaluate isCallFullscreen.
priv.fullScreenItemsChanged() priv.fullScreenItemsChanged();
} }
// Only leave fullscreen mode if our window isn't in fullscreen // Only leave fullscreen mode if our window isn't in fullscreen mode already.
// mode already.
if (priv.fullScreenItems.length === 0 && priv.windowedVisibility !== Window.Hidden) { if (priv.fullScreenItems.length === 0 && priv.windowedVisibility !== Window.Hidden) {
// Simply recall the last visibility state. // 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. // When fullScreenItems is changed, we can recompute isCallFullscreen.
onFullScreenItemsChanged: { onFullScreenItemsChanged: {
isCallFullscreen = fullScreenItems isCallFullscreen = fullScreenItems
.filter(o => o.item instanceof OngoingCallPage) .filter(o => o.item.objectName === "callViewLoader")
.length
isWebFullscreen = fullScreenItems
.filter(o => o.item instanceof WebEngineView)
.length .length
} }
@@ -258,7 +265,7 @@ QtObject {
function onHasCallChanged() { function onHasCallChanged() {
if (!CallAdapter.hasCall && isCallFullscreen) { if (!CallAdapter.hasCall && isCallFullscreen) {
priv.fullScreenItems.forEach(o => { priv.fullScreenItems.forEach(o => {
if (o.item instanceof OngoingCallPage) { if (o.item.objectName === "callViewLoader") {
popFullScreenItem(o) popFullScreenItem(o)
return return
} }

View File

@@ -136,17 +136,12 @@ Rectangle {
} }
Shortcut { Shortcut {
sequence: "F11" sequence: "Esc"
context: Qt.ApplicationShortcut context: Qt.ApplicationShortcut
onActivated: layoutManager.toggleWindowFullScreen() onActivated: {
}
Keys.onPressed: function (keyEvent) {
if (keyEvent.key === Qt.Key_Escape) {
MessagesAdapter.replyToId = ""; MessagesAdapter.replyToId = "";
MessagesAdapter.editId = ""; MessagesAdapter.editId = "";
layoutManager.popFullScreenItem(); layoutManager.popFullScreenItem();
keyEvent.accepted = true;
} }
} }

View File

@@ -171,8 +171,10 @@ ItemDelegate {
Connections { Connections {
target: menuAction !== undefined ? menuAction : null target: menuAction !== undefined ? menuAction : null
function onTriggered() { function onTriggered() {
if (menuAction.popupMode !== CallActionBar.ActionPopupMode.ListElement) if (menuAction.popupMode !== CallActionBar.ActionPopupMode.ListElement) {
itemListView.currentIndex = menuAction.listModel.getCurrentIndex(); var index = menuAction.listModel.currentIndex;
itemListView.currentIndex = index !== undefined ? index : 0;
}
} }
} }

View File

@@ -40,6 +40,13 @@ Item {
onActivatedAmbiguously: CallAdapter.hangUpThisCall() onActivatedAmbiguously: CallAdapter.hangUpThisCall()
} }
Shortcut {
sequence: "F11"
context: Qt.ApplicationShortcut
enabled: CurrentConversation.hasCall && !layoutManager.isWebFullscreen
onActivated: toggleFullScreen();
}
Keys.onPressed: { Keys.onPressed: {
if (LRCInstance.currentAccountType !== Profile.Type.SIP) if (LRCInstance.currentAccountType !== Profile.Type.SIP)
return; return;
@@ -72,14 +79,15 @@ Item {
function toggleFullScreen() { function toggleFullScreen() {
if (!layoutManager.isCallFullscreen) { if (!layoutManager.isCallFullscreen) {
layoutManager.pushFullScreenItem(callStackMainView.item, callStackMainView, null, null); layoutManager.pushFullScreenItem(callStackMainView);
} else { } else {
layoutManager.removeFullScreenItem(callStackMainView.item); layoutManager.removeFullScreenItem(callStackMainView);
} }
} }
Loader { Loader {
id: callStackMainView id: callStackMainView
objectName: "callViewLoader"
anchors.fill: parent anchors.fill: parent

View File

@@ -59,10 +59,6 @@ Window {
shortcut: "Ctrl+F" shortcut: "Ctrl+F"
description: qsTr("Search bar") description: qsTr("Search bar")
} }
ListElement {
shortcut: "F11"
description: qsTr("Full screen")
}
ListElement { ListElement {
shortcut: "Ctrl++" shortcut: "Ctrl++"
description: qsTr("Increase font size") description: qsTr("Increase font size")
@@ -131,6 +127,10 @@ Window {
shortcut: "Ctrl+Shift+D" shortcut: "Ctrl+Shift+D"
description: qsTr("Decline call") description: qsTr("Decline call")
} }
ListElement {
shortcut: "F11"
description: qsTr("Full screen")
}
ListElement { ListElement {
shortcut: "M" shortcut: "M"
description: qsTr("Mute microphone") description: qsTr("Mute microphone")

View File

@@ -53,7 +53,7 @@ WebEngineView {
} }
onFullScreenRequested: function (request) { onFullScreenRequested: function (request) {
if (request.toggleOn) { if (request.toggleOn) {
layoutManager.pushFullScreenItem(this, localMediaCompLoader, null, function () { layoutManager.pushFullScreenItem(this, function () {
wev.fullScreenCancelled(); wev.fullScreenCancelled();
}); });
} else if (!request.toggleOn) { } else if (!request.toggleOn) {

View File

@@ -38,7 +38,7 @@ Rectangle {
Component.onCompleted: loadHtml(root.html, 'file:///') Component.onCompleted: loadHtml(root.html, 'file:///')
onFullScreenRequested: function (request) { onFullScreenRequested: function (request) {
if (request.toggleOn) { if (request.toggleOn) {
layoutManager.pushFullScreenItem(this, root, null, function () { layoutManager.pushFullScreenItem(this, function () {
wev.fullScreenCancelled(); wev.fullScreenCancelled();
}); });
} else if (!request.toggleOn) { } else if (!request.toggleOn) {