diff --git a/qml.qrc b/qml.qrc
index 1f5a159b..3b8d6be2 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -123,7 +123,6 @@
src/mainview/components/VideoCallPageContextMenuDeviceItem.qml
src/mainview/components/SelectScreen.qml
src/mainview/components/ScreenRubberBand.qml
- src/mainview/components/VideoCallFullScreenWindowContainer.qml
src/mainview/components/ContactPicker.qml
src/mainview/components/PluginHandlerPicker.qml
src/mainview/components/ContactPickerItemDelegate.qml
@@ -135,7 +134,6 @@
src/mainview/js/incomingcallpagecreation.js
src/mainview/js/selectscreenwindowcreation.js
src/mainview/js/screenrubberbandcreation.js
- src/mainview/js/callfullscreenwindowcontainercreation.js
src/mainview/js/contactpickercreation.js
src/mainview/js/pluginhandlerpickercreation.js
diff --git a/src/MainApplicationWindow.qml b/src/MainApplicationWindow.qml
index 9d89dd46..1cfd2b52 100644
--- a/src/MainApplicationWindow.qml
+++ b/src/MainApplicationWindow.qml
@@ -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()
+ }
}
}
diff --git a/src/constant/JamiQmlUtils.qml b/src/constant/JamiQmlUtils.qml
index 9bb10775..9cacecaa 100644
--- a/src/constant/JamiQmlUtils.qml
+++ b/src/constant/JamiQmlUtils.qml
@@ -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()
}
}
diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml
index 9e2d63f2..635b099d 100644
--- a/src/mainview/MainView.qml
+++ b/src/mainview/MainView.qml
@@ -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()
}
}
diff --git a/src/mainview/components/CallStackView.qml b/src/mainview/components/CallStackView.qml
index 418816c8..31d7816f 100644
--- a/src/mainview/components/CallStackView.qml
+++ b/src/mainview/components/CallStackView.qml
@@ -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
diff --git a/src/mainview/components/VideoCallFullScreenWindowContainer.qml b/src/mainview/components/VideoCallFullScreenWindowContainer.qml
deleted file mode 100644
index cae72835..00000000
--- a/src/mainview/components/VideoCallFullScreenWindowContainer.qml
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Mingrui Zhang
- *
- * 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 .
- */
-
-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
- }
-}
diff --git a/src/mainview/js/callfullscreenwindowcontainercreation.js b/src/mainview/js/callfullscreenwindowcontainercreation.js
deleted file mode 100644
index 2ce42c14..00000000
--- a/src/mainview/js/callfullscreenwindowcontainercreation.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2020 by Savoir-faire Linux
- * Author: Mingrui Zhang
- *
- * 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 .
- */
-
-// 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()
-}