Skip to content
Snippets Groups Projects
Commit 3f476205 authored by Andreas Traczyk's avatar Andreas Traczyk
Browse files

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
parent c19fb112
No related branches found
No related tags found
No related merge requests found
...@@ -123,7 +123,6 @@ ...@@ -123,7 +123,6 @@
<file>src/mainview/components/VideoCallPageContextMenuDeviceItem.qml</file> <file>src/mainview/components/VideoCallPageContextMenuDeviceItem.qml</file>
<file>src/mainview/components/SelectScreen.qml</file> <file>src/mainview/components/SelectScreen.qml</file>
<file>src/mainview/components/ScreenRubberBand.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/ContactPicker.qml</file>
<file>src/mainview/components/PluginHandlerPicker.qml</file> <file>src/mainview/components/PluginHandlerPicker.qml</file>
<file>src/mainview/components/ContactPickerItemDelegate.qml</file> <file>src/mainview/components/ContactPickerItemDelegate.qml</file>
...@@ -135,7 +134,6 @@ ...@@ -135,7 +134,6 @@
<file>src/mainview/js/incomingcallpagecreation.js</file> <file>src/mainview/js/incomingcallpagecreation.js</file>
<file>src/mainview/js/selectscreenwindowcreation.js</file> <file>src/mainview/js/selectscreenwindowcreation.js</file>
<file>src/mainview/js/screenrubberbandcreation.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/contactpickercreation.js</file>
<file>src/mainview/js/pluginhandlerpickercreation.js</file> <file>src/mainview/js/pluginhandlerpickercreation.js</file>
</qresource> </qresource>
......
...@@ -39,6 +39,23 @@ import "commoncomponents" ...@@ -39,6 +39,23 @@ import "commoncomponents"
ApplicationWindow { ApplicationWindow {
id: root 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 { enum LoadedSource {
WizardView = 0, WizardView = 0,
MainView, MainView,
...@@ -92,8 +109,7 @@ ApplicationWindow { ...@@ -92,8 +109,7 @@ ApplicationWindow {
setY(Screen.height / 2 - height / 2) setY(Screen.height / 2 - height / 2)
if (UtilsAdapter.getAccountListSize() !== 0) { if (UtilsAdapter.getAccountListSize() !== 0) {
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath, mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath)
{"containerWindow": root})
} else { } else {
mainApplicationLoader.setSource(JamiQmlUtils.wizardViewLoadPath) mainApplicationLoader.setSource(JamiQmlUtils.wizardViewLoadPath)
} }
...@@ -125,6 +141,7 @@ ApplicationWindow { ...@@ -125,6 +141,7 @@ ApplicationWindow {
id: mainApplicationLoader id: mainApplicationLoader
anchors.fill: parent anchors.fill: parent
z: -1
asynchronous: true asynchronous: true
visible: status == Loader.Ready visible: status == Loader.Ready
...@@ -137,8 +154,7 @@ ApplicationWindow { ...@@ -137,8 +154,7 @@ ApplicationWindow {
if (sourceToLoad === MainApplicationWindow.LoadedSource.WizardView) if (sourceToLoad === MainApplicationWindow.LoadedSource.WizardView)
mainApplicationLoader.setSource(JamiQmlUtils.wizardViewLoadPath) mainApplicationLoader.setSource(JamiQmlUtils.wizardViewLoadPath)
else else
mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath, mainApplicationLoader.setSource(JamiQmlUtils.mainViewLoadPath)
{"containerWindow": root})
} }
} }
} }
...@@ -159,15 +175,22 @@ ApplicationWindow { ...@@ -159,15 +175,22 @@ ApplicationWindow {
function onRestoreAppRequested() { function onRestoreAppRequested() {
requestActivate() requestActivate()
showNormal() if (isFullScreen)
showFullScreen()
else
showNormal()
} }
function onNotificationClicked() { function onNotificationClicked() {
requestActivate() requestActivate()
raise() raise()
if (visibility === Window.Hidden || if (visibility === Window.Hidden ||
visibility === Window.Minimized) visibility === Window.Minimized) {
showNormal() if (isFullScreen)
showFullScreen()
else
showNormal()
}
} }
} }
......
...@@ -29,14 +29,16 @@ Item { ...@@ -29,14 +29,16 @@ Item {
readonly property string base64StringTitle: "data:image/png;base64," readonly property string base64StringTitle: "data:image/png;base64,"
property var mainApplicationScreen: "" property var mainApplicationScreen: ""
property bool callIsFullscreen: false property bool callIsFullscreen: false
signal fullScreenCallEnded
Connections { Connections {
target: CallAdapter target: CallAdapter
function onHasCallChanged() { function onHasCallChanged() {
if (!CallAdapter.hasCall && callIsFullscreen) if (!CallAdapter.hasCall && callIsFullscreen)
callIsFullscreen = false fullScreenCallEnded()
} }
} }
......
...@@ -39,8 +39,6 @@ Rectangle { ...@@ -39,8 +39,6 @@ Rectangle {
objectName: "mainView" objectName: "mainView"
property var containerWindow: ""
property int sidePanelViewStackMinimumWidth: 300 property int sidePanelViewStackMinimumWidth: 300
property int mainViewStackPreferredWidth: 425 property int mainViewStackPreferredWidth: 425
property int settingsViewPreferredWidth: 460 property int settingsViewPreferredWidth: 460
...@@ -163,8 +161,8 @@ Rectangle { ...@@ -163,8 +161,8 @@ Rectangle {
var windowCurrentMinimizedSize = settingsViewPreferredWidth var windowCurrentMinimizedSize = settingsViewPreferredWidth
+ sidePanelViewStackMinimumWidth + onWidthChangedTriggerDistance + sidePanelViewStackMinimumWidth + onWidthChangedTriggerDistance
if (containerWindow.width < windowCurrentMinimizedSize) if (appWindow.width < windowCurrentMinimizedSize)
containerWindow.width = windowCurrentMinimizedSize appWindow.width = windowCurrentMinimizedSize
} }
} else { } else {
sidePanelViewStack.pop(StackView.Immediate) sidePanelViewStack.pop(StackView.Immediate)
...@@ -243,21 +241,6 @@ Rectangle { ...@@ -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 { StackLayout {
id: mainViewStackLayout id: mainViewStackLayout
...@@ -614,12 +597,11 @@ Rectangle { ...@@ -614,12 +597,11 @@ Rectangle {
sequence: "F11" sequence: "F11"
context: Qt.ApplicationShortcut context: Qt.ApplicationShortcut
onActivated: { onActivated: {
// Don't toggle fullscreen mode when we're already
// in a fullscreen call.
if (JamiQmlUtils.callIsFullscreen) if (JamiQmlUtils.callIsFullscreen)
return return
if (containerWindow.visibility !== Window.FullScreen) appWindow.toggleFullScreen()
containerWindow.visibility = Window.FullScreen
else
containerWindow.visibility = Window.Windowed
} }
} }
...@@ -651,6 +633,8 @@ Rectangle { ...@@ -651,6 +633,8 @@ Rectangle {
onActivated: { onActivated: {
if (JamiQmlUtils.callIsFullscreen) if (JamiQmlUtils.callIsFullscreen)
callStackView.toggleFullScreen() callStackView.toggleFullScreen()
else if (appWindow.isFullScreen)
appWindow.toggleFullScreen()
} }
} }
......
...@@ -25,7 +25,6 @@ import net.jami.Models 1.0 ...@@ -25,7 +25,6 @@ import net.jami.Models 1.0
import net.jami.Adapters 1.0 import net.jami.Adapters 1.0
import "../js/incomingcallpagecreation.js" as IncomingCallPageCreation import "../js/incomingcallpagecreation.js" as IncomingCallPageCreation
import "../js/callfullscreenwindowcontainercreation.js" as CallFullScreenWindowContainerCreation
Rectangle { Rectangle {
id: callStackViewWindow id: callStackViewWindow
...@@ -57,11 +56,9 @@ Rectangle { ...@@ -57,11 +56,9 @@ Rectangle {
return return
if (callStackMainView.currentItem.stackNumber === CallStackView.AudioPageStack) { if (callStackMainView.currentItem.stackNumber === CallStackView.AudioPageStack) {
audioCallPage.closeInCallConversation() audioCallPage.closeInCallConversation()
CallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
audioCallPage.closeContextMenuAndRelatedWindows() audioCallPage.closeContextMenuAndRelatedWindows()
} else if (callStackMainView.currentItem.stackNumber === CallStackView.VideoPageStack) { } else if (callStackMainView.currentItem.stackNumber === CallStackView.VideoPageStack) {
videoCallPage.closeInCallConversation() videoCallPage.closeInCallConversation()
CallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
videoCallPage.closeContextMenuAndRelatedWindows() videoCallPage.closeContextMenuAndRelatedWindows()
} }
} }
...@@ -124,25 +121,36 @@ Rectangle { ...@@ -124,25 +121,36 @@ Rectangle {
} }
function toggleFullScreen() { function toggleFullScreen() {
JamiQmlUtils.callIsFullscreen = !JamiQmlUtils.callIsFullscreen
var callPage = callStackMainView.currentItem var callPage = callStackMainView.currentItem
if (!callPage) if (!callPage)
return return
CallFullScreenWindowContainerCreation.createvideoCallFullScreenWindowContainerObject()
if (!CallFullScreenWindowContainerCreation.checkIfVisible()) { // manual toggle here because of our fake fullscreen mode (F11)
CallFullScreenWindowContainerCreation.setAsContainerChild(callPage) // TODO: handle and save window states, not just a boolean isFullScreen
CallFullScreenWindowContainerCreation.showVideoCallFullScreenWindowContainer() if (!appWindow.isFullScreen && !JamiQmlUtils.callIsFullscreen)
} else { appWindow.isFullScreen = true
callPage.parent = callStackMainView else if (JamiQmlUtils.callIsFullscreen)
CallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer() appWindow.isFullScreen = false
}
JamiQmlUtils.callIsFullscreen = !JamiQmlUtils.callIsFullscreen
callPage.parent = JamiQmlUtils.callIsFullscreen ?
appContainer :
callStackMainView
if (callPage.stackNumber === CallStackView.VideoPageStack) { if (callPage.stackNumber === CallStackView.VideoPageStack) {
videoCallPage.handleParticipantsInfo(CallAdapter.getConferencesInfos()) videoCallPage.handleParticipantsInfo(CallAdapter.getConferencesInfos())
} }
} }
Connections {
target: JamiQmlUtils
function onFullScreenCallEnded() {
if (appWindow.isFullScreen) {
toggleFullScreen()
}
}
}
Connections { Connections {
target: CallAdapter target: CallAdapter
......
/*
* 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
}
}
/*
* 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()
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment