mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-23 08:55:26 +02:00
misc: change application fullscreen mechanism
Use a simpler fullscreen mechanism that maintains the primary application window as a fullscreen container for the call view. GitLab: #339 Change-Id: Ib67ac4798c77117aea0830eece485e229680684d
This commit is contained in:
parent
c19fb112bb
commit
3f476205fa
7 changed files with 60 additions and 171 deletions
2
qml.qrc
2
qml.qrc
|
@ -123,7 +123,6 @@
|
|||
<file>src/mainview/components/VideoCallPageContextMenuDeviceItem.qml</file>
|
||||
<file>src/mainview/components/SelectScreen.qml</file>
|
||||
<file>src/mainview/components/ScreenRubberBand.qml</file>
|
||||
<file>src/mainview/components/VideoCallFullScreenWindowContainer.qml</file>
|
||||
<file>src/mainview/components/ContactPicker.qml</file>
|
||||
<file>src/mainview/components/PluginHandlerPicker.qml</file>
|
||||
<file>src/mainview/components/ContactPickerItemDelegate.qml</file>
|
||||
|
@ -135,7 +134,6 @@
|
|||
<file>src/mainview/js/incomingcallpagecreation.js</file>
|
||||
<file>src/mainview/js/selectscreenwindowcreation.js</file>
|
||||
<file>src/mainview/js/screenrubberbandcreation.js</file>
|
||||
<file>src/mainview/js/callfullscreenwindowcontainercreation.js</file>
|
||||
<file>src/mainview/js/contactpickercreation.js</file>
|
||||
<file>src/mainview/js/pluginhandlerpickercreation.js</file>
|
||||
</qresource>
|
||||
|
|
|
@ -39,6 +39,23 @@ import "commoncomponents"
|
|||
ApplicationWindow {
|
||||
id: root
|
||||
|
||||
property ApplicationWindow appWindow : root
|
||||
|
||||
// To facilitate reparenting of the callview during
|
||||
// fullscreen mode, we need QQuickItem based object.
|
||||
Item {
|
||||
id: appContainer
|
||||
anchors.fill: parent
|
||||
}
|
||||
property bool isFullScreen: false
|
||||
visibility: !visible ?
|
||||
Window.Hidden : (isFullScreen ?
|
||||
Window.FullScreen :
|
||||
Window.Windowed)
|
||||
function toggleFullScreen() {
|
||||
isFullScreen = !isFullScreen
|
||||
}
|
||||
|
||||
enum LoadedSource {
|
||||
WizardView = 0,
|
||||
MainView,
|
||||
|
@ -92,8 +109,7 @@ ApplicationWindow {
|
|||
setY(Screen.height / 2 - height / 2)
|
||||
|
||||
if (UtilsAdapter.getAccountListSize() !== 0) {
|
||||
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath,
|
||||
{"containerWindow": root})
|
||||
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath)
|
||||
} else {
|
||||
mainApplicationLoader.setSource(JamiQmlUtils.wizardViewLoadPath)
|
||||
}
|
||||
|
@ -125,6 +141,7 @@ ApplicationWindow {
|
|||
id: mainApplicationLoader
|
||||
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
|
||||
asynchronous: true
|
||||
visible: status == Loader.Ready
|
||||
|
@ -137,8 +154,7 @@ ApplicationWindow {
|
|||
if (sourceToLoad === MainApplicationWindow.LoadedSource.WizardView)
|
||||
mainApplicationLoader.setSource(JamiQmlUtils.wizardViewLoadPath)
|
||||
else
|
||||
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath,
|
||||
{"containerWindow": root})
|
||||
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -159,15 +175,22 @@ ApplicationWindow {
|
|||
|
||||
function onRestoreAppRequested() {
|
||||
requestActivate()
|
||||
showNormal()
|
||||
if (isFullScreen)
|
||||
showFullScreen()
|
||||
else
|
||||
showNormal()
|
||||
}
|
||||
|
||||
function onNotificationClicked() {
|
||||
requestActivate()
|
||||
raise()
|
||||
if (visibility === Window.Hidden ||
|
||||
visibility === Window.Minimized)
|
||||
showNormal()
|
||||
visibility === Window.Minimized) {
|
||||
if (isFullScreen)
|
||||
showFullScreen()
|
||||
else
|
||||
showNormal()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,14 +29,16 @@ Item {
|
|||
readonly property string base64StringTitle: "data:image/png;base64,"
|
||||
|
||||
property var mainApplicationScreen: ""
|
||||
|
||||
property bool callIsFullscreen: false
|
||||
signal fullScreenCallEnded
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
|
||||
function onHasCallChanged() {
|
||||
if (!CallAdapter.hasCall && callIsFullscreen)
|
||||
callIsFullscreen = false
|
||||
fullScreenCallEnded()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,6 @@ Rectangle {
|
|||
|
||||
objectName: "mainView"
|
||||
|
||||
property var containerWindow: ""
|
||||
|
||||
property int sidePanelViewStackMinimumWidth: 300
|
||||
property int mainViewStackPreferredWidth: 425
|
||||
property int settingsViewPreferredWidth: 460
|
||||
|
@ -163,8 +161,8 @@ Rectangle {
|
|||
|
||||
var windowCurrentMinimizedSize = settingsViewPreferredWidth
|
||||
+ sidePanelViewStackMinimumWidth + onWidthChangedTriggerDistance
|
||||
if (containerWindow.width < windowCurrentMinimizedSize)
|
||||
containerWindow.width = windowCurrentMinimizedSize
|
||||
if (appWindow.width < windowCurrentMinimizedSize)
|
||||
appWindow.width = windowCurrentMinimizedSize
|
||||
}
|
||||
} else {
|
||||
sidePanelViewStack.pop(StackView.Immediate)
|
||||
|
@ -243,21 +241,6 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: JamiQmlUtils
|
||||
|
||||
// TODO: call in fullscreen inside containerWindow
|
||||
function onCallIsFullscreenChanged() {
|
||||
if (JamiQmlUtils.callIsFullscreen) {
|
||||
UtilsAdapter.setSystemTrayIconVisible(false)
|
||||
containerWindow.hide()
|
||||
} else {
|
||||
UtilsAdapter.setSystemTrayIconVisible(true)
|
||||
containerWindow.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: mainViewStackLayout
|
||||
|
||||
|
@ -614,12 +597,11 @@ Rectangle {
|
|||
sequence: "F11"
|
||||
context: Qt.ApplicationShortcut
|
||||
onActivated: {
|
||||
// Don't toggle fullscreen mode when we're already
|
||||
// in a fullscreen call.
|
||||
if (JamiQmlUtils.callIsFullscreen)
|
||||
return
|
||||
if (containerWindow.visibility !== Window.FullScreen)
|
||||
containerWindow.visibility = Window.FullScreen
|
||||
else
|
||||
containerWindow.visibility = Window.Windowed
|
||||
appWindow.toggleFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -651,6 +633,8 @@ Rectangle {
|
|||
onActivated: {
|
||||
if (JamiQmlUtils.callIsFullscreen)
|
||||
callStackView.toggleFullScreen()
|
||||
else if (appWindow.isFullScreen)
|
||||
appWindow.toggleFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import net.jami.Models 1.0
|
|||
import net.jami.Adapters 1.0
|
||||
|
||||
import "../js/incomingcallpagecreation.js" as IncomingCallPageCreation
|
||||
import "../js/callfullscreenwindowcontainercreation.js" as CallFullScreenWindowContainerCreation
|
||||
|
||||
Rectangle {
|
||||
id: callStackViewWindow
|
||||
|
@ -57,11 +56,9 @@ Rectangle {
|
|||
return
|
||||
if (callStackMainView.currentItem.stackNumber === CallStackView.AudioPageStack) {
|
||||
audioCallPage.closeInCallConversation()
|
||||
CallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
|
||||
audioCallPage.closeContextMenuAndRelatedWindows()
|
||||
} else if (callStackMainView.currentItem.stackNumber === CallStackView.VideoPageStack) {
|
||||
videoCallPage.closeInCallConversation()
|
||||
CallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
|
||||
videoCallPage.closeContextMenuAndRelatedWindows()
|
||||
}
|
||||
}
|
||||
|
@ -124,25 +121,36 @@ Rectangle {
|
|||
}
|
||||
|
||||
function toggleFullScreen() {
|
||||
JamiQmlUtils.callIsFullscreen = !JamiQmlUtils.callIsFullscreen
|
||||
var callPage = callStackMainView.currentItem
|
||||
if (!callPage)
|
||||
return
|
||||
CallFullScreenWindowContainerCreation.createvideoCallFullScreenWindowContainerObject()
|
||||
|
||||
if (!CallFullScreenWindowContainerCreation.checkIfVisible()) {
|
||||
CallFullScreenWindowContainerCreation.setAsContainerChild(callPage)
|
||||
CallFullScreenWindowContainerCreation.showVideoCallFullScreenWindowContainer()
|
||||
} else {
|
||||
callPage.parent = callStackMainView
|
||||
CallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
|
||||
}
|
||||
// manual toggle here because of our fake fullscreen mode (F11)
|
||||
// TODO: handle and save window states, not just a boolean isFullScreen
|
||||
if (!appWindow.isFullScreen && !JamiQmlUtils.callIsFullscreen)
|
||||
appWindow.isFullScreen = true
|
||||
else if (JamiQmlUtils.callIsFullscreen)
|
||||
appWindow.isFullScreen = false
|
||||
|
||||
JamiQmlUtils.callIsFullscreen = !JamiQmlUtils.callIsFullscreen
|
||||
callPage.parent = JamiQmlUtils.callIsFullscreen ?
|
||||
appContainer :
|
||||
callStackMainView
|
||||
if (callPage.stackNumber === CallStackView.VideoPageStack) {
|
||||
videoCallPage.handleParticipantsInfo(CallAdapter.getConferencesInfos())
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: JamiQmlUtils
|
||||
|
||||
function onFullScreenCallEnded() {
|
||||
if (appWindow.isFullScreen) {
|
||||
toggleFullScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Window 2.14
|
||||
|
||||
import net.jami.Models 1.0
|
||||
|
||||
Window {
|
||||
id: videoWindow
|
||||
|
||||
function setAsChild(obj) {
|
||||
obj.parent = containerRect
|
||||
}
|
||||
|
||||
flags: Qt.FramelessWindowHint
|
||||
|
||||
screen: JamiQmlUtils.mainApplicationScreen
|
||||
|
||||
// +1 so that it does not fallback to the previous screen
|
||||
x: screen.virtualX + 1
|
||||
y: screen.virtualY + 1
|
||||
|
||||
visible: false
|
||||
|
||||
Rectangle {
|
||||
id: containerRect
|
||||
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// Global call full screen window container, object variable for creation.
|
||||
var callFullScreenWindowContainerComponent
|
||||
var callFullScreenWindowContainerObject
|
||||
|
||||
function createvideoCallFullScreenWindowContainerObject() {
|
||||
if (callFullScreenWindowContainerObject)
|
||||
return
|
||||
callFullScreenWindowContainerComponent = Qt.createComponent(
|
||||
"../components/VideoCallFullScreenWindowContainer.qml")
|
||||
if (callFullScreenWindowContainerComponent.status === Component.Ready)
|
||||
finishCreation()
|
||||
else if (callFullScreenWindowContainerComponent.status === Component.Error)
|
||||
console.log("Error loading component:",
|
||||
callFullScreenWindowContainerComponent.errorString())
|
||||
}
|
||||
|
||||
function finishCreation() {
|
||||
callFullScreenWindowContainerObject
|
||||
= callFullScreenWindowContainerComponent.createObject()
|
||||
if (callFullScreenWindowContainerObject === null) {
|
||||
// Error Handling.
|
||||
console.log("Error creating video call full screen window container object")
|
||||
}
|
||||
|
||||
// Signal connection.
|
||||
callFullScreenWindowContainerObject.onClosing.connect(
|
||||
destroyVideoCallFullScreenWindowContainer)
|
||||
}
|
||||
|
||||
function checkIfVisible() {
|
||||
if (!callFullScreenWindowContainerObject)
|
||||
return false
|
||||
return callFullScreenWindowContainerObject.visible
|
||||
}
|
||||
|
||||
function setAsContainerChild(obj) {
|
||||
if (callFullScreenWindowContainerObject)
|
||||
callFullScreenWindowContainerObject.setAsChild(obj)
|
||||
}
|
||||
|
||||
// Destroy and reset callFullScreenWindowContainerObject when window is closed.
|
||||
function destroyVideoCallFullScreenWindowContainer() {
|
||||
if (!callFullScreenWindowContainerObject)
|
||||
return
|
||||
callFullScreenWindowContainerObject.destroy()
|
||||
callFullScreenWindowContainerObject = false
|
||||
}
|
||||
|
||||
function showVideoCallFullScreenWindowContainer() {
|
||||
if (callFullScreenWindowContainerObject) {
|
||||
|
||||
// Hack: show first, then showFullScreen to make sure that the showFullScreen
|
||||
// display on the correct screen.
|
||||
callFullScreenWindowContainerObject.show()
|
||||
callFullScreenWindowContainerObject.showFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
function closeVideoCallFullScreenWindowContainer() {
|
||||
if (callFullScreenWindowContainerObject)
|
||||
callFullScreenWindowContainerObject.close()
|
||||
}
|
Loading…
Add table
Reference in a new issue