Qml - ApplicationWindow fullscreen issues
-
Hi all,
[Setup]
Qt 5.4.1
Windows DesktopI'm struggling with the fullscreen mode of ApplicationWindow in a full-qml based project.
When using the method showFullScreen(), the expected result occurs : the window get displayed fullscreen.
The trouble is that I get strange black screen flashes whenever I hover a Button or click items in the menu bar for instance.
I also get those flashes on a dual screen setup, when I click somewhere on the second screen and click back inside the fullscreen Qml app (it seems to run fine when the app is shown fullscreen on the secondary screen though).
This is making the application really hard to use. Also, tooltips are not displayed.
I guess the issue is related to the OpenGL surface being set to fullscreen and the way Windows handles that (like it does with a fullscreen game).I was able to solve this problem back in Qt 4.8 by using a QMainWindow and embedding the QDeclarativeView inside a QWidget used as the central widget with a QLayout with 1px margin. This way, when making the central widget go fullscreen, the OpenGL viewport of the QDeclarativeView is not filling the screen and everything works fine.
Since I'm now using an ApplicationWindow instanciated in Qml, this trick is outdated. I thought I had found another workaround by manually settings visibility [1] and window flags [2].
import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Window 2.2 import QtQuick.Dialogs 1.2 ApplicationWindow { id: mainWindow title: qsTr("Hello World") width: 640 height: 480 property bool fullscreen: false menuBar: MenuBar { Menu { title: qsTr("&File") MenuItem { text: qsTr("&Open") onTriggered: messageDialog.show(qsTr("Open action triggered")); } MenuItem { text: qsTr("E&xit") onTriggered: Qt.quit(); } } } Item { states: [ State { when: mainWindow.fullscreen name: "Full" PropertyChanges { target: mainWindow // [1] using Window.FullScreen => still have black flashes. // have to use "FullScreen" // visibility: Window.FullScreen visibility: "FullScreen" // [2] The unfamous workaround flags: Qt.WindowFullScreen } } ] } Button { anchors.centerIn: parent checkable: true tooltip: "Change mode" text: mainWindow.fullscreen ? "Go Windowed" : "Go Fullscreen" onClicked: mainWindow.fullscreen = !mainWindow.fullscreen } }
Setting the WindowFullScreen flag does resolve the flashes (and the tooltips) when combined with the visibility set to "Fullscreen". But it introduces another showstopper bug : it breaks Drop events from outside when going back to windowed mode, making it impossible to use DropAreas.
And this might only be one bug among others, so this workaround does not seem viable...Has anyone another solution or have insights into what is really happening with the fullscreen mode ?
Thanks,
Yann -
After taking a closer at the C++ code of
QWindowsWindow::setWindowFlag
, I stumbled upon a call toQWindowsWindow::updateDropSite
. This enables/disables the window drop capabilities according to its WindowType.
The thing is thatd->windowFlags
, used to determine the type of the window is updated after the call toupdateDropSite
. This is why messing up with the flags when switching to fullscreen breaks the drop system when switching back flags to its initial value; Qt.WindowFullScreen is an invalid WindowType => drops are disabled.Knowing that, I was able to improve my previous workaround :
StateGroup { state: mainWindow.fullScreen ? "FullScreen" : "" states: [ State { name: "FullScreen" PropertyChanges { target: mainWindow // [1] using Window.FullScreen => still have black flashes. // have to use "FullScreen" // visibility: Window.FullScreen visibility: "FullScreen" // [2] Flag this window as a Widget to prevent black flashes from happening. // updateDropSite considers type Window : drops work flags: Qt.Widget } }, State { name: "" StateChangeScript { // [2.b] When switching back to default state, use a script to change the flags value a first time. // updateDropSite considers type Widget: drops don't work script: { mainWindow.flags = Qt.Window } // [2.c] Then flags will be reset to its default value because we use a script, not a direct binding. // updateDropSite considers type Window: drops work } } ] }
So, this solves my problem but if feels a bit too hacky, especially setting the Window type to Qt.Widget in a full Qml app... (or any invalid Window type, that's why it worked with Qt.WindowFullScreen).
Before marking this thread as (kinda) solved, I would still appreciate some feedback :).
Yann
-
Hi, I had similar issue, qml app in full screen flickers when showing dialog. This is in Win10 using Qt 5.9. Graphics NVidia GForce GT 710 (using OpenGL Version: 4.4.0 NVIDIA 378.78).
My workaround is:flags: Qt.FramelessWindowHint x: 0 y: - 1 width: Screen.width height: Screen.height + 1
This is satisfactory solution for me ;)