summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/corewlan/qcorewlanengine.mm40
-rw-r--r--src/plugins/generic/bsdkeyboard/main.cpp32
-rw-r--r--src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp32
-rw-r--r--src/plugins/generic/bsdkeyboard/qbsdkeyboard.h32
-rw-r--r--src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h36
-rw-r--r--src/plugins/generic/bsdmouse/main.cpp34
-rw-r--r--src/plugins/generic/bsdmouse/qbsdmouse.cpp34
-rw-r--r--src/plugins/generic/bsdmouse/qbsdmouse.h34
-rw-r--r--src/plugins/generic/generic.pro4
-rw-r--r--src/plugins/platforms/android/android.pro6
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp14
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.cpp5
-rw-r--r--src/plugins/platforms/android/qandroidplatformforeignwindow.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp20
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h1
-rw-r--r--src/plugins/platforms/android/qandroidplatformoffscreensurface.cpp73
-rw-r--r--src/plugins/platforms/android/qandroidplatformoffscreensurface.h67
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp13
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.h2
-rw-r--r--src/plugins/platforms/bsdfb/main.cpp34
-rw-r--r--src/plugins/platforms/bsdfb/qbsdfbintegration.cpp34
-rw-r--r--src/plugins/platforms/bsdfb/qbsdfbintegration.h34
-rw-r--r--src/plugins/platforms/bsdfb/qbsdfbscreen.cpp36
-rw-r--r--src/plugins/platforms/bsdfb/qbsdfbscreen.h34
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro2
-rw-r--r--src/plugins/platforms/cocoa/images/copyarrowcursor.pngbin1976 -> 0 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/forbiddencursor.pngbin1745 -> 0 bytes
-rw-r--r--src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.pngbin356 -> 0 bytes
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplication.mm24
-rw-r--r--src/plugins/platforms/cocoa/qcocoabackingstore.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm14
-rw-r--r--src/plugins/platforms/cocoa/qcocoacursor.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoadrag.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm14
-rw-r--r--src/plugins/platforms/cocoa/qcocoaglcontext.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm17
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h14
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm110
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenu.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoaresources.qrc17
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm6
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h84
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm959
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h9
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm146
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.h8
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm73
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp21
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp18
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h2
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp5
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp21
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp19
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp166
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp9
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp27
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h4
-rw-r--r--src/plugins/platforms/eglfs/api/api.pri13
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscontext_p.h10
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor.cpp4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfscursor_p.h16
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp11
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsintegration.cpp62
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsintegration_p.h45
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h4
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsscreen.cpp11
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfsscreen_p.h22
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow.cpp42
-rw-r--r--src/plugins/platforms/eglfs/api/qeglfswindow_p.h50
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.json3
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.pro27
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp134
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.h74
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.cpp178
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.h85
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemumain.cpp56
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h8
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp36
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h15
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp25
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h12
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp17
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h12
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp27
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp31
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h19
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp17
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h8
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp462
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h61
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp121
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h48
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp59
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h62
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h6
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp4
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h10
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h12
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h14
-rw-r--r--src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp2
-rw-r--r--src/plugins/platforms/eglfs/eglfs-plugin.pro2
-rw-r--r--src/plugins/platforms/eglfs/eglfsdeviceintegration.pro5
-rw-r--r--src/plugins/platforms/eglfs/qeglfsmain.cpp2
-rw-r--r--src/plugins/platforms/integrity/main.cpp34
-rw-r--r--src/plugins/platforms/integrity/qintegrityfbintegration.cpp34
-rw-r--r--src/plugins/platforms/integrity/qintegrityfbintegration.h34
-rw-r--r--src/plugins/platforms/integrity/qintegrityfbscreen.cpp36
-rw-r--r--src/plugins/platforms/integrity/qintegrityfbscreen.h34
-rw-r--r--src/plugins/platforms/integrity/qintegrityhidmanager.cpp34
-rw-r--r--src/plugins/platforms/integrity/qintegrityhidmanager.h34
-rw-r--r--src/plugins/platforms/ios/kernel.pro7
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro6
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm34
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h34
-rw-r--r--src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm34
-rw-r--r--src/plugins/platforms/ios/qiosbackingstore.mm12
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm49
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm3
-rw-r--r--src/plugins/platforms/ios/qiosmessagedialog.mm3
-rw-r--r--src/plugins/platforms/ios/qiosoptionalplugininterface.h34
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm12
-rw-r--r--src/plugins/platforms/ios/qiostextinputoverlay.h34
-rw-r--r--src/plugins/platforms/ios/qiostextinputoverlay.mm38
-rw-r--r--src/plugins/platforms/ios/quiview.mm26
-rw-r--r--src/plugins/platforms/linuxfb/linuxfb.pro14
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp412
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h68
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp13
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbintegration.h4
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp2
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.h6
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.cpp36
-rw-r--r--src/plugins/platforms/minimal/qminimalintegration.h3
-rw-r--r--src/plugins/platforms/minimalegl/minimalegl.pro7
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglintegration.cpp12
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglintegration.h3
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglscreen.cpp14
-rw-r--r--src/plugins/platforms/minimalegl/qminimaleglscreen.h4
-rw-r--r--src/plugins/platforms/mirclient/mirclient.pro18
-rw-r--r--src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp102
-rw-r--r--src/plugins/platforms/mirclient/qmirclientappstatecontroller.h62
-rw-r--r--src/plugins/platforms/mirclient/qmirclientbackingstore.cpp12
-rw-r--r--src/plugins/platforms/mirclient/qmirclientbackingstore.h1
-rw-r--r--src/plugins/platforms/mirclient/qmirclientclipboard.cpp303
-rw-r--r--src/plugins/platforms/mirclient/qmirclientclipboard.h37
-rw-r--r--src/plugins/platforms/mirclient/qmirclientcursor.cpp43
-rw-r--r--src/plugins/platforms/mirclient/qmirclientcursor.h2
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdebugextension.cpp79
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdebugextension.h63
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp50
-rw-r--r--src/plugins/platforms/mirclient/qmirclientdesktopwindow.h53
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.cpp159
-rw-r--r--src/plugins/platforms/mirclient/qmirclientglcontext.h28
-rw-r--r--src/plugins/platforms/mirclient/qmirclientinput.cpp331
-rw-r--r--src/plugins/platforms/mirclient/qmirclientinput.h10
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.cpp255
-rw-r--r--src/plugins/platforms/mirclient/qmirclientintegration.h47
-rw-r--r--src/plugins/platforms/mirclient/qmirclientlogging.h24
-rw-r--r--src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp103
-rw-r--r--src/plugins/platforms/mirclient/qmirclientnativeinterface.h19
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.cpp10
-rw-r--r--src/plugins/platforms/mirclient/qmirclientplugin.h3
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.cpp278
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreen.h41
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp161
-rw-r--r--src/plugins/platforms/mirclient/qmirclientscreenobserver.h78
-rw-r--r--src/plugins/platforms/mirclient/qmirclientwindow.cpp819
-rw-r--r--src/plugins/platforms/mirclient/qmirclientwindow.h50
-rw-r--r--src/plugins/platforms/platforms.pro2
-rw-r--r--src/plugins/platforms/qnx/qnx.pro14
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.cpp8
-rw-r--r--src/plugins/platforms/qnx/qqnxintegration.h4
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxscreeneventhandler.h8
-rw-r--r--src/plugins/platforms/vnc/main.cpp2
-rw-r--r--src/plugins/platforms/vnc/qvnc.cpp8
-rw-r--r--src/plugins/platforms/vnc/qvnc_p.h9
-rw-r--r--src/plugins/platforms/vnc/qvncclient.cpp4
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h18
-rw-r--r--src/plugins/platforms/vnc/qvncscreen.cpp24
-rw-r--r--src/plugins/platforms/vnc/qvncscreen.h14
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.h2
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp17
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json14
-rw-r--r--src/plugins/platforms/windows/qtwindowsglobal.h10
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.h12
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsclipboard.h20
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp140
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.h39
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.cpp527
-rw-r--r--src/plugins/platforms/windows/qwindowsdialoghelpers.h18
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp37
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.h18
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowseglcontext.h34
-rw-r--r--src/plugins/platforms/windows/qwindowsgdiintegration.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsgdinativeinterface.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsglcontext.h31
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsinputcontext.h26
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp43
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h39
-rw-r--r--src/plugins/platforms/windows/qwindowsinternalmimedata.h6
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp7
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.cpp52
-rw-r--r--src/plugins/platforms/windows/qwindowsmime.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.h6
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp16
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h20
-rw-r--r--src/plugins/platforms/windows/qwindowsole.cpp11
-rw-r--r--src/plugins/platforms/windows/qwindowsole.h12
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h10
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h53
-rw-r--r--src/plugins/platforms/windows/qwindowssessionmanager.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowssessionmanager.h14
-rw-r--r--src/plugins/platforms/windows/qwindowstabletsupport.h21
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp129
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h14
-rw-r--r--src/plugins/platforms/windows/qwindowsthreadpoolrunner.h36
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp175
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h153
-rw-r--r--src/plugins/platforms/windows/windows.pri4
-rw-r--r--src/plugins/platforms/winrt/qwinrtclipboard.cpp14
-rw-r--r--src/plugins/platforms/winrt/qwinrtclipboard.h4
-rw-r--r--src/plugins/platforms/winrt/qwinrtdrag.cpp2
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp143
-rw-r--r--src/plugins/platforms/winrt/qwinrtfiledialoghelper.h5
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp8
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp17
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp20
-rw-r--r--src/plugins/platforms/winrt/qwinrttheme.cpp98
-rw-r--r--src/plugins/platforms/winrt/qwinrtwindow.cpp2
-rw-r--r--src/plugins/platforms/winrt/winrt.pro2
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h10
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp73
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h101
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp50
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h14
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp3
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h30
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp39
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h44
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3menu.cpp36
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3menu.h34
-rw-r--r--src/plugins/platformthemes/gtk3/qgtk3theme.cpp23
-rw-r--r--src/plugins/sqldrivers/psql/qsql_psql.cpp2
-rw-r--r--src/plugins/sqldrivers/tds/qsql_tds.cpp7
277 files changed, 7029 insertions, 4639 deletions
diff --git a/src/plugins/bearer/corewlan/qcorewlanengine.mm b/src/plugins/bearer/corewlan/qcorewlanengine.mm
index 7cf9365513..341d3bccf2 100644
--- a/src/plugins/bearer/corewlan/qcorewlanengine.mm
+++ b/src/plugins/bearer/corewlan/qcorewlanengine.mm
@@ -61,14 +61,14 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time
#include <net/if.h>
#include <ifaddrs.h>
-@interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject
+@interface QT_MANGLE_NAMESPACE(QNSListener) : NSObject <CWEventDelegate>
{
NSNotificationCenter *notificationCenter;
- CWInterface *currentInterface;
+ CWWiFiClient *client;
QCoreWlanEngine *engine;
NSLock *locker;
}
-- (void)notificationHandler:(NSNotification *)notification;
+- (void)powerStateDidChangeForWiFiInterfaceWithName:(NSString *)interfaceName;
- (void)remove;
- (void)setEngine:(QCoreWlanEngine *)coreEngine;
- (QCoreWlanEngine *)engine;
@@ -85,8 +85,9 @@ extern "C" { // Otherwise it won't find CWKeychain* symbols at link time
[locker lock];
QMacAutoReleasePool pool;
notificationCenter = [NSNotificationCenter defaultCenter];
- currentInterface = [CWInterface interface];
- [notificationCenter addObserver:self selector:@selector(notificationHandler:) name:CWPowerDidChangeNotification object:nil];
+ client = [CWWiFiClient sharedWiFiClient];
+ client.delegate = self;
+ [client startMonitoringEventWithType:CWEventTypePowerDidChange error:nil];
[locker unlock];
return self;
}
@@ -95,6 +96,7 @@ static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0;
-(void)dealloc
{
+ client.delegate = nil;
listener = nil;
[super dealloc];
}
@@ -115,13 +117,13 @@ static QT_MANGLE_NAMESPACE(QNSListener) *listener = 0;
-(void)remove
{
[locker lock];
- [notificationCenter removeObserver:self];
+ [client stopMonitoringAllEventsAndReturnError:nil];
[locker unlock];
}
-- (void)notificationHandler:(NSNotification *)notification
+- (void)powerStateDidChangeForWiFiInterfaceWithName:(NSString *)interfaceName
{
- Q_UNUSED(notification);
+ Q_UNUSED(interfaceName);
engine->requestUpdate();
}
@end
@@ -162,7 +164,8 @@ void QScanThread::run()
QMacAutoReleasePool pool;
QStringList found;
mutex.lock();
- CWInterface *currentInterface = [CWInterface interfaceWithName:interfaceName.toNSString()];
+ CWInterface *currentInterface = [[CWWiFiClient sharedWiFiClient]
+ interfaceWithName:interfaceName.toNSString()];
mutex.unlock();
const bool currentInterfaceServiceActive = currentInterface.serviceActive;
@@ -284,10 +287,10 @@ void QScanThread::getUserConfigurations()
QMacAutoReleasePool pool;
userProfiles.clear();
- NSSet *wifiInterfaces = [CWInterface interfaceNames];
+ NSArray<NSString *> *wifiInterfaces = [CWWiFiClient interfaceNames];
for (NSString *ifName in wifiInterfaces) {
- CWInterface *wifiInterface = [CWInterface interfaceWithName:ifName];
+ CWInterface *wifiInterface = [[CWWiFiClient sharedWiFiClient] interfaceWithName:ifName];
NSString *nsInterfaceName = wifiInterface.ssid;
// add user configured system networks
@@ -442,7 +445,7 @@ void QCoreWlanEngine::initialize()
QMutexLocker locker(&mutex);
QMacAutoReleasePool pool;
- if ([[CWInterface interfaceNames] count] > 0 && !listener) {
+ if ([[CWWiFiClient interfaceNames] count] > 0 && !listener) {
listener = [[QT_MANGLE_NAMESPACE(QNSListener) alloc] init];
listener.engine = this;
hasWifi = true;
@@ -476,7 +479,7 @@ void QCoreWlanEngine::connectToId(const QString &id)
QString interfaceString = getInterfaceFromId(id);
CWInterface *wifiInterface =
- [CWInterface interfaceWithName:interfaceString.toNSString()];
+ [[CWWiFiClient sharedWiFiClient] interfaceWithName:interfaceString.toNSString()];
if (wifiInterface.powerOn) {
NSError *err = nil;
@@ -559,7 +562,7 @@ void QCoreWlanEngine::disconnectFromId(const QString &id)
QMacAutoReleasePool pool;
CWInterface *wifiInterface =
- [CWInterface interfaceWithName:interfaceString.toNSString()];
+ [[CWWiFiClient sharedWiFiClient] interfaceWithName:interfaceString.toNSString()];
disconnectedInterfaceString = interfaceString;
[wifiInterface disassociate];
@@ -573,8 +576,8 @@ void QCoreWlanEngine::checkDisconnect()
if (!disconnectedInterfaceString.isEmpty()) {
QMacAutoReleasePool pool;
- CWInterface *wifiInterface =
- [CWInterface interfaceWithName:disconnectedInterfaceString.toNSString()];
+ CWInterface *wifiInterface = [[CWWiFiClient sharedWiFiClient]
+ interfaceWithName:disconnectedInterfaceString.toNSString()];
const QString networkSsid = QString::fromNSString([wifiInterface ssid]);
if (!networkSsid.isEmpty()) {
@@ -599,7 +602,7 @@ void QCoreWlanEngine::doRequestUpdate()
QMacAutoReleasePool pool;
- NSSet *wifiInterfaces = [CWInterface interfaceNames];
+ NSArray<NSString *> *wifiInterfaces = [CWWiFiClient interfaceNames];
for (NSString *ifName in wifiInterfaces) {
scanThread->interfaceName = QString::fromNSString(ifName);
scanThread->start();
@@ -615,7 +618,8 @@ bool QCoreWlanEngine::isWifiReady(const QString &wifiDeviceName)
bool haswifi = false;
if(hasWifi) {
QMacAutoReleasePool pool;
- CWInterface *defaultInterface = [CWInterface interfaceWithName:wifiDeviceName.toNSString()];
+ CWInterface *defaultInterface = [[CWWiFiClient sharedWiFiClient]
+ interfaceWithName:wifiDeviceName.toNSString()];
if (defaultInterface.powerOn) {
haswifi = true;
}
diff --git a/src/plugins/generic/bsdkeyboard/main.cpp b/src/plugins/generic/bsdkeyboard/main.cpp
index f48af0ae28..b65d500230 100644
--- a/src/plugins/generic/bsdkeyboard/main.cpp
+++ b/src/plugins/generic/bsdkeyboard/main.cpp
@@ -3,29 +3,35 @@
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp
index 6f34d066c6..784ec54542 100644
--- a/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp
+++ b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.cpp
@@ -3,29 +3,35 @@
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h
index 1a7cbc1f9a..46d8988d3a 100644
--- a/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h
+++ b/src/plugins/generic/bsdkeyboard/qbsdkeyboard.h
@@ -3,29 +3,35 @@
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h b/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h
index 45cf5944bc..69c03b3daf 100644
--- a/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h
+++ b/src/plugins/generic/bsdkeyboard/qbsdkeyboard_defaultmap.h
@@ -1,32 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/bsdmouse/main.cpp b/src/plugins/generic/bsdmouse/main.cpp
index 4abc7609c1..d676d5a1bb 100644
--- a/src/plugins/generic/bsdmouse/main.cpp
+++ b/src/plugins/generic/bsdmouse/main.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/bsdmouse/qbsdmouse.cpp b/src/plugins/generic/bsdmouse/qbsdmouse.cpp
index 4875fd96bd..55905199b8 100644
--- a/src/plugins/generic/bsdmouse/qbsdmouse.cpp
+++ b/src/plugins/generic/bsdmouse/qbsdmouse.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/bsdmouse/qbsdmouse.h b/src/plugins/generic/bsdmouse/qbsdmouse.h
index 9a4cb8dd82..724b9c8484 100644
--- a/src/plugins/generic/bsdmouse/qbsdmouse.h
+++ b/src/plugins/generic/bsdmouse/qbsdmouse.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/generic/generic.pro b/src/plugins/generic/generic.pro
index 996e57d015..e323f32d2c 100644
--- a/src/plugins/generic/generic.pro
+++ b/src/plugins/generic/generic.pro
@@ -2,7 +2,9 @@ TEMPLATE = subdirs
QT_FOR_CONFIG += gui-private network-private
qtConfig(evdev) {
- SUBDIRS += evdevmouse evdevtouch evdevkeyboard evdevtablet
+ SUBDIRS += evdevmouse evdevtouch evdevkeyboard
+ qtConfig(tabletevent): \
+ SUBDIRS += evdevtablet
}
qtConfig(tslib) {
diff --git a/src/plugins/platforms/android/android.pro b/src/plugins/platforms/android/android.pro
index bd3fe5a6cc..03592bfa7d 100644
--- a/src/plugins/platforms/android/android.pro
+++ b/src/plugins/platforms/android/android.pro
@@ -43,7 +43,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
$$PWD/qandroidplatformbackingstore.cpp \
$$PWD/qandroidplatformopenglcontext.cpp \
$$PWD/qandroidplatformforeignwindow.cpp \
- $$PWD/qandroideventdispatcher.cpp
+ $$PWD/qandroideventdispatcher.cpp \
+ $$PWD/qandroidplatformoffscreensurface.cpp
HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/androiddeadlockprotector.h \
@@ -71,7 +72,8 @@ HEADERS += $$PWD/qandroidplatformintegration.h \
$$PWD/qandroidplatformbackingstore.h \
$$PWD/qandroidplatformopenglcontext.h \
$$PWD/qandroidplatformforeignwindow.h \
- $$PWD/qandroideventdispatcher.h
+ $$PWD/qandroideventdispatcher.h \
+ $$PWD/qandroidplatformoffscreensurface.h
qtConfig(android-style-assets): SOURCES += $$PWD/extract.cpp
else: SOURCES += $$PWD/extract-dummy.cpp
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index d3bb089aa4..8372bf6484 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -206,7 +206,8 @@ namespace QtAndroidInput
m_touchPoints.clear();
}
- static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean /*primary*/, jint x, jint y, jfloat size, jfloat pressure)
+ static void touchAdd(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint id, jint action, jboolean /*primary*/, jint x, jint y,
+ jfloat major, jfloat minor, jfloat rotation, jfloat pressure)
{
Qt::TouchPointState state = Qt::TouchPointStationary;
switch (action) {
@@ -229,12 +230,13 @@ namespace QtAndroidInput
QWindowSystemInterface::TouchPoint touchPoint;
touchPoint.id = id;
touchPoint.pressure = pressure;
+ touchPoint.rotation = rotation * 180 / M_PI;
touchPoint.normalPosition = QPointF(double(x / dw), double(y / dh));
touchPoint.state = state;
- touchPoint.area = QRectF(x - double(dw*size) / 2.0,
- y - double(dh*size) / 2.0,
- double(dw*size),
- double(dh*size));
+ touchPoint.area = QRectF(x - double(minor),
+ y - double(major),
+ double(minor * 2),
+ double(major * 2));
m_touchPoints.push_back(touchPoint);
if (state == Qt::TouchPointPressed) {
@@ -817,7 +819,7 @@ namespace QtAndroidInput
static JNINativeMethod methods[] = {
{"touchBegin","(I)V",(void*)touchBegin},
- {"touchAdd","(IIIZIIFF)V",(void*)touchAdd},
+ {"touchAdd","(IIIZIIFFFF)V",(void*)touchAdd},
{"touchEnd","(II)V",(void*)touchEnd},
{"mouseDown", "(III)V", (void *)mouseDown},
{"mouseUp", "(III)V", (void *)mouseUp},
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
index 8c1f0ea8d2..1c920c0af9 100644
--- a/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.cpp
@@ -45,12 +45,11 @@
QT_BEGIN_NAMESPACE
-QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window)
+QAndroidPlatformForeignWindow::QAndroidPlatformForeignWindow(QWindow *window, WId nativeHandle)
: QAndroidPlatformWindow(window),
m_surfaceId(-1)
{
- const WId wId = window->property("_q_foreignWinId").value<WId>();
- m_view = reinterpret_cast<jobject>(wId);
+ m_view = reinterpret_cast<jobject>(nativeHandle);
if (m_view.isValid())
QtAndroid::setViewVisibility(m_view.object(), false);
}
diff --git a/src/plugins/platforms/android/qandroidplatformforeignwindow.h b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
index d42c36dcee..af1eee5499 100644
--- a/src/plugins/platforms/android/qandroidplatformforeignwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformforeignwindow.h
@@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE
class QAndroidPlatformForeignWindow : public QAndroidPlatformWindow
{
public:
- explicit QAndroidPlatformForeignWindow(QWindow *window);
+ explicit QAndroidPlatformForeignWindow(QWindow *window, WId nativeHandle);
~QAndroidPlatformForeignWindow();
void lower() override;
void raise() override;
@@ -57,6 +57,7 @@ public:
void setVisible(bool visible) override;
void applicationStateChanged(Qt::ApplicationState state) override;
void setParent(const QPlatformWindow *window) override;
+ bool isForeignWindow() const override { return true; }
private:
int m_surfaceId;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index de9e27e595..73aa9d0e8a 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -65,6 +65,7 @@
#include "qandroidplatformservices.h"
#include "qandroidplatformtheme.h"
#include "qandroidsystemlocale.h"
+#include "qandroidplatformoffscreensurface.h"
#include <QtPlatformHeaders/QEGLNativeContext>
@@ -262,12 +263,20 @@ QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenS
{
if (!QtAndroid::activity())
return nullptr;
+
QSurfaceFormat format(surface->requestedFormat());
format.setAlphaBufferSize(8);
format.setRedBufferSize(8);
format.setGreenBufferSize(8);
format.setBlueBufferSize(8);
+ if (surface->nativeHandle()) {
+ // Adopt existing offscreen Surface
+ // The expectation is that nativeHandle is an ANativeWindow* representing
+ // an android.view.Surface
+ return new QAndroidPlatformOffscreenSurface(m_eglDisplay, format, surface);
+ }
+
return new QEGLPbuffer(m_eglDisplay, format, surface);
}
@@ -275,10 +284,13 @@ QPlatformWindow *QAndroidPlatformIntegration::createPlatformWindow(QWindow *wind
{
if (!QtAndroid::activity())
return nullptr;
- if (window->type() == Qt::ForeignWindow)
- return new QAndroidPlatformForeignWindow(window);
- else
- return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
+
+ return new QAndroidPlatformOpenGLWindow(window, m_eglDisplay);
+}
+
+QPlatformWindow *QAndroidPlatformIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
+{
+ return new QAndroidPlatformForeignWindow(window, nativeHandle);
}
QAbstractEventDispatcher *QAndroidPlatformIntegration::createEventDispatcher() const
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 2337801250..be10c3d161 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -78,6 +78,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const override;
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
+ QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
QAbstractEventDispatcher *createEventDispatcher() const override;
diff --git a/src/plugins/platforms/android/qandroidplatformoffscreensurface.cpp b/src/plugins/platforms/android/qandroidplatformoffscreensurface.cpp
new file mode 100644
index 0000000000..c7d832efb6
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformoffscreensurface.cpp
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qandroidplatformoffscreensurface.h"
+
+#include <QtGui/QOffscreenSurface>
+#include <QtEglSupport/private/qeglconvenience_p.h>
+
+#include <android/native_window.h>
+
+QT_BEGIN_NAMESPACE
+
+QAndroidPlatformOffscreenSurface::QAndroidPlatformOffscreenSurface(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
+ : QPlatformOffscreenSurface(offscreenSurface)
+ , m_format(format)
+ , m_display(display)
+ , m_surface(EGL_NO_SURFACE)
+{
+ // Get native handle
+ ANativeWindow *surfaceTexture = (ANativeWindow*)offscreenSurface->nativeHandle();
+
+ EGLConfig config = q_configFromGLFormat(m_display, m_format, false);
+ if (config) {
+ const EGLint attributes[] = {
+ EGL_NONE
+ };
+ m_surface = eglCreateWindowSurface(m_display, config, surfaceTexture, attributes);
+ }
+}
+
+QAndroidPlatformOffscreenSurface::~QAndroidPlatformOffscreenSurface()
+{
+ eglDestroySurface(m_display, m_surface);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/plugins/platforms/android/qandroidplatformoffscreensurface.h b/src/plugins/platforms/android/qandroidplatformoffscreensurface.h
new file mode 100644
index 0000000000..461f949254
--- /dev/null
+++ b/src/plugins/platforms/android/qandroidplatformoffscreensurface.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANDROIDPLATFORMOFFSCREENSURFACETEXTURE_H
+#define QANDROIDPLATFORMOFFSCREENSURFACETEXTURE_H
+
+#include <qpa/qplatformoffscreensurface.h>
+#include <QtEglSupport/private/qeglplatformcontext_p.h>
+
+QT_BEGIN_NAMESPACE
+class QOffscreenSurface;
+class QAndroidPlatformOffscreenSurface : public QPlatformOffscreenSurface
+{
+public:
+ QAndroidPlatformOffscreenSurface(EGLDisplay display, const QSurfaceFormat &format,
+ QOffscreenSurface *offscreenSurface);
+ ~QAndroidPlatformOffscreenSurface();
+
+ QSurfaceFormat format() const override { return m_format; }
+ bool isValid() const override { return m_surface != EGL_NO_SURFACE; }
+
+ EGLSurface surface() const { return m_surface; }
+private:
+ QSurfaceFormat m_format;
+ EGLDisplay m_display;
+ EGLSurface m_surface;
+};
+
+QT_END_NAMESPACE
+
+#endif // QANDROIDPLATFORMOFFSCREENSURFACETEXTURE_H
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 4d52085a83..d3810329c5 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -41,11 +41,13 @@
#include "qandroidplatformopenglcontext.h"
#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformintegration.h"
+#include "qandroidplatformoffscreensurface.h"
#include <QtEglSupport/private/qeglpbuffer_p.h>
#include <QSurface>
#include <QtGui/private/qopenglcontext_p.h>
+#include <QtGui/QOffscreenSurface>
QT_BEGIN_NAMESPACE
@@ -106,10 +108,15 @@ bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
- if (surface->surface()->surfaceClass() == QSurface::Window)
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
- else
- return static_cast<QEGLPbuffer *>(surface)->pbuffer();
+ } else {
+ auto platformOffscreenSurface = static_cast<QPlatformOffscreenSurface*>(surface);
+ if (platformOffscreenSurface->offscreenSurface()->nativeHandle())
+ return static_cast<QAndroidPlatformOffscreenSurface *>(surface)->surface();
+ else
+ return static_cast<QEGLPbuffer *>(surface)->pbuffer();
+ }
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h
index 87e5cbaa4f..91cb1e76e6 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.h
+++ b/src/plugins/platforms/android/qandroidplatformwindow.h
@@ -71,7 +71,7 @@ public:
void requestActivateWindow() override;
void updateStatusBarVisibility();
inline bool isRaster() const {
- if ((window()->flags() & Qt::ForeignWindow) == Qt::ForeignWindow)
+ if (isForeignWindow())
return false;
return window()->surfaceType() == QSurface::RasterSurface
diff --git a/src/plugins/platforms/bsdfb/main.cpp b/src/plugins/platforms/bsdfb/main.cpp
index f4ab3dee39..b2cd1373a7 100644
--- a/src/plugins/platforms/bsdfb/main.cpp
+++ b/src/plugins/platforms/bsdfb/main.cpp
@@ -1,32 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp b/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp
index 1fa13183f8..6a7d445e69 100644
--- a/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp
+++ b/src/plugins/platforms/bsdfb/qbsdfbintegration.cpp
@@ -1,32 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/bsdfb/qbsdfbintegration.h b/src/plugins/platforms/bsdfb/qbsdfbintegration.h
index 2be5ea260d..81195edf7e 100644
--- a/src/plugins/platforms/bsdfb/qbsdfbintegration.h
+++ b/src/plugins/platforms/bsdfb/qbsdfbintegration.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp b/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp
index 0ef57d37e5..067a26a7b1 100644
--- a/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp
+++ b/src/plugins/platforms/bsdfb/qbsdfbscreen.cpp
@@ -1,32 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -243,7 +249,7 @@ QRegion QBsdFbScreen::doRedraw()
const auto rects = touched.rects();
for (const QRect &rect : rects)
- m_blitter->drawImage(rect, *mScreenImage, rect);
+ m_blitter->drawImage(rect, mScreenImage, rect);
return touched;
}
diff --git a/src/plugins/platforms/bsdfb/qbsdfbscreen.h b/src/plugins/platforms/bsdfb/qbsdfbscreen.h
index 3e244e3460..890a2eb757 100644
--- a/src/plugins/platforms/bsdfb/qbsdfbscreen.h
+++ b/src/plugins/platforms/bsdfb/qbsdfbscreen.h
@@ -1,32 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
** Copyright (C) 2015-2016 Oleksandr Tymoshenko <gonzo@bluezbox.com>
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index 0664841c2d..62935210be 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -86,6 +86,8 @@ QT += \
accessibility_support-private clipboard_support-private theme_support-private \
fontdatabase_support-private graphics_support-private cgl_support-private
+CONFIG += no_app_extension_api_only
+
qtHaveModule(widgets) {
OBJECTIVE_SOURCES += \
qpaintengine_mac.mm \
diff --git a/src/plugins/platforms/cocoa/images/copyarrowcursor.png b/src/plugins/platforms/cocoa/images/copyarrowcursor.png
deleted file mode 100644
index 13dfca95bc..0000000000
--- a/src/plugins/platforms/cocoa/images/copyarrowcursor.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/forbiddencursor.png b/src/plugins/platforms/cocoa/images/forbiddencursor.png
deleted file mode 100644
index a9f21b4a5e..0000000000
--- a/src/plugins/platforms/cocoa/images/forbiddencursor.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png b/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png
deleted file mode 100644
index 6716597046..0000000000
--- a/src/plugins/platforms/cocoa/images/leopard-unified-toolbar-on.png
+++ /dev/null
Binary files differ
diff --git a/src/plugins/platforms/cocoa/qcocoaapplication.mm b/src/plugins/platforms/cocoa/qcocoaapplication.mm
index c5ae4bc2bf..3b950efa55 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplication.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplication.mm
@@ -76,6 +76,7 @@
#include "qcocoaintrospection.h"
#include "qcocoaapplicationdelegate.h"
#include "qcocoahelpers.h"
+#include "qcocoawindow.h"
#include <qguiapplication.h>
#include <qdebug.h>
@@ -148,6 +149,21 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
@end
+static void qt_maybeSendKeyEquivalentUpEvent(NSEvent *event)
+{
+ // Cocoa is known for not sending key up events for key
+ // equivalents, regardless of whether it's an actual
+ // recognized key equivalent. We decide to force fate
+ // and forward the key event to the key (focus) window.
+ // However, non-Qt windows will not (and should not) get
+ // any special treatment, only QWindow-owned NSWindows.
+ if (event.type == NSKeyUp && (event.modifierFlags & NSCommandKeyMask)) {
+ NSWindow *targetWindow = event.window;
+ if ([targetWindow.class conformsToProtocol:@protocol(QNSWindowProtocol)])
+ [targetWindow sendEvent:event];
+ }
+}
+
@implementation QT_MANGLE_NAMESPACE(QNSApplication)
- (void)QT_MANGLE_NAMESPACE(qt_sendEvent_original):(NSEvent *)event
@@ -164,16 +180,20 @@ static const QByteArray q_macLocalEventType = QByteArrayLiteral("mac_generic_NSE
// be called instead of sendEvent if redirection occurs.
// 'self' will then be an instance of NSApplication
// (and not QNSApplication)
- if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event])
+ if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event]) {
[self QT_MANGLE_NAMESPACE(qt_sendEvent_original):event];
+ qt_maybeSendKeyEquivalentUpEvent(event);
+ }
}
- (void)sendEvent:(NSEvent *)event
{
// This method will be called if
// no redirection occurs
- if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event])
+ if (![NSApp QT_MANGLE_NAMESPACE(qt_filterEvent):event]) {
[super sendEvent:event];
+ qt_maybeSendKeyEquivalentUpEvent(event);
+ }
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
index a74995319b..1d7ad772dc 100644
--- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm
+++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm
@@ -57,7 +57,8 @@ QCocoaBackingStore::~QCocoaBackingStore()
QImage::Format QCocoaBackingStore::format() const
{
- if (static_cast<QCocoaWindow *>(window()->handle())->m_drawContentBorderGradient)
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle());
+ if (cocoaWindow && cocoaWindow->m_drawContentBorderGradient)
return QImage::Format_ARGB32_Premultiplied;
return QRasterBackingStore::format();
diff --git a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
index e53c085e41..a8974c4de5 100644
--- a/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoacolordialoghelper.mm
@@ -80,7 +80,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
mHelper = 0;
mStolenContentView = 0;
mPanelButtons = nil;
- mResultCode = NSCancelButton;
+ mResultCode = NSModalResponseCancel;
mDialogIsExecuting = false;
mResultSet = false;
mClosingDueToKnownButton = false;
@@ -168,7 +168,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
mClosingDueToKnownButton = true;
[mColorPanel close];
[self updateQtColor];
- [self finishOffWithCode:NSOKButton];
+ [self finishOffWithCode:NSModalResponseOK];
}
- (void)onCancelClicked
@@ -177,7 +177,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
mClosingDueToKnownButton = true;
[mColorPanel close];
mQtColor = QColor();
- [self finishOffWithCode:NSCancelButton];
+ [self finishOffWithCode:NSModalResponseCancel];
}
}
@@ -238,12 +238,12 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
[NSApp runModalForWindow:mColorPanel];
mDialogIsExecuting = false;
- return (mResultCode == NSOKButton);
+ return (mResultCode == NSModalResponseOK);
}
- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
+ return (mResultCode == NSModalResponseOK) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
@@ -252,7 +252,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
if (!mPanelButtons)
[self updateQtColor];
if (mDialogIsExecuting) {
- [self finishOffWithCode:NSCancelButton];
+ [self finishOffWithCode:NSModalResponseCancel];
} else {
mResultSet = true;
if (mHelper)
@@ -278,7 +278,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSColorPanelDelegate);
// This check will prevent any such recursion.
if (!mResultSet) {
mResultSet = true;
- if (mResultCode == NSCancelButton) {
+ if (mResultCode == NSModalResponseCancel) {
emit mHelper->reject();
} else {
emit mHelper->accept();
diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm
index 3df2a7c962..99a136d384 100644
--- a/src/plugins/platforms/cocoa/qcocoacursor.mm
+++ b/src/plugins/platforms/cocoa/qcocoacursor.mm
@@ -97,6 +97,9 @@ NSCursor *QCocoaCursor::convertCursor(QCursor *cursor)
case Qt::ArrowCursor:
cocoaCursor= [NSCursor arrowCursor];
break;
+ case Qt::ForbiddenCursor:
+ cocoaCursor = [NSCursor operationNotAllowedCursor];
+ break;
case Qt::CrossCursor:
cocoaCursor = [NSCursor crosshairCursor];
break;
@@ -123,7 +126,7 @@ NSCursor *QCocoaCursor::convertCursor(QCursor *cursor)
cocoaCursor = [NSCursor crosshairCursor];
break;
case Qt::DragCopyCursor:
- cocoaCursor = [NSCursor crosshairCursor];
+ cocoaCursor = [NSCursor dragCopyCursor];
break;
case Qt::DragLinkCursor:
cocoaCursor = [NSCursor dragLinkCursor];
@@ -235,10 +238,6 @@ NSCursor *QCocoaCursor::createCursorData(QCursor *cursor)
QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/waitcursor.png"));
return createCursorFromPixmap(pixmap, hotspot);
break; }
- case Qt::ForbiddenCursor: {
- QPixmap pixmap = QPixmap(QLatin1String(":/qt-project.org/mac/cursors/images/forbiddencursor.png"));
- return createCursorFromPixmap(pixmap, hotspot);
- break; }
#define QT_USE_APPROXIMATE_CURSORS
#ifdef QT_USE_APPROXIMATE_CURSORS
case Qt::SizeVerCursor:
diff --git a/src/plugins/platforms/cocoa/qcocoadrag.mm b/src/plugins/platforms/cocoa/qcocoadrag.mm
index a0967750e7..c71e80d191 100644
--- a/src/plugins/platforms/cocoa/qcocoadrag.mm
+++ b/src/plugins/platforms/cocoa/qcocoadrag.mm
@@ -132,7 +132,7 @@ Qt::DropAction QCocoaDrag::drag(QDrag *o)
QPixmap pm = dragPixmap(m_drag, hotSpot);
QSize pmDeviceIndependentSize = pm.size() / pm.devicePixelRatio();
NSImage *nsimage = qt_mac_create_nsimage(pm);
- [nsimage setSize:pmDeviceIndependentSize.toCGSize()];
+ [nsimage setSize:NSSizeFromCGSize(pmDeviceIndependentSize.toCGSize())];
QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacInternalPasteboardMime::MIME_DND);
m_drag->mimeData()->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy"));
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 72c7856c2d..d2f985ec87 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -401,7 +401,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
// [NSApp run], which is the normal code path for cocoa applications.
if (NSModalSession session = d->currentModalSession()) {
QBoolBlocker execGuard(d->currentExecIsNSAppRun, false);
- while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt)
+ while ([NSApp runModalSession:session] == NSModalResponseContinue && !d->interrupt)
qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode);
if (!d->interrupt && session == d->currentModalSessionCached) {
@@ -435,7 +435,7 @@ bool QCocoaEventDispatcher::processEvents(QEventLoop::ProcessEventsFlags flags)
if (flags & QEventLoop::WaitForMoreEvents)
qt_mac_waitForMoreEvents(NSModalPanelRunLoopMode);
NSInteger status = [NSApp runModalSession:session];
- if (status != NSRunContinuesResponse && session == d->currentModalSessionCached) {
+ if (status != NSModalResponseContinue && session == d->currentModalSessionCached) {
// INVARIANT: Someone called [NSApp stopModal:] from outside the event
// dispatcher (e.g to stop a native dialog). But that call wrongly stopped
// 'session' as well. As a result, we need to restart all internal sessions:
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index 234da57f59..41a809cdd2 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -63,6 +63,7 @@
#include <stdlib.h>
#include <qabstracteventdispatcher.h>
#include <qsysinfo.h>
+#include <qoperatingsystemversion.h>
#include <qglobal.h>
#include <QDir>
@@ -164,7 +165,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSOpenSavePanelDelegate);
[mSavePanel setDelegate:self];
#if QT_OSX_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_11)
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_11)
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::OSXElCapitan)
mOpenPanel.accessoryViewDisclosed = YES;
#endif
diff --git a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
index 33dd4260a5..e4b796dcde 100644
--- a/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafontdialoghelper.mm
@@ -106,7 +106,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
mHelper = 0;
mStolenContentView = 0;
mPanelButtons = 0;
- mResultCode = NSCancelButton;
+ mResultCode = NSModalResponseCancel;
mDialogIsExecuting = false;
mResultSet = false;
@@ -171,7 +171,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
- (void)onOkClicked
{
[mFontPanel close];
- [self finishOffWithCode:NSOKButton];
+ [self finishOffWithCode:NSModalResponseOK];
}
- (void)onCancelClicked
@@ -179,7 +179,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
if (mPanelButtons) {
[mFontPanel close];
mQtFont = QFont();
- [self finishOffWithCode:NSCancelButton];
+ [self finishOffWithCode:NSModalResponseCancel];
}
}
@@ -224,12 +224,12 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
[NSApp runModalForWindow:mFontPanel];
mDialogIsExecuting = false;
- return (mResultCode == NSOKButton);
+ return (mResultCode == NSModalResponseOK);
}
- (QPlatformDialogHelper::DialogCode)dialogResultCode
{
- return (mResultCode == NSOKButton) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
+ return (mResultCode == NSModalResponseOK) ? QPlatformDialogHelper::Accepted : QPlatformDialogHelper::Rejected;
}
- (BOOL)windowShouldClose:(id)window
@@ -238,7 +238,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
if (!mPanelButtons)
[self updateQtFont];
if (mDialogIsExecuting) {
- [self finishOffWithCode:NSCancelButton];
+ [self finishOffWithCode:NSModalResponseCancel];
} else {
mResultSet = true;
if (mHelper)
@@ -264,7 +264,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSFontPanelDelegate);
// This check will prevent any such recursion.
if (!mResultSet) {
mResultSet = true;
- if (mResultCode == NSCancelButton) {
+ if (mResultCode == NSModalResponseCancel) {
emit mHelper->reject();
} else {
emit mHelper->accept();
diff --git a/src/plugins/platforms/cocoa/qcocoaglcontext.mm b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
index a7cc19b3bf..9e688f4d1b 100644
--- a/src/plugins/platforms/cocoa/qcocoaglcontext.mm
+++ b/src/plugins/platforms/cocoa/qcocoaglcontext.mm
@@ -255,7 +255,8 @@ void QCocoaGLContext::setActiveWindow(QWindow *window)
QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
cocoaWindow->setCurrentContext(this);
- [(QNSView *) cocoaWindow->view() setQCocoaGLContext:this];
+ Q_ASSERT(!cocoaWindow->isForeignWindow());
+ [qnsview_cast(cocoaWindow->view()) setQCocoaGLContext:this];
}
void QCocoaGLContext::updateSurfaceFormat()
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index 3ab6b641fa..232e40769b 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -151,7 +151,8 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
a no-op.
For extra verbosity and clearer code, please consider checking
- that window()->type() != Qt::ForeignWindow before using this cast.
+ that the platform window is not a foreign window before using
+ this cast, via QPlatformWindow::isForeignWindow().
Do not use this method soley to check for foreign windows, as
that will make the code harder to read for people not working
@@ -160,10 +161,8 @@ Qt::DropActions qt_mac_mapNSDragOperations(NSDragOperation nsActions)
*/
QNSView *qnsview_cast(NSView *view)
{
- if (![view isKindOfClass:[QNSView class]]) {
- qCWarning(lcQpaCocoaWindow) << "NSView is not QNSView, consider checking for Qt::ForeignWindow";
+ if (![view isKindOfClass:[QNSView class]])
return nil;
- }
return static_cast<QNSView *>(view);
}
@@ -235,13 +234,13 @@ QString qt_mac_applicationName()
return appName;
}
-int qt_mac_mainScreenHeight()
+int qt_mac_primaryScreenHeight()
{
QMacAutoReleasePool pool;
NSArray *screens = [NSScreen screens];
if ([screens count] > 0) {
- // The first screen in the screens array is documented
- // to have the (0,0) origin.
+ // The first screen in the screens array is documented to
+ // have the (0,0) origin and is designated the primary screen.
NSRect screenFrame = [[screens objectAtIndex: 0] frame];
return screenFrame.size.height;
}
@@ -250,12 +249,12 @@ int qt_mac_mainScreenHeight()
int qt_mac_flipYCoordinate(int y)
{
- return qt_mac_mainScreenHeight() - y;
+ return qt_mac_primaryScreenHeight() - y;
}
qreal qt_mac_flipYCoordinate(qreal y)
{
- return qt_mac_mainScreenHeight() - y;
+ return qt_mac_primaryScreenHeight() - y;
}
QPointF qt_mac_flipPoint(const NSPoint &p)
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index 32f6fe0af1..ecdd20c4dc 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -84,9 +84,18 @@ public:
// ----------------------------------------------------
// Additional methods
void setVirtualSiblings(const QList<QPlatformScreen *> &siblings) { m_siblings = siblings; }
- NSScreen *osScreen() const;
+ NSScreen *nativeScreen() const;
void updateGeometry();
+ QPointF mapToNative(const QPointF &pos) const { return flipCoordinate(pos); }
+ QRectF mapToNative(const QRectF &rect) const { return flipCoordinate(rect); }
+ QPointF mapFromNative(const QPointF &pos) const { return flipCoordinate(pos); }
+ QRectF mapFromNative(const QRectF &rect) const { return flipCoordinate(rect); }
+
+private:
+ QPointF flipCoordinate(const QPointF &pos) const;
+ QRectF flipCoordinate(const QRectF &rect) const;
+
public:
int m_screenIndex;
QRect m_geometry;
@@ -117,6 +126,7 @@ public:
bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const Q_DECL_OVERRIDE;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
#endif
@@ -144,7 +154,7 @@ public:
QList<int> possibleKeys(const QKeyEvent *event) const Q_DECL_OVERRIDE;
void updateScreens();
- QCocoaScreen *screenAtIndex(int index);
+ QCocoaScreen *screenForNSScreen(NSScreen *nsScreen);
void setToolbar(QWindow *window, NSToolbar *toolbar);
NSToolbar *toolbar(QWindow *window) const;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 18340f4ee1..91f408e5c2 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -69,8 +69,8 @@ static void initResources()
QT_BEGIN_NAMESPACE
-QCocoaScreen::QCocoaScreen(int screenIndex) :
- QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
+QCocoaScreen::QCocoaScreen(int screenIndex)
+ : QPlatformScreen(), m_screenIndex(screenIndex), m_refreshRate(60.0)
{
updateGeometry();
m_cursor = new QCocoaCursor;
@@ -81,41 +81,65 @@ QCocoaScreen::~QCocoaScreen()
delete m_cursor;
}
-NSScreen *QCocoaScreen::osScreen() const
+NSScreen *QCocoaScreen::nativeScreen() const
{
NSArray *screens = [NSScreen screens];
- return ((NSUInteger)m_screenIndex < [screens count]) ? [screens objectAtIndex:m_screenIndex] : nil;
+
+ // Stale reference, screen configuration has changed
+ if (m_screenIndex < 0 || (NSUInteger)m_screenIndex >= [screens count])
+ return nil;
+
+ return [screens objectAtIndex:m_screenIndex];
+}
+
+/*!
+ Flips the Y coordinate of the point between quadrant I and IV.
+
+ The native coordinate system on macOS uses quadrant I, with origin
+ in bottom left, and Qt uses quadrant IV, with origin in top left.
+
+ By flippig the Y coordinate, we can map the position between the
+ two coordinate systems.
+*/
+QPointF QCocoaScreen::flipCoordinate(const QPointF &pos) const
+{
+ return QPointF(pos.x(), m_geometry.height() - pos.y());
+}
+
+/*!
+ Flips the Y coordinate of the rectangle between quadrant I and IV.
+
+ The native coordinate system on macOS uses quadrant I, with origin
+ in bottom left, and Qt uses quadrant IV, with origin in top left.
+
+ By flippig the Y coordinate, we can map the rectangle between the
+ two coordinate systems.
+*/
+QRectF QCocoaScreen::flipCoordinate(const QRectF &rect) const
+{
+ return QRectF(flipCoordinate(rect.topLeft() + QPoint(0, rect.height())), rect.size());
}
void QCocoaScreen::updateGeometry()
{
- NSScreen *nsScreen = osScreen();
+ NSScreen *nsScreen = nativeScreen();
if (!nsScreen)
return;
- NSRect frameRect = [nsScreen frame];
+ // At this point the geometry is in native coordinates, but the size
+ // is correct, which we take advantage of next when we map the native
+ // coordinates to the Qt coordinate system.
+ m_geometry = QRectF::fromCGRect(NSRectToCGRect(nsScreen.frame)).toRect();
+ m_availableGeometry = QRectF::fromCGRect(NSRectToCGRect(nsScreen.visibleFrame)).toRect();
- if (m_screenIndex == 0) {
- m_geometry = QRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width, frameRect.size.height);
- // This is the primary screen, the one that contains the menubar. Its origin should be
- // (0, 0), and it's the only one whose available geometry differs from its full geometry.
- NSRect visibleRect = [nsScreen visibleFrame];
- m_availableGeometry = QRect(visibleRect.origin.x,
- frameRect.size.height - (visibleRect.origin.y + visibleRect.size.height), // invert y
- visibleRect.size.width, visibleRect.size.height);
- } else {
- // NSScreen origin is at the bottom-left corner, QScreen is at the top-left corner.
- // When we get the NSScreen frame rect, we need to re-align its origin y coordinate
- // w.r.t. the primary screen, whose origin is (0, 0).
- NSRect r = [[[NSScreen screens] objectAtIndex:0] frame];
- QRect referenceScreenGeometry = QRect(r.origin.x, r.origin.y, r.size.width, r.size.height);
- m_geometry = QRect(frameRect.origin.x,
- referenceScreenGeometry.height() - (frameRect.origin.y + frameRect.size.height),
- frameRect.size.width, frameRect.size.height);
-
- // Not primary screen. See above.
- m_availableGeometry = m_geometry;
- }
+ // The reference screen for the geometry is always the primary screen, but since
+ // we may be in the process of creating and registering the primary screen, we
+ // must special-case that and assign it direcly.
+ QCocoaScreen *primaryScreen = (nsScreen == [[NSScreen screens] firstObject]) ?
+ this : static_cast<QCocoaScreen*>(QGuiApplication::primaryScreen()->handle());
+
+ m_geometry = primaryScreen->mapFromNative(m_geometry).toRect();
+ m_availableGeometry = primaryScreen->mapFromNative(m_availableGeometry).toRect();
m_format = QImage::Format_RGB32;
m_depth = NSBitsPerPixelFromDepth([nsScreen depth]);
@@ -147,8 +171,8 @@ void QCocoaScreen::updateGeometry()
qreal QCocoaScreen::devicePixelRatio() const
{
QMacAutoReleasePool pool;
- NSScreen * screen = osScreen();
- return qreal(screen ? [screen backingScaleFactor] : 1.0);
+ NSScreen *nsScreen = nativeScreen();
+ return qreal(nsScreen ? [nsScreen backingScaleFactor] : 1.0);
}
QPlatformScreen::SubpixelAntialiasingType QCocoaScreen::subpixelAntialiasingTypeHint() const
@@ -427,7 +451,7 @@ void QCocoaIntegration::updateScreens()
// NSScreen documentation says do not cache the array returned from [NSScreen screens].
// However in practice, we can identify a screen by its pointer: if resolution changes,
// the NSScreen object will be the same instance, just with different values.
- if (existingScr->osScreen() == scr) {
+ if (existingScr->nativeScreen() == scr) {
screen = existingScr;
break;
}
@@ -451,20 +475,27 @@ void QCocoaIntegration::updateScreens()
// Now the leftovers in remainingScreens are no longer current, so we can delete them.
foreach (QCocoaScreen* screen, remainingScreens) {
mScreens.removeOne(screen);
+ // Prevent stale references to NSScreen during destroy
+ screen->m_screenIndex = -1;
destroyScreen(screen);
}
}
-QCocoaScreen *QCocoaIntegration::screenAtIndex(int index)
+QCocoaScreen *QCocoaIntegration::screenForNSScreen(NSScreen *nsScreen)
{
- if (index >= mScreens.count())
+ NSUInteger index = [[NSScreen screens] indexOfObject:nsScreen];
+ if (index == NSNotFound)
+ return 0;
+
+ if (index >= unsigned(mScreens.count()))
updateScreens();
- // It is possible that the screen got removed while updateScreens was called
- // so we do a sanity check to be certain
- if (index >= mScreens.count())
- return 0;
- return mScreens.at(index);
+ for (QCocoaScreen *screen : mScreens) {
+ if (screen->nativeScreen() == nsScreen)
+ return screen;
+ }
+
+ return 0;
}
bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -493,6 +524,11 @@ QPlatformWindow *QCocoaIntegration::createPlatformWindow(QWindow *window) const
return new QCocoaWindow(window);
}
+QPlatformWindow *QCocoaIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
+{
+ return new QCocoaWindow(window, nativeHandle);
+}
+
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QCocoaIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
diff --git a/src/plugins/platforms/cocoa/qcocoamenu.mm b/src/plugins/platforms/cocoa/qcocoamenu.mm
index e177a24e73..8e47974d12 100644
--- a/src/plugins/platforms/cocoa/qcocoamenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenu.mm
@@ -581,8 +581,8 @@ void QCocoaMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect,
// The calls above block, and also swallow any mouse release event,
// so we need to clear any mouse button that triggered the menu popup.
- if ([view isKindOfClass:[QNSView class]])
- [(QNSView *)view resetMouseButtons];
+ if (!cocoaWindow->isForeignWindow())
+ [qnsview_cast(view) resetMouseButtons];
}
void QCocoaMenu::dismiss()
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 972230349b..26ab07ffaf 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -172,11 +172,12 @@ void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine
QPixmap QCocoaNativeInterface::defaultBackgroundPixmapForQWizard()
{
- QCFType<CFURLRef> url;
const int ExpectedImageWidth = 242;
const int ExpectedImageHeight = 414;
- if (LSFindApplicationForInfo(kLSUnknownCreator, CFSTR("com.apple.KeyboardSetupAssistant"),
- 0, 0, &url) == noErr) {
+ QCFType<CFArrayRef> urls = LSCopyApplicationURLsForBundleIdentifier(
+ CFSTR("com.apple.KeyboardSetupAssistant"), nullptr);
+ if (urls && CFArrayGetCount(urls) > 0) {
+ CFURLRef url = (CFURLRef)CFArrayGetValueAtIndex(urls, 0);
QCFType<CFBundleRef> bundle = CFBundleCreate(kCFAllocatorDefault, url);
if (bundle) {
url = CFBundleCopyResourceURL(bundle, CFSTR("Background"), CFSTR("png"), 0);
diff --git a/src/plugins/platforms/cocoa/qcocoaresources.qrc b/src/plugins/platforms/cocoa/qcocoaresources.qrc
index 4255bfba9d..1c4b941b9b 100644
--- a/src/plugins/platforms/cocoa/qcocoaresources.qrc
+++ b/src/plugins/platforms/cocoa/qcocoaresources.qrc
@@ -1,12 +1,7 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/qt-project.org/mac/cursors">
-<file>images/copyarrowcursor.png</file>
-<file>images/forbiddencursor.png</file>
-<file>images/spincursor.png</file>
-<file>images/waitcursor.png</file>
-<file>images/sizeallcursor.png</file>
-</qresource>
-<qresource prefix="/qt-project.org/mac/style">
-<file>images/leopard-unified-toolbar-on.png</file>
-</qresource>
+<RCC>
+ <qresource prefix="/qt-project.org/mac/cursors">
+ <file>images/spincursor.png</file>
+ <file>images/waitcursor.png</file>
+ <file>images/sizeallcursor.png</file>
+ </qresource>
</RCC>
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index d47e620fbb..27c071a8cd 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -74,6 +74,7 @@ public:
QVariant themeHint(ThemeHint hint) const Q_DECL_OVERRIDE;
QString standardButtonText(int button) const Q_DECL_OVERRIDE;
+ QKeySequence standardButtonShortcut(int button) const Q_DECL_OVERRIDE;
static const char *name;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 4d74c11581..d2345f9abc 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -344,6 +344,12 @@ QString QCocoaTheme::standardButtonText(int button) const
return button == QPlatformDialogHelper::Discard ? msgDialogButtonDiscard() : QPlatformTheme::standardButtonText(button);
}
+QKeySequence QCocoaTheme::standardButtonShortcut(int button) const
+{
+ return button == QPlatformDialogHelper::Discard ? QKeySequence(Qt::CTRL | Qt::Key_Delete)
+ : QPlatformTheme::standardButtonShortcut(button);
+}
+
QPlatformMenuItem *QCocoaTheme::createPlatformMenuItem() const
{
return new QCocoaMenuItem();
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 16639fd8b1..567eb7438b 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -96,6 +96,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindowHelper);
@property (nonatomic, readonly) QNSWindowHelper *helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw;
@@ -111,6 +112,7 @@ QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSWindow);
@property (nonatomic, readonly) QNSWindowHelper *helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw;
@@ -141,13 +143,20 @@ QT_BEGIN_NAMESPACE
// See the qt_on_cocoa manual tests for a working example, located
// in tests/manual/cocoa at the time of writing.
+#ifdef Q_MOC_RUN
+#define Q_NOTIFICATION_HANDLER(notification) Q_INVOKABLE Q_COCOA_NOTIFICATION_##notification
+#else
+#define Q_NOTIFICATION_HANDLER(notification)
+#define Q_NOTIFICATION_PREFIX QT_STRINGIFY2(Q_COCOA_NOTIFICATION_)
+#endif
+
class QCocoaMenuBar;
class QCocoaWindow : public QObject, public QPlatformWindow
{
Q_OBJECT
public:
- QCocoaWindow(QWindow *tlw);
+ QCocoaWindow(QWindow *tlw, WId nativeHandle = 0);
~QCocoaWindow();
void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
@@ -177,6 +186,8 @@ public:
QMargins frameMargins() const Q_DECL_OVERRIDE;
QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ bool isForeignWindow() const Q_DECL_OVERRIDE;
+
void requestActivateWindow() Q_DECL_OVERRIDE;
WId winId() const Q_DECL_OVERRIDE;
@@ -187,15 +198,30 @@ public:
void setEmbeddedInForeignView(bool subwindow);
- void windowWillMove();
- void windowDidMove();
- void windowDidResize();
- void windowDidEndLiveResize();
+ Q_NOTIFICATION_HANDLER(NSWindowWillMoveNotification) void windowWillMove();
+ Q_NOTIFICATION_HANDLER(NSWindowDidMoveNotification) void windowDidMove();
+ Q_NOTIFICATION_HANDLER(NSWindowDidResizeNotification) void windowDidResize();
+ Q_NOTIFICATION_HANDLER(NSViewFrameDidChangeNotification) void viewDidChangeFrame();
+ Q_NOTIFICATION_HANDLER(NSViewGlobalFrameDidChangeNotification) void viewDidChangeGlobalFrame();
+ Q_NOTIFICATION_HANDLER(NSWindowDidEndLiveResizeNotification) void windowDidEndLiveResize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidBecomeKeyNotification) void windowDidBecomeKey();
+ Q_NOTIFICATION_HANDLER(NSWindowDidResignKeyNotification) void windowDidResignKey();
+ Q_NOTIFICATION_HANDLER(NSWindowDidMiniaturizeNotification) void windowDidMiniaturize();
+ Q_NOTIFICATION_HANDLER(NSWindowDidDeminiaturizeNotification) void windowDidDeminiaturize();
+ Q_NOTIFICATION_HANDLER(NSWindowWillEnterFullScreenNotification) void windowWillEnterFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidEnterFullScreenNotification) void windowDidEnterFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowWillExitFullScreenNotification) void windowWillExitFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidExitFullScreenNotification) void windowDidExitFullScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidOrderOffScreenNotification) void windowDidOrderOffScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidOrderOnScreenAndFinishAnimatingNotification) void windowDidOrderOnScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowDidChangeOcclusionStateNotification) void windowDidChangeOcclusionState();
+ Q_NOTIFICATION_HANDLER(NSWindowDidChangeScreenNotification) void windowDidChangeScreen();
+ Q_NOTIFICATION_HANDLER(NSWindowWillCloseNotification) void windowWillClose();
+
bool windowShouldClose();
- void windowWillClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
- void setSynchedWindowStateFromWindow();
+ void reportCurrentWindowState(bool unconditionally = false);
NSInteger windowLevel(Qt::WindowFlags flags);
NSUInteger windowStyleMask(Qt::WindowFlags flags);
@@ -239,19 +265,37 @@ public:
static QPoint bottomLeftClippedByNSWindowOffsetStatic(QWindow *window);
QPoint bottomLeftClippedByNSWindowOffset() const;
+
+ enum RecreationReason {
+ RecreationNotNeeded = 0,
+ ParentChanged = 0x1,
+ MissingWindow = 0x2,
+ WindowModalityChanged = 0x4,
+ ChildNSWindowChanged = 0x8,
+ ContentViewChanged = 0x10,
+ PanelChanged = 0x20,
+ };
+ Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
+ Q_FLAG(RecreationReasons)
+
protected:
- void recreateWindow(const QPlatformWindow *parentWindow);
- QCocoaNSWindow *createNSWindow();
- void setNSWindow(QCocoaNSWindow *window);
+ bool isChildNSWindow() const;
+ bool isContentView() const;
+
+ void foreachChildNSWindow(void (^block)(QCocoaWindow *));
- bool shouldUseNSPanel();
+ void recreateWindowIfNeeded();
+ QCocoaNSWindow *createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel);
QRect nativeWindowGeometry() const;
- QCocoaWindow *parentCocoaWindow() const;
- void syncWindowState(Qt::WindowState newState);
void reinsertChildWindow(QCocoaWindow *child);
void removeChildWindow(QCocoaWindow *child);
- bool isNativeWindowTypeInconsistent();
+
+ Qt::WindowState windowState() const;
+ void applyWindowState(Qt::WindowState newState);
+ void toggleMaximized();
+ void toggleFullScreen();
+ bool isTransitioningToFullScreen() const;
// private:
public: // for QNSView
@@ -268,13 +312,8 @@ public: // for QNSView
bool m_viewIsEmbedded; // true if the m_view is actually embedded in a "foreign" NSView hiearchy
bool m_viewIsToBeEmbedded; // true if the m_view is intended to be embedded in a "foreign" NSView hiearchy
- QCocoaWindow *m_parentCocoaWindow;
- bool m_isNSWindowChild; // this window is a non-top level QWindow with a NSWindow.
- QList<QCocoaWindow *> m_childWindows;
-
Qt::WindowFlags m_windowFlags;
- bool m_effectivelyMaximized;
- Qt::WindowState m_synchedWindowState;
+ Qt::WindowState m_lastReportedWindowState;
Qt::WindowModality m_windowModality;
QPointer<QWindow> m_enterLeaveTargetWindow;
bool m_windowUnderMouse;
@@ -308,11 +347,6 @@ public: // for QNSView
int m_topContentBorderThickness;
int m_bottomContentBorderThickness;
- // used by showFullScreen in fake mode
- QRect m_normalGeometry;
- Qt::WindowFlags m_oldWindowFlags;
- NSApplicationPresentationOptions m_presentationOptions;
-
struct BorderRange {
BorderRange(quintptr i, int u, int l) : identifier(i), upper(u), lower(l) { }
quintptr identifier;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 40666772c5..75c13d6bbc 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -87,6 +87,36 @@ static void qt_closePopups()
}
}
+@interface NSWindow (FullScreenProperty)
+@property(readonly) BOOL qt_fullScreen;
+@end
+
+@implementation NSWindow (FullScreenProperty)
+
++ (void)load
+{
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+ [center addObserverForName:NSWindowDidEnterFullScreenNotification object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+ objc_setAssociatedObject(notification.object, @selector(qt_fullScreen),
+ [NSNumber numberWithBool:YES], OBJC_ASSOCIATION_RETAIN);
+ }
+ ];
+ [center addObserverForName:NSWindowDidExitFullScreenNotification object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+ objc_setAssociatedObject(notification.object, @selector(qt_fullScreen),
+ nil, OBJC_ASSOCIATION_RETAIN);
+ }
+ ];
+}
+
+- (BOOL)qt_fullScreen
+{
+ NSNumber *number = objc_getAssociatedObject(self, @selector(qt_fullScreen));
+ return [number boolValue];
+}
+@end
+
@implementation QNSWindowHelper
@synthesize window = _window;
@@ -130,8 +160,7 @@ static void qt_closePopups()
[forwardView mouseDragged:theEvent];
}
}
-
- if (!pw->m_isNSWindowChild && theEvent.type == NSLeftMouseDown) {
+ if (pw->window()->isTopLevel() && theEvent.type == NSLeftMouseDown) {
pw->m_forwardWindow.clear();
}
}
@@ -202,13 +231,14 @@ static void qt_closePopups()
@synthesize helper = _helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw
{
self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ defer:NO screen:screen]; // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
if (self) {
@@ -222,7 +252,7 @@ static void qt_closePopups()
// Prevent child NSWindows from becoming the key window in
// order keep the active apperance of the top-level window.
QCocoaWindow *pw = self.helper.platformWindow;
- if (!pw || pw->m_isNSWindowChild)
+ if (!pw || !pw->window()->isTopLevel())
return NO;
if (pw->shouldRefuseKeyWindowAndFirstResponder())
@@ -241,7 +271,7 @@ static void qt_closePopups()
// Windows with a transient parent (such as combobox popup windows)
// cannot become the main window:
QCocoaWindow *pw = self.helper.platformWindow;
- if (!pw || pw->m_isNSWindowChild || pw->window()->transientParent())
+ if (!pw || !pw->window()->isTopLevel() || pw->window()->transientParent())
canBecomeMain = NO;
return canBecomeMain;
@@ -284,13 +314,14 @@ static void qt_closePopups()
@synthesize helper = _helper;
- (id)initWithContentRect:(NSRect)contentRect
+ screen:(NSScreen*)screen
styleMask:(NSUInteger)windowStyle
qPlatformWindow:(QCocoaWindow *)qpw
{
self = [super initWithContentRect:contentRect
styleMask:windowStyle
backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is
+ defer:NO screen:screen]; // Deferring window creation breaks OpenGL (the GL context is
// set up before the window is shown and needs a proper window)
if (self) {
@@ -343,18 +374,72 @@ static void qt_closePopups()
@end
+static void qRegisterNotificationCallbacks()
+{
+ static const QLatin1String notificationHandlerPrefix(Q_NOTIFICATION_PREFIX);
+
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
+
+ const QMetaObject *metaObject = QMetaType::metaObjectForType(qRegisterMetaType<QCocoaWindow*>());
+ Q_ASSERT(metaObject);
+
+ for (int i = 0; i < metaObject->methodCount(); ++i) {
+ QMetaMethod method = metaObject->method(i);
+ const QString methodTag = QString::fromLatin1(method.tag());
+ if (!methodTag.startsWith(notificationHandlerPrefix))
+ continue;
+
+ const QString notificationName = methodTag.mid(notificationHandlerPrefix.size());
+ [center addObserverForName:notificationName.toNSString() object:nil queue:nil
+ usingBlock:^(NSNotification *notification) {
+
+ NSView *view = nullptr;
+ if ([notification.object isKindOfClass:[NSWindow class]]) {
+ NSWindow *window = notification.object;
+ // Only top level NSWindows should notify their QNSViews
+ if (window.parentWindow)
+ return;
+
+ if (!window.contentView)
+ return;
+
+ view = window.contentView;
+ } else if ([notification.object isKindOfClass:[NSView class]]) {
+ view = notification.object;
+ } else {
+ qCWarning(lcQpaCocoaWindow) << "Unhandled notifcation"
+ << notification.name << "for" << notification.object;
+ return;
+ }
+ Q_ASSERT(view);
+
+ QCocoaWindow *cocoaWindow = nullptr;
+ if (QNSView *qnsView = qnsview_cast(view))
+ cocoaWindow = qnsView.platformWindow;
+
+ // FIXME: Could be a foreign window, look up by iterating top level QWindows
+
+ if (!cocoaWindow)
+ return;
+
+ if (!method.invoke(cocoaWindow, Qt::DirectConnection)) {
+ qCWarning(lcQpaCocoaWindow) << "Failed to invoke NSNotification callback for"
+ << notification.name << "on" << cocoaWindow;
+ }
+ }];
+ }
+}
+Q_CONSTRUCTOR_FUNCTION(qRegisterNotificationCallbacks)
+
const int QCocoaWindow::NoAlertRequest = -1;
-QCocoaWindow::QCocoaWindow(QWindow *tlw)
+QCocoaWindow::QCocoaWindow(QWindow *tlw, WId nativeHandle)
: QPlatformWindow(tlw)
, m_view(nil)
, m_nsWindow(0)
, m_viewIsEmbedded(false)
, m_viewIsToBeEmbedded(false)
- , m_parentCocoaWindow(0)
- , m_isNSWindowChild(false)
- , m_effectivelyMaximized(false)
- , m_synchedWindowState(Qt::WindowActive)
+ , m_lastReportedWindowState(Qt::WindowNoState)
, m_windowModality(Qt::NonModal)
, m_windowUnderMouse(false)
, m_inConstructor(true)
@@ -379,15 +464,15 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_drawContentBorderGradient(false)
, m_topContentBorderThickness(0)
, m_bottomContentBorderThickness(0)
- , m_normalGeometry(QRect(0,0,-1,-1))
, m_hasWindowFilePath(false)
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::QCocoaWindow" << window();
QMacAutoReleasePool pool;
- if (tlw->type() == Qt::ForeignWindow) {
- m_view = (NSView *)WId(tlw->property("_q_foreignWinId").value<WId>());
+ if (nativeHandle) {
+ m_view = reinterpret_cast<NSView *>(nativeHandle);
+ [m_view retain];
} else {
m_view = [[QNSView alloc] initWithCocoaWindow:this];
// Enable high-dpi OpenGL for retina displays. Enabling has the side
@@ -405,7 +490,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
[m_view setWantsLayer:enable];
}
setGeometry(tlw->geometry());
- recreateWindow(QPlatformWindow::parent());
+ recreateWindowIfNeeded();
tlw->setGeometry(geometry());
if (tlw->isTopLevel())
setWindowIcon(tlw->icon());
@@ -420,18 +505,16 @@ QCocoaWindow::~QCocoaWindow()
[m_nsWindow makeFirstResponder:nil];
[m_nsWindow setContentView:nil];
[m_nsWindow.helper detachFromPlatformWindow];
- if (m_isNSWindowChild) {
- if (m_parentCocoaWindow)
- m_parentCocoaWindow->removeChildWindow(this);
- } else if ([m_view superview]) {
+ if (m_view.window.parentWindow)
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
+ else if ([m_view superview])
[m_view removeFromSuperview];
- }
removeMonitor();
// Make sure to disconnect observer in all case if view is valid
// to avoid notifications received when deleting when using Qt::AA_NativeWindows attribute
- if (window()->type() != Qt::ForeignWindow)
+ if (!isForeignWindow())
[[NSNotificationCenter defaultCenter] removeObserver:m_view];
// While it is unlikely that this window will be in the popup stack
@@ -440,10 +523,9 @@ QCocoaWindow::~QCocoaWindow()
QCocoaIntegration::instance()->popupWindowStack()->removeAll(this);
}
- foreach (QCocoaWindow *child, m_childWindows) {
- [m_nsWindow removeChildWindow:child->m_nsWindow];
- child->m_parentCocoaWindow = 0;
- }
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
+ [m_nsWindow removeChildWindow:childWindow->m_nsWindow];
+ });
[m_view release];
[m_nsWindow release];
@@ -481,6 +563,11 @@ void QCocoaWindow::setGeometry(const QRect &rectIn)
setCocoaGeometry(rect);
}
+bool QCocoaWindow::isForeignWindow() const
+{
+ return ![m_view isKindOfClass:[QNSView class]];
+}
+
QRect QCocoaWindow::geometry() const
{
// QWindows that are embedded in a NSView hiearchy may be considered
@@ -491,7 +578,7 @@ QRect QCocoaWindow::geometry() const
NSRect screenRect = [[m_view window] convertRectToScreen:NSMakeRect(windowPoint.x, windowPoint.y, 1, 1)];
NSPoint screenPoint = screenRect.origin;
QPoint position = qt_mac_flipPoint(screenPoint).toPoint();
- QSize size = QRectF::fromCGRect([m_view bounds]).toRect().size();
+ QSize size = QRectF::fromCGRect(NSRectToCGRect([m_view bounds])).toRect().size();
return QRect(position, size);
}
@@ -504,7 +591,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
QMacAutoReleasePool pool;
if (m_viewIsEmbedded) {
- if (window()->type() != Qt::ForeignWindow) {
+ if (!isForeignWindow()) {
[m_view setFrame:NSMakeRect(0, 0, rect.width(), rect.height())];
} else {
QPlatformWindow::setGeometry(rect);
@@ -512,9 +599,9 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
return;
}
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
QPlatformWindow::setGeometry(rect);
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
NSRect parentWindowFrame = [parentNSWindow contentRectForFrameRect:parentNSWindow.frame];
clipWindow(parentWindowFrame);
@@ -528,7 +615,7 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
[m_view setFrame:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())];
}
- if (window()->type() == Qt::ForeignWindow)
+ if (isForeignWindow())
QPlatformWindow::setGeometry(rect);
// will call QPlatformWindow::setGeometry(rect) during resize confirmation (see qnsview.mm)
@@ -536,14 +623,14 @@ void QCocoaWindow::setCocoaGeometry(const QRect &rect)
void QCocoaWindow::clipChildWindows()
{
- foreach (QCocoaWindow *childWindow, m_childWindows) {
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->clipWindow(m_nsWindow.frame);
- }
+ });
}
void QCocoaWindow::clipWindow(const NSRect &clipRect)
{
- if (!m_isNSWindowChild)
+ if (!isChildNSWindow())
return;
NSRect clippedWindowRect = NSZeroRect;
@@ -568,15 +655,15 @@ void QCocoaWindow::clipWindow(const NSRect &clipRect)
m_hiddenByClipping = false;
if (!m_hiddenByAncestor) {
[m_nsWindow orderFront:nil];
- m_parentCocoaWindow->reinsertChildWindow(this);
+ static_cast<QCocoaWindow *>(QPlatformWindow::parent())->reinsertChildWindow(this);
}
}
}
// recurse
- foreach (QCocoaWindow *childWindow, m_childWindows) {
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->clipWindow(clippedWindowRect);
- }
+ });
}
void QCocoaWindow::hide(bool becauseOfAncestor)
@@ -593,8 +680,9 @@ void QCocoaWindow::hide(bool becauseOfAncestor)
if (!visible) // Could have been clipped before
return;
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->hide(true);
+ });
[m_nsWindow orderOut:nil];
}
@@ -604,20 +692,21 @@ void QCocoaWindow::show(bool becauseOfAncestor)
if ([m_nsWindow isVisible])
return;
- if (m_parentCocoaWindow && ![m_parentCocoaWindow->m_nsWindow isVisible]) {
+ if (m_view.window.parentWindow && !m_view.window.parentWindow.visible) {
m_hiddenByAncestor = true; // Parent still hidden, don't show now
} else if ((becauseOfAncestor == m_hiddenByAncestor) // Was NEITHER explicitly hidden
&& !m_hiddenByClipping) { // ... NOR clipped
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
m_hiddenByAncestor = false;
setCocoaGeometry(windowGeometry());
}
if (!m_hiddenByClipping) { // setCocoaGeometry() can change the clipping status
[m_nsWindow orderFront:nil];
- if (m_isNSWindowChild)
- m_parentCocoaWindow->reinsertChildWindow(this);
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ if (isChildNSWindow())
+ static_cast<QCocoaWindow *>(QPlatformWindow::parent())->reinsertChildWindow(this);
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->show(true);
+ });
}
}
}
@@ -626,7 +715,7 @@ void QCocoaWindow::setVisible(bool visible)
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::setVisible" << window() << visible;
- if (m_isNSWindowChild && m_hiddenByClipping)
+ if (isChildNSWindow() && m_hiddenByClipping)
return;
m_inSetVisible = true;
@@ -638,8 +727,7 @@ void QCocoaWindow::setVisible(bool visible)
if (visible) {
// We need to recreate if the modality has changed as the style mask will need updating
- if (m_windowModality != window()->modality() || isNativeWindowTypeInconsistent())
- recreateWindow(QPlatformWindow::parent());
+ recreateWindowIfNeeded();
// Register popup windows. The Cocoa platform plugin will forward mouse events
// to them and close them when needed.
@@ -674,14 +762,14 @@ void QCocoaWindow::setVisible(bool visible)
// setWindowState might have been called while the window was hidden and
// will not change the NSWindow state in that case. Sync up here:
- syncWindowState(window()->windowState());
+ applyWindowState(window()->windowState());
if (window()->windowState() != Qt::WindowMinimized) {
if ((window()->modality() == Qt::WindowModal
|| window()->type() == Qt::Sheet)
&& parentCocoaWindow) {
// show the window as a sheet
- [NSApp beginSheet:m_nsWindow modalForWindow:parentCocoaWindow->m_nsWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
+ [parentCocoaWindow->m_nsWindow beginSheet:m_nsWindow completionHandler:nil];
} else if (window()->modality() != Qt::NonModal) {
// show the window as application modal
QCocoaEventDispatcher *cocoaEventDispatcher = qobject_cast<QCocoaEventDispatcher *>(QGuiApplication::instance()->eventDispatcher());
@@ -700,8 +788,9 @@ void QCocoaWindow::setVisible(bool visible)
else
[m_nsWindow orderFront:nil];
- foreach (QCocoaWindow *childWindow, m_childWindows)
+ foreachChildNSWindow(^(QCocoaWindow *childWindow) {
childWindow->show(true);
+ });
} else {
show();
}
@@ -742,8 +831,10 @@ void QCocoaWindow::setVisible(bool visible)
cocoaEventDispatcherPrivate->endModalSession(window());
m_hasModalSession = false;
} else {
- if ([m_nsWindow isSheet])
- [NSApp endSheet:m_nsWindow];
+ if ([m_nsWindow isSheet]) {
+ Q_ASSERT_X(parentCocoaWindow, "QCocoaWindow", "Window modal dialog has no transient parent.");
+ [parentCocoaWindow->m_nsWindow endSheet:m_nsWindow];
+ }
}
hide();
@@ -856,6 +947,10 @@ NSUInteger QCocoaWindow::windowStyleMask(Qt::WindowFlags flags)
if (m_drawContentBorderGradient)
styleMask |= NSTexturedBackgroundWindowMask;
+ // Don't wipe fullscreen state
+ if (m_nsWindow.styleMask & NSFullScreenWindowMask)
+ styleMask |= NSFullScreenWindowMask;
+
return styleMask;
}
@@ -873,13 +968,14 @@ void QCocoaWindow::setWindowZoomButton(Qt::WindowFlags flags)
// in line with the platform style guidelines.
bool fixedSizeNoZoom = (windowMinimumSize().isValid() && windowMaximumSize().isValid()
&& windowMinimumSize() == windowMaximumSize());
- bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint) && !(flags & Qt::WindowMaximizeButtonHint));
+ bool customizeNoZoom = ((flags & Qt::CustomizeWindowHint)
+ && !(flags & (Qt::WindowMaximizeButtonHint | Qt::WindowFullscreenButtonHint)));
[[m_nsWindow standardWindowButton:NSWindowZoomButton] setEnabled:!(fixedSizeNoZoom || customizeNoZoom)];
}
void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
{
- if (m_nsWindow && !m_isNSWindowChild) {
+ if (m_nsWindow && !isChildNSWindow()) {
NSUInteger styleMask = windowStyleMask(flags);
NSInteger level = this->windowLevel(flags);
// While setting style mask we can have -updateGeometry calls on a content
@@ -908,13 +1004,16 @@ void QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
setWindowZoomButton(flags);
}
+ if (m_nsWindow)
+ m_nsWindow.ignoresMouseEvents = flags & Qt::WindowTransparentForInput;
+
m_windowFlags = flags;
}
void QCocoaWindow::setWindowState(Qt::WindowState state)
{
if (window()->isVisible())
- syncWindowState(state); // Window state set for hidden windows take effect when show() is called.
+ applyWindowState(state); // Window state set for hidden windows take effect when show() is called
}
void QCocoaWindow::setWindowTitle(const QString &title)
@@ -983,19 +1082,16 @@ void QCocoaWindow::raise()
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
if (!m_nsWindow)
return;
- if (m_isNSWindowChild) {
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- siblings.removeOne(this);
- siblings.append(this);
+ if (isChildNSWindow()) {
if (m_hiddenByClipping)
return;
}
if ([m_nsWindow isVisible]) {
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
// -[NSWindow orderFront:] doesn't work with attached windows.
// The only solution is to remove and add the child window.
// This will place it on top of all the other NSWindows.
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
[parentNSWindow removeChildWindow:m_nsWindow];
[parentNSWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
} else {
@@ -1021,20 +1117,17 @@ void QCocoaWindow::lower()
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::lower" << window();
if (!m_nsWindow)
return;
- if (m_isNSWindowChild) {
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- siblings.removeOne(this);
- siblings.prepend(this);
+ if (isChildNSWindow()) {
if (m_hiddenByClipping)
return;
}
if ([m_nsWindow isVisible]) {
- if (m_isNSWindowChild) {
+ if (isChildNSWindow()) {
// -[NSWindow orderBack:] doesn't work with attached windows.
// The only solution is to remove and add all the child windows except this one.
// This will keep the current window at the bottom while adding the others on top of it,
// hopefully in the same order (this is not documented anywhere in the Cocoa documentation).
- NSWindow *parentNSWindow = m_parentCocoaWindow->m_nsWindow;
+ NSWindow *parentNSWindow = m_view.window.parentWindow;
NSArray *children = [parentNSWindow.childWindows copy];
for (NSWindow *child in children)
if (m_nsWindow != child) {
@@ -1095,7 +1188,7 @@ void QCocoaWindow::propagateSizeHints()
QSize sizeIncrement = windowSizeIncrement();
if (sizeIncrement.isEmpty())
sizeIncrement = QSize(1, 1);
- [m_nsWindow setResizeIncrements:sizeIncrement.toCGSize()];
+ [m_nsWindow setResizeIncrements:NSSizeFromCGSize(sizeIncrement.toCGSize())];
QRect rect = geometry();
QSize baseSize = windowBaseSize();
@@ -1158,7 +1251,7 @@ void QCocoaWindow::setParent(const QPlatformWindow *parentWindow)
// recreate the window for compatibility
bool unhideAfterRecreate = parentWindow && !m_viewIsToBeEmbedded && ![m_view isHidden];
- recreateWindow(parentWindow);
+ recreateWindowIfNeeded();
if (unhideAfterRecreate)
[m_view setHidden:NO];
setCocoaGeometry(geometry());
@@ -1182,6 +1275,8 @@ void QCocoaWindow::setEmbeddedInForeignView(bool embedded)
m_nsWindow = 0;
}
+// ----------------------- NSWindow notifications -----------------------
+
void QCocoaWindow::windowWillMove()
{
// Close any open popups on window move
@@ -1190,10 +1285,13 @@ void QCocoaWindow::windowWillMove()
void QCocoaWindow::windowDidMove()
{
- if (m_isNSWindowChild)
+ if (isChildNSWindow())
return;
[qnsview_cast(m_view) updateGeometry];
+
+ // Moving a window might bring it out of maximized state
+ reportCurrentWindowState();
}
void QCocoaWindow::windowDidResize()
@@ -1201,21 +1299,172 @@ void QCocoaWindow::windowDidResize()
if (!m_nsWindow)
return;
- if (m_isNSWindowChild)
+ if (isChildNSWindow())
return;
clipChildWindows();
[qnsview_cast(m_view) updateGeometry];
+
+ if (!m_view.inLiveResize)
+ reportCurrentWindowState();
+}
+
+void QCocoaWindow::viewDidChangeFrame()
+{
+ [qnsview_cast(m_view) updateGeometry];
+}
+
+/*!
+ Callback for NSViewGlobalFrameDidChangeNotification.
+
+ Posted whenever an NSView object that has attached surfaces (that is,
+ NSOpenGLContext objects) moves to a different screen, or other cases
+ where the NSOpenGLContext object needs to be updated.
+*/
+void QCocoaWindow::viewDidChangeGlobalFrame()
+{
+ updateExposedGeometry();
}
void QCocoaWindow::windowDidEndLiveResize()
{
- if (m_synchedWindowState == Qt::WindowMaximized && ![m_nsWindow isZoomed]) {
- m_effectivelyMaximized = false;
- [qnsview_cast(m_view) notifyWindowStateChanged:Qt::WindowNoState];
+ reportCurrentWindowState();
+}
+
+void QCocoaWindow::windowDidBecomeKey()
+{
+ if (isForeignWindow())
+ return;
+
+ if (m_windowUnderMouse) {
+ QPointF windowPoint;
+ QPointF screenPoint;
+ [qnsview_cast(m_view) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
+ QWindowSystemInterface::handleEnterEvent(m_enterLeaveTargetWindow, windowPoint, screenPoint);
}
+
+ if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
+ QWindowSystemInterface::handleWindowActivated(window());
}
+void QCocoaWindow::windowDidResignKey()
+{
+ if (isForeignWindow())
+ return;
+
+ // Key window will be non-nil if another window became key, so do not
+ // set the active window to zero here -- the new key window's
+ // NSWindowDidBecomeKeyNotification hander will change the active window.
+ NSWindow *keyWindow = [NSApp keyWindow];
+ if (!keyWindow || keyWindow == m_view.window) {
+ // No new key window, go ahead and set the active window to zero
+ if (!windowIsPopupType() && !qnsview_cast(m_view).isMenuView)
+ QWindowSystemInterface::handleWindowActivated(0);
+ }
+}
+
+void QCocoaWindow::windowDidMiniaturize()
+{
+ reportCurrentWindowState();
+}
+
+void QCocoaWindow::windowDidDeminiaturize()
+{
+ reportCurrentWindowState();
+}
+
+void QCocoaWindow::windowWillEnterFullScreen()
+{
+ // The NSWindow needs to be resizable, otherwise we'll end up with
+ // the normal window geometry, centered in the middle of the screen
+ // on a black background. The styleMask will be reset below.
+ m_nsWindow.styleMask |= NSResizableWindowMask;
+}
+
+void QCocoaWindow::windowDidEnterFullScreen()
+{
+ Q_ASSERT_X(m_nsWindow.qt_fullScreen, "QCocoaWindow",
+ "FullScreen category processes window notifications first");
+
+ // Reset to original styleMask
+ setWindowFlags(m_windowFlags);
+
+ reportCurrentWindowState();
+}
+
+void QCocoaWindow::windowWillExitFullScreen()
+{
+ // The NSWindow needs to be resizable, otherwise we'll end up with
+ // a weird zoom animation. The styleMask will be reset below.
+ m_nsWindow.styleMask |= NSResizableWindowMask;
+}
+
+void QCocoaWindow::windowDidExitFullScreen()
+{
+ Q_ASSERT_X(!m_nsWindow.qt_fullScreen, "QCocoaWindow",
+ "FullScreen category processes window notifications first");
+
+ // Reset to original styleMask
+ setWindowFlags(m_windowFlags);
+
+ Qt::WindowState requestedState = window()->windowState();
+
+ // Deliver update of QWindow state
+ reportCurrentWindowState();
+
+ if (requestedState != windowState() && requestedState != Qt::WindowFullScreen) {
+ // We were only going out of full screen as an intermediate step before
+ // progressing into the final step, so re-sync the desired state.
+ applyWindowState(requestedState);
+ }
+}
+
+void QCocoaWindow::windowDidOrderOffScreen()
+{
+ obscureWindow();
+}
+
+void QCocoaWindow::windowDidOrderOnScreen()
+{
+ exposeWindow();
+}
+
+void QCocoaWindow::windowDidChangeOcclusionState()
+{
+ // Several unit tests expect paint and/or expose events for windows that are
+ // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed.
+ // Don't send Expose/Obscure events when running under QTestLib.
+ static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
+ if (!onTestLib) {
+ if ((NSUInteger)[m_view.window occlusionState] & NSWindowOcclusionStateVisible) {
+ exposeWindow();
+ } else {
+ // Send Obscure events on window occlusion to stop animations.
+ obscureWindow();
+ }
+ }
+}
+
+void QCocoaWindow::windowDidChangeScreen()
+{
+ if (!window())
+ return;
+
+ if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_view.window.screen))
+ QWindowSystemInterface::handleWindowScreenChanged(window(), cocoaScreen->screen());
+
+ updateExposedGeometry();
+}
+
+void QCocoaWindow::windowWillClose()
+{
+ // Close any open popups on window closing.
+ if (window() && !windowIsPopupType(window()->type()))
+ qt_closePopups();
+}
+
+// ----------------------- NSWindowDelegate callbacks -----------------------
+
bool QCocoaWindow::windowShouldClose()
{
qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::windowShouldClose" << window();
@@ -1229,18 +1478,7 @@ bool QCocoaWindow::windowShouldClose()
return accepted;
}
-void QCocoaWindow::windowWillClose()
-{
- // Close any open popups on window closing.
- if (window() && !windowIsPopupType(window()->type()))
- qt_closePopups();
-}
-
-void QCocoaWindow::setSynchedWindowStateFromWindow()
-{
- if (QWindow *w = window())
- m_synchedWindowState = w->windowState();
-}
+// --------------------------------------------------------------------------
bool QCocoaWindow::windowIsPopupType(Qt::WindowType type) const
{
@@ -1264,62 +1502,141 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
}
#endif
-void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
+/*!
+ Checks if the window is a non-top level QWindow with a NSWindow.
+
+ \sa _q_platform_MacUseNSWindow, QT_MAC_USE_NSWINDOW
+*/
+bool QCocoaWindow::isChildNSWindow() const
+{
+ return m_view.window.parentWindow != nil;
+}
+
+/*!
+ Checks if the window is the content view of its immediate NSWindow.
+
+ Being the content view of a NSWindow means the QWindow is
+ the highest accessible NSView object in the window's view
+ hierarchy.
+
+ This can only happen in two cases, either if the QWindow is
+ itself a top level window, or if it's a child NSWindow.
+
+ \sa isChildNSWindow
+*/
+bool QCocoaWindow::isContentView() const
+{
+ return m_view.window.contentView == m_view;
+}
+
+/*!
+ Iterates child NSWindows that have a corresponding QCocoaWindow.
+*/
+void QCocoaWindow::foreachChildNSWindow(void (^block)(QCocoaWindow *))
{
- qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindow" << window()
+ NSArray *windows = m_view.window.childWindows;
+ [windows enumerateObjectsUsingBlock:^(NSWindow *window, NSUInteger index, BOOL *stop) {
+ Q_UNUSED(index);
+ Q_UNUSED(stop);
+ if (QNSView *view = qnsview_cast(window.contentView))
+ block(view.platformWindow);
+ }];
+}
+
+/*!
+ Recreates (or removes) the NSWindow for this QWindow, if needed.
+
+ A QWindow may need a corresponding NSWindow, depending on whether
+ or not it's a top level or not (or explicitly set to be a child
+ NSWindow), whether it is a NSPanel or not, etc.
+*/
+void QCocoaWindow::recreateWindowIfNeeded()
+{
+ QPlatformWindow *parentWindow = QPlatformWindow::parent();
+ qCDebug(lcQpaCocoaWindow) << "QCocoaWindow::recreateWindowIfNeeded" << window()
<< "parent" << (parentWindow ? parentWindow->window() : 0);
- bool wasNSWindowChild = m_isNSWindowChild;
- BOOL requestNSWindowChild = qt_mac_resolveOption(NO, window(), "_q_platform_MacUseNSWindow",
- "QT_MAC_USE_NSWINDOW");
- m_isNSWindowChild = parentWindow && requestNSWindowChild;
- bool needsNSWindow = m_isNSWindowChild || !parentWindow;
+ RecreationReasons recreateReason = RecreationNotNeeded;
+
+ QCocoaWindow *oldParentCocoaWindow = nullptr;
+ if (QNSView *qnsView = qnsview_cast(m_view.superview))
+ oldParentCocoaWindow = qnsView.platformWindow;
+
+ if (parentWindow != oldParentCocoaWindow)
+ recreateReason |= ParentChanged;
+
+ if (!m_view.window)
+ recreateReason |= MissingWindow;
+
+ // If the modality has changed the style mask will need updating
+ if (m_windowModality != window()->modality())
+ recreateReason |= WindowModalityChanged;
+
+ const bool shouldBeChildNSWindow = parentWindow && qt_mac_resolveOption(NO,
+ window(), "_q_platform_MacUseNSWindow", "QT_MAC_USE_NSWINDOW");
+
+ if (isChildNSWindow() != shouldBeChildNSWindow)
+ recreateReason |= ChildNSWindowChanged;
+
+ const bool shouldBeContentView = !parentWindow || shouldBeChildNSWindow;
+ if (isContentView() != shouldBeContentView)
+ recreateReason |= ContentViewChanged;
+
+ Qt::WindowType type = window()->type();
+ const bool isPanel = isContentView() && [m_view.window isKindOfClass:[QNSPanel class]];
+ const bool shouldBePanel = shouldBeContentView && !shouldBeChildNSWindow &&
+ ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
+
+ if (isPanel != shouldBePanel)
+ recreateReason |= PanelChanged;
+
+ if (recreateReason == RecreationNotNeeded) {
+ qCDebug(lcQpaCocoaWindow) << "No need to recreate NSWindow";
+ return;
+ }
+
+ qCDebug(lcQpaCocoaWindow) << "Recreating NSWindow due to" << recreateReason;
+
+ QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(parentWindow);
- QCocoaWindow *oldParentCocoaWindow = m_parentCocoaWindow;
- m_parentCocoaWindow = const_cast<QCocoaWindow *>(static_cast<const QCocoaWindow *>(parentWindow));
- if (m_parentCocoaWindow && m_isNSWindowChild) {
- QWindow *parentQWindow = m_parentCocoaWindow->window();
+ if (shouldBeChildNSWindow) {
+ QWindow *parentQWindow = parentWindow->window();
+ // Ensure that all parents in the hierarchy are also child NSWindows
if (!parentQWindow->property("_q_platform_MacUseNSWindow").toBool()) {
parentQWindow->setProperty("_q_platform_MacUseNSWindow", QVariant(true));
- m_parentCocoaWindow->recreateWindow(m_parentCocoaWindow->m_parentCocoaWindow);
+ parentCocoaWindow->recreateWindowIfNeeded();
}
}
- bool usesNSPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
-
- // No child QNSWindow should notify its QNSView
- if (m_nsWindow && (window()->type() != Qt::ForeignWindow) && m_parentCocoaWindow && !oldParentCocoaWindow)
- [[NSNotificationCenter defaultCenter] removeObserver:m_view
- name:nil object:m_nsWindow];
-
// Remove current window (if any)
- if ((m_nsWindow && !needsNSWindow) || (usesNSPanel != shouldUseNSPanel())) {
+ if ((isContentView() && !shouldBeContentView) || (recreateReason & PanelChanged)) {
[m_nsWindow closeAndRelease];
- if (wasNSWindowChild && oldParentCocoaWindow)
- oldParentCocoaWindow->removeChildWindow(this);
+ if (isChildNSWindow())
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
m_nsWindow = 0;
}
- if (needsNSWindow) {
+ if (shouldBeContentView) {
bool noPreviousWindow = m_nsWindow == 0;
if (noPreviousWindow)
- m_nsWindow = createNSWindow();
-
- // Only non-child QNSWindows should notify their QNSViews
- // (but don't register more than once).
- if ((window()->type() != Qt::ForeignWindow) && (noPreviousWindow || (wasNSWindowChild && !m_isNSWindowChild)))
- [[NSNotificationCenter defaultCenter] addObserver:m_view
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:m_nsWindow];
-
- if (oldParentCocoaWindow) {
- if (!m_isNSWindowChild || oldParentCocoaWindow != m_parentCocoaWindow)
- oldParentCocoaWindow->removeChildWindow(this);
+ m_nsWindow = createNSWindow(shouldBeChildNSWindow, shouldBePanel);
+
+ if (m_view.window.parentWindow) {
+ if (!shouldBeChildNSWindow || (recreateReason & ParentChanged))
+ [m_view.window.parentWindow removeChildWindow:m_view.window];
m_forwardWindow = oldParentCocoaWindow;
}
- setNSWindow(m_nsWindow);
+ // Move view to new NSWindow if needed
+ if (m_nsWindow.contentView != m_view) {
+ [m_view setPostsFrameChangedNotifications:NO];
+ [m_view retain];
+ if (m_view.superview) // m_view comes from another NSWindow
+ [m_view removeFromSuperview];
+ [m_nsWindow setContentView:m_view];
+ [m_view release];
+ [m_view setPostsFrameChangedNotifications:YES];
+ }
}
if (m_viewIsToBeEmbedded) {
@@ -1330,32 +1647,21 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
setWindowFlags(window()->flags());
setWindowTitle(window()->title());
setWindowState(window()->windowState());
- } else if (m_isNSWindowChild) {
- m_nsWindow.styleMask = NSBorderlessWindowMask;
- m_nsWindow.hasShadow = NO;
- m_nsWindow.level = NSNormalWindowLevel;
- NSWindowCollectionBehavior collectionBehavior =
- NSWindowCollectionBehaviorManaged | NSWindowCollectionBehaviorIgnoresCycle
- | NSWindowCollectionBehaviorFullScreenAuxiliary;
- m_nsWindow.animationBehavior = NSWindowAnimationBehaviorNone;
- m_nsWindow.collectionBehavior = collectionBehavior;
- setCocoaGeometry(windowGeometry());
-
- QList<QCocoaWindow *> &siblings = m_parentCocoaWindow->m_childWindows;
- if (siblings.contains(this)) {
- if (!m_hiddenByClipping)
- m_parentCocoaWindow->reinsertChildWindow(this);
- } else {
- if (!m_hiddenByClipping)
- [m_parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
- siblings.append(this);
+ } else if (shouldBeChildNSWindow) {
+ if (!m_hiddenByClipping) {
+ [parentCocoaWindow->m_nsWindow addChildWindow:m_nsWindow ordered:NSWindowAbove];
+ parentCocoaWindow->reinsertChildWindow(this);
}
+
+ // Set properties after the window has been made a child NSWindow
+ setCocoaGeometry(windowGeometry());
+ setWindowFlags(window()->flags());
} else {
// Child windows have no NSWindow, link the NSViews instead.
if ([m_view superview])
[m_view removeFromSuperview];
- [m_parentCocoaWindow->m_view addSubview:m_view];
+ [parentCocoaWindow->m_view addSubview:m_view];
QRect rect = windowGeometry();
// Prevent setting a (0,0) window size; causes opengl context
// "Invalid Drawable" warnings.
@@ -1366,9 +1672,6 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
[m_view setHidden:!window()->isVisible()];
}
- m_nsWindow.ignoresMouseEvents =
- (window()->flags() & Qt::WindowTransparentForInput) == Qt::WindowTransparentForInput;
-
const qreal opacity = qt_window_private(window())->opacity;
if (!qFuzzyCompare(opacity, qreal(1.0)))
setOpacity(opacity);
@@ -1381,11 +1684,17 @@ void QCocoaWindow::recreateWindow(const QPlatformWindow *parentWindow)
void QCocoaWindow::reinsertChildWindow(QCocoaWindow *child)
{
- int childIndex = m_childWindows.indexOf(child);
+ const QObjectList &childWindows = window()->children();
+ int childIndex = childWindows.indexOf(child->window());
Q_ASSERT(childIndex != -1);
- for (int i = childIndex; i < m_childWindows.size(); i++) {
- NSWindow *nsChild = m_childWindows[i]->m_nsWindow;
+ for (int i = childIndex; i < childWindows.size(); ++i) {
+ QWindow *window = static_cast<QWindow *>(childWindows.at(i));
+ QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window->handle());
+ if (!cocoaWindow)
+ continue;
+
+ NSWindow *nsChild = cocoaWindow->m_nsWindow;
if (i != childIndex)
[m_nsWindow removeChildWindow:nsChild];
[m_nsWindow addChildWindow:nsChild ordered:NSWindowAbove];
@@ -1399,114 +1708,80 @@ void QCocoaWindow::requestActivateWindow()
[window makeKeyWindow];
}
-bool QCocoaWindow::shouldUseNSPanel()
-{
- Qt::WindowType type = window()->type();
-
- return !m_isNSWindowChild &&
- ((type & Qt::Popup) == Qt::Popup || (type & Qt::Dialog) == Qt::Dialog);
-}
-
-QCocoaNSWindow * QCocoaWindow::createNSWindow()
+QCocoaNSWindow *QCocoaWindow::createNSWindow(bool shouldBeChildNSWindow, bool shouldBePanel)
{
QMacAutoReleasePool pool;
QRect rect = initialGeometry(window(), windowGeometry(), defaultWindowWidth, defaultWindowHeight);
- NSRect frame = qt_mac_flipRect(rect);
-
- Qt::WindowType type = window()->type();
- Qt::WindowFlags flags = window()->flags();
- NSUInteger styleMask;
- if (m_isNSWindowChild) {
- styleMask = NSBorderlessWindowMask;
- } else {
- styleMask = windowStyleMask(flags);
+ QScreen *targetScreen = nullptr;
+ for (QScreen *screen : QGuiApplication::screens()) {
+ if (screen->geometry().contains(rect.topLeft())) {
+ targetScreen = screen;
+ break;
+ }
}
- QCocoaNSWindow *createdWindow = 0;
-
- // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
- // and dialogs
- if (shouldUseNSPanel()) {
- QNSPanel *window;
- window = [[QNSPanel alloc] initWithContentRect:frame
- styleMask: styleMask
- qPlatformWindow:this];
- if ((type & Qt::Popup) == Qt::Popup)
- [window setHasShadow:YES];
-
- // Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set.
- QVariant showWithoutActivating = QPlatformWindow::window()->property("_q_macAlwaysShowToolWindow");
- bool shouldHideOnDeactivate = ((type & Qt::Tool) == Qt::Tool) &&
- !(showWithoutActivating.isValid() && showWithoutActivating.toBool());
- [window setHidesOnDeactivate: shouldHideOnDeactivate];
-
- // Make popup windows show on the same desktop as the parent full-screen window.
- [window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenAuxiliary];
- if ((type & Qt::Popup) == Qt::Popup)
- [window setAnimationBehavior:NSWindowAnimationBehaviorUtilityWindow];
-
- createdWindow = window;
- } else {
- QNSWindow *window;
- window = [[QNSWindow alloc] initWithContentRect:frame
- styleMask: styleMask
- qPlatformWindow:this];
- createdWindow = window;
+
+ if (!targetScreen) {
+ qCWarning(lcQpaCocoaWindow) << "Window position outside any known screen, using primary screen";
+ targetScreen = QGuiApplication::primaryScreen();
}
- if ([createdWindow respondsToSelector:@selector(setRestorable:)])
- [createdWindow setRestorable: NO];
+ rect.translate(-targetScreen->geometry().topLeft());
+ QCocoaScreen *cocoaScreen = static_cast<QCocoaScreen *>(targetScreen->handle());
+ NSRect frame = NSRectFromCGRect(cocoaScreen->mapToNative(rect).toCGRect());
- NSInteger level = windowLevel(flags);
- [createdWindow setLevel:level];
+ // Note: The macOS window manager has a bug, where if a screen is rotated, it will not allow
+ // a window to be created within the area of the screen that has a Y coordinate (I quadrant)
+ // higher than the height of the screen in its non-rotated state, unless the window is
+ // created with the NSWindowStyleMaskBorderless style mask.
- // OpenGL surfaces can be ordered either above(default) or below the NSWindow.
- // When ordering below the window must be tranclucent and have a clear background color.
- static GLint openglSourfaceOrder = qt_mac_resolveOption(1, "QT_MAC_OPENGL_SURFACE_ORDER");
+ Qt::WindowType type = window()->type();
+ Qt::WindowFlags flags = window()->flags();
+
+ // Create NSWindow
+ Class windowClass = shouldBePanel ? [QNSPanel class] : [QNSWindow class];
+ NSUInteger styleMask = shouldBeChildNSWindow ? NSBorderlessWindowMask : windowStyleMask(flags);
+ QCocoaNSWindow *window = [[windowClass alloc] initWithContentRect:frame
+ screen:cocoaScreen->nativeScreen() styleMask:styleMask qPlatformWindow:this];
+
+ window.restorable = NO;
+ window.level = shouldBeChildNSWindow ? NSNormalWindowLevel : windowLevel(flags);
- bool isTranslucent = window()->format().alphaBufferSize() > 0
- || (surface()->supportsOpenGL() && openglSourfaceOrder == -1);
- if (isTranslucent) {
- [createdWindow setBackgroundColor:[NSColor clearColor]];
- [createdWindow setOpaque:NO];
+ if (!isOpaque()) {
+ window.backgroundColor = [NSColor clearColor];
+ window.opaque = NO;
}
- m_windowModality = window()->modality();
+ Q_ASSERT(!(shouldBePanel && shouldBeChildNSWindow));
- applyContentBorderThickness(createdWindow);
+ if (shouldBePanel) {
+ // Qt::Tool windows hide on app deactivation, unless Qt::WA_MacAlwaysShowToolWindow is set
+ window.hidesOnDeactivate = ((type & Qt::Tool) == Qt::Tool) &&
+ !qt_mac_resolveOption(false, QPlatformWindow::window(), "_q_macAlwaysShowToolWindow", "");
- return createdWindow;
-}
+ // Make popup windows show on the same desktop as the parent full-screen window
+ window.collectionBehavior = NSWindowCollectionBehaviorFullScreenAuxiliary;
-void QCocoaWindow::setNSWindow(QCocoaNSWindow *window)
-{
- if (window.contentView != m_view) {
- [m_view setPostsFrameChangedNotifications:NO];
- [m_view retain];
- if (m_view.superview) // m_view comes from another NSWindow
- [m_view removeFromSuperview];
- [window setContentView:m_view];
- [m_view release];
- [m_view setPostsFrameChangedNotifications:YES];
+ if ((type & Qt::Popup) == Qt::Popup) {
+ window.hasShadow = YES;
+ window.animationBehavior = NSWindowAnimationBehaviorUtilityWindow;
+ }
+ } else if (shouldBeChildNSWindow) {
+ window.collectionBehavior =
+ NSWindowCollectionBehaviorManaged
+ | NSWindowCollectionBehaviorIgnoresCycle
+ | NSWindowCollectionBehaviorFullScreenAuxiliary;
+ window.hasShadow = NO;
+ window.animationBehavior = NSWindowAnimationBehaviorNone;
}
-}
-
-void QCocoaWindow::removeChildWindow(QCocoaWindow *child)
-{
- m_childWindows.removeOne(child);
- [m_nsWindow removeChildWindow:child->m_nsWindow];
-}
-bool QCocoaWindow::isNativeWindowTypeInconsistent()
-{
- if (!m_nsWindow)
- return false;
+ // Persist modality so we can detect changes later on
+ m_windowModality = QPlatformWindow::window()->modality();
- const bool isPanel = [m_nsWindow isKindOfClass:[QNSPanel class]];
- const bool usePanel = shouldUseNSPanel();
+ applyContentBorderThickness(window);
- return isPanel != usePanel;
+ return window;
}
void QCocoaWindow::removeMonitor()
@@ -1520,7 +1795,7 @@ void QCocoaWindow::removeMonitor()
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::nativeWindowGeometry() const
{
- if (!m_nsWindow || m_isNSWindowChild)
+ if (!m_nsWindow || isChildNSWindow())
return geometry();
NSRect rect = [m_nsWindow frame];
@@ -1530,94 +1805,144 @@ QRect QCocoaWindow::nativeWindowGeometry() const
return qRect;
}
-// Returns a pointer to the parent QCocoaWindow for this window, or 0 if there is none.
-QCocoaWindow *QCocoaWindow::parentCocoaWindow() const
-{
- if (window() && window()->transientParent()) {
- return static_cast<QCocoaWindow*>(window()->transientParent()->handle());
- }
- return 0;
-}
+/*!
+ Applies the given state to the NSWindow, going in/out of minimize/zoomed/fullscreen
-// Syncs the NSWindow minimize/maximize/fullscreen state with the current QWindow state
-void QCocoaWindow::syncWindowState(Qt::WindowState newState)
+ When this is called from QWindow::setWindowState(), the QWindow state has not been
+ updated yet, so window()->windowState() will reflect the previous state that was
+ reported to QtGui.
+*/
+void QCocoaWindow::applyWindowState(Qt::WindowState newState)
{
+ const Qt::WindowState currentState = windowState();
+ if (newState == currentState)
+ return;
+
if (!m_nsWindow)
return;
- // if content view width or height is 0 then the window animations will crash so
- // do nothing except set the new state
- NSRect contentRect = m_view.frame;
- if (contentRect.size.width <= 0 || contentRect.size.height <= 0) {
+
+ const NSSize contentSize = m_view.frame.size;
+ if (contentSize.width <= 0 || contentSize.height <= 0) {
+ // If content view width or height is 0 then the window animations will crash so
+ // do nothing. We report the current state back to reflect the failed operation.
qWarning("invalid window content view size, check your window geometry");
- m_synchedWindowState = newState;
+ reportCurrentWindowState(true);
return;
}
- Qt::WindowState predictedState = newState;
- if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
- const int styleMask = [m_nsWindow styleMask];
- const bool usePerform = styleMask & NSResizableWindowMask;
- [m_nsWindow setStyleMask:styleMask | NSResizableWindowMask];
- if (usePerform)
- [m_nsWindow performZoom : m_nsWindow]; // toggles
- else
- [m_nsWindow zoom : m_nsWindow]; // toggles
- [m_nsWindow setStyleMask:styleMask];
+ if (m_nsWindow.styleMask & NSUtilityWindowMask) {
+ // Utility panels cannot be fullscreen
+ qWarning() << window()->type() << "windows can not be made full screen";
+ reportCurrentWindowState(true);
+ return;
}
- if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) {
- if (newState & Qt::WindowMinimized) {
- if ([m_nsWindow styleMask] & NSMiniaturizableWindowMask)
- [m_nsWindow performMiniaturize : m_nsWindow];
- else
- [m_nsWindow miniaturize : m_nsWindow];
- } else {
- [m_nsWindow deminiaturize : m_nsWindow];
- }
+ const id sender = m_nsWindow;
+
+ // First we need to exit states that can't transition directly to other states
+ switch (currentState) {
+ case Qt::WindowMinimized:
+ [m_nsWindow deminiaturize:sender];
+ Q_ASSERT_X(windowState() != Qt::WindowMinimized, "QCocoaWindow",
+ "[NSWindow deminiaturize:] is synchronous");
+ break;
+ case Qt::WindowFullScreen: {
+ toggleFullScreen();
+ // Exiting fullscreen is not synchronous, so we need to wait for the
+ // NSWindowDidExitFullScreenNotification before continuing to apply
+ // the new state.
+ return;
}
-
- const bool effMax = m_effectivelyMaximized;
- if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) {
- if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) {
- [m_nsWindow zoom : m_nsWindow]; // toggles
- m_effectivelyMaximized = !effMax;
- } else if (!(newState & Qt::WindowMaximized)) {
- // it would be nice to change the target geometry that toggleFullScreen will animate toward
- // but there is no known way, so the maximized state is not possible at this time
- predictedState = static_cast<Qt::WindowState>(static_cast<int>(newState) | Qt::WindowMaximized);
- m_effectivelyMaximized = true;
- }
+ default:
+ Q_FALLTHROUGH();
}
- if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) {
- if (window()->flags() & Qt::WindowFullscreenButtonHint) {
- if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen)
- predictedState = Qt::WindowMaximized;
- [m_nsWindow toggleFullScreen : m_nsWindow];
- } else {
- if (newState & Qt::WindowFullScreen) {
- QScreen *screen = window()->screen();
- if (screen) {
- if (m_normalGeometry.width() < 0) {
- m_oldWindowFlags = m_windowFlags;
- window()->setFlags(window()->flags() | Qt::FramelessWindowHint);
- m_normalGeometry = nativeWindowGeometry();
- setGeometry(screen->geometry());
- m_presentationOptions = [NSApp presentationOptions];
- [NSApp setPresentationOptions : m_presentationOptions | NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock];
- }
- }
- } else {
- window()->setFlags(m_oldWindowFlags);
- setGeometry(m_normalGeometry);
- m_normalGeometry.setRect(0, 0, -1, -1);
- [NSApp setPresentationOptions : m_presentationOptions];
- }
+ // Then we apply the new state if needed
+ if (newState == windowState())
+ return;
+
+ switch (newState) {
+ case Qt::WindowFullScreen:
+ toggleFullScreen();
+ break;
+ case Qt::WindowMaximized:
+ toggleMaximized();
+ break;
+ case Qt::WindowMinimized:
+ [m_nsWindow miniaturize:sender];
+ break;
+ case Qt::WindowNoState:
+ switch (windowState()) {
+ case Qt::WindowMaximized:
+ toggleMaximized();
+ default:
+ Q_FALLTHROUGH();
}
+ break;
+ default:
+ Q_UNREACHABLE();
}
+}
+
+void QCocoaWindow::toggleMaximized()
+{
+ // The NSWindow needs to be resizable, otherwise the window will
+ // not be possible to zoom back to non-zoomed state.
+ const bool wasResizable = m_nsWindow.styleMask & NSResizableWindowMask;
+ m_nsWindow.styleMask |= NSResizableWindowMask;
+
+ const id sender = m_nsWindow;
+ [m_nsWindow zoom:sender];
+
+ if (!wasResizable)
+ m_nsWindow.styleMask &= ~NSResizableWindowMask;
+}
+
+void QCocoaWindow::toggleFullScreen()
+{
+ // The window needs to have the correct collection behavior for the
+ // toggleFullScreen call to have an effect. The collection behavior
+ // will be reset in windowDidEnterFullScreen/windowDidLeaveFullScreen.
+ m_nsWindow.collectionBehavior |= NSWindowCollectionBehaviorFullScreenPrimary;
+
+ const id sender = m_nsWindow;
+ [m_nsWindow toggleFullScreen:sender];
+}
+
+bool QCocoaWindow::isTransitioningToFullScreen() const
+{
+ NSWindow *window = m_view.window;
+ return window.styleMask & NSFullScreenWindowMask && !window.qt_fullScreen;
+}
+
+Qt::WindowState QCocoaWindow::windowState() const
+{
+ // FIXME: Support compound states (Qt::WindowStates)
+
+ NSWindow *window = m_view.window;
+ if (window.miniaturized)
+ return Qt::WindowMinimized;
+ if (window.qt_fullScreen)
+ return Qt::WindowFullScreen;
+ if ((window.zoomed && !isTransitioningToFullScreen())
+ || (m_lastReportedWindowState == Qt::WindowMaximized && isTransitioningToFullScreen()))
+ return Qt::WindowMaximized;
+
+ // Note: We do not report Qt::WindowActive, even if isActive()
+ // is true, as QtGui does not expect this window state to be set.
+
+ return Qt::WindowNoState;
+}
+
+void QCocoaWindow::reportCurrentWindowState(bool unconditionally)
+{
+ Qt::WindowState currentState = windowState();
+ if (!unconditionally && currentState == m_lastReportedWindowState)
+ return;
- // New state is now the current synched state
- m_synchedWindowState = predictedState;
+ QWindowSystemInterface::handleWindowStateChanged<QWindowSystemInterface::SynchronousDelivery>(
+ window(), currentState, m_lastReportedWindowState);
+ m_lastReportedWindowState = currentState;
}
bool QCocoaWindow::setWindowModified(bool modified)
@@ -1671,7 +1996,7 @@ void QCocoaWindow::setWindowCursor(NSCursor *cursor)
return;
// Setting a cursor in a foregin view is not supported.
- if (window()->type() == Qt::ForeignWindow)
+ if (isForeignWindow())
return;
[m_windowCursor release];
@@ -1814,15 +2139,13 @@ void QCocoaWindow::exposeWindow()
if (!isWindowExposable())
return;
- // Update the QWindow's screen property. This property is set
- // to QGuiApplication::primaryScreen() at QWindow construciton
- // time, and we won't get a NSWindowDidChangeScreenNotification
- // on show. The case where the window is initially displayed
- // on a non-primary screen needs special handling here.
- NSUInteger screenIndex = [[NSScreen screens] indexOfObject:m_nsWindow.screen];
- if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
- if (cocoaScreen)
+ if (window()->isTopLevel()) {
+ // Update the QWindow's screen property. This property is set
+ // to QGuiApplication::primaryScreen() at QWindow construciton
+ // time, and we won't get a NSWindowDidChangeScreenNotification
+ // on show. The case where the window is initially displayed
+ // on a non-primary screen needs special handling here.
+ if (QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenForNSScreen(m_nsWindow.screen))
window()->setScreen(cocoaScreen->screen());
}
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index f226547b90..75a508370f 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -74,7 +74,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
QStringList *currentCustomDragTypes;
bool m_sendUpAsRightButton;
Qt::KeyboardModifiers currentWheelModifiers;
- bool m_subscribesForGlobalFrameNotifications;
#ifndef QT_NO_OPENGL
QCocoaGLContext *m_glContext;
bool m_shouldSetGLContextinDrawRect;
@@ -101,9 +100,6 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
- (void)drawRect:(NSRect)dirtyRect;
- (void)drawBackingStoreUsingCoreGraphics:(NSRect)dirtyRect;
- (void)updateGeometry;
-- (void)notifyWindowStateChanged:(Qt::WindowState)newState;
-- (void)windowNotification : (NSNotification *) windowNotification;
-- (void)notifyWindowWillZoom:(BOOL)willZoom;
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification;
- (void)viewDidHide;
- (void)viewDidUnhide;
@@ -152,6 +148,11 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
@end
+@interface QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
+@property (nonatomic, readonly) QCocoaWindow *platformWindow;
+@property (nonatomic, readonly) BOOL isMenuView;
+@end
+
QT_NAMESPACE_ALIAS_OBJC_CLASS(QNSView);
#endif //QNSVIEW_H
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 970ce9e785..fbf4f99f2e 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -149,7 +149,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_acceptedMouseDowns = Qt::NoButton;
m_frameStrutButtons = Qt::NoButton;
m_sendKeyEvent = false;
- m_subscribesForGlobalFrameNotifications = false;
#ifndef QT_NO_OPENGL
m_glContext = 0;
m_shouldSetGLContextinDrawRect = false;
@@ -181,7 +180,6 @@ static bool _q_dontOverrideCtrlLMB = false;
CGImageRelease(m_maskImage);
[m_trackingArea release];
m_maskImage = 0;
- m_subscribesForGlobalFrameNotifications = false;
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
[m_mouseMoveHelper release];
@@ -217,11 +215,6 @@ static bool _q_dontOverrideCtrlLMB = false;
#endif
[self registerDragTypes];
- [self setPostsFrameChangedNotifications : YES];
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(updateGeometry)
- name:NSViewFrameDidChangeNotification
- object:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(textInputContextKeyboardSelectionDidChangeNotification:)
@@ -240,27 +233,9 @@ static bool _q_dontOverrideCtrlLMB = false;
//was unable to set view
m_shouldSetGLContextinDrawRect = true;
}
-
- if (!m_subscribesForGlobalFrameNotifications) {
- // NSOpenGLContext expects us to repaint (or update) the view when
- // it changes position on screen. Since this happens unnoticed for
- // the view when the parent view moves, we need to register a special
- // notification that lets us handle this case:
- m_subscribesForGlobalFrameNotifications = true;
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(globalFrameChanged:)
- name:NSViewGlobalFrameDidChangeNotification
- object:self];
- }
}
#endif
-- (void) globalFrameChanged:(NSNotification*)notification
-{
- Q_UNUSED(notification);
- m_platformWindow->updateExposedGeometry();
-}
-
- (void)viewDidMoveToSuperview
{
if (!(m_platformWindow->m_viewIsToBeEmbedded))
@@ -281,22 +256,6 @@ static bool _q_dontOverrideCtrlLMB = false;
m_backingStore = Q_NULLPTR;
}
-- (void)viewWillMoveToWindow:(NSWindow *)newWindow
-{
- // ### Merge "normal" window code path with this one for 5.1.
- if (!(m_platformWindow->window()->type() & Qt::SubWindow))
- return;
-
- if (newWindow) {
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(windowNotification:)
- name:nil // Get all notifications
- object:newWindow];
- }
- if ([self window])
- [[NSNotificationCenter defaultCenter] removeObserver:self name:nil object:[self window]];
-}
-
- (QWindow *)topLevelWindow
{
QWindow *focusWindow = m_platformWindow->window();
@@ -316,7 +275,7 @@ static bool _q_dontOverrideCtrlLMB = false;
{
QRect geometry;
- if (m_platformWindow->m_isNSWindowChild) {
+ if (self.window.parentWindow) {
return;
#if 0
//geometry = QRectF::fromCGRect([self frame]).toRect();
@@ -336,10 +295,10 @@ static bool _q_dontOverrideCtrlLMB = false;
geometry = QRect(windowRect.origin.x, qt_mac_flipYCoordinate(windowRect.origin.y + rect.size.height), rect.size.width, rect.size.height);
} else if (m_platformWindow->m_viewIsToBeEmbedded) {
// embedded child window, use the frame rect ### merge with case below
- geometry = QRectF::fromCGRect([self bounds]).toRect();
+ geometry = QRectF::fromCGRect(NSRectToCGRect([self bounds])).toRect();
} else {
// child window, use the frame rect
- geometry = QRectF::fromCGRect([self frame]).toRect();
+ geometry = QRectF::fromCGRect(NSRectToCGRect([self frame])).toRect();
}
if (m_platformWindow->m_nsWindow && geometry == m_platformWindow->geometry())
@@ -380,79 +339,6 @@ static bool _q_dontOverrideCtrlLMB = false;
}
}
-- (void)notifyWindowStateChanged:(Qt::WindowState)newState
-{
- // If the window was maximized, then fullscreen, then tried to go directly to "normal" state,
- // this notification will say that it is "normal", but it will still look maximized, and
- // if you called performZoom it would actually take it back to "normal".
- // So we should say that it is maximized because it actually is.
- if (newState == Qt::WindowNoState && m_platformWindow->m_effectivelyMaximized)
- newState = Qt::WindowMaximized;
- QWindowSystemInterface::handleWindowStateChanged(m_platformWindow->window(), newState);
- // We want to read the window state back from the window,
- // but the event we just sent may be asynchronous.
- QWindowSystemInterface::flushWindowSystemEvents();
- m_platformWindow->setSynchedWindowStateFromWindow();
-}
-
-- (void)windowNotification : (NSNotification *) windowNotification
-{
- //qDebug() << "windowNotification" << QString::fromNSString([windowNotification name]);
-
- NSString *notificationName = [windowNotification name];
- if (notificationName == NSWindowDidBecomeKeyNotification) {
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
- QWindowSystemInterface::handleWindowActivated(m_platformWindow->window());
- } else if (notificationName == NSWindowDidResignKeyNotification) {
- // key window will be non-nil if another window became key... do not
- // set the active window to zero here, the new key window's
- // NSWindowDidBecomeKeyNotification hander will change the active window
- NSWindow *keyWindow = [NSApp keyWindow];
- if (!keyWindow || keyWindow == windowNotification.object) {
- // no new key window, go ahead and set the active window to zero
- if (!m_platformWindow->windowIsPopupType() && !m_isMenuView)
- QWindowSystemInterface::handleWindowActivated(0);
- }
- } else if (notificationName == NSWindowDidMiniaturizeNotification
- || notificationName == NSWindowDidDeminiaturizeNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidMiniaturizeNotification ?
- Qt::WindowMinimized : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- } else if ([notificationName isEqualToString: @"NSWindowDidOrderOffScreenNotification"]) {
- m_platformWindow->obscureWindow();
- } else if ([notificationName isEqualToString: @"NSWindowDidOrderOnScreenAndFinishAnimatingNotification"]) {
- m_platformWindow->exposeWindow();
- } else if ([notificationName isEqualToString:NSWindowDidChangeOcclusionStateNotification]) {
- // Several unit tests expect paint and/or expose events for windows that are
- // sometimes (unpredictably) occluded and some unit tests depend on QWindow::isExposed -
- // don't send Expose/Obscure events when running under QTestLib.
- static const bool onTestLib = qt_mac_resolveOption(false, "QT_QTESTLIB_RUNNING");
- if (!onTestLib) {
- if ((NSUInteger)[self.window occlusionState] & NSWindowOcclusionStateVisible) {
- m_platformWindow->exposeWindow();
- } else {
- // Send Obscure events on window occlusion to stop animations.
- m_platformWindow->obscureWindow();
- }
- }
- } else if (notificationName == NSWindowDidChangeScreenNotification) {
- if (m_platformWindow->window()) {
- NSUInteger screenIndex = [[NSScreen screens] indexOfObject:self.window.screen];
- if (screenIndex != NSNotFound) {
- QCocoaScreen *cocoaScreen = QCocoaIntegration::instance()->screenAtIndex(screenIndex);
- if (cocoaScreen)
- QWindowSystemInterface::handleWindowScreenChanged(m_platformWindow->window(), cocoaScreen->screen());
- m_platformWindow->updateExposedGeometry();
- }
- }
- } else if (notificationName == NSWindowDidEnterFullScreenNotification
- || notificationName == NSWindowDidExitFullScreenNotification) {
- Qt::WindowState newState = notificationName == NSWindowDidEnterFullScreenNotification ?
- Qt::WindowFullScreen : Qt::WindowNoState;
- [self notifyWindowStateChanged:newState];
- }
-}
-
- (void)textInputContextKeyboardSelectionDidChangeNotification : (NSNotification *) textInputContextKeyboardSelectionDidChangeNotification
{
Q_UNUSED(textInputContextKeyboardSelectionDidChangeNotification)
@@ -462,14 +348,6 @@ static bool _q_dontOverrideCtrlLMB = false;
}
}
-- (void)notifyWindowWillZoom:(BOOL)willZoom
-{
- Qt::WindowState newState = willZoom ? Qt::WindowMaximized : Qt::WindowNoState;
- if (!willZoom)
- m_platformWindow->m_effectivelyMaximized = false;
- [self notifyWindowStateChanged:newState];
-}
-
- (void)viewDidHide
{
m_platformWindow->obscureWindow();
@@ -553,7 +431,7 @@ static bool _q_dontOverrideCtrlLMB = false;
- (void) drawRect:(NSRect)dirtyRect
{
- qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << QRectF::fromCGRect(dirtyRect);
+ qCDebug(lcQpaCocoaWindow) << "[QNSView drawRect:]" << m_platformWindow->window() << QRectF::fromCGRect(NSRectToCGRect(dirtyRect));
#ifndef QT_NO_OPENGL
if (m_glContext && m_shouldSetGLContextinDrawRect) {
@@ -1333,7 +1211,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
- (bool)handleGestureAsBeginEnd:(NSEvent *)event
{
- if (QSysInfo::QSysInfo::MacintoshVersion < QSysInfo::MV_10_11)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::OSXElCapitan)
return false;
if ([event phase] == NSEventPhaseBegan) {
@@ -2199,3 +2077,17 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin
}
@end
+
+@implementation QT_MANGLE_NAMESPACE(QNSView) (QtExtras)
+
+- (QCocoaWindow*)platformWindow
+{
+ return m_platformWindow.data();;
+}
+
+- (BOOL)isMenuView
+{
+ return m_isMenuView;
+}
+
+@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.h b/src/plugins/platforms/cocoa/qnswindowdelegate.h
index f29aa97b68..d2078b5786 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.h
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.h
@@ -49,15 +49,9 @@
QCocoaWindow *m_cocoaWindow;
}
-- (id)initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow;
+- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow;
-- (void)windowDidBecomeKey:(NSNotification *)notification;
-- (void)windowDidResize:(NSNotification *)notification;
-- (void)windowDidMove:(NSNotification *)notification;
-- (void)windowWillMove:(NSNotification *)notification;
- (BOOL)windowShouldClose:(NSNotification *)notification;
-- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame;
-- (void)windowWillClose:(NSNotification *)notification;
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu;
- (BOOL)window:(NSWindow *)window shouldDragDocumentWithEvent:(NSEvent *)event from:(NSPoint)dragImageLocation withPasteboard:(NSPasteboard *)pasteboard;
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index 7f988ac963..ce74aa9973 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -41,61 +41,17 @@
#include "qcocoahelpers.h"
#include <QDebug>
+#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
@implementation QNSWindowDelegate
-- (id) initWithQCocoaWindow: (QCocoaWindow *) cocoaWindow
+- (id)initWithQCocoaWindow:(QCocoaWindow *)cocoaWindow
{
- self = [super init];
-
- if (self) {
+ if (self = [super init])
m_cocoaWindow = cocoaWindow;
- }
- return self;
-}
-
-- (void)windowDidBecomeKey:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow->m_windowUnderMouse) {
- QPointF windowPoint;
- QPointF screenPoint;
- [qnsview_cast(m_cocoaWindow->view()) convertFromScreen:[NSEvent mouseLocation] toWindowPoint:&windowPoint andScreenPoint:&screenPoint];
- QWindowSystemInterface::handleEnterEvent(m_cocoaWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
- }
-}
-- (void)windowDidResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidResize();
- }
-}
-
-- (void)windowDidEndLiveResize:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidEndLiveResize();
- }
-}
-
-- (void)windowWillMove:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowWillMove();
- }
-}
-
-- (void)windowDidMove:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow) {
- m_cocoaWindow->windowDidMove();
- }
+ return self;
}
- (BOOL)windowShouldClose:(NSNotification *)notification
@@ -107,20 +63,19 @@
return YES;
}
-
-- (BOOL)windowShouldZoom:(NSWindow *)window toFrame:(NSRect)newFrame
+/*!
+ Overridden to ensure that the zoomed state always results in a maximized
+ window, which would otherwise not be the case for borderless windows.
+*/
+- (NSRect)windowWillUseStandardFrame:(NSWindow *)window defaultFrame:(NSRect)newFrame
{
Q_UNUSED(newFrame);
- if (m_cocoaWindow && m_cocoaWindow->window()->type() != Qt::ForeignWindow)
- [qnsview_cast(m_cocoaWindow->view()) notifyWindowWillZoom:![window isZoomed]];
- return YES;
-}
-- (void)windowWillClose:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- if (m_cocoaWindow)
- m_cocoaWindow->windowWillClose();
+ // We explicitly go through the QScreen API here instead of just using
+ // window.screen.visibleFrame directly, as that ensures we have the same
+ // behavior for both use-cases/APIs.
+ Q_ASSERT(window == m_cocoaWindow->nativeWindow());
+ return m_cocoaWindow->screen()->availableGeometry().toCGRect();
}
- (BOOL)window:(NSWindow *)window shouldPopUpDocumentPathMenu:(NSMenu *)menu
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
index b5065ba380..38425f8fa1 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dbitmap.cpp
@@ -55,8 +55,9 @@ class QWindowsDirect2DBitmapPrivate
{
public:
QWindowsDirect2DBitmapPrivate(ID2D1DeviceContext *dc = 0, ID2D1Bitmap1 *bm = 0)
- : bitmap(bm)
- , deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ : deviceContext(new QWindowsDirect2DDeviceContext(dc))
+ , bitmap(bm)
+
{
deviceContext->get()->SetTarget(bm);
}
@@ -83,13 +84,13 @@ public:
UINT32(width), UINT32(height)
};
- HRESULT hr = deviceContext->get()->CreateBitmap(size, data, pitch,
+ HRESULT hr = deviceContext->get()->CreateBitmap(size, data, UINT32(pitch),
bitmapProperties(),
bitmap.ReleaseAndGetAddressOf());
if (SUCCEEDED(hr))
deviceContext->get()->SetTarget(bitmap.Get());
else
- qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create bitmap: %#lx", __FUNCTION__, hr);
return SUCCEEDED(hr);
}
@@ -107,28 +108,28 @@ public:
D2D1_BITMAP_PROPERTIES1 properties = bitmapProperties();
properties.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | D2D1_BITMAP_OPTIONS_CPU_READ;
- hr = deviceContext->get()->CreateBitmap(size, NULL, NULL,
+ hr = deviceContext->get()->CreateBitmap(size, NULL, 0,
properties, &mappingCopy);
if (FAILED(hr)) {
- qWarning("%s: Could not create bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create bitmap: %#lx", __FUNCTION__, hr);
return QImage();
}
hr = mappingCopy->CopyFromBitmap(NULL, bitmap.Get(), NULL);
if (FAILED(hr)) {
- qWarning("%s: Could not copy from bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy from bitmap: %#lx", __FUNCTION__, hr);
return QImage();
}
D2D1_MAPPED_RECT mappedRect;
hr = mappingCopy->Map(D2D1_MAP_OPTIONS_READ, &mappedRect);
if (FAILED(hr)) {
- qWarning("%s: Could not map: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not map: %#lx", __FUNCTION__, hr);
return QImage();
}
return QImage(static_cast<const uchar *>(mappedRect.bits),
- size.width, size.height, mappedRect.pitch,
+ int(size.width), int(size.height), int(mappedRect.pitch),
QImage::Format_ARGB32_Premultiplied).copy(rect);
}
@@ -197,7 +198,7 @@ QSize QWindowsDirect2DBitmap::size() const
Q_D(const QWindowsDirect2DBitmap);
D2D1_SIZE_U size = d->bitmap->GetPixelSize();
- return QSize(size.width, size.height);
+ return QSize(int(size.width), int(size.height));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
index fb5bb43d17..a5817016e6 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.cpp
@@ -84,7 +84,7 @@ public:
}
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct3D Device: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct3D Device: %#lx", __FUNCTION__, hr);
return false;
}
@@ -93,7 +93,7 @@ public:
hr = d3dDevice.As(&dxgiDevice);
if (FAILED(hr)) {
- qWarning("%s: DXGI Device interface query failed on D3D Device: %#x", __FUNCTION__, hr);
+ qWarning("%s: DXGI Device interface query failed on D3D Device: %#lx", __FUNCTION__, hr);
return false;
}
@@ -102,13 +102,13 @@ public:
hr = dxgiDevice->GetAdapter(&dxgiAdapter);
if (FAILED(hr)) {
- qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#x", __FUNCTION__, hr);
+ qWarning("%s: Failed to probe DXGI Device for parent DXGI Adapter: %#lx", __FUNCTION__, hr);
return false;
}
hr = dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
if (FAILED(hr)) {
- qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#x", __FUNCTION__, hr);
+ qWarning("%s: Failed to probe DXGI Adapter for parent DXGI Factory: %#lx", __FUNCTION__, hr);
return false;
}
@@ -121,26 +121,26 @@ public:
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, options, d2dFactory.GetAddressOf());
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D Factory: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D Factory: %#lx", __FUNCTION__, hr);
return false;
}
hr = d2dFactory->CreateDevice(dxgiDevice.Get(), &d2dDevice);
if (FAILED(hr)) {
- qWarning("%s: Could not create D2D Device: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create D2D Device: %#lx", __FUNCTION__, hr);
return false;
}
hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
static_cast<IUnknown **>(&directWriteFactory));
if (FAILED(hr)) {
- qWarning("%s: Could not create DirectWrite factory: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create DirectWrite factory: %#lx", __FUNCTION__, hr);
return false;
}
hr = directWriteFactory->GetGdiInterop(&directWriteGdiInterop);
if (FAILED(hr)) {
- qWarning("%s: Could not create DirectWrite GDI Interop: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create DirectWrite GDI Interop: %#lx", __FUNCTION__, hr);
return false;
}
@@ -161,7 +161,7 @@ QWindowsDirect2DContext::QWindowsDirect2DContext()
{
}
-QWindowsDirect2DContext::~QWindowsDirect2DContext() {}
+QWindowsDirect2DContext::~QWindowsDirect2DContext() = default;
bool QWindowsDirect2DContext::init()
{
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
index a3478d2d4e..0d42c65964 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dcontext.h
@@ -59,7 +59,7 @@ class QWindowsDirect2DContext
public:
QWindowsDirect2DContext();
- virtual ~QWindowsDirect2DContext();
+ ~QWindowsDirect2DContext();
bool init();
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
index 30238217dd..8a34f6974f 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2ddevicecontext.cpp
@@ -51,14 +51,13 @@ class QWindowsDirect2DDeviceContextPrivate {
public:
QWindowsDirect2DDeviceContextPrivate(ID2D1DeviceContext *dc)
: deviceContext(dc)
- , refCount(0)
{
if (!dc) {
HRESULT hr = QWindowsDirect2DContext::instance()->d2dDevice()->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&deviceContext);
if (Q_UNLIKELY(FAILED(hr)))
- qFatal("%s: Couldn't create Direct2D Device Context: %#x", __FUNCTION__, hr);
+ qFatal("%s: Couldn't create Direct2D Device Context: %#lx", __FUNCTION__, hr);
}
Q_ASSERT(deviceContext);
@@ -98,7 +97,7 @@ public:
}
ComPtr<ID2D1DeviceContext> deviceContext;
- int refCount;
+ int refCount = 0;
};
QWindowsDirect2DDeviceContext::QWindowsDirect2DDeviceContext(ID2D1DeviceContext *dc)
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index da4a4e6ce6..ea51135583 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -76,12 +76,7 @@ public:
class Direct2DVersion
{
private:
- Direct2DVersion()
- : partOne(0)
- , partTwo(0)
- , partThree(0)
- , partFour(0)
- {}
+ Direct2DVersion() = default;
Direct2DVersion(int one, int two, int three, int four)
: partOne(one)
@@ -108,13 +103,14 @@ public:
if (_tcscat_s(filename, bufSize, __TEXT("\\d2d1.dll")) == 0) {
DWORD versionInfoSize = GetFileVersionInfoSize(filename, NULL);
if (versionInfoSize) {
- QVarLengthArray<BYTE> info(versionInfoSize);
- if (GetFileVersionInfo(filename, NULL, versionInfoSize, info.data())) {
+ QVarLengthArray<BYTE> info(static_cast<int>(versionInfoSize));
+ if (GetFileVersionInfo(filename, 0, versionInfoSize, info.data())) {
UINT size;
DWORD *fi;
- if (VerQueryValue(info.constData(), __TEXT("\\"), (LPVOID *) &fi, &size) && size) {
- VS_FIXEDFILEINFO *verInfo = (VS_FIXEDFILEINFO *) fi;
+ if (VerQueryValue(info.constData(), __TEXT("\\"),
+ reinterpret_cast<void **>(&fi), &size) && size) {
+ const VS_FIXEDFILEINFO *verInfo = reinterpret_cast<const VS_FIXEDFILEINFO *>(fi);
return Direct2DVersion(HIWORD(verInfo->dwFileVersionMS),
LOWORD(verInfo->dwFileVersionMS),
HIWORD(verInfo->dwFileVersionLS),
@@ -171,7 +167,10 @@ public:
return a - b;
}
- int partOne, partTwo, partThree, partFour;
+ int partOne = 0;
+ int partTwo = 0;
+ int partThree = 0;
+ int partFour = 0;
};
QWindowsDirect2DIntegration *QWindowsDirect2DIntegration::create(const QStringList &paramList)
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
index 29b01391e2..3c86168a74 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintdevice.cpp
@@ -93,42 +93,33 @@ int QWindowsDirect2DPaintDevice::metric(QPaintDevice::PaintDeviceMetric metric)
switch (metric) {
case QPaintDevice::PdmWidth:
- return d->bitmap->bitmap()->GetPixelSize().width;
- break;
+ return int(d->bitmap->bitmap()->GetPixelSize().width);
case QPaintDevice::PdmHeight:
- return d->bitmap->bitmap()->GetPixelSize().height;
- break;
+ return int(d->bitmap->bitmap()->GetPixelSize().height);
case QPaintDevice::PdmNumColors:
return INT_MAX;
- break;
case QPaintDevice::PdmDepth:
return 32;
- break;
case QPaintDevice::PdmDpiX:
case QPaintDevice::PdmPhysicalDpiX:
{
FLOAT x, y;
QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
- return x;
+ return qRound(x);
}
- break;
case QPaintDevice::PdmDpiY:
case QPaintDevice::PdmPhysicalDpiY:
{
FLOAT x, y;
QWindowsDirect2DContext::instance()->d2dFactory()->GetDesktopDpi(&x, &y);
- return y;
+ return qRound(y);
}
- break;
case QPaintDevice::PdmDevicePixelRatio:
return 1;
- break;
case QPaintDevice::PdmDevicePixelRatioScaled:
- return 1 * devicePixelRatioFScale();
- break;
+ return qRound(devicePixelRatioFScale());
case QPaintDevice::PdmWidthMM:
case QPaintDevice::PdmHeightMM:
- return -1;
break;
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
index c4ff937a0b..164429ba30 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dpaintengine.cpp
@@ -87,7 +87,7 @@ enum {
};
//Clipping flags
-enum {
+enum : unsigned {
SimpleSystemClip = 0x1
};
@@ -125,28 +125,30 @@ static inline D2D1_MATRIX_3X2_F transformFromLine(const QLineF &line, qreal penW
static void adjustLine(QPointF *p1, QPointF *p2);
static bool isLinePositivelySloped(const QPointF &p1, const QPointF &p2);
-class Direct2DPathGeometryWriter
+static QVector<D2D1_GRADIENT_STOP> qGradientStopsToD2DStops(const QGradientStops &qstops)
{
-public:
- Direct2DPathGeometryWriter()
- : m_inFigure(false)
- , m_roundCoordinates(false)
- , m_adjustPositivelySlopedLines(false)
- {
-
+ QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
+ for (int i = 0, count = stops.size(); i < count; ++i) {
+ stops[i].position = FLOAT(qstops.at(i).first);
+ stops[i].color = to_d2d_color_f(qstops.at(i).second);
}
+ return stops;
+}
+class Direct2DPathGeometryWriter
+{
+public:
bool begin()
{
HRESULT hr = factory()->CreatePathGeometry(&m_geometry);
if (FAILED(hr)) {
- qWarning("%s: Could not create path geometry: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create path geometry: %#lx", __FUNCTION__, hr);
return false;
}
hr = m_geometry->Open(&m_sink);
if (FAILED(hr)) {
- qWarning("%s: Could not create geometry sink: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create geometry sink: %#lx", __FUNCTION__, hr);
return false;
}
@@ -239,9 +241,9 @@ private:
ComPtr<ID2D1PathGeometry1> m_geometry;
ComPtr<ID2D1GeometrySink> m_sink;
- bool m_inFigure;
- bool m_roundCoordinates;
- bool m_adjustPositivelySlopedLines;
+ bool m_inFigure = false;
+ bool m_roundCoordinates = false;
+ bool m_adjustPositivelySlopedLines = false;
QPointF m_previousPoint;
};
@@ -262,7 +264,6 @@ class QWindowsDirect2DPaintEnginePrivate : public QPaintEngineExPrivate
public:
QWindowsDirect2DPaintEnginePrivate(QWindowsDirect2DBitmap *bm, QWindowsDirect2DPaintEngine::Flags flags)
: bitmap(bm)
- , clipFlags(0)
, flags(flags)
{
pen.reset();
@@ -274,7 +275,7 @@ public:
QWindowsDirect2DBitmap *bitmap;
QImage fallbackImage;
- unsigned int clipFlags;
+ unsigned int clipFlags = 0;
QStack<ClipType> pushedClips;
QWindowsDirect2DPaintEngine::Flags flags;
@@ -348,9 +349,9 @@ public:
void updateOpacity(qreal opacity)
{
if (brush.brush)
- brush.brush->SetOpacity(opacity);
+ brush.brush->SetOpacity(FLOAT(opacity));
if (pen.brush)
- pen.brush->SetOpacity(opacity);
+ pen.brush->SetOpacity(FLOAT(opacity));
}
void pushClip(const QVectorPath &path)
@@ -459,7 +460,7 @@ public:
brush.qbrush = newBrush;
if (brush.brush) {
- brush.brush->SetOpacity(q->state()->opacity);
+ brush.brush->SetOpacity(FLOAT(q->state()->opacity));
applyBrushOrigin(currentBrushOrigin);
}
}
@@ -477,8 +478,8 @@ public:
brush.brush->GetTransform(&transform);
brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
- * D2D1::Matrix3x2F::Translation(-currentBrushOrigin.x(),
- -currentBrushOrigin.y()));
+ * D2D1::Matrix3x2F::Translation(FLOAT(-currentBrushOrigin.x()),
+ FLOAT(-currentBrushOrigin.y())));
}
}
@@ -489,7 +490,7 @@ public:
brush.brush->GetTransform(&transform);
brush.brush->SetTransform(*(D2D1::Matrix3x2F::ReinterpretBaseType(&transform))
- * D2D1::Matrix3x2F::Translation(origin.x(), origin.y()));
+ * D2D1::Matrix3x2F::Translation(FLOAT(origin.x()), FLOAT(origin.y())));
}
currentBrushOrigin = origin;
@@ -511,7 +512,7 @@ public:
if (!pen.brush)
return;
- pen.brush->SetOpacity(q->state()->opacity);
+ pen.brush->SetOpacity(FLOAT(q->state()->opacity));
D2D1_STROKE_STYLE_PROPERTIES1 props = {};
@@ -541,8 +542,8 @@ public:
break;
}
- props.miterLimit = newPen.miterLimit() * qreal(2.0); // D2D and Qt miter specs differ
- props.dashOffset = newPen.dashOffset();
+ props.miterLimit = FLOAT(newPen.miterLimit() * qreal(2.0)); // D2D and Qt miter specs differ
+ props.dashOffset = FLOAT(newPen.dashOffset());
if (newPen.widthF() == 0)
props.transformType = D2D1_STROKE_TRANSFORM_TYPE_HAIRLINE;
@@ -577,24 +578,24 @@ public:
qreal penWidth = pen.qpen.widthF();
qreal brushWidth = 0;
for (int i = 0; i < dashes.size(); i++) {
- converted[i] = dashes[i];
+ converted[i] = FLOAT(dashes[i]);
brushWidth += penWidth * dashes[i];
}
- hr = factory()->CreateStrokeStyle(props, converted.constData(), converted.size(), &pen.strokeStyle);
+ hr = factory()->CreateStrokeStyle(props, converted.constData(), UINT32(converted.size()), &pen.strokeStyle);
// Create a combined brush/dash pattern for optimized line drawing
QWindowsDirect2DBitmap bitmap;
- bitmap.resize(ceil(brushWidth), ceil(penWidth));
+ bitmap.resize(int(ceil(brushWidth)), int(ceil(penWidth)));
bitmap.deviceContext()->begin();
bitmap.deviceContext()->get()->SetAntialiasMode(antialiasMode());
bitmap.deviceContext()->get()->SetTransform(D2D1::IdentityMatrix());
bitmap.deviceContext()->get()->Clear();
const qreal offsetX = (qreal(bitmap.size().width()) - brushWidth) / 2;
const qreal offsetY = qreal(bitmap.size().height()) / 2;
- bitmap.deviceContext()->get()->DrawLine(D2D1::Point2F(offsetX, offsetY),
- D2D1::Point2F(brushWidth, offsetY),
- pen.brush.Get(), penWidth, pen.strokeStyle.Get());
+ bitmap.deviceContext()->get()->DrawLine(D2D1::Point2F(FLOAT(offsetX), FLOAT(offsetY)),
+ D2D1::Point2F(FLOAT(brushWidth), FLOAT(offsetY)),
+ pen.brush.Get(), FLOAT(penWidth), pen.strokeStyle.Get());
bitmap.deviceContext()->end();
D2D1_BITMAP_BRUSH_PROPERTIES1 bitmapBrushProperties = D2D1::BitmapBrushProperties1(
D2D1_EXTEND_MODE_WRAP, D2D1_EXTEND_MODE_CLAMP, D2D1_INTERPOLATION_MODE_LINEAR);
@@ -605,7 +606,7 @@ public:
}
if (FAILED(hr))
- qWarning("%s: Could not create stroke style: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create stroke style: %#lx", __FUNCTION__, hr);
}
ComPtr<ID2D1Brush> to_d2d_brush(const QBrush &newBrush, bool *needsEmulation)
@@ -627,13 +628,13 @@ public:
hr = dc()->CreateSolidColorBrush(to_d2d_color_f(newBrush.color()), &solid);
if (FAILED(hr)) {
- qWarning("%s: Could not create solid color brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create solid color brush: %#lx", __FUNCTION__, hr);
break;
}
hr = solid.As(&result);
if (FAILED(hr))
- qWarning("%s: Could not convert solid color brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert solid color brush: %#lx", __FUNCTION__, hr);
}
break;
@@ -673,13 +674,13 @@ public:
bitmapBrushProperties,
&bitmapBrush);
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D bitmap brush for Qt pattern brush: %#lx", __FUNCTION__, hr);
break;
}
hr = bitmapBrush.As(&result);
if (FAILED(hr))
- qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert Direct2D bitmap brush for Qt pattern brush: %#lx", __FUNCTION__, hr);
}
break;
@@ -693,33 +694,29 @@ public:
D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties;
ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
- const QGradientStops &qstops = qlinear->stops();
- QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
-
linearGradientBrushProperties.startPoint = to_d2d_point_2f(qlinear->start());
linearGradientBrushProperties.endPoint = to_d2d_point_2f(qlinear->finalStop());
- for (int i = 0; i < stops.size(); i++) {
- stops[i].position = qstops[i].first;
- stops[i].color = to_d2d_color_f(qstops[i].second);
- }
+ const QVector<D2D1_GRADIENT_STOP> stops = qGradientStopsToD2DStops(qlinear->stops());
- hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
+ hr = dc()->CreateGradientStopCollection(stops.constData(),
+ UINT32(stops.size()),
+ &gradientStopCollection);
if (FAILED(hr)) {
- qWarning("%s: Could not create gradient stop collection for linear gradient: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create gradient stop collection for linear gradient: %#lx", __FUNCTION__, hr);
break;
}
hr = dc()->CreateLinearGradientBrush(linearGradientBrushProperties, gradientStopCollection.Get(),
&linear);
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D linear gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D linear gradient brush: %#lx", __FUNCTION__, hr);
break;
}
hr = linear.As(&result);
if (FAILED(hr)) {
- qWarning("%s: Could not convert Direct2D linear gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert Direct2D linear gradient brush: %#lx", __FUNCTION__, hr);
break;
}
}
@@ -735,35 +732,29 @@ public:
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties;
ComPtr<ID2D1GradientStopCollection> gradientStopCollection;
- const QGradientStops &qstops = qradial->stops();
- QVector<D2D1_GRADIENT_STOP> stops(qstops.count());
-
radialGradientBrushProperties.center = to_d2d_point_2f(qradial->center());
radialGradientBrushProperties.gradientOriginOffset = to_d2d_point_2f(qradial->focalPoint() - qradial->center());
- radialGradientBrushProperties.radiusX = qradial->radius();
- radialGradientBrushProperties.radiusY = qradial->radius();
+ radialGradientBrushProperties.radiusX = FLOAT(qradial->radius());
+ radialGradientBrushProperties.radiusY = FLOAT(qradial->radius());
- for (int i = 0; i < stops.size(); i++) {
- stops[i].position = qstops[i].first;
- stops[i].color = to_d2d_color_f(qstops[i].second);
- }
+ const QVector<D2D1_GRADIENT_STOP> stops = qGradientStopsToD2DStops(qradial->stops());
hr = dc()->CreateGradientStopCollection(stops.constData(), stops.size(), &gradientStopCollection);
if (FAILED(hr)) {
- qWarning("%s: Could not create gradient stop collection for radial gradient: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create gradient stop collection for radial gradient: %#lx", __FUNCTION__, hr);
break;
}
hr = dc()->CreateRadialGradientBrush(radialGradientBrushProperties, gradientStopCollection.Get(),
&radial);
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D radial gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D radial gradient brush: %#lx", __FUNCTION__, hr);
break;
}
radial.As(&result);
if (FAILED(hr)) {
- qWarning("%s: Could not convert Direct2D radial gradient brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert Direct2D radial gradient brush: %#lx", __FUNCTION__, hr);
break;
}
}
@@ -789,13 +780,13 @@ public:
&bitmapBrush);
if (FAILED(hr)) {
- qWarning("%s: Could not create texture brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create texture brush: %#lx", __FUNCTION__, hr);
break;
}
hr = bitmapBrush.As(&result);
if (FAILED(hr))
- qWarning("%s: Could not convert texture brush: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not convert texture brush: %#lx", __FUNCTION__, hr);
}
break;
}
@@ -958,7 +949,8 @@ public:
qWarning("%s: Could not convert path to d2d geometry", __FUNCTION__);
return;
}
- dc()->DrawGeometry(geometry.Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get());
+ dc()->DrawGeometry(geometry.Get(), pen.brush.Get(),
+ FLOAT(pen.qpen.widthF()), pen.strokeStyle.Get());
return;
}
@@ -998,7 +990,7 @@ public:
dashOffset = pen.dashLength - fmod(lineLength - dashOffset, pen.dashLength);
}
dc()->DrawLine(to_d2d_point_2f(p1), to_d2d_point_2f(p2),
- brush, pen.qpen.widthF(), NULL);
+ brush, FLOAT(pen.qpen.widthF()), NULL);
if (skipJoin)
continue;
@@ -1013,7 +1005,8 @@ public:
writer.lineTo(p1);
writer.lineTo(line.pointAt(patchSegment));
writer.close();
- dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get());
+ dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(),
+ FLOAT(pen.qpen.widthF()), pen.strokeStyle.Get());
}
// Record the start position of the next joint
jointStart = line.pointAt(1 - patchSegment);
@@ -1025,7 +1018,8 @@ public:
writer.lineTo(p2);
writer.lineTo(QLineF(p2, QPointF(points[2], points[3])).pointAt(patchSegment));
writer.close();
- dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(), pen.qpen.widthF(), pen.strokeStyle.Get());
+ dc()->DrawGeometry(writer.geometry().Get(), pen.brush.Get(),
+ FLOAT(pen.qpen.widthF()), pen.strokeStyle.Get());
}
}
}
@@ -1045,20 +1039,20 @@ public:
const QString nameSubstitute = QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString();
if (nameSubstitute != familyName) {
const int nameSubstituteLength = qMin(nameSubstitute.length(), LF_FACESIZE - 1);
- memcpy(lf.lfFaceName, nameSubstitute.utf16(), nameSubstituteLength * sizeof(wchar_t));
+ memcpy(lf.lfFaceName, nameSubstitute.utf16(), size_t(nameSubstituteLength) * sizeof(wchar_t));
lf.lfFaceName[nameSubstituteLength] = 0;
}
ComPtr<IDWriteFont> dwriteFont;
HRESULT hr = QWindowsDirect2DContext::instance()->dwriteGdiInterop()->CreateFontFromLOGFONT(&lf, &dwriteFont);
if (FAILED(hr)) {
- qDebug("%s: CreateFontFromLOGFONT failed: %#x", __FUNCTION__, hr);
+ qDebug("%s: CreateFontFromLOGFONT failed: %#lx", __FUNCTION__, hr);
return fontFace;
}
hr = dwriteFont->CreateFontFace(&fontFace);
if (FAILED(hr)) {
- qDebug("%s: CreateFontFace failed: %#x", __FUNCTION__, hr);
+ qDebug("%s: CreateFontFace failed: %#lx", __FUNCTION__, hr);
return fontFace;
}
@@ -1332,7 +1326,8 @@ void QWindowsDirect2DPaintEngine::drawRects(const QRect *rects, int rectCount)
d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()), d->pen.strokeStyle.Get());
}
}
}
@@ -1359,7 +1354,8 @@ void QWindowsDirect2DPaintEngine::drawRects(const QRectF *rects, int rectCount)
d->dc()->FillRectangle(d2d_rect, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawRectangle(d2d_rect, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()), d->pen.strokeStyle.Get());
}
}
}
@@ -1407,7 +1403,9 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRectF &r)
d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()),
+ d->pen.strokeStyle.Get());
}
}
@@ -1435,7 +1433,9 @@ void QWindowsDirect2DPaintEngine::drawEllipse(const QRect &r)
d->dc()->FillEllipse(ellipse, d->brush.brush.Get());
if (d->pen.brush)
- d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(), d->pen.qpen.widthF(), d->pen.strokeStyle.Get());
+ d->dc()->DrawEllipse(ellipse, d->pen.brush.Get(),
+ FLOAT(d->pen.qpen.widthF()),
+ d->pen.strokeStyle.Get());
}
}
@@ -1490,12 +1490,12 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
// Good, src bitmap != dst bitmap
if (sr.isValid())
d->dc()->DrawBitmap(bitmap->bitmap(),
- to_d2d_rect_f(r), state()->opacity,
+ to_d2d_rect_f(r), FLOAT(state()->opacity),
d->interpolationMode(),
to_d2d_rect_f(sr));
else
d->dc()->DrawBitmap(bitmap->bitmap(),
- to_d2d_rect_f(r), state()->opacity,
+ to_d2d_rect_f(r), FLOAT(state()->opacity),
d->interpolationMode());
} else {
// Ok, so the source pixmap and destination pixmap is the same.
@@ -1504,7 +1504,7 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
QWindowsDirect2DBitmap intermediate;
if (sr.isValid()) {
- bool r = intermediate.resize(sr.width(), sr.height());
+ bool r = intermediate.resize(int(sr.width()), int(sr.height()));
if (!r) {
qWarning("%s: Could not resize intermediate bitmap to source rect size", __FUNCTION__);
return;
@@ -1515,7 +1515,7 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
bitmap->bitmap(),
&d2d_sr);
if (FAILED(hr)) {
- qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy source rect area from source bitmap to intermediate bitmap: %#lx", __FUNCTION__, hr);
return;
}
} else {
@@ -1530,13 +1530,13 @@ void QWindowsDirect2DPaintEngine::drawPixmap(const QRectF &r,
bitmap->bitmap(),
NULL);
if (FAILED(hr)) {
- qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy source bitmap to intermediate bitmap: %#lx", __FUNCTION__, hr);
return;
}
}
d->dc()->DrawBitmap(intermediate.bitmap(),
- to_d2d_rect_f(r), state()->opacity,
+ to_d2d_rect_f(r), FLOAT(state()->opacity),
d->interpolationMode());
}
}
@@ -1573,9 +1573,9 @@ void QWindowsDirect2DPaintEngine::drawStaticTextItem(QStaticTextItem *staticText
// This looks a little funky because the positions are precalculated
glyphAdvances[i] = 0;
- glyphOffsets[i].advanceOffset = staticTextItem->glyphPositions[i].x.toReal();
+ glyphOffsets[i].advanceOffset = FLOAT(staticTextItem->glyphPositions[i].x.toReal());
// Qt and Direct2D seem to disagree on the direction of the ascender offset...
- glyphOffsets[i].ascenderOffset = staticTextItem->glyphPositions[i].y.toReal() * -1;
+ glyphOffsets[i].ascenderOffset = FLOAT(staticTextItem->glyphPositions[i].y.toReal() * -1);
}
d->drawGlyphRun(D2D1::Point2F(0, 0),
@@ -1618,11 +1618,11 @@ void QWindowsDirect2DPaintEngine::drawTextItem(const QPointF &p, const QTextItem
for (int i = 0; i < ti.glyphs.numGlyphs; i++) {
glyphIndices[i] = UINT16(ti.glyphs.glyphs[i]); // Imperfect conversion here
- glyphAdvances[i] = ti.glyphs.effectiveAdvance(i).toReal();
- glyphOffsets[i].advanceOffset = ti.glyphs.offsets[i].x.toReal();
+ glyphAdvances[i] = FLOAT(ti.glyphs.effectiveAdvance(i).toReal());
+ glyphOffsets[i].advanceOffset = FLOAT(ti.glyphs.offsets[i].x.toReal());
// XXX Should we negate the y value like for static text items?
- glyphOffsets[i].ascenderOffset = ti.glyphs.offsets[i].y.toReal();
+ glyphOffsets[i].ascenderOffset = FLOAT(ti.glyphs.offsets[i].y.toReal());
}
const bool rtl = (ti.flags & QTextItem::RightToLeft);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
index e7e2fa4ff7..65e056d312 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dplatformpixmap.cpp
@@ -57,15 +57,12 @@ public:
: owns_bitmap(true)
, bitmap(new QWindowsDirect2DBitmap)
, device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap))
- , devicePixelRatio(1.0)
{}
QWindowsDirect2DPlatformPixmapPrivate(QWindowsDirect2DBitmap *bitmap,
QWindowsDirect2DPaintEngine::Flags flags)
- : owns_bitmap(false)
- , bitmap(bitmap)
+ : bitmap(bitmap)
, device(new QWindowsDirect2DPaintDevice(bitmap, QInternal::Pixmap, flags))
- , devicePixelRatio(1.0)
{}
~QWindowsDirect2DPlatformPixmapPrivate()
@@ -74,10 +71,10 @@ public:
delete bitmap;
}
- bool owns_bitmap;
+ bool owns_bitmap = false;
QWindowsDirect2DBitmap *bitmap;
QScopedPointer<QWindowsDirect2DPaintDevice> device;
- qreal devicePixelRatio;
+ qreal devicePixelRatio = 1.0;
};
static int qt_d2dpixmap_serno = 0;
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
index c750b02078..21294cfb15 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.cpp
@@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE
QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWindowData &data)
: QWindowsWindow(window, data)
- , m_needsFullFlush(true)
, m_directRendering(!(data.flags & Qt::FramelessWindowHint && window->format().hasAlpha()))
{
if (window->type() == Qt::Desktop)
@@ -67,7 +66,7 @@ QWindowsDirect2DWindow::QWindowsDirect2DWindow(QWindow *window, const QWindowsWi
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
m_deviceContext.GetAddressOf());
if (FAILED(hr))
- qWarning("%s: Couldn't create Direct2D Device context: %#x", __FUNCTION__, hr);
+ qWarning("%s: Couldn't create Direct2D Device context: %#lx", __FUNCTION__, hr);
}
QWindowsDirect2DWindow::~QWindowsDirect2DWindow()
@@ -100,12 +99,12 @@ void QWindowsDirect2DWindow::flush(QWindowsDirect2DBitmap *bitmap, const QRegion
HRESULT hr = m_swapChain->GetDesc1(&desc);
QRect geom = geometry();
- if ((FAILED(hr) || (desc.Width != geom.width()) || (desc.Height != geom.height()))) {
+ if (FAILED(hr) || (desc.Width != UINT(geom.width()) || (desc.Height != UINT(geom.height())))) {
resizeSwapChain(geom.size());
m_swapChain->GetDesc1(&desc);
}
- size.setWidth(desc.Width);
- size.setHeight(desc.Height);
+ size.setWidth(int(desc.Width));
+ size.setHeight(int(desc.Height));
} else {
size = geometry().size();
}
@@ -175,7 +174,7 @@ void QWindowsDirect2DWindow::present(const QRegion &region)
UPDATELAYEREDWINDOWINFO info = { sizeof(UPDATELAYEREDWINDOWINFO), NULL,
&ptDst, &size, hdc, &ptSrc, 0, &blend, ULW_ALPHA, &dirty };
if (!UpdateLayeredWindowIndirect(handle(), &info))
- qErrnoWarning(GetLastError(), "Failed to update the layered window");
+ qErrnoWarning(int(GetLastError()), "Failed to update the layered window");
hr = dxgiSurface->ReleaseDC(NULL);
if (FAILED(hr))
@@ -201,7 +200,7 @@ void QWindowsDirect2DWindow::setupSwapChain()
m_swapChain.ReleaseAndGetAddressOf()); // [out] IDXGISwapChain1 **ppSwapChain
if (FAILED(hr))
- qWarning("%s: Could not create swap chain: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create swap chain: %#lx", __FUNCTION__, hr);
m_needsFullFlush = true;
}
@@ -217,11 +216,11 @@ void QWindowsDirect2DWindow::resizeSwapChain(const QSize &size)
return;
HRESULT hr = m_swapChain->ResizeBuffers(0,
- size.width(), size.height(),
+ UINT(size.width()), UINT(size.height()),
DXGI_FORMAT_UNKNOWN,
0);
if (FAILED(hr))
- qWarning("%s: Could not resize swap chain: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not resize swap chain: %#lx", __FUNCTION__, hr);
}
QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer() const
@@ -248,13 +247,13 @@ QSharedPointer<QWindowsDirect2DBitmap> QWindowsDirect2DWindow::copyBackBuffer()
HRESULT hr = m_deviceContext.Get()->CreateBitmap(size, NULL, 0, properties, &copy);
if (FAILED(hr)) {
- qWarning("%s: Could not create staging bitmap: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create staging bitmap: %#lx", __FUNCTION__, hr);
return null_result;
}
hr = copy.Get()->CopyFromBitmap(NULL, m_bitmap->bitmap(), NULL);
if (FAILED(hr)) {
- qWarning("%s: Could not copy from bitmap! %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not copy from bitmap! %#lx", __FUNCTION__, hr);
return null_result;
}
@@ -277,12 +276,12 @@ void QWindowsDirect2DWindow::setupBitmap()
if (m_directRendering) {
hr = m_swapChain->GetBuffer(0, IID_PPV_ARGS(&backBufferSurface));
if (FAILED(hr)) {
- qWarning("%s: Could not query backbuffer for DXGI Surface: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not query backbuffer for DXGI Surface: %#lx", __FUNCTION__, hr);
return;
}
} else {
const QRect rect = geometry();
- CD3D11_TEXTURE2D_DESC backBufferDesc(DXGI_FORMAT_B8G8R8A8_UNORM, rect.width(), rect.height(), 1, 1);
+ CD3D11_TEXTURE2D_DESC backBufferDesc(DXGI_FORMAT_B8G8R8A8_UNORM, UINT(rect.width()), UINT(rect.height()), 1, 1);
backBufferDesc.BindFlags = D3D11_BIND_RENDER_TARGET;
backBufferDesc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
ComPtr<ID3D11Texture2D> backBufferTexture;
@@ -302,7 +301,7 @@ void QWindowsDirect2DWindow::setupBitmap()
ComPtr<ID2D1Bitmap1> backBufferBitmap;
hr = m_deviceContext->CreateBitmapFromDxgiSurface(backBufferSurface.Get(), NULL, backBufferBitmap.GetAddressOf());
if (FAILED(hr)) {
- qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#x", __FUNCTION__, hr);
+ qWarning("%s: Could not create Direct2D Bitmap from DXGI Surface: %#lx", __FUNCTION__, hr);
return;
}
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
index 2da0e5f507..156d4660d1 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dwindow.h
@@ -74,8 +74,8 @@ private:
Microsoft::WRL::ComPtr<ID2D1DeviceContext> m_deviceContext;
QScopedPointer<QWindowsDirect2DBitmap> m_bitmap;
QScopedPointer<QPixmap> m_pixmap;
- bool m_needsFullFlush;
- bool m_directRendering;
+ bool m_needsFullFlush = true;
+ bool m_directRendering = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/api.pri b/src/plugins/platforms/eglfs/api/api.pri
index 0ea65bd1ff..a6d81016b6 100644
--- a/src/plugins/platforms/eglfs/api/api.pri
+++ b/src/plugins/platforms/eglfs/api/api.pri
@@ -1,21 +1,26 @@
SOURCES += $$PWD/qeglfswindow.cpp \
$$PWD/qeglfsscreen.cpp \
- $$PWD/qeglfscursor.cpp \
$$PWD/qeglfshooks.cpp \
$$PWD/qeglfsdeviceintegration.cpp \
$$PWD/qeglfsintegration.cpp \
- $$PWD/qeglfscontext.cpp \
$$PWD/qeglfsoffscreenwindow.cpp
HEADERS += $$PWD/qeglfswindow_p.h \
$$PWD/qeglfsscreen_p.h \
- $$PWD/qeglfscursor_p.h \
$$PWD/qeglfshooks_p.h \
$$PWD/qeglfsdeviceintegration_p.h \
$$PWD/qeglfsintegration_p.h \
- $$PWD/qeglfscontext_p.h \
$$PWD/qeglfsoffscreenwindow_p.h \
$$PWD/qeglfsglobal_p.h
+qtConfig(opengl) {
+ SOURCES += \
+ $$PWD/qeglfscursor.cpp \
+ $$PWD/qeglfscontext.cpp
+ HEADERS += \
+ $$PWD/qeglfscursor_p.h \
+ $$PWD/qeglfscontext_p.h
+}
+
INCLUDEPATH += $$PWD
diff --git a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h
index ab5bf99c3c..96f7f01381 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscontext_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscontext_p.h
@@ -62,11 +62,11 @@ class Q_EGLFS_EXPORT QEglFSContext : public QEGLPlatformContext
public:
QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display,
EGLConfig *config, const QVariant &nativeHandle);
- EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- EGLSurface createTemporaryOffscreenSurface() Q_DECL_OVERRIDE;
- void destroyTemporaryOffscreenSurface(EGLSurface surface) Q_DECL_OVERRIDE;
- void runGLChecks() Q_DECL_OVERRIDE;
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) override;
+ EGLSurface createTemporaryOffscreenSurface() override;
+ void destroyTemporaryOffscreenSurface(EGLSurface surface) override;
+ void runGLChecks() override;
+ void swapBuffers(QPlatformSurface *surface) override;
private:
EGLNativeWindowType m_tempWindow;
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
index 2b54251a06..19a0e03212 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor.cpp
@@ -146,8 +146,8 @@ void QEglFSCursor::createShaderPrograms()
GraphicsContextData &gfx(m_gfx[QOpenGLContext::currentContext()]);
gfx.program = new QOpenGLShaderProgram;
- gfx.program->addShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
- gfx.program->addShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
+ gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, textureVertexProgram);
+ gfx.program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, textureFragmentProgram);
gfx.program->bindAttributeLocation("vertexCoordEntry", 0);
gfx.program->bindAttributeLocation("textureCoordEntry", 1);
gfx.program->link();
diff --git a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
index bf6dbc8a21..aaeb83cb99 100644
--- a/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfscursor_p.h
@@ -79,7 +79,10 @@ private:
QEglFSCursor *m_cursor;
};
-class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor, protected QOpenGLFunctions
+#if QT_CONFIG(opengl)
+
+class Q_EGLFS_EXPORT QEglFSCursor : public QPlatformCursor
+ , protected QOpenGLFunctions
{
Q_OBJECT
public:
@@ -87,11 +90,11 @@ public:
~QEglFSCursor();
#ifndef QT_NO_CURSOR
- void changeCursor(QCursor *cursor, QWindow *widget) Q_DECL_OVERRIDE;
+ void changeCursor(QCursor *cursor, QWindow *widget) override;
#endif
- void pointerEvent(const QMouseEvent &event) Q_DECL_OVERRIDE;
- QPoint pos() const Q_DECL_OVERRIDE;
- void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
+ void pointerEvent(const QMouseEvent &event) override;
+ QPoint pos() const override;
+ void setPos(const QPoint &pos) override;
QRect cursorRect() const;
void paintOnScreen();
@@ -100,7 +103,7 @@ public:
void updateMouseStatus();
private:
- bool event(QEvent *e) Q_DECL_OVERRIDE;
+ bool event(QEvent *e) override;
#ifndef QT_NO_CURSOR
bool setCurrentCursor(QCursor *cursor);
#endif
@@ -153,6 +156,7 @@ private:
};
QHash<QOpenGLContext *, GraphicsContextData> m_gfx;
};
+#endif // QT_CONFIG(opengl)
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
index 3558b929fa..e411ea55e9 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsdeviceintegration.cpp
@@ -39,7 +39,9 @@
#include "qeglfsdeviceintegration_p.h"
#include "qeglfsintegration_p.h"
-#include "qeglfscursor_p.h"
+#ifndef QT_NO_OPENGL
+# include "qeglfscursor_p.h"
+#endif
#include "qeglfswindow_p.h"
#include "qeglfsscreen_p.h"
#include "qeglfshooks_p.h"
@@ -312,7 +314,12 @@ bool QEglFSDeviceIntegration::hasCapability(QPlatformIntegration::Capability cap
QPlatformCursor *QEglFSDeviceIntegration::createCursor(QPlatformScreen *screen) const
{
+#ifndef QT_NO_OPENGL
return new QEglFSCursor(static_cast<QEglFSScreen *>(screen));
+#else
+ Q_UNUSED(screen);
+ return nullptr;
+#endif
}
void QEglFSDeviceIntegration::waitForVSync(QPlatformSurface *surface) const
@@ -355,7 +362,7 @@ EGLConfig QEglFSDeviceIntegration::chooseConfig(EGLDisplay display, const QSurfa
public:
Chooser(EGLDisplay display)
: QEglConfigChooser(display) { }
- bool filterConfig(EGLConfig config) const Q_DECL_OVERRIDE {
+ bool filterConfig(EGLConfig config) const override {
return qt_egl_device_integration()->filterConfig(display(), config)
&& QEglConfigChooser::filterConfig(config);
}
diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
index 8cf6660c44..73110dba61 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsintegration.cpp
@@ -42,9 +42,11 @@
#include <qpa/qplatformwindow.h>
#include <QtGui/QSurfaceFormat>
-#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
-#include <QtGui/QOffscreenSurface>
+#ifndef QT_NO_OPENGL
+# include <QtGui/QOpenGLContext>
+# include <QtGui/QOffscreenSurface>
+#endif
#include <QtGui/QWindow>
#include <QtCore/QLoggingCategory>
#include <qpa/qwindowsysteminterface.h>
@@ -53,20 +55,26 @@
#include "qeglfsintegration_p.h"
#include "qeglfswindow_p.h"
#include "qeglfshooks_p.h"
-#include "qeglfscontext_p.h"
+#ifndef QT_NO_OPENGL
+# include "qeglfscontext_p.h"
+# include "qeglfscursor_p.h"
+#endif
#include "qeglfsoffscreenwindow_p.h"
-#include "qeglfscursor_p.h"
#include <QtEglSupport/private/qeglconvenience_p.h>
-#include <QtEglSupport/private/qeglplatformcontext_p.h>
-#include <QtEglSupport/private/qeglpbuffer_p.h>
+#ifndef QT_NO_OPENGL
+# include <QtEglSupport/private/qeglplatformcontext_p.h>
+# include <QtEglSupport/private/qeglpbuffer_p.h>
+#endif
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
#include <QtServiceSupport/private/qgenericunixservices_p.h>
#include <QtThemeSupport/private/qgenericunixthemes_p.h>
#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
#include <QtFbSupport/private/qfbvthandler_p.h>
-#include <QtPlatformCompositorSupport/private/qopenglcompositorbackingstore_p.h>
+#ifndef QT_NO_OPENGL
+# include <QtPlatformCompositorSupport/private/qopenglcompositorbackingstore_p.h>
+#endif
#include <QtPlatformHeaders/QEGLNativeContext>
@@ -108,9 +116,9 @@ QEglFSIntegration::QEglFSIntegration()
initResources();
}
-void QEglFSIntegration::addScreen(QPlatformScreen *screen)
+void QEglFSIntegration::addScreen(QPlatformScreen *screen, bool isPrimary)
{
- screenAdded(screen);
+ screenAdded(screen, isPrimary);
}
void QEglFSIntegration::removeScreen(QPlatformScreen *screen)
@@ -179,11 +187,15 @@ QPlatformTheme *QEglFSIntegration::createPlatformTheme(const QString &name) cons
QPlatformBackingStore *QEglFSIntegration::createPlatformBackingStore(QWindow *window) const
{
+#ifndef QT_NO_OPENGL
QOpenGLCompositorBackingStore *bs = new QOpenGLCompositorBackingStore(window);
if (!window->handle())
window->create();
static_cast<QEglFSWindow *>(window->handle())->setBackingStore(bs);
return bs;
+#else
+ return nullptr;
+#endif
}
QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
@@ -191,11 +203,15 @@ QPlatformWindow *QEglFSIntegration::createPlatformWindow(QWindow *window) const
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
QEglFSWindow *w = qt_egl_device_integration()->createWindow(window);
w->create();
- if (window->type() != Qt::ToolTip)
+
+ // Activate only the window for the primary screen to make input work
+ if (window->type() != Qt::ToolTip && window->screen() == QGuiApplication::primaryScreen())
w->requestActivateWindow();
+
return w;
}
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QEglFSIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
EGLDisplay dpy = context->screen() ? static_cast<QEglFSScreen *>(context->screen()->handle())->display() : display();
@@ -230,6 +246,7 @@ QPlatformOffscreenSurface *QEglFSIntegration::createPlatformOffscreenSurface(QOf
}
// Never return null. Multiple QWindows are not supported by this plugin.
}
+#endif // QT_NO_OPENGL
bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
@@ -239,10 +256,16 @@ bool QEglFSIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
switch (cap) {
case ThreadedPixmaps: return true;
+#ifndef QT_NO_OPENGL
case OpenGL: return true;
case ThreadedOpenGL: return true;
- case WindowManagement: return false;
case RasterGLSurface: return true;
+#else
+ case OpenGL: return false;
+ case ThreadedOpenGL: return false;
+ case RasterGLSurface: return false;
+#endif
+ case WindowManagement: return false;
default: return QPlatformIntegration::hasCapability(cap);
}
}
@@ -259,7 +282,8 @@ enum ResourceType {
EglConfig,
NativeDisplay,
XlibDisplay,
- WaylandDisplay
+ WaylandDisplay,
+ EglSurface
};
static int resourceType(const QByteArray &key)
@@ -271,7 +295,8 @@ static int resourceType(const QByteArray &key)
QByteArrayLiteral("eglconfig"),
QByteArrayLiteral("nativedisplay"),
QByteArrayLiteral("display"),
- QByteArrayLiteral("server_wl_display")
+ QByteArrayLiteral("server_wl_display"),
+ QByteArrayLiteral("eglsurface")
};
const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
const QByteArray *result = std::find(names, end, key);
@@ -333,6 +358,10 @@ void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWi
if (window && window->handle())
result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->eglWindow());
break;
+ case EglSurface:
+ if (window && window->handle())
+ result = reinterpret_cast<void*>(static_cast<QEglFSWindow *>(window->handle())->surface());
+ break;
default:
break;
}
@@ -340,6 +369,7 @@ void *QEglFSIntegration::nativeResourceForWindow(const QByteArray &resource, QWi
return result;
}
+#ifndef QT_NO_OPENGL
void *QEglFSIntegration::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
void *result = 0;
@@ -374,13 +404,17 @@ static void *eglContextForContext(QOpenGLContext *context)
return handle->eglContext();
}
+#endif
QPlatformNativeInterface::NativeResourceForContextFunction QEglFSIntegration::nativeResourceFunctionForContext(const QByteArray &resource)
{
+#ifndef QT_NO_OPENGL
QByteArray lowerCaseResource = resource.toLower();
if (lowerCaseResource == "get_egl_context")
return NativeResourceForContextFunction(eglContextForContext);
-
+#else
+ Q_UNUSED(resource);
+#endif
return 0;
}
diff --git a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
index 1a3a44d441..c288876678 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfsintegration_p.h
@@ -69,38 +69,41 @@ class Q_EGLFS_EXPORT QEglFSIntegration : public QPlatformIntegration, public QPl
public:
QEglFSIntegration();
- void initialize() Q_DECL_OVERRIDE;
- void destroy() Q_DECL_OVERRIDE;
+ void initialize() override;
+ void destroy() override;
EGLDisplay display() const { return m_display; }
- QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
- QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QPlatformServices *services() const Q_DECL_OVERRIDE;
- QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
- QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const override;
+ QPlatformFontDatabase *fontDatabase() const override;
+ QPlatformServices *services() const override;
+ QPlatformInputContext *inputContext() const override { return m_inputContext; }
+ QPlatformTheme *createPlatformTheme(const QString &name) const override;
- QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const override;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
+#ifndef QT_NO_OPENGL
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
+#endif
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
-
- QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformNativeInterface *nativeInterface() const override;
// QPlatformNativeInterface
- void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
- void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) Q_DECL_OVERRIDE;
- void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
- void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
- NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) Q_DECL_OVERRIDE;
+ void *nativeResourceForIntegration(const QByteArray &resource) override;
+ void *nativeResourceForScreen(const QByteArray &resource, QScreen *screen) override;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
+#ifndef QT_NO_OPENGL
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
+#endif
+ NativeResourceForContextFunction nativeResourceFunctionForContext(const QByteArray &resource) override;
- QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+ QFunctionPointer platformFunction(const QByteArray &function) const override;
QFbVtHandler *vtHandler() { return m_vtHandler.data(); }
- void addScreen(QPlatformScreen *screen);
+ void addScreen(QPlatformScreen *screen, bool isPrimary = false);
void removeScreen(QPlatformScreen *screen);
private:
diff --git a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h
index ec483c64e2..9fdb81efdd 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfsoffscreenwindow_p.h
@@ -62,8 +62,8 @@ public:
QEglFSOffscreenWindow(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface);
~QEglFSOffscreenWindow();
- QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- bool isValid() const Q_DECL_OVERRIDE { return m_surface != EGL_NO_SURFACE; }
+ QSurfaceFormat format() const override { return m_format; }
+ bool isValid() const override { return m_surface != EGL_NO_SURFACE; }
private:
QSurfaceFormat m_format;
diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
index 5613179041..d5c22b3d37 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfsscreen.cpp
@@ -41,7 +41,9 @@
#include <QtGui/qwindow.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformcursor.h>
-#include <QtPlatformCompositorSupport/private/qopenglcompositor_p.h>
+#ifndef QT_NO_OPENGL
+# include <QtPlatformCompositorSupport/private/qopenglcompositor_p.h>
+#endif
#include "qeglfsscreen_p.h"
#include "qeglfswindow_p.h"
@@ -60,7 +62,9 @@ QEglFSScreen::QEglFSScreen(EGLDisplay dpy)
QEglFSScreen::~QEglFSScreen()
{
delete m_cursor;
+#ifndef QT_NO_OPENGL
QOpenGLCompositor::destroy();
+#endif
}
QRect QEglFSScreen::geometry() const
@@ -145,6 +149,7 @@ void QEglFSScreen::setPrimarySurface(EGLSurface surface)
void QEglFSScreen::handleCursorMove(const QPoint &pos)
{
+#ifndef QT_NO_OPENGL
const QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
@@ -178,10 +183,12 @@ void QEglFSScreen::handleCursorMove(const QPoint &pos)
if (enter && leave)
QWindowSystemInterface::handleEnterLeaveEvent(enter, leave, enter->mapFromGlobal(pos), pos);
+#endif
}
QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) const
{
+#ifndef QT_NO_OPENGL
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
const QList<QOpenGLCompositorWindow *> windows = compositor->windows();
Q_ASSERT(!windows.isEmpty());
@@ -224,7 +231,7 @@ QPixmap QEglFSScreen::grabWindow(WId wid, int x, int y, int width, int height) c
return QPixmap::fromImage(img).copy(rect);
}
}
-
+#endif // QT_NO_OPENGL
return QPixmap();
}
diff --git a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h
index 131e619e06..bea7b4c8ef 100644
--- a/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfsscreen_p.h
@@ -67,22 +67,22 @@ public:
QEglFSScreen(EGLDisplay display);
~QEglFSScreen();
- QRect geometry() const Q_DECL_OVERRIDE;
+ QRect geometry() const override;
virtual QRect rawGeometry() const;
- int depth() const Q_DECL_OVERRIDE;
- QImage::Format format() const Q_DECL_OVERRIDE;
+ int depth() const override;
+ QImage::Format format() const override;
- QSizeF physicalSize() const Q_DECL_OVERRIDE;
- QDpi logicalDpi() const Q_DECL_OVERRIDE;
- qreal pixelDensity() const Q_DECL_OVERRIDE;
- Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
- Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
+ QSizeF physicalSize() const override;
+ QDpi logicalDpi() const override;
+ qreal pixelDensity() const override;
+ Qt::ScreenOrientation nativeOrientation() const override;
+ Qt::ScreenOrientation orientation() const override;
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
+ QPlatformCursor *cursor() const override;
- qreal refreshRate() const Q_DECL_OVERRIDE;
+ qreal refreshRate() const override;
- QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
+ QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
EGLSurface primarySurface() const { return m_surface; }
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
index 639fc56d2b..9b4732eab4 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow.cpp
@@ -41,13 +41,17 @@
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformintegration.h>
#include <private/qguiapplication_p.h>
-#include <QtGui/private/qopenglcontext_p.h>
-#include <QtGui/QOpenGLContext>
+#ifndef QT_NO_OPENGL
+# include <QtGui/private/qopenglcontext_p.h>
+# include <QtGui/QOpenGLContext>
+# include <QtPlatformCompositorSupport/private/qopenglcompositorbackingstore_p.h>
+#endif
#include <QtEglSupport/private/qeglconvenience_p.h>
-#include <QtPlatformCompositorSupport/private/qopenglcompositorbackingstore_p.h>
#include "qeglfswindow_p.h"
-#include "qeglfscursor_p.h"
+#ifndef QT_NO_OPENGL
+# include "qeglfscursor_p.h"
+#endif
#include "qeglfshooks_p.h"
#include "qeglfsdeviceintegration_p.h"
@@ -55,7 +59,9 @@ QT_BEGIN_NAMESPACE
QEglFSWindow::QEglFSWindow(QWindow *w)
: QPlatformWindow(w),
+#ifndef QT_NO_OPENGL
m_backingStore(0),
+#endif
m_raster(false),
m_winId(0),
m_surface(EGL_NO_SURFACE),
@@ -107,6 +113,7 @@ void QEglFSWindow::create()
// raster windows will not have their own native window, surface and context. Instead,
// they will be composited onto the root window's surface.
QEglFSScreen *screen = this->screen();
+#ifndef QT_NO_OPENGL
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
if (screen->primarySurface() != EGL_NO_SURFACE) {
if (Q_UNLIKELY(!isRaster() || !compositor->targetWindow())) {
@@ -120,10 +127,10 @@ void QEglFSWindow::create()
m_format = compositor->targetWindow()->format();
return;
}
+#endif // QT_NO_OPENGL
m_flags |= HasNativeWindow;
setGeometry(QRect()); // will become fullscreen
- QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size()));
resetSurface();
@@ -135,6 +142,7 @@ void QEglFSWindow::create()
screen->setPrimarySurface(m_surface);
+#ifndef QT_NO_OPENGL
if (isRaster()) {
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
context->setShareContext(qt_gl_global_share_context());
@@ -153,16 +161,18 @@ void QEglFSWindow::create()
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
}
}
+#endif // QT_NO_OPENGL
}
void QEglFSWindow::destroy()
{
QEglFSScreen *screen = this->screen();
if (m_flags.testFlag(HasNativeWindow)) {
+#ifndef QT_NO_OPENGL
QEglFSCursor *cursor = qobject_cast<QEglFSCursor *>(screen->cursor());
if (cursor)
cursor->resetResources();
-
+#endif
if (screen->primarySurface() == m_surface)
screen->setPrimarySurface(EGL_NO_SURFACE);
@@ -170,7 +180,9 @@ void QEglFSWindow::destroy()
}
m_flags = 0;
+#ifndef QT_NO_OPENGL
QOpenGLCompositor::instance()->removeWindow(this);
+#endif
}
void QEglFSWindow::invalidateSurface()
@@ -197,6 +209,7 @@ void QEglFSWindow::resetSurface()
void QEglFSWindow::setVisible(bool visible)
{
+#ifndef QT_NO_OPENGL
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QList<QOpenGLCompositorWindow *> windows = compositor->windows();
QWindow *wnd = window();
@@ -211,7 +224,9 @@ void QEglFSWindow::setVisible(bool visible)
windows.last()->sourceWindow()->requestActivate();
}
}
-
+#else
+ QWindow *wnd = window();
+#endif
QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
if (visible)
@@ -227,11 +242,15 @@ void QEglFSWindow::setGeometry(const QRect &r)
else
rect = r;
+ const bool changed = rect != QPlatformWindow::geometry();
QPlatformWindow::setGeometry(rect);
// if we corrected the size, trigger a resize event
if (rect != r)
QWindowSystemInterface::handleGeometryChange(window(), rect, r);
+
+ if (changed)
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), rect.size()));
}
QRect QEglFSWindow::geometry() const
@@ -247,9 +266,10 @@ QRect QEglFSWindow::geometry() const
void QEglFSWindow::requestActivateWindow()
{
+#ifndef QT_NO_OPENGL
if (window()->type() != Qt::Desktop)
QOpenGLCompositor::instance()->moveToTop(this);
-
+#endif
QWindow *wnd = window();
QWindowSystemInterface::handleWindowActivated(wnd);
QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
@@ -259,13 +279,16 @@ void QEglFSWindow::raise()
{
QWindow *wnd = window();
if (wnd->type() != Qt::Desktop) {
+#ifndef QT_NO_OPENGL
QOpenGLCompositor::instance()->moveToTop(this);
+#endif
QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
}
}
void QEglFSWindow::lower()
{
+#ifndef QT_NO_OPENGL
QOpenGLCompositor *compositor = QOpenGLCompositor::instance();
QList<QOpenGLCompositorWindow *> windows = compositor->windows();
if (window()->type() != Qt::Desktop && windows.count() > 1) {
@@ -276,6 +299,7 @@ void QEglFSWindow::lower()
QRect(QPoint(0, 0), windows.last()->sourceWindow()->geometry().size()));
}
}
+#endif
}
EGLSurface QEglFSWindow::surface() const
@@ -303,6 +327,7 @@ bool QEglFSWindow::isRaster() const
return m_raster || window()->surfaceType() == QSurface::RasterGLSurface;
}
+#ifndef QT_NO_OPENGL
QWindow *QEglFSWindow::sourceWindow() const
{
return window();
@@ -321,6 +346,7 @@ void QEglFSWindow::endCompositing()
if (m_backingStore)
m_backingStore->notifyComposited();
}
+#endif
WId QEglFSWindow::winId() const
{
diff --git a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h
index 0889f27ae3..6bda262523 100644
--- a/src/plugins/platforms/eglfs/api/qeglfswindow_p.h
+++ b/src/plugins/platforms/eglfs/api/qeglfswindow_p.h
@@ -56,14 +56,19 @@
#include "qeglfsscreen_p.h"
#include <qpa/qplatformwindow.h>
-#include <QtPlatformCompositorSupport/private/qopenglcompositor_p.h>
+#ifndef QT_NO_OPENGL
+# include <QtPlatformCompositorSupport/private/qopenglcompositor_p.h>
+#endif
QT_BEGIN_NAMESPACE
class QOpenGLCompositorBackingStore;
class QPlatformTextureList;
-
+#ifndef QT_NO_OPENGL
class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow, public QOpenGLCompositorWindow
+#else
+class Q_EGLFS_EXPORT QEglFSWindow : public QPlatformWindow
+#endif
{
public:
QEglFSWindow(QWindow *w);
@@ -72,21 +77,21 @@ public:
void create();
void destroy();
- void setGeometry(const QRect &) Q_DECL_OVERRIDE;
- QRect geometry() const Q_DECL_OVERRIDE;
- void setVisible(bool visible) Q_DECL_OVERRIDE;
- void requestActivateWindow() Q_DECL_OVERRIDE;
- void raise() Q_DECL_OVERRIDE;
- void lower() Q_DECL_OVERRIDE;
+ void setGeometry(const QRect &) override;
+ QRect geometry() const override;
+ void setVisible(bool visible) override;
+ void requestActivateWindow() override;
+ void raise() override;
+ void lower() override;
- void propagateSizeHints() Q_DECL_OVERRIDE { }
- void setMask(const QRegion &) Q_DECL_OVERRIDE { }
- bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
- bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
- void setOpacity(qreal) Q_DECL_OVERRIDE;
- WId winId() const Q_DECL_OVERRIDE;
+ void propagateSizeHints() override { }
+ void setMask(const QRegion &) override { }
+ bool setKeyboardGrabEnabled(bool) override { return false; }
+ bool setMouseGrabEnabled(bool) override { return false; }
+ void setOpacity(qreal) override;
+ WId winId() const override;
- QSurfaceFormat format() const Q_DECL_OVERRIDE;
+ QSurfaceFormat format() const override;
EGLNativeWindowType eglWindow() const;
EGLSurface surface() const;
@@ -94,19 +99,24 @@ public:
bool hasNativeWindow() const { return m_flags.testFlag(HasNativeWindow); }
- virtual void invalidateSurface() Q_DECL_OVERRIDE;
+ void invalidateSurface() override;
virtual void resetSurface();
+#ifndef QT_NO_OPENGL
QOpenGLCompositorBackingStore *backingStore() { return m_backingStore; }
void setBackingStore(QOpenGLCompositorBackingStore *backingStore) { m_backingStore = backingStore; }
+#endif
bool isRaster() const;
-
- QWindow *sourceWindow() const Q_DECL_OVERRIDE;
- const QPlatformTextureList *textures() const Q_DECL_OVERRIDE;
- void endCompositing() Q_DECL_OVERRIDE;
+#ifndef QT_NO_OPENGL
+ QWindow *sourceWindow() const override;
+ const QPlatformTextureList *textures() const override;
+ void endCompositing() override;
+#endif
protected:
+#ifndef QT_NO_OPENGL
QOpenGLCompositorBackingStore *m_backingStore;
+#endif
bool m_raster;
WId m_winId;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
index f936d05927..6d759938b5 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/deviceintegration.pro
@@ -9,5 +9,7 @@ qtConfig(eglfs_mali): SUBDIRS += eglfs_mali
qtConfig(eglfs_viv): SUBDIRS += eglfs_viv
qtConfig(eglfs_viv_wl): SUBDIRS += eglfs_viv_wl
+qtConfig(opengl): SUBDIRS += eglfs_emu
+
eglfs_kms_egldevice.depends = eglfs_kms_support
eglfs_kms.depends = eglfs_kms_support
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h
index 5af628dedd..83bcc487af 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmintegration.h
@@ -47,13 +47,13 @@ QT_BEGIN_NAMESPACE
class QEglFSBrcmIntegration : public QEglFSDeviceIntegration
{
public:
- void platformInit() Q_DECL_OVERRIDE;
- void platformDestroy() Q_DECL_OVERRIDE;
- EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE;
- QSize screenSize() const Q_DECL_OVERRIDE;
- EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ void platformInit() override;
+ void platformDestroy() override;
+ EGLNativeDisplayType platformDisplay() const override;
+ QSize screenSize() const override;
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp
index 80d7631931..fd6665e560 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_brcm/qeglfsbrcmmain.cpp
@@ -48,7 +48,7 @@ class QEglFSBrcmIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_brcm.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSBrcmIntegration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSBrcmIntegration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.json b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.json
new file mode 100644
index 0000000000..3aa38abd7a
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "eglfs_emu" ]
+}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.pro
new file mode 100644
index 0000000000..609f04e8a9
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/eglfs_emu.pro
@@ -0,0 +1,27 @@
+TARGET = qeglfs-emu-integration
+
+QT += core-private gui-private eglfsdeviceintegration-private
+
+INCLUDEPATH += $$PWD/../../api
+CONFIG += egl
+
+# Avoid X11 header collision
+DEFINES += QT_EGL_NO_X11
+
+OTHER_FILES += $$PWD/eglfs_emu.json
+
+PLUGIN_TYPE = egldeviceintegrations
+PLUGIN_CLASS_NAME = QEglFSEmulatorIntegrationPlugin
+load(qt_plugin)
+
+DISTFILES += \
+ eglfs_emu.json
+
+SOURCES += \
+ qeglfsemumain.cpp \
+ qeglfsemulatorintegration.cpp \
+ qeglfsemulatorscreen.cpp
+
+HEADERS += \
+ qeglfsemulatorintegration.h \
+ qeglfsemulatorscreen.h
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp
new file mode 100644
index 0000000000..1abc430da6
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfsemulatorintegration.h"
+#include "qeglfsemulatorscreen.h"
+#include "private/qeglfsintegration_p.h"
+
+#include <private/qguiapplication_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglplatformcontext_p.h>
+
+#include <QtCore/QJsonDocument>
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonParseError>
+
+QT_BEGIN_NAMESPACE
+
+QEglFSEmulatorIntegration::QEglFSEmulatorIntegration()
+{
+ // The Qt Emulator provides the ability to render to multiple displays
+ // In addition to the usual EGL and OpenGLESv2 API's, there are also a
+ // few additional API's that enable the client (this plugin) to query
+ // the available screens and their properties, as well as the ability
+ // to select which screen is the active render target (as this is
+ // usually handled in a platform specific way and not by EGL itself).
+
+ getDisplays = reinterpret_cast<PFNQGSGETDISPLAYSPROC>(eglGetProcAddress("qgsGetDisplays"));
+ setDisplay = reinterpret_cast<PFNQGSSETDISPLAYPROC>(eglGetProcAddress("qgsSetDisplay"));
+}
+
+void QEglFSEmulatorIntegration::platformInit()
+{
+}
+
+void QEglFSEmulatorIntegration::platformDestroy()
+{
+}
+
+bool QEglFSEmulatorIntegration::usesDefaultScreen()
+{
+ // This makes it possible to remotely query and then register our own set of screens
+ return false;
+}
+
+void QEglFSEmulatorIntegration::screenInit()
+{
+ QEglFSIntegration *integration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
+
+ // Use qgsGetDisplays() call to retrieve the available screens from the Emulator
+ if (getDisplays) {
+ QByteArray displaysInfo = getDisplays();
+ QJsonParseError error;
+ QJsonDocument displaysDocument = QJsonDocument::fromJson(displaysInfo, &error);
+ if (error.error == QJsonParseError::NoError) {
+ // Document should be an array of screen objects
+ if (displaysDocument.isArray()){
+ QJsonArray screenArray = displaysDocument.array();
+ for (auto screenValue : screenArray) {
+ if (screenValue.isObject())
+ integration->addScreen(new QEglFSEmulatorScreen(screenValue.toObject()));
+ }
+ }
+ } else {
+ qWarning() << "eglfs_emu: Failed to parse display info JSON with error: " << error.errorString();
+ }
+ } else {
+ qFatal("EGL library doesn't support Emulator extensions");
+ }
+}
+
+bool QEglFSEmulatorIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+{
+ switch (cap) {
+ case QPlatformIntegration::ThreadedPixmaps:
+ case QPlatformIntegration::OpenGL:
+ case QPlatformIntegration::ThreadedOpenGL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+EGLNativeWindowType QEglFSEmulatorIntegration::createNativeWindow(QPlatformWindow *platformWindow,
+ const QSize &size,
+ const QSurfaceFormat &format)
+{
+ Q_UNUSED(size);
+ Q_UNUSED(format);
+ QEglFSEmulatorScreen *screen = static_cast<QEglFSEmulatorScreen *>(platformWindow->screen());
+ if (screen && setDisplay) {
+ // Let the emulator know which screen the window surface is attached to
+ setDisplay(screen->id());
+ }
+ static QBasicAtomicInt uniqueWindowId = Q_BASIC_ATOMIC_INITIALIZER(0);
+ return EGLNativeWindowType(qintptr(1 + uniqueWindowId.fetchAndAddRelaxed(1)));
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.h
new file mode 100644
index 0000000000..513a5063fb
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorintegration.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLFSEMULATORINTEGRATION_H
+#define QEGLFSEMULATORINTEGRATION_H
+
+#include "private/qeglfsdeviceintegration_p.h"
+
+#include <QtCore/QLoggingCategory>
+#include <QtCore/QFunctionPointer>
+
+typedef const char *(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC) ();
+typedef void (EGLAPIENTRYP PFNQGSSETDISPLAYPROC) (uint screen);
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(qLcEglfsEmuDebug)
+
+class QEglFSEmulatorIntegration : public QEglFSDeviceIntegration
+{
+public:
+ QEglFSEmulatorIntegration();
+
+ void platformInit() override;
+ void platformDestroy() override;
+ bool usesDefaultScreen() override;
+ void screenInit() override;
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
+
+ PFNQGSGETDISPLAYSPROC getDisplays;
+ PFNQGSSETDISPLAYPROC setDisplay;
+
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow, const QSize &size, const QSurfaceFormat &format) override;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLFSEMULATORINTEGRATION_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.cpp
new file mode 100644
index 0000000000..4546088327
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.cpp
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qeglfsemulatorscreen.h"
+
+QT_BEGIN_NAMESPACE
+
+QEglFSEmulatorScreen::QEglFSEmulatorScreen(const QJsonObject &screenDescription)
+ : QEglFSScreen(eglGetDisplay(EGL_DEFAULT_DISPLAY))
+ , m_id(0)
+{
+ initFromJsonObject(screenDescription);
+}
+
+QRect QEglFSEmulatorScreen::geometry() const
+{
+ return m_geometry;
+}
+
+QRect QEglFSEmulatorScreen::rawGeometry() const
+{
+ return QRect(QPoint(0, 0), m_geometry.size());
+}
+
+int QEglFSEmulatorScreen::depth() const
+{
+ return m_depth;
+}
+
+QImage::Format QEglFSEmulatorScreen::format() const
+{
+ return m_format;
+}
+
+QSizeF QEglFSEmulatorScreen::physicalSize() const
+{
+ return m_physicalSize;
+}
+
+QDpi QEglFSEmulatorScreen::logicalDpi() const
+{
+ const QSizeF ps = m_physicalSize;
+ const QSize s = m_geometry.size();
+
+ if (!ps.isEmpty() && !s.isEmpty())
+ return QDpi(25.4 * s.width() / ps.width(),
+ 25.4 * s.height() / ps.height());
+ else
+ return QDpi(100, 100);
+}
+
+qreal QEglFSEmulatorScreen::pixelDensity() const
+{
+ return m_pixelDensity;
+}
+
+qreal QEglFSEmulatorScreen::refreshRate() const
+{
+ return m_refreshRate;
+}
+
+Qt::ScreenOrientation QEglFSEmulatorScreen::nativeOrientation() const
+{
+ return m_nativeOrientation;
+}
+
+Qt::ScreenOrientation QEglFSEmulatorScreen::orientation() const
+{
+ return m_orientation;
+}
+
+uint QEglFSEmulatorScreen::id() const
+{
+ return m_id;
+}
+
+void QEglFSEmulatorScreen::initFromJsonObject(const QJsonObject &description)
+{
+ QJsonValue value;
+
+ value = description.value(QLatin1String("id"));
+ if (!value.isUndefined() && value.isDouble())
+ m_id = value.toInt();
+
+ value = description.value(QLatin1String("description"));
+ if (!value.isUndefined() && value.isString())
+ m_description = value.toString();
+
+ value = description.value(QLatin1String("geometry"));
+ if (!value.isUndefined() && value.isObject()) {
+ QJsonObject geometryObject = value.toObject();
+ value = geometryObject.value(QLatin1String("x"));
+ if (!value.isUndefined() && value.isDouble())
+ m_geometry.setX(value.toInt());
+ value = geometryObject.value(QLatin1String("y"));
+ if (!value.isUndefined() && value.isDouble())
+ m_geometry.setY(value.toInt());
+ value = geometryObject.value(QLatin1String("width"));
+ if (!value.isUndefined() && value.isDouble())
+ m_geometry.setWidth(value.toInt());
+ value = geometryObject.value(QLatin1String("height"));
+ if (!value.isUndefined() && value.isDouble())
+ m_geometry.setHeight(value.toInt());
+ }
+
+ value = description.value(QLatin1String("depth"));
+ if (!value.isUndefined() && value.isDouble())
+ m_depth = value.toInt();
+
+ value = description.value(QLatin1String("format"));
+ if (!value.isUndefined() && value.isDouble())
+ m_format = static_cast<QImage::Format>(value.toInt());
+
+ value = description.value(QLatin1String("physicalSize"));
+ if (!value.isUndefined() && value.isObject()) {
+ QJsonObject physicalSizeObject = value.toObject();
+ value = physicalSizeObject.value(QLatin1String("width"));
+ if (!value.isUndefined() && value.isDouble())
+ m_physicalSize.setWidth(value.toInt());
+ value = physicalSizeObject.value(QLatin1String("height"));
+ if (!value.isUndefined() && value.isDouble())
+ m_physicalSize.setHeight(value.toInt());
+ }
+
+ value = description.value(QLatin1String("pixelDensity"));
+ if (!value.isUndefined() && value.isDouble())
+ m_pixelDensity = value.toDouble();
+
+ value = description.value(QLatin1String("refreshRate"));
+ if (!value.isUndefined() && value.isDouble())
+ m_refreshRate = value.toDouble();
+
+ value = description.value(QLatin1String("nativeOrientation"));
+ if (!value.isUndefined() && value.isDouble())
+ m_nativeOrientation = static_cast<Qt::ScreenOrientation>(value.toInt());
+
+ value = description.value(QLatin1String("orientation"));
+ if (!value.isUndefined() && value.isDouble())
+ m_orientation = static_cast<Qt::ScreenOrientation>(value.toInt());
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.h
new file mode 100644
index 0000000000..3e5113c9c2
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemulatorscreen.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEGLFSEMULATORSCREEN_H
+#define QEGLFSEMULATORSCREEN_H
+
+#include <QtCore/QJsonObject>
+
+#include "qeglfsemulatorintegration.h"
+#include "private/qeglfsscreen_p.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSEmulatorScreen : public QEglFSScreen
+{
+public:
+ QEglFSEmulatorScreen(const QJsonObject &screenDescription);
+
+ QRect geometry() const override;
+ QRect rawGeometry() const override;
+ int depth() const override;
+ QImage::Format format() const override;
+ QSizeF physicalSize() const override;
+ QDpi logicalDpi() const override;
+ qreal pixelDensity() const override;
+ qreal refreshRate() const override;
+ Qt::ScreenOrientation nativeOrientation() const override;
+ Qt::ScreenOrientation orientation() const override;
+
+ uint id() const;
+
+private:
+ void initFromJsonObject(const QJsonObject &description);
+
+ QString m_description;
+ QRect m_geometry;
+ int m_depth;
+ QImage::Format m_format;
+ QSizeF m_physicalSize;
+ float m_pixelDensity;
+ float m_refreshRate;
+ Qt::ScreenOrientation m_nativeOrientation;
+ Qt::ScreenOrientation m_orientation;
+ uint m_id;
+};
+
+QT_END_NAMESPACE
+
+#endif // QEGLFSEMULATORSCREEN_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemumain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemumain.cpp
new file mode 100644
index 0000000000..a9923851ef
--- /dev/null
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_emu/qeglfsemumain.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "private/qeglfsdeviceintegration_p.h"
+#include "qeglfsemulatorintegration.h"
+
+QT_BEGIN_NAMESPACE
+
+class QEglFSEmulatorIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_emu.json")
+
+public:
+ QEglFSDeviceIntegration *create() override { return new QEglFSEmulatorIntegration; }
+};
+
+QT_END_NAMESPACE
+
+#include "qeglfsemumain.moc"
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro
index 255db824b7..e522c0ee1b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/eglfs_kms.pro
@@ -4,7 +4,7 @@ PLUGIN_TYPE = egldeviceintegrations
PLUGIN_CLASS_NAME = QEglFSKmsGbmIntegrationPlugin
load(qt_plugin)
-QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private
+QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private
INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
index de13a058cf..c96dd585d3 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmcursor.h
@@ -76,12 +76,12 @@ public:
~QEglFSKmsGbmCursor();
// input methods
- void pointerEvent(const QMouseEvent & event) Q_DECL_OVERRIDE;
+ void pointerEvent(const QMouseEvent & event) override;
#ifndef QT_NO_CURSOR
- void changeCursor(QCursor * windowCursor, QWindow * window) Q_DECL_OVERRIDE;
+ void changeCursor(QCursor * windowCursor, QWindow * window) override;
#endif
- QPoint pos() const Q_DECL_OVERRIDE;
- void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
+ QPoint pos() const override;
+ void setPos(const QPoint &pos) override;
void updateMouseStatus();
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
index 3a220ec942..2040d6bc0e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
@@ -46,7 +46,6 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/private/qcore_unix_p.h>
-#include <QtGui/private/qguiapplication_p.h>
#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
@@ -65,8 +64,8 @@ void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned int sequence, unsigned
screen->flipFinished();
}
-QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path)
- : QEglFSKmsDevice(integration, path)
+QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path)
+ : QEglFSKmsDevice(screenConfig, path)
, m_gbm_device(Q_NULLPTR)
, m_globalCursor(Q_NULLPTR)
{
@@ -77,7 +76,6 @@ bool QEglFSKmsGbmDevice::open()
Q_ASSERT(fd() == -1);
Q_ASSERT(m_gbm_device == Q_NULLPTR);
- qCDebug(qLcEglfsKmsDebug) << "Opening device" << devicePath();
int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
if (fd == -1) {
qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath()));
@@ -101,6 +99,8 @@ bool QEglFSKmsGbmDevice::open()
void QEglFSKmsGbmDevice::close()
{
+ // Note: screens are gone at this stage.
+
if (m_gbm_device) {
gbm_device_destroy(m_gbm_device);
m_gbm_device = Q_NULLPTR;
@@ -110,15 +110,11 @@ void QEglFSKmsGbmDevice::close()
qt_safe_close(fd());
setFd(-1);
}
-
- if (m_globalCursor)
- m_globalCursor->deleteLater();
- m_globalCursor = Q_NULLPTR;
}
-EGLNativeDisplayType QEglFSKmsGbmDevice::nativeDisplay() const
+void *QEglFSKmsGbmDevice::nativeDisplay() const
{
- return reinterpret_cast<EGLNativeDisplayType>(m_gbm_device);
+ return m_gbm_device;
}
gbm_device * QEglFSKmsGbmDevice::gbmDevice() const
@@ -131,6 +127,17 @@ QPlatformCursor *QEglFSKmsGbmDevice::globalCursor() const
return m_globalCursor;
}
+// Cannot do this from close(), it may be too late.
+// Call this from the last screen dtor instead.
+void QEglFSKmsGbmDevice::destroyGlobalCursor()
+{
+ if (m_globalCursor) {
+ qCDebug(qLcEglfsKmsDebug, "Destroying global GBM mouse cursor");
+ delete m_globalCursor;
+ m_globalCursor = Q_NULLPTR;
+ }
+}
+
void QEglFSKmsGbmDevice::handleDrmEvent()
{
drmEventContext drmEvent = {
@@ -142,14 +149,13 @@ void QEglFSKmsGbmDevice::handleDrmEvent()
drmHandleEvent(fd(), &drmEvent);
}
-QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output)
+QPlatformScreen *QEglFSKmsGbmDevice::createScreen(const QKmsOutput &output)
{
- static bool firstScreen = true;
- QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(integration, device, output);
+ QEglFSKmsGbmScreen *screen = new QEglFSKmsGbmScreen(this, output);
- if (firstScreen && integration->hwCursor()) {
+ if (!m_globalCursor && screenConfig()->hwCursor()) {
+ qCDebug(qLcEglfsKmsDebug, "Creating new global GBM mouse cursor");
m_globalCursor = new QEglFSKmsGbmCursor(screen);
- firstScreen = false;
}
return screen;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
index 7c0af84422..08ca28d48e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
@@ -43,7 +43,7 @@
#define QEGLFSKMSGBMDEVICE_H
#include "qeglfskmsgbmcursor.h"
-#include "qeglfskmsdevice.h"
+#include <qeglfskmsdevice.h>
#include <gbm.h>
@@ -54,21 +54,20 @@ class QEglFSKmsScreen;
class QEglFSKmsGbmDevice: public QEglFSKmsDevice
{
public:
- QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, const QString &path);
+ QEglFSKmsGbmDevice(QKmsScreenConfig *screenConfig, const QString &path);
- bool open() Q_DECL_OVERRIDE;
- void close() Q_DECL_OVERRIDE;
+ bool open() override;
+ void close() override;
- EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
+ void *nativeDisplay() const override;
gbm_device *gbmDevice() const;
QPlatformCursor *globalCursor() const;
+ void destroyGlobalCursor();
void handleDrmEvent();
- virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output) Q_DECL_OVERRIDE;
+ QPlatformScreen *createScreen(const QKmsOutput &output) override;
private:
Q_DISABLE_COPY(QEglFSKmsGbmDevice)
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
index 38419a55c8..b6cdcf92b6 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
@@ -63,8 +63,9 @@ QT_BEGIN_NAMESPACE
QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex;
QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
- : QEglFSKmsIntegration()
-{}
+{
+ qCDebug(qLcEglfsKmsDebug, "New DRM/KMS via GBM integration created");
+}
EGLNativeWindowType QEglFSKmsGbmIntegration::createNativeWindow(QPlatformWindow *platformWindow,
const QSize &size,
@@ -104,10 +105,13 @@ void QEglFSKmsGbmIntegration::destroyNativeWindow(EGLNativeWindowType window)
QPlatformCursor *QEglFSKmsGbmIntegration::createCursor(QPlatformScreen *screen) const
{
- if (hwCursor())
- return Q_NULLPTR;
- else
+#if QT_CONFIG(opengl)
+ if (!screenConfig()->hwCursor()) {
+ qCDebug(qLcEglfsKmsDebug, "Using plain OpenGL mouse cursor");
return new QEglFSCursor(screen);
+ }
+#endif
+ return nullptr;
}
void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface)
@@ -118,13 +122,12 @@ void QEglFSKmsGbmIntegration::presentBuffer(QPlatformSurface *surface)
screen->flip();
}
-QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath)
+QKmsDevice *QEglFSKmsGbmIntegration::createDevice()
{
- QString path = devicePath;
- if (!devicePath.isEmpty()) {
- qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << path << "specified in config file";
+ QString path = screenConfig()->devicePath();
+ if (!path.isEmpty()) {
+ qCDebug(qLcEglfsKmsDebug) << "GBM: Using DRM device" << path << "specified in config file";
} else {
-
QDeviceDiscovery *d = QDeviceDiscovery::create(QDeviceDiscovery::Device_VideoMask);
const QStringList devices = d->scanConnectedDevices();
qCDebug(qLcEglfsKmsDebug) << "Found the following video devices:" << devices;
@@ -137,7 +140,7 @@ QEglFSKmsDevice *QEglFSKmsGbmIntegration::createDevice(const QString &devicePath
qCDebug(qLcEglfsKmsDebug) << "Using" << path;
}
- return new QEglFSKmsGbmDevice(this, path);
+ return new QEglFSKmsGbmDevice(screenConfig(), path);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
index 727571d3e3..38f132d72e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
@@ -57,15 +57,15 @@ public:
EGLNativeWindowType createNativeWindow(QPlatformWindow *platformWindow,
const QSize &size,
- const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE;
+ const QSurfaceFormat &format) override;
+ EGLNativeWindowType createNativeOffscreenWindow(const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
- QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE;
- void presentBuffer(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ QPlatformCursor *createCursor(QPlatformScreen *screen) const override;
+ void presentBuffer(QPlatformSurface *surface) override;
protected:
- QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE;
+ QKmsDevice *createDevice() override;
private:
};
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp
index f34e4859c6..945c8b4255 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmmain.cpp
@@ -49,7 +49,7 @@ class QEglFSKmsGbmIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsGbmIntegration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSKmsGbmIntegration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
index d4df0dc66e..3723142f0b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
@@ -92,10 +92,8 @@ QEglFSKmsGbmScreen::FrameBuffer *QEglFSKmsGbmScreen::framebufferForBufferObject(
return fb.take();
}
-QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output)
- : QEglFSKmsScreen(integration, device, output)
+QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output)
+ : QEglFSKmsScreen(device, output)
, m_gbm_surface(Q_NULLPTR)
, m_gbm_bo_current(Q_NULLPTR)
, m_gbm_bo_next(Q_NULLPTR)
@@ -105,12 +103,17 @@ QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen()
{
+ const int remainingScreenCount = qGuiApp->screens().count();
+ qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount);
+ if (!remainingScreenCount && !device()->screenConfig()->separateScreens())
+ static_cast<QEglFSKmsGbmDevice *>(device())->destroyGlobalCursor();
}
QPlatformCursor *QEglFSKmsGbmScreen::cursor() const
{
- if (integration()->hwCursor()) {
- if (!integration()->separateScreens())
+ QKmsScreenConfig *config = device()->screenConfig();
+ if (config->hwCursor()) {
+ if (!config->separateScreens())
return static_cast<QEglFSKmsGbmDevice *>(device())->globalCursor();
if (m_cursor.isNull()) {
@@ -181,7 +184,7 @@ void QEglFSKmsGbmScreen::flip()
FrameBuffer *fb = framebufferForBufferObject(m_gbm_bo_next);
- QEglFSKmsOutput &op(output());
+ QKmsOutput &op(output());
const int fd = device()->fd();
const uint32_t w = op.modes[op.mode].hdisplay;
const uint32_t h = op.modes[op.mode].vdisplay;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
index d7ad348291..341cc95bbe 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
@@ -54,20 +54,18 @@ class QEglFSKmsGbmCursor;
class QEglFSKmsGbmScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
+ QEglFSKmsGbmScreen(QKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsGbmScreen();
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
+ QPlatformCursor *cursor() const override;
gbm_surface *surface() const { return m_gbm_surface; }
gbm_surface *createSurface();
void destroySurface();
- void waitForFlip() Q_DECL_OVERRIDE;
- void flip() Q_DECL_OVERRIDE;
- void flipFinished() Q_DECL_OVERRIDE;
+ void waitForFlip() override;
+ void flip() override;
+ void flipFinished() override;
private:
gbm_surface *m_gbm_surface;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
index a625021aba..a2dc9c4a50 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/eglfs_kms_egldevice.pro
@@ -1,6 +1,6 @@
TARGET = qeglfs-kms-egldevice-integration
-QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private
+QT += core-private gui-private eglfsdeviceintegration-private eglfs_kms_support-private kms_support-private
INCLUDEPATH += $$PWD/../../api $$PWD/../eglfs_kms_support
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
index 60989e2bd0..0a66a897a1 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.cpp
@@ -40,14 +40,16 @@
#include "qeglfskmsegldevice.h"
#include "qeglfskmsegldevicescreen.h"
#include "qeglfskmsegldeviceintegration.h"
+#include "private/qeglfsintegration_p.h"
#include "private/qeglfscursor_p.h"
#include <QtCore/private/qcore_unix_p.h>
QT_BEGIN_NAMESPACE
-QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path)
- : QEglFSKmsDevice(integration, path),
+QEglFSKmsEglDevice::QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path)
+ : QEglFSKmsDevice(screenConfig, path),
+ m_devInt(devInt),
m_globalCursor(nullptr)
{
}
@@ -56,11 +58,9 @@ bool QEglFSKmsEglDevice::open()
{
Q_ASSERT(fd() == -1);
- qCDebug(qLcEglfsKmsDebug, "Opening DRM device %s", qPrintable(devicePath()));
-
int fd = drmOpen(devicePath().toLocal8Bit().constData(), Q_NULLPTR);
if (Q_UNLIKELY(fd < 0))
- qFatal("Could not open DRM device");
+ qFatal("Could not open DRM (NV) device");
setFd(fd);
@@ -69,29 +69,28 @@ bool QEglFSKmsEglDevice::open()
void QEglFSKmsEglDevice::close()
{
- qCDebug(qLcEglfsKmsDebug, "Closing DRM device");
+ // Note: screens are gone at this stage.
if (qt_safe_close(fd()) == -1)
- qErrnoWarning("Could not close DRM device");
+ qErrnoWarning("Could not close DRM (NV) device");
setFd(-1);
}
EGLNativeDisplayType QEglFSKmsEglDevice::nativeDisplay() const
{
- return reinterpret_cast<EGLNativeDisplayType>(static_cast<QEglFSKmsEglDeviceIntegration *>(m_integration)->eglDevice());
+ return reinterpret_cast<EGLNativeDisplayType>(m_devInt->eglDevice());
}
-QEglFSKmsScreen *QEglFSKmsEglDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device,
- QEglFSKmsOutput output)
+QPlatformScreen *QEglFSKmsEglDevice::createScreen(const QKmsOutput &output)
{
- QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(integration, device, output);
-
- if (!m_globalCursor && !integration->separateScreens()) {
+ QEglFSKmsScreen *screen = new QEglFSKmsEglDeviceScreen(this, output);
+#if QT_CONFIG(opengl)
+ if (!m_globalCursor && !screenConfig()->separateScreens()) {
qCDebug(qLcEglfsKmsDebug, "Creating new global mouse cursor");
m_globalCursor = new QEglFSCursor(screen);
}
-
+#endif
return screen;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
index 8c8f79f70c..8d469879ab 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevice.h
@@ -45,25 +45,25 @@
QT_BEGIN_NAMESPACE
class QPlatformCursor;
+class QEglFSKmsEglDeviceIntegration;
class QEglFSKmsEglDevice: public QEglFSKmsDevice
{
public:
- QEglFSKmsEglDevice(QEglFSKmsIntegration *integration, const QString &path);
+ QEglFSKmsEglDevice(QEglFSKmsEglDeviceIntegration *devInt, QKmsScreenConfig *screenConfig, const QString &path);
- virtual bool open() Q_DECL_OVERRIDE;
- virtual void close() Q_DECL_OVERRIDE;
+ bool open() override;
+ void close() override;
- virtual EGLNativeDisplayType nativeDisplay() const Q_DECL_OVERRIDE;
+ void *nativeDisplay() const override;
- virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output) Q_DECL_OVERRIDE;
+ QPlatformScreen *createScreen(const QKmsOutput &output) override;
QPlatformCursor *globalCursor() { return m_globalCursor; }
void destroyGlobalCursor();
private:
+ QEglFSKmsEglDeviceIntegration *m_devInt;
QPlatformCursor *m_globalCursor;
};
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
index cf1de71831..43bdb77a18 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.cpp
@@ -50,8 +50,7 @@
QT_BEGIN_NAMESPACE
QEglFSKmsEglDeviceIntegration::QEglFSKmsEglDeviceIntegration()
- : QEglFSKmsIntegration()
- , m_egl_device(EGL_NO_DEVICE_EXT)
+ : m_egl_device(EGL_NO_DEVICE_EXT)
, m_funcs(Q_NULLPTR)
{
qCDebug(qLcEglfsKmsDebug, "New DRM/KMS on EGLDevice integration created");
@@ -101,30 +100,30 @@ bool QEglFSKmsEglDeviceIntegration::supportsPBuffers() const
return true;
}
-class QEglJetsonTK1Window : public QEglFSWindow
+class QEglFSKmsEglDeviceWindow : public QEglFSWindow
{
public:
- QEglJetsonTK1Window(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration)
+ QEglFSKmsEglDeviceWindow(QWindow *w, const QEglFSKmsEglDeviceIntegration *integration)
: QEglFSWindow(w)
, m_integration(integration)
, m_egl_stream(EGL_NO_STREAM_KHR)
{ }
- void invalidateSurface() Q_DECL_OVERRIDE;
- void resetSurface() Q_DECL_OVERRIDE;
+ void invalidateSurface() override;
+ void resetSurface() override;
const QEglFSKmsEglDeviceIntegration *m_integration;
EGLStreamKHR m_egl_stream;
EGLint m_latency;
};
-void QEglJetsonTK1Window::invalidateSurface()
+void QEglFSKmsEglDeviceWindow::invalidateSurface()
{
QEglFSWindow::invalidateSurface();
m_integration->m_funcs->destroy_stream(screen()->display(), m_egl_stream);
}
-void QEglJetsonTK1Window::resetSurface()
+void QEglFSKmsEglDeviceWindow::resetSurface()
{
qCDebug(qLcEglfsKmsDebug, "Creating stream");
@@ -173,7 +172,7 @@ void QEglJetsonTK1Window::resetSurface()
QEglFSKmsEglDeviceScreen *cur_screen = static_cast<QEglFSKmsEglDeviceScreen *>(screen());
Q_ASSERT(cur_screen);
- QEglFSKmsOutput &output(cur_screen->output());
+ QKmsOutput &output(cur_screen->output());
const uint32_t wantedId = !output.wants_plane ? output.crtc_id : output.plane_id;
qCDebug(qLcEglfsKmsDebug, "Searching for id: %d", wantedId);
@@ -235,7 +234,7 @@ void QEglJetsonTK1Window::resetSurface()
QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
{
- QEglJetsonTK1Window *eglWindow = new QEglJetsonTK1Window(window, this);
+ QEglFSKmsEglDeviceWindow *eglWindow = new QEglFSKmsEglDeviceWindow(window, this);
m_funcs->initialize(eglWindow->screen()->display());
if (Q_UNLIKELY(!(m_funcs->has_egl_output_base && m_funcs->has_egl_output_drm && m_funcs->has_egl_stream &&
@@ -245,10 +244,8 @@ QEglFSWindow *QEglFSKmsEglDeviceIntegration::createWindow(QWindow *window) const
return eglWindow;
}
-QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devicePath)
+QKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice()
{
- Q_UNUSED(devicePath)
-
if (Q_UNLIKELY(!query_egl_device()))
qFatal("Could not set up EGL device!");
@@ -256,7 +253,7 @@ QEglFSKmsDevice *QEglFSKmsEglDeviceIntegration::createDevice(const QString &devi
if (Q_UNLIKELY(!deviceName))
qFatal("Failed to query device name from EGLDevice");
- return new QEglFSKmsEglDevice(this, deviceName);
+ return new QEglFSKmsEglDevice(this, screenConfig(), deviceName);
}
bool QEglFSKmsEglDeviceIntegration::query_egl_device()
@@ -283,7 +280,11 @@ bool QEglFSKmsEglDeviceIntegration::query_egl_device()
QPlatformCursor *QEglFSKmsEglDeviceIntegration::createCursor(QPlatformScreen *screen) const
{
- return separateScreens() ? new QEglFSCursor(screen) : nullptr;
+#if QT_CONFIG(opengl)
+ if (screenConfig()->separateScreens())
+ return new QEglFSCursor(screen);
+#endif
+ return nullptr;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
index cddfdbd5c6..62404cfcd1 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldeviceintegration.h
@@ -55,27 +55,26 @@ class QEglFSKmsEglDeviceIntegration : public QEglFSKmsIntegration
public:
QEglFSKmsEglDeviceIntegration();
- EGLint surfaceType() const Q_DECL_OVERRIDE;
- EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) Q_DECL_OVERRIDE;
- bool supportsSurfacelessContexts() const Q_DECL_OVERRIDE;
- bool supportsPBuffers() const Q_DECL_OVERRIDE;
- QEglFSWindow *createWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ EGLint surfaceType() const override;
+ EGLDisplay createDisplay(EGLNativeDisplayType nativeDisplay) override;
+ bool supportsSurfacelessContexts() const override;
+ bool supportsPBuffers() const override;
+ QEglFSWindow *createWindow(QWindow *window) const override;
EGLDeviceEXT eglDevice() const { return m_egl_device; }
protected:
- QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE;
- QPlatformCursor *createCursor(QPlatformScreen *screen) const Q_DECL_OVERRIDE;
+ QKmsDevice *createDevice() override;
+ QPlatformCursor *createCursor(QPlatformScreen *screen) const override;
private:
bool setup_kms();
bool query_egl_device();
EGLDeviceEXT m_egl_device;
-
- friend class QEglJetsonTK1Window;
- // EGLStream infrastructure
QEGLStreamConvenience *m_funcs;
+
+ friend class QEglFSKmsEglDeviceWindow;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp
index 42fec073f1..5763ab45cc 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicemain.cpp
@@ -47,7 +47,7 @@ class QEglFSKmsEglDeviceIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_kms_egldevice.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSKmsEglDeviceIntegration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSKmsEglDeviceIntegration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
index 3935c99b9e..a27c89faab 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.cpp
@@ -40,11 +40,15 @@
#include "qeglfskmsegldevicescreen.h"
#include "qeglfskmsegldevice.h"
#include <QGuiApplication>
+#include <QLoggingCategory>
+#include <errno.h>
QT_BEGIN_NAMESPACE
-QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output)
- : QEglFSKmsScreen(integration, device, output)
+Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+
+QEglFSKmsEglDeviceScreen::QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output)
+ : QEglFSKmsScreen(device, output)
{
}
@@ -52,7 +56,7 @@ QEglFSKmsEglDeviceScreen::~QEglFSKmsEglDeviceScreen()
{
const int remainingScreenCount = qGuiApp->screens().count();
qCDebug(qLcEglfsKmsDebug, "Screen dtor. Remaining screens: %d", remainingScreenCount);
- if (!remainingScreenCount && !m_integration->separateScreens())
+ if (!remainingScreenCount && !device()->screenConfig()->separateScreens())
static_cast<QEglFSKmsEglDevice *>(device())->destroyGlobalCursor();
}
@@ -62,12 +66,15 @@ QPlatformCursor *QEglFSKmsEglDeviceScreen::cursor() const
// in its ctor. With separateScreens just use that. Otherwise
// there's a virtual desktop and the device has a global cursor
// and the base class has no dedicated cursor at all.
- return m_integration->separateScreens() ? QEglFSScreen::cursor() : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor();
+ // config->hwCursor() is ignored for now, just use the standard OpenGL cursor.
+ return device()->screenConfig()->separateScreens()
+ ? QEglFSScreen::cursor()
+ : static_cast<QEglFSKmsEglDevice *>(device())->globalCursor();
}
void QEglFSKmsEglDeviceScreen::waitForFlip()
{
- QEglFSKmsOutput &op(output());
+ QKmsOutput &op(output());
const int fd = device()->fd();
const uint32_t w = op.modes[op.mode].hdisplay;
const uint32_t h = op.modes[op.mode].vdisplay;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
index c57f52c6b7..5efe35f8b3 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_egldevice/qeglfskmsegldevicescreen.h
@@ -47,14 +47,12 @@ QT_BEGIN_NAMESPACE
class QEglFSKmsEglDeviceScreen : public QEglFSKmsScreen
{
public:
- QEglFSKmsEglDeviceScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
+ QEglFSKmsEglDeviceScreen(QKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsEglDeviceScreen();
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
+ QPlatformCursor *cursor() const override;
- void waitForFlip() Q_DECL_OVERRIDE;
+ void waitForFlip() override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
index 487edb569e..3c0a0ce30f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/eglfs_kms_support.pro
@@ -2,7 +2,7 @@ TARGET = QtEglFsKmsSupport
CONFIG += no_module_headers internal_module
load(qt_module)
-QT += core-private gui-private eglfsdeviceintegration-private
+QT += core-private gui-private eglfsdeviceintegration-private kms_support-private
INCLUDEPATH += $$PWD/../../api
@@ -15,8 +15,8 @@ QMAKE_LFLAGS += $$QMAKE_LFLAGS_NOUNDEF
SOURCES += $$PWD/qeglfskmsintegration.cpp \
$$PWD/qeglfskmsdevice.cpp \
- $$PWD/qeglfskmsscreen.cpp \
+ $$PWD/qeglfskmsscreen.cpp
HEADERS += $$PWD/qeglfskmsintegration.h \
$$PWD/qeglfskmsdevice.h \
- $$PWD/qeglfskmsscreen.h \
+ $$PWD/qeglfskmsscreen.h
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
index f372b9d156..b073577797 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
@@ -1,6 +1,5 @@
/****************************************************************************
**
-** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Pelagicore AG
** Contact: https://www.qt.io/licensing/
@@ -41,464 +40,25 @@
#include "qeglfskmsdevice.h"
#include "qeglfskmsscreen.h"
-
-#include "qeglfsintegration_p.h"
-
-#include <QtCore/QLoggingCategory>
-#include <QtCore/private/qcore_unix_p.h>
+#include "private/qeglfsintegration_p.h"
#include <QtGui/private/qguiapplication_p.h>
-#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
-
QT_BEGIN_NAMESPACE
-Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
-
-enum OutputConfiguration {
- OutputConfigOff,
- OutputConfigPreferred,
- OutputConfigCurrent,
- OutputConfigMode,
- OutputConfigModeline
-};
-
-int QEglFSKmsDevice::crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector)
-{
- for (int i = 0; i < connector->count_encoders; i++) {
- drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->encoders[i]);
- if (!encoder) {
- qWarning("Failed to get encoder");
- continue;
- }
-
- quint32 possibleCrtcs = encoder->possible_crtcs;
- drmModeFreeEncoder(encoder);
-
- for (int j = 0; j < resources->count_crtcs; j++) {
- bool isPossible = possibleCrtcs & (1 << j);
- bool isAvailable = !(m_crtc_allocator & 1 << resources->crtcs[j]);
-
- if (isPossible && isAvailable)
- return j;
- }
- }
-
- return -1;
-}
-
-static const char * const connector_type_names[] = { // must match DRM_MODE_CONNECTOR_*
- "None",
- "VGA",
- "DVI",
- "DVI",
- "DVI",
- "Composite",
- "TV",
- "LVDS",
- "CTV",
- "DIN",
- "DP",
- "HDMI",
- "HDMI",
- "TV",
- "eDP",
- "Virtual",
- "DSI"
-};
-
-static QByteArray nameForConnector(const drmModeConnectorPtr connector)
-{
- const QByteArray id = QByteArray::number(connector->connector_type_id);
- if (connector->connector_type < ARRAY_LENGTH(connector_type_names))
- return connector_type_names[connector->connector_type] + id;
- return "UNKNOWN" + id;
-}
-
-static bool parseModeline(const QByteArray &text, drmModeModeInfoPtr mode)
-{
- char hsync[16];
- char vsync[16];
- float fclock;
-
- mode->type = DRM_MODE_TYPE_USERDEF;
- mode->hskew = 0;
- mode->vscan = 0;
- mode->vrefresh = 0;
- mode->flags = 0;
-
- if (sscanf(text.constData(), "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
- &fclock,
- &mode->hdisplay,
- &mode->hsync_start,
- &mode->hsync_end,
- &mode->htotal,
- &mode->vdisplay,
- &mode->vsync_start,
- &mode->vsync_end,
- &mode->vtotal, hsync, vsync) != 11)
- return false;
-
- mode->clock = fclock * 1000;
-
- if (strcmp(hsync, "+hsync") == 0)
- mode->flags |= DRM_MODE_FLAG_PHSYNC;
- else if (strcmp(hsync, "-hsync") == 0)
- mode->flags |= DRM_MODE_FLAG_NHSYNC;
- else
- return false;
-
- if (strcmp(vsync, "+vsync") == 0)
- mode->flags |= DRM_MODE_FLAG_PVSYNC;
- else if (strcmp(vsync, "-vsync") == 0)
- mode->flags |= DRM_MODE_FLAG_NVSYNC;
- else
- return false;
-
- return true;
-}
-
-QEglFSKmsScreen *QEglFSKmsDevice::createScreenForConnector(drmModeResPtr resources,
- drmModeConnectorPtr connector,
- VirtualDesktopInfo *vinfo)
-{
- const QByteArray connectorName = nameForConnector(connector);
-
- const int crtc = crtcForConnector(resources, connector);
- if (crtc < 0) {
- qWarning() << "No usable crtc/encoder pair for connector" << connectorName;
- return Q_NULLPTR;
- }
-
- OutputConfiguration configuration;
- QSize configurationSize;
- drmModeModeInfo configurationModeline;
-
- auto userConfig = m_integration->outputSettings();
- auto userConnectorConfig = userConfig.value(QString::fromUtf8(connectorName));
- // default to the preferred mode unless overridden in the config
- const QByteArray mode = userConnectorConfig.value(QStringLiteral("mode"), QStringLiteral("preferred"))
- .toByteArray().toLower();
- if (mode == "off") {
- configuration = OutputConfigOff;
- } else if (mode == "preferred") {
- configuration = OutputConfigPreferred;
- } else if (mode == "current") {
- configuration = OutputConfigCurrent;
- } else if (sscanf(mode.constData(), "%dx%d", &configurationSize.rwidth(), &configurationSize.rheight()) == 2) {
- configuration = OutputConfigMode;
- } else if (parseModeline(mode, &configurationModeline)) {
- configuration = OutputConfigModeline;
- } else {
- qWarning("Invalid mode \"%s\" for output %s", mode.constData(), connectorName.constData());
- configuration = OutputConfigPreferred;
- }
- if (vinfo) {
- *vinfo = VirtualDesktopInfo();
- vinfo->virtualIndex = userConnectorConfig.value(QStringLiteral("virtualIndex"), INT_MAX).toInt();
- if (userConnectorConfig.contains(QStringLiteral("virtualPos"))) {
- const QByteArray vpos = userConnectorConfig.value(QStringLiteral("virtualPos")).toByteArray();
- const QByteArrayList vposComp = vpos.split(',');
- if (vposComp.count() == 2)
- vinfo->virtualPos = QPoint(vposComp[0].trimmed().toInt(), vposComp[1].trimmed().toInt());
- }
- }
-
- const uint32_t crtc_id = resources->crtcs[crtc];
-
- if (configuration == OutputConfigOff) {
- qCDebug(qLcEglfsKmsDebug) << "Turning off output" << connectorName;
- drmModeSetCrtc(m_dri_fd, crtc_id, 0, 0, 0, 0, 0, Q_NULLPTR);
- return Q_NULLPTR;
- }
-
- // Skip disconnected output
- if (configuration == OutputConfigPreferred && connector->connection == DRM_MODE_DISCONNECTED) {
- qCDebug(qLcEglfsKmsDebug) << "Skipping disconnected output" << connectorName;
- return Q_NULLPTR;
- }
-
- // Get the current mode on the current crtc
- drmModeModeInfo crtc_mode;
- memset(&crtc_mode, 0, sizeof crtc_mode);
- if (drmModeEncoderPtr encoder = drmModeGetEncoder(m_dri_fd, connector->connector_id)) {
- drmModeCrtcPtr crtc = drmModeGetCrtc(m_dri_fd, encoder->crtc_id);
- drmModeFreeEncoder(encoder);
-
- if (!crtc)
- return Q_NULLPTR;
-
- if (crtc->mode_valid)
- crtc_mode = crtc->mode;
-
- drmModeFreeCrtc(crtc);
- }
-
- QList<drmModeModeInfo> modes;
- modes.reserve(connector->count_modes);
- qCDebug(qLcEglfsKmsDebug) << connectorName << "mode count:" << connector->count_modes;
- for (int i = 0; i < connector->count_modes; i++) {
- const drmModeModeInfo &mode = connector->modes[i];
- qCDebug(qLcEglfsKmsDebug) << "mode" << i << mode.hdisplay << "x" << mode.vdisplay
- << '@' << mode.vrefresh << "hz";
- modes << connector->modes[i];
- }
-
- int preferred = -1;
- int current = -1;
- int configured = -1;
- int best = -1;
-
- for (int i = modes.size() - 1; i >= 0; i--) {
- const drmModeModeInfo &m = modes.at(i);
-
- if (configuration == OutputConfigMode &&
- m.hdisplay == configurationSize.width() &&
- m.vdisplay == configurationSize.height()) {
- configured = i;
- }
-
- if (!memcmp(&crtc_mode, &m, sizeof m))
- current = i;
-
- if (m.type & DRM_MODE_TYPE_PREFERRED)
- preferred = i;
-
- best = i;
- }
-
- if (configuration == OutputConfigModeline) {
- modes << configurationModeline;
- configured = modes.size() - 1;
- }
-
- if (current < 0 && crtc_mode.clock != 0) {
- modes << crtc_mode;
- current = mode.size() - 1;
- }
-
- if (configuration == OutputConfigCurrent)
- configured = current;
-
- int selected_mode = -1;
-
- if (configured >= 0)
- selected_mode = configured;
- else if (preferred >= 0)
- selected_mode = preferred;
- else if (current >= 0)
- selected_mode = current;
- else if (best >= 0)
- selected_mode = best;
-
- if (selected_mode < 0) {
- qWarning() << "No modes available for output" << connectorName;
- return Q_NULLPTR;
- } else {
- int width = modes[selected_mode].hdisplay;
- int height = modes[selected_mode].vdisplay;
- int refresh = modes[selected_mode].vrefresh;
- qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" << width << "x" << height
- << '@' << refresh << "hz for output" << connectorName;
- }
-
- // physical size from connector < config values < env vars
- static const int width = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH");
- static const int height = qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT");
- QSizeF physSize(width, height);
- if (physSize.isEmpty()) {
- physSize = QSize(userConnectorConfig.value(QStringLiteral("physicalWidth")).toInt(),
- userConnectorConfig.value(QStringLiteral("physicalHeight")).toInt());
- if (physSize.isEmpty()) {
- physSize.setWidth(connector->mmWidth);
- physSize.setHeight(connector->mmHeight);
- }
- }
- qCDebug(qLcEglfsKmsDebug) << "Physical size is" << physSize << "mm" << "for output" << connectorName;
-
- QEglFSKmsOutput output = {
- QString::fromUtf8(connectorName),
- connector->connector_id,
- crtc_id,
- physSize,
- selected_mode,
- false,
- drmModeGetCrtc(m_dri_fd, crtc_id),
- modes,
- connector->subpixel,
- connectorProperty(connector, QByteArrayLiteral("DPMS")),
- false,
- 0,
- false
- };
-
- bool ok;
- int idx = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_PLANE_INDEX", &ok);
- if (ok) {
- drmModePlaneRes *planeResources = drmModeGetPlaneResources(m_dri_fd);
- if (planeResources) {
- if (idx >= 0 && idx < int(planeResources->count_planes)) {
- drmModePlane *plane = drmModeGetPlane(m_dri_fd, planeResources->planes[idx]);
- if (plane) {
- output.wants_plane = true;
- output.plane_id = plane->plane_id;
- qCDebug(qLcEglfsKmsDebug, "Forcing plane index %d, plane id %u (belongs to crtc id %u)",
- idx, plane->plane_id, plane->crtc_id);
- drmModeFreePlane(plane);
- }
- } else {
- qWarning("Invalid plane index %d, must be between 0 and %u", idx, planeResources->count_planes - 1);
- }
- }
- }
-
- m_crtc_allocator |= (1 << output.crtc_id);
- m_connector_allocator |= (1 << output.connector_id);
-
- return createScreen(m_integration, this, output);
-}
-
-drmModePropertyPtr QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connector, const QByteArray &name)
-{
- drmModePropertyPtr prop;
-
- for (int i = 0; i < connector->count_props; i++) {
- prop = drmModeGetProperty(m_dri_fd, connector->props[i]);
- if (!prop)
- continue;
- if (strcmp(prop->name, name.constData()) == 0)
- return prop;
- drmModeFreeProperty(prop);
- }
-
- return Q_NULLPTR;
-}
-
-QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path)
- : m_integration(integration)
- , m_path(path)
- , m_dri_fd(-1)
- , m_crtc_allocator(0)
- , m_connector_allocator(0)
-{
-}
-
-QEglFSKmsDevice::~QEglFSKmsDevice()
-{
-}
-
-struct OrderedScreen
-{
- OrderedScreen() : screen(nullptr) { }
- OrderedScreen(QEglFSKmsScreen *screen, const QEglFSKmsDevice::VirtualDesktopInfo &vinfo)
- : screen(screen), vinfo(vinfo) { }
- QEglFSKmsScreen *screen;
- QEglFSKmsDevice::VirtualDesktopInfo vinfo;
-};
-
-QDebug operator<<(QDebug dbg, const OrderedScreen &s)
-{
- QDebugStateSaver saver(dbg);
- dbg.nospace() << "OrderedScreen(" << s.screen << " : " << s.vinfo.virtualIndex
- << " / " << s.vinfo.virtualPos << ")";
- return dbg;
-}
-
-static bool orderedScreenLessThan(const OrderedScreen &a, const OrderedScreen &b)
-{
- return a.vinfo.virtualIndex < b.vinfo.virtualIndex;
-}
-
-void QEglFSKmsDevice::createScreens()
-{
- drmModeResPtr resources = drmModeGetResources(m_dri_fd);
- if (!resources) {
- qWarning("drmModeGetResources failed");
- return;
- }
-
- QVector<OrderedScreen> screens;
-
- int wantedConnectorIndex = -1;
- bool ok;
- int idx = qEnvironmentVariableIntValue("QT_QPA_EGLFS_KMS_CONNECTOR_INDEX", &ok);
- if (ok) {
- if (idx >= 0 && idx < resources->count_connectors)
- wantedConnectorIndex = idx;
- else
- qWarning("Invalid connector index %d, must be between 0 and %u", idx, resources->count_connectors - 1);
- }
-
- for (int i = 0; i < resources->count_connectors; i++) {
- if (wantedConnectorIndex >= 0 && i != wantedConnectorIndex)
- continue;
-
- drmModeConnectorPtr connector = drmModeGetConnector(m_dri_fd, resources->connectors[i]);
- if (!connector)
- continue;
-
- VirtualDesktopInfo vinfo;
- QEglFSKmsScreen *screen = createScreenForConnector(resources, connector, &vinfo);
- if (screen)
- screens.append(OrderedScreen(screen, vinfo));
-
- drmModeFreeConnector(connector);
- }
-
- drmModeFreeResources(resources);
-
- // Use stable sort to preserve the original order for outputs with unspecified indices.
- std::stable_sort(screens.begin(), screens.end(), orderedScreenLessThan);
- qCDebug(qLcEglfsKmsDebug) << "Sorted screen list:" << screens;
-
- QPoint pos(0, 0);
- QList<QPlatformScreen *> siblings;
- QEglFSIntegration *qpaIntegration = static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration());
-
- for (const OrderedScreen &orderedScreen : screens) {
- QEglFSKmsScreen *s = orderedScreen.screen;
- // set up a horizontal or vertical virtual desktop
- if (orderedScreen.vinfo.virtualPos.isNull()) {
- s->setVirtualPosition(pos);
- if (m_integration->virtualDesktopLayout() == QEglFSKmsIntegration::VirtualDesktopLayoutVertical)
- pos.ry() += s->geometry().height();
- else
- pos.rx() += s->geometry().width();
- } else {
- s->setVirtualPosition(orderedScreen.vinfo.virtualPos);
- }
- qCDebug(qLcEglfsKmsDebug) << "Adding screen" << s << "to QPA with geometry" << s->geometry();
- // The order in qguiapp's screens list will match the order set by
- // virtualIndex. This is not only handy but also required since for instance
- // evdevtouch relies on it when performing touch device - screen mapping.
- qpaIntegration->addScreen(s);
- siblings << s;
- }
-
- if (!m_integration->separateScreens()) {
- // enable the virtual desktop
- Q_FOREACH (QPlatformScreen *screen, siblings)
- static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings);
- }
-}
-
-int QEglFSKmsDevice::fd() const
-{
- return m_dri_fd;
-}
-
-QString QEglFSKmsDevice::devicePath() const
-{
- return m_path;
-}
-
-QEglFSKmsScreen *QEglFSKmsDevice::createScreen(QEglFSKmsIntegration *integration, QEglFSKmsDevice *device, QEglFSKmsOutput output)
+QEglFSKmsDevice::QEglFSKmsDevice(QKmsScreenConfig *screenConfig, const QString &path)
+ : QKmsDevice(screenConfig, path)
{
- return new QEglFSKmsScreen(integration, device, output);
}
-void QEglFSKmsDevice::setFd(int fd)
+void QEglFSKmsDevice::registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings)
{
- m_dri_fd = fd;
+ QEglFSKmsScreen *s = static_cast<QEglFSKmsScreen *>(screen);
+ s->setVirtualPosition(virtualPos);
+ s->setVirtualSiblings(virtualSiblings);
+ static_cast<QEglFSIntegration *>(QGuiApplicationPrivate::platformIntegration())->addScreen(s, isPrimary);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
index 3e7ac7e3f0..fc83a620d9 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
@@ -1,6 +1,5 @@
/****************************************************************************
**
-** Copyright (C) 2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Pelagicore AG
** Contact: https://www.qt.io/licensing/
@@ -42,64 +41,22 @@
#ifndef QEGLFSKMSDEVICE_H
#define QEGLFSKMSDEVICE_H
-#include "qeglfskmsintegration.h"
-#include "qeglfskmsscreen.h"
-
-#include <xf86drm.h>
-#include <xf86drmMode.h>
+#include "private/qeglfsglobal_p.h"
+#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
-class Q_EGLFS_EXPORT QEglFSKmsDevice
+class Q_EGLFS_EXPORT QEglFSKmsDevice : public QKmsDevice
{
public:
- struct VirtualDesktopInfo {
- VirtualDesktopInfo() : virtualIndex(0) { }
- int virtualIndex;
- QPoint virtualPos;
- };
-
- QEglFSKmsDevice(QEglFSKmsIntegration *integration, const QString &path);
- virtual ~QEglFSKmsDevice();
-
- virtual bool open() = 0;
- virtual void close() = 0;
-
- virtual void createScreens();
-
- virtual EGLNativeDisplayType nativeDisplay() const = 0;
- int fd() const;
- QString devicePath() const;
-
-protected:
- virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
- void setFd(int fd);
-
- QEglFSKmsIntegration *m_integration;
- QString m_path;
- int m_dri_fd;
-
- quint32 m_crtc_allocator;
- quint32 m_connector_allocator;
-
- int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr connector);
- QEglFSKmsScreen *createScreenForConnector(drmModeResPtr resources,
- drmModeConnectorPtr connector,
- VirtualDesktopInfo *vinfo);
- drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const QByteArray &name);
-
- static void pageFlipHandler(int fd,
- unsigned int sequence,
- unsigned int tv_sec,
- unsigned int tv_usec,
- void *user_data);
+ QEglFSKmsDevice(QKmsScreenConfig *screenConfig, const QString &path);
-private:
- Q_DISABLE_COPY(QEglFSKmsDevice)
+ void registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings) override;
};
QT_END_NAMESPACE
-#endif
+#endif // QEGLFSKMSDEVICE_H
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
index 5368a6d031..c77151181e 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.cpp
@@ -40,13 +40,10 @@
****************************************************************************/
#include "qeglfskmsintegration.h"
-#include "qeglfskmsdevice.h"
#include "qeglfskmsscreen.h"
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonObject>
-#include <QtCore/QJsonArray>
-#include <QtCore/QFile>
+#include <QtKmsSupport/private/qkmsdevice_p.h>
+
#include <QtGui/qpa/qplatformwindow.h>
#include <QtGui/QScreen>
@@ -58,28 +55,27 @@ QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(qLcEglfsKmsDebug, "qt.qpa.eglfs.kms")
QEglFSKmsIntegration::QEglFSKmsIntegration()
- : m_device(Q_NULLPTR)
- , m_hwCursor(false)
- , m_pbuffers(false)
- , m_separateScreens(false)
- , m_virtualDesktopLayout(VirtualDesktopLayoutHorizontal)
-{}
-
-void QEglFSKmsIntegration::platformInit()
+ : m_device(Q_NULLPTR),
+ m_screenConfig(new QKmsScreenConfig)
{
- loadConfig();
+}
- if (!m_devicePath.isEmpty()) {
- qCDebug(qLcEglfsKmsDebug) << "Using DRM device" << m_devicePath << "specified in config file";
- }
+QEglFSKmsIntegration::~QEglFSKmsIntegration()
+{
+ delete m_screenConfig;
+}
- m_device = createDevice(m_devicePath);
+void QEglFSKmsIntegration::platformInit()
+{
+ qCDebug(qLcEglfsKmsDebug, "platformInit: Opening DRM device");
+ m_device = createDevice();
if (Q_UNLIKELY(!m_device->open()))
- qFatal("Could not open device %s - aborting!", qPrintable(m_devicePath));
+ qFatal("Could not open DRM device");
}
void QEglFSKmsIntegration::platformDestroy()
{
+ qCDebug(qLcEglfsKmsDebug, "platformDestroy: Closing DRM device");
m_device->close();
delete m_device;
m_device = Q_NULLPTR;
@@ -88,7 +84,7 @@ void QEglFSKmsIntegration::platformDestroy()
EGLNativeDisplayType QEglFSKmsIntegration::platformDisplay() const
{
Q_ASSERT(m_device);
- return m_device->nativeDisplay();
+ return (EGLNativeDisplayType) m_device->nativeDisplay();
}
bool QEglFSKmsIntegration::usesDefaultScreen()
@@ -134,94 +130,17 @@ void QEglFSKmsIntegration::waitForVSync(QPlatformSurface *surface) const
bool QEglFSKmsIntegration::supportsPBuffers() const
{
- return m_pbuffers;
-}
-
-bool QEglFSKmsIntegration::hwCursor() const
-{
- return m_hwCursor;
-}
-
-bool QEglFSKmsIntegration::separateScreens() const
-{
- return m_separateScreens;
-}
-
-QEglFSKmsIntegration::VirtualDesktopLayout QEglFSKmsIntegration::virtualDesktopLayout() const
-{
- return m_virtualDesktopLayout;
+ return m_screenConfig->supportsPBuffers();
}
-QMap<QString, QVariantMap> QEglFSKmsIntegration::outputSettings() const
-{
- return m_outputSettings;
-}
-
-QEglFSKmsDevice *QEglFSKmsIntegration::device() const
+QKmsDevice *QEglFSKmsIntegration::device() const
{
return m_device;
}
-void QEglFSKmsIntegration::loadConfig()
+QKmsScreenConfig *QEglFSKmsIntegration::screenConfig() const
{
- static QByteArray json = qgetenv("QT_QPA_EGLFS_KMS_CONFIG");
- if (json.isEmpty())
- return;
-
- qCDebug(qLcEglfsKmsDebug) << "Loading KMS setup from" << json;
-
- QFile file(QString::fromUtf8(json));
- if (!file.open(QFile::ReadOnly)) {
- qCWarning(qLcEglfsKmsDebug) << "Could not open config file"
- << json << "for reading";
- return;
- }
-
- const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
- if (!doc.isObject()) {
- qCWarning(qLcEglfsKmsDebug) << "Invalid config file" << json
- << "- no top-level JSON object";
- return;
- }
-
- const QJsonObject object = doc.object();
-
- m_hwCursor = object.value(QLatin1String("hwcursor")).toBool(m_hwCursor);
- m_pbuffers = object.value(QLatin1String("pbuffers")).toBool(m_pbuffers);
- m_devicePath = object.value(QLatin1String("device")).toString();
- m_separateScreens = object.value(QLatin1String("separateScreens")).toBool(m_separateScreens);
-
- const QString vdOriString = object.value(QLatin1String("virtualDesktopLayout")).toString();
- if (!vdOriString.isEmpty()) {
- if (vdOriString == QLatin1String("horizontal"))
- m_virtualDesktopLayout = VirtualDesktopLayoutHorizontal;
- else if (vdOriString == QLatin1String("vertical"))
- m_virtualDesktopLayout = VirtualDesktopLayoutVertical;
- else
- qCWarning(qLcEglfsKmsDebug) << "Unknown virtualDesktopOrientation value" << vdOriString;
- }
-
- const QJsonArray outputs = object.value(QLatin1String("outputs")).toArray();
- for (int i = 0; i < outputs.size(); i++) {
- const QVariantMap outputSettings = outputs.at(i).toObject().toVariantMap();
-
- if (outputSettings.contains(QStringLiteral("name"))) {
- const QString name = outputSettings.value(QStringLiteral("name")).toString();
-
- if (m_outputSettings.contains(name)) {
- qCDebug(qLcEglfsKmsDebug) << "Output" << name << "configured multiple times!";
- }
-
- m_outputSettings.insert(name, outputSettings);
- }
- }
-
- qCDebug(qLcEglfsKmsDebug) << "Configuration:\n"
- << "\thwcursor:" << m_hwCursor << "\n"
- << "\tpbuffers:" << m_pbuffers << "\n"
- << "\tseparateScreens:" << m_separateScreens << "\n"
- << "\tvirtualDesktopLayout:" << m_virtualDesktopLayout << "\n"
- << "\toutputs:" << m_outputSettings;
+ return m_screenConfig;
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h
index ba49945715..9955616919 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsintegration.h
@@ -49,49 +49,35 @@
QT_BEGIN_NAMESPACE
-class QEglFSKmsDevice;
+class QKmsDevice;
+class QKmsScreenConfig;
Q_EGLFS_EXPORT Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
class Q_EGLFS_EXPORT QEglFSKmsIntegration : public QEglFSDeviceIntegration
{
public:
- enum VirtualDesktopLayout {
- VirtualDesktopLayoutHorizontal,
- VirtualDesktopLayoutVertical
- };
-
QEglFSKmsIntegration();
+ ~QEglFSKmsIntegration();
- void platformInit() Q_DECL_OVERRIDE;
- void platformDestroy() Q_DECL_OVERRIDE;
- EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE;
- bool usesDefaultScreen() Q_DECL_OVERRIDE;
- void screenInit() Q_DECL_OVERRIDE;
- QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const Q_DECL_OVERRIDE;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
- void waitForVSync(QPlatformSurface *surface) const Q_DECL_OVERRIDE;
- bool supportsPBuffers() const Q_DECL_OVERRIDE;
-
- virtual bool hwCursor() const;
- virtual bool separateScreens() const;
- virtual VirtualDesktopLayout virtualDesktopLayout() const;
- QMap<QString, QVariantMap> outputSettings() const;
+ void platformInit() override;
+ void platformDestroy() override;
+ EGLNativeDisplayType platformDisplay() const override;
+ bool usesDefaultScreen() override;
+ void screenInit() override;
+ QSurfaceFormat surfaceFormatFor(const QSurfaceFormat &inputFormat) const override;
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
+ void waitForVSync(QPlatformSurface *surface) const override;
+ bool supportsPBuffers() const override;
- QEglFSKmsDevice *device() const;
+ QKmsDevice *device() const;
+ QKmsScreenConfig *screenConfig() const;
protected:
- virtual QEglFSKmsDevice *createDevice(const QString &devicePath) = 0;
-
- void loadConfig();
+ virtual QKmsDevice *createDevice() = 0;
- QEglFSKmsDevice *m_device;
- bool m_hwCursor;
- bool m_pbuffers;
- bool m_separateScreens;
- VirtualDesktopLayout m_virtualDesktopLayout;
- QString m_devicePath;
- QMap<QString, QVariantMap> m_outputSettings;
+ QKmsDevice *m_device;
+ QKmsScreenConfig *m_screenConfig;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
index 4021609407..3951f46a82 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "qeglfskmsscreen.h"
-#include "qeglfskmsdevice.h"
#include "qeglfsintegration_p.h"
#include <QtCore/QLoggingCategory>
@@ -69,30 +68,19 @@ private:
QEglFSKmsScreen *m_screen;
};
-QEglFSKmsScreen::QEglFSKmsScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output)
- : QEglFSScreen(eglGetDisplay(device->nativeDisplay()))
- , m_integration(integration)
+QEglFSKmsScreen::QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output)
+ : QEglFSScreen(eglGetDisplay((EGLNativeDisplayType) device->nativeDisplay()))
, m_device(device)
, m_output(output)
, m_powerState(PowerStateOn)
, m_interruptHandler(new QEglFSKmsInterruptHandler(this))
{
- m_siblings << this; // gets overridden by QEglFSKmsDevice later if !separateScreens
+ m_siblings << this; // gets overridden later
}
QEglFSKmsScreen::~QEglFSKmsScreen()
{
- if (m_output.dpms_prop) {
- drmModeFreeProperty(m_output.dpms_prop);
- m_output.dpms_prop = Q_NULLPTR;
- }
- restoreMode();
- if (m_output.saved_crtc) {
- drmModeFreeCrtc(m_output.saved_crtc);
- m_output.saved_crtc = Q_NULLPTR;
- }
+ m_output.cleanup(m_device);
delete m_interruptHandler;
}
@@ -123,7 +111,12 @@ QImage::Format QEglFSKmsScreen::format() const
QSizeF QEglFSKmsScreen::physicalSize() const
{
- return m_output.physical_size;
+ if (!m_output.physical_size.isEmpty()) {
+ return m_output.physical_size;
+ } else {
+ const QSize s = geometry().size();
+ return QSizeF(0.254 * s.width(), 0.254 * s.height());
+ }
}
QDpi QEglFSKmsScreen::logicalDpi() const
@@ -171,16 +164,7 @@ void QEglFSKmsScreen::flipFinished()
void QEglFSKmsScreen::restoreMode()
{
- if (m_output.mode_set && m_output.saved_crtc) {
- drmModeSetCrtc(m_device->fd(),
- m_output.saved_crtc->crtc_id,
- m_output.saved_crtc->buffer_id,
- 0, 0,
- &m_output.connector_id, 1,
- &m_output.saved_crtc->mode);
-
- m_output.mode_set = false;
- }
+ m_output.restoreMode(m_device);
}
qreal QEglFSKmsScreen::refreshRate() const
@@ -191,20 +175,7 @@ qreal QEglFSKmsScreen::refreshRate() const
QPlatformScreen::SubpixelAntialiasingType QEglFSKmsScreen::subpixelAntialiasingTypeHint() const
{
- switch (m_output.subpixel) {
- default:
- case DRM_MODE_SUBPIXEL_UNKNOWN:
- case DRM_MODE_SUBPIXEL_NONE:
- return Subpixel_None;
- case DRM_MODE_SUBPIXEL_HORIZONTAL_RGB:
- return Subpixel_RGB;
- case DRM_MODE_SUBPIXEL_HORIZONTAL_BGR:
- return Subpixel_BGR;
- case DRM_MODE_SUBPIXEL_VERTICAL_RGB:
- return Subpixel_VRGB;
- case DRM_MODE_SUBPIXEL_VERTICAL_BGR:
- return Subpixel_VBGR;
- }
+ return m_output.subpixelAntialiasingTypeHint();
}
QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const
@@ -214,11 +185,7 @@ QPlatformScreen::PowerState QEglFSKmsScreen::powerState() const
void QEglFSKmsScreen::setPowerState(QPlatformScreen::PowerState state)
{
- if (!m_output.dpms_prop)
- return;
-
- drmModeConnectorSetProperty(m_device->fd(), m_output.connector_id,
- m_output.dpms_prop->prop_id, (int)state);
+ m_output.setPowerState(m_device, state);
m_powerState = state;
}
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
index fa331f0931..80bbb0c7f1 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
@@ -42,65 +42,42 @@
#ifndef QEGLFSKMSSCREEN_H
#define QEGLFSKMSSCREEN_H
-#include "qeglfskmsintegration.h"
#include "private/qeglfsscreen_p.h"
#include <QtCore/QList>
#include <QtCore/QMutex>
-#include <xf86drm.h>
-#include <xf86drmMode.h>
+#include <QtKmsSupport/private/qkmsdevice_p.h>
QT_BEGIN_NAMESPACE
-class QEglFSKmsDevice;
class QEglFSKmsInterruptHandler;
-struct QEglFSKmsOutput
-{
- QString name;
- uint32_t connector_id;
- uint32_t crtc_id;
- QSizeF physical_size;
- int mode; // index of selected mode in list below
- bool mode_set;
- drmModeCrtcPtr saved_crtc;
- QList<drmModeModeInfo> modes;
- int subpixel;
- drmModePropertyPtr dpms_prop;
- bool wants_plane;
- uint32_t plane_id;
- bool plane_set;
-};
-
class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen
{
public:
- QEglFSKmsScreen(QEglFSKmsIntegration *integration,
- QEglFSKmsDevice *device,
- QEglFSKmsOutput output);
+ QEglFSKmsScreen(QKmsDevice *device, const QKmsOutput &output);
~QEglFSKmsScreen();
void setVirtualPosition(const QPoint &pos);
- QRect rawGeometry() const Q_DECL_OVERRIDE;
+ QRect rawGeometry() const override;
- int depth() const Q_DECL_OVERRIDE;
- QImage::Format format() const Q_DECL_OVERRIDE;
+ int depth() const override;
+ QImage::Format format() const override;
- QSizeF physicalSize() const Q_DECL_OVERRIDE;
- QDpi logicalDpi() const Q_DECL_OVERRIDE;
- Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
- Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
+ QSizeF physicalSize() const override;
+ QDpi logicalDpi() const override;
+ Qt::ScreenOrientation nativeOrientation() const override;
+ Qt::ScreenOrientation orientation() const override;
- QString name() const Q_DECL_OVERRIDE;
+ QString name() const override;
- qreal refreshRate() const Q_DECL_OVERRIDE;
+ qreal refreshRate() const override;
- QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE { return m_siblings; }
+ QList<QPlatformScreen *> virtualSiblings() const override { return m_siblings; }
void setVirtualSiblings(QList<QPlatformScreen *> sl) { m_siblings = sl; }
- QEglFSKmsIntegration *integration() const { return m_integration; }
- QEglFSKmsDevice *device() const { return m_device; }
+ QKmsDevice *device() const { return m_device; }
void destroySurface();
@@ -108,19 +85,18 @@ public:
virtual void flip();
virtual void flipFinished();
- QEglFSKmsOutput &output() { return m_output; }
+ QKmsOutput &output() { return m_output; }
void restoreMode();
- SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
+ SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override;
- QPlatformScreen::PowerState powerState() const Q_DECL_OVERRIDE;
- void setPowerState(QPlatformScreen::PowerState state) Q_DECL_OVERRIDE;
+ QPlatformScreen::PowerState powerState() const override;
+ void setPowerState(QPlatformScreen::PowerState state) override;
protected:
- QEglFSKmsIntegration *m_integration;
- QEglFSKmsDevice *m_device;
+ QKmsDevice *m_device;
- QEglFSKmsOutput m_output;
+ QKmsOutput m_output;
QPoint m_pos;
QList<QPlatformScreen *> m_siblings;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h
index 56883a3676..85eda4889f 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmaliintegration.h
@@ -47,9 +47,9 @@ QT_BEGIN_NAMESPACE
class QEglFSMaliIntegration : public QEglFSDeviceIntegration
{
public:
- void platformInit() Q_DECL_OVERRIDE;
- EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE;
+ void platformInit() override;
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp
index a3c804f54d..4f87dab967 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_mali/qeglfsmalimain.cpp
@@ -48,7 +48,7 @@ class QEglFSMaliIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_mali.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSMaliIntegration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSMaliIntegration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
index f2fcc0d3ff..763a4a462b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.cpp
@@ -63,9 +63,11 @@ void QEglFSVivIntegration::platformInit()
#ifdef Q_OS_INTEGRITY
VivanteInit();
+ mNativeDisplay = fbGetDisplay();
+#else
+ mNativeDisplay = fbGetDisplayByIndex(framebufferIndex());
#endif
- mNativeDisplay = fbGetDisplayByIndex(framebufferIndex());
fbGetDisplayGeometry(mNativeDisplay, &width, &height);
mScreenSize.setHeight(height);
mScreenSize.setWidth(width);
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h
index 2e98c2b4b1..4d1718afcf 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivintegration.h
@@ -47,11 +47,11 @@ QT_BEGIN_NAMESPACE
class QEglFSVivIntegration : public QEglFSDeviceIntegration
{
public:
- void platformInit() Q_DECL_OVERRIDE;
- QSize screenSize() const Q_DECL_OVERRIDE;
- EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE;
- EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE;
+ void platformInit() override;
+ QSize screenSize() const override;
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
+ EGLNativeDisplayType platformDisplay() const override;
private:
QSize mScreenSize;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp
index ebe2091b1e..0736637b6b 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv/qeglfsvivmain.cpp
@@ -48,7 +48,7 @@ class QEglFSVivIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivIntegration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSVivIntegration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h
index 9abbe817a6..2c49eb6440 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlintegration.h
@@ -48,13 +48,13 @@ QT_BEGIN_NAMESPACE
class QEglFSVivWaylandIntegration : public QEglFSDeviceIntegration
{
public:
- void platformInit() Q_DECL_OVERRIDE;
- QSize screenSize() const Q_DECL_OVERRIDE;
- EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE;
- EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE;
+ void platformInit() override;
+ QSize screenSize() const override;
+ EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
+ EGLNativeDisplayType platformDisplay() const override;
- void *wlDisplay() const Q_DECL_OVERRIDE;
+ void *wlDisplay() const override;
private:
QSize mScreenSize;
EGLNativeDisplayType mNativeDisplay;
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp
index 3b26feda07..6cdc9346c0 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_viv_wl/qeglfsvivwlmain.cpp
@@ -48,7 +48,7 @@ class QEglFSVivWaylandIntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_viv_wl.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSVivWaylandIntegration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSVivWaylandIntegration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
index 0a547b832f..64d0d9b515 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.cpp
@@ -114,7 +114,7 @@ void EventReader::run()
{
Qt::MouseButtons buttons;
- xcb_generic_event_t *event;
+ xcb_generic_event_t *event = nullptr;
while (running.load() && (event = xcb_wait_for_event(m_integration->connection()))) {
uint response_type = event->response_type & ~0x80;
switch (response_type) {
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
index c0f0ee5f22..bf431caaac 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11integration.h
@@ -69,15 +69,15 @@ class QEglFSX11Integration : public QEglFSDeviceIntegration
public:
QEglFSX11Integration() : m_connection(0), m_window(0), m_eventReader(0) {}
- void platformInit() Q_DECL_OVERRIDE;
- void platformDestroy() Q_DECL_OVERRIDE;
- EGLNativeDisplayType platformDisplay() const Q_DECL_OVERRIDE;
- QSize screenSize() const Q_DECL_OVERRIDE;
+ void platformInit() override;
+ void platformDestroy() override;
+ EGLNativeDisplayType platformDisplay() const override;
+ QSize screenSize() const override;
EGLNativeWindowType createNativeWindow(QPlatformWindow *window,
const QSize &size,
- const QSurfaceFormat &format) Q_DECL_OVERRIDE;
- void destroyNativeWindow(EGLNativeWindowType window) Q_DECL_OVERRIDE;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ const QSurfaceFormat &format) override;
+ void destroyNativeWindow(EGLNativeWindowType window) override;
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
xcb_connection_t *connection() { return m_connection; }
const xcb_atom_t *atoms() const { return m_atoms; }
diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp
index c15e05b657..39ab54ae5a 100644
--- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp
+++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_x11/qeglfsx11main.cpp
@@ -48,7 +48,7 @@ class QEglFSX11IntegrationPlugin : public QEglFSDeviceIntegrationPlugin
Q_PLUGIN_METADATA(IID QEglFSDeviceIntegrationFactoryInterface_iid FILE "eglfs_x11.json")
public:
- QEglFSDeviceIntegration *create() Q_DECL_OVERRIDE { return new QEglFSX11Integration; }
+ QEglFSDeviceIntegration *create() override { return new QEglFSX11Integration; }
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/eglfs-plugin.pro b/src/plugins/platforms/eglfs/eglfs-plugin.pro
index cf4863975a..3844328ee0 100644
--- a/src/plugins/platforms/eglfs/eglfs-plugin.pro
+++ b/src/plugins/platforms/eglfs/eglfs-plugin.pro
@@ -2,6 +2,8 @@ TARGET = qeglfs
QT += eglfsdeviceintegration-private
+CONFIG += egl
+
SOURCES += $$PWD/qeglfsmain.cpp
OTHER_FILES += $$PWD/eglfs.json
diff --git a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro
index 2593df937b..187cbc025f 100644
--- a/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro
+++ b/src/plugins/platforms/eglfs/eglfsdeviceintegration.pro
@@ -12,11 +12,14 @@ QT += \
core-private gui-private \
devicediscovery_support-private eventdispatcher_support-private \
service_support-private theme_support-private fontdatabase_support-private \
- fb_support-private egl_support-private platformcompositor_support-private
+ fb_support-private egl_support-private
qtHaveModule(input_support-private): \
QT += input_support-private
+qtHaveModule(platformcompositor_support-private): \
+ QT += platformcompositor_support-private
+
# Avoid X11 header collision, use generic EGL native types
DEFINES += QT_EGL_NO_X11
diff --git a/src/plugins/platforms/eglfs/qeglfsmain.cpp b/src/plugins/platforms/eglfs/qeglfsmain.cpp
index 2885d397c6..4f77b7cd17 100644
--- a/src/plugins/platforms/eglfs/qeglfsmain.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsmain.cpp
@@ -47,7 +47,7 @@ class QEglFSIntegrationPlugin : public QPlatformIntegrationPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "eglfs.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE;
+ QPlatformIntegration *create(const QString&, const QStringList&) override;
};
QPlatformIntegration* QEglFSIntegrationPlugin::create(const QString& system, const QStringList& paramList)
diff --git a/src/plugins/platforms/integrity/main.cpp b/src/plugins/platforms/integrity/main.cpp
index 3330ddc5ae..f75e227335 100644
--- a/src/plugins/platforms/integrity/main.cpp
+++ b/src/plugins/platforms/integrity/main.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/integrity/qintegrityfbintegration.cpp b/src/plugins/platforms/integrity/qintegrityfbintegration.cpp
index a88c85e30d..ae802bb1fa 100644
--- a/src/plugins/platforms/integrity/qintegrityfbintegration.cpp
+++ b/src/plugins/platforms/integrity/qintegrityfbintegration.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/integrity/qintegrityfbintegration.h b/src/plugins/platforms/integrity/qintegrityfbintegration.h
index 3210cc9369..a954dc2356 100644
--- a/src/plugins/platforms/integrity/qintegrityfbintegration.h
+++ b/src/plugins/platforms/integrity/qintegrityfbintegration.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/integrity/qintegrityfbscreen.cpp b/src/plugins/platforms/integrity/qintegrityfbscreen.cpp
index 256cc117a2..3979937955 100644
--- a/src/plugins/platforms/integrity/qintegrityfbscreen.cpp
+++ b/src/plugins/platforms/integrity/qintegrityfbscreen.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -206,7 +212,7 @@ QRegion QIntegrityFbScreen::doRedraw()
(uint32_t)rects[i].width(),
(uint32_t)rects[i].height()
};
- mBlitter->drawImage(rects[i], *mScreenImage, rects[i]);
+ mBlitter->drawImage(rects[i], mScreenImage, rects[i]);
gh_FB_expose(mFbh, &fbrect, NULL);
}
return touched;
diff --git a/src/plugins/platforms/integrity/qintegrityfbscreen.h b/src/plugins/platforms/integrity/qintegrityfbscreen.h
index 5b4d900a4b..6bc78913c9 100644
--- a/src/plugins/platforms/integrity/qintegrityfbscreen.h
+++ b/src/plugins/platforms/integrity/qintegrityfbscreen.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/integrity/qintegrityhidmanager.cpp b/src/plugins/platforms/integrity/qintegrityhidmanager.cpp
index 64eda98e2a..49583735f5 100644
--- a/src/plugins/platforms/integrity/qintegrityhidmanager.cpp
+++ b/src/plugins/platforms/integrity/qintegrityhidmanager.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2015 Green Hills Software
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/integrity/qintegrityhidmanager.h b/src/plugins/platforms/integrity/qintegrityhidmanager.h
index 9a0f27d833..c8780b2dc2 100644
--- a/src/plugins/platforms/integrity/qintegrityhidmanager.h
+++ b/src/plugins/platforms/integrity/qintegrityhidmanager.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2015 Green Hills Software
-** Contact: http://www.qt.io/licensing/
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the QtGui module of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/ios/kernel.pro b/src/plugins/platforms/ios/kernel.pro
index caafe89730..6eb9f2c534 100644
--- a/src/plugins/platforms/ios/kernel.pro
+++ b/src/plugins/platforms/ios/kernel.pro
@@ -1,5 +1,12 @@
TARGET = qios
+# QTBUG-42937: Work around linker errors caused by circular
+# dependencies between the iOS platform plugin and the user
+# application's main() when the plugin is a shared library.
+qtConfig(shared): CONFIG += static
+
+CONFIG += no_app_extension_api_only
+
QT += \
core-private gui-private \
clipboard_support-private fontdatabase_support-private graphics_support-private
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro
index f4588dda03..7379765599 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/nsphotolibrarysupport.pro
@@ -1,7 +1,11 @@
TARGET = qiosnsphotolibrarysupport
+# QTBUG-42937: Since the iOS plugin (kernel) is
+# static, this plugin needs to be static as well.
+qtConfig(shared): CONFIG += static
+
QT += core gui gui-private
-LIBS += -framework UIKit -framework AssetsLibrary
+LIBS += -framework Foundation -framework UIKit -framework AssetsLibrary
HEADERS = \
qiosfileengineassetslibrary.h \
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm
index 2ec0d33a41..8b372b8749 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/plugin.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
index df3f6b9fa3..c52d498cd4 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm
index f9662b964a..78e0f00ab4 100644
--- a/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm
+++ b/src/plugins/platforms/ios/optional/nsphotolibrarysupport/qiosimagepickercontroller.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/ios/qiosbackingstore.mm b/src/plugins/platforms/ios/qiosbackingstore.mm
index 076e34c1a5..96be28af81 100644
--- a/src/plugins/platforms/ios/qiosbackingstore.mm
+++ b/src/plugins/platforms/ios/qiosbackingstore.mm
@@ -122,7 +122,17 @@ QIOSBackingStore::QIOSBackingStore(QWindow *window)
QIOSBackingStore::~QIOSBackingStore()
{
- delete m_context;
+ if (window()->surfaceType() == QSurface::RasterGLSurface) {
+ // We're using composeAndFlush from QPlatformBackingStore, which
+ // need to clean up any textures in its destructor, so make the
+ // context current and keep it alive until QPlatformBackingStore
+ // has cleaned up everything.
+ makeCurrent();
+ m_context->deleteLater();
+ } else {
+ delete m_context;
+ }
+
delete m_glDevice;
}
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 68088540c6..237077400b 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -498,15 +498,32 @@ void QIOSInputContext::scrollToCursor()
return;
}
- const int margin = 20;
- QRectF translatedCursorPos = qApp->inputMethod()->cursorRectangle();
- translatedCursorPos.translate(focusView().qwindow->geometry().topLeft());
-
- qreal keyboardY = [rootView convertRect:m_keyboardState.keyboardEndRect fromView:nil].origin.y;
- int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y();
+ QWindow *focusWindow = qApp->focusWindow();
+ QRect cursorRect = qApp->inputMethod()->cursorRectangle().translated(focusWindow->geometry().topLeft()).toRect();
+ if (cursorRect.isNull()) {
+ scroll(0);
+ return;
+ }
- scroll((translatedCursorPos.bottomLeft().y() < keyboardY - margin) ? 0
- : qMin(rootView.bounds.size.height - keyboardY, translatedCursorPos.y() - statusBarY - margin));
+ // Add some padding so that the cusor does not end up directly above the keyboard
+ static const int kCursorRectPadding = 20;
+ cursorRect.adjust(0, -kCursorRectPadding, 0, kCursorRectPadding);
+
+ // We explicitly ask for the geometry of the screen instead of the availableGeometry,
+ // as we hide the statusbar when scrolling the screen, so the available geometry will
+ // include the space taken by the status bar at the moment.
+ QRect screenGeometry = focusWindow->screen()->geometry();
+ QRect keyboardGeometry = QRectF::fromCGRect(m_keyboardState.keyboardEndRect).toRect();
+ QRect availableGeometry = (QRegion(screenGeometry) - keyboardGeometry).boundingRect();
+
+ if (!availableGeometry.contains(cursorRect, true)) {
+ qImDebug() << "cursor rect" << cursorRect << "not fully within" << availableGeometry;
+ int scrollToCenter = -(availableGeometry.center() - cursorRect.center()).y();
+ int scrollToBottom = focusWindow->screen()->geometry().bottom() - availableGeometry.bottom();
+ scroll(qMin(scrollToCenter, scrollToBottom));
+ } else {
+ scroll(0);
+ }
}
void QIOSInputContext::scroll(int y)
@@ -519,6 +536,8 @@ void QIOSInputContext::scroll(int y)
if (CATransform3DEqualToTransform(translationTransform, rootView.layer.sublayerTransform))
return;
+ qImDebug() << "scrolling root view to y =" << -y;
+
QPointer<QIOSInputContext> self = this;
[UIView animateWithDuration:m_keyboardState.animationDuration delay:0
options:(m_keyboardState.animationCurve << 16) | UIViewAnimationOptionBeginFromCurrentState
@@ -631,11 +650,21 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
*/
void QIOSInputContext::update(Qt::InputMethodQueries updatedProperties)
{
+ qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject();
+
+ // Changes to the focus object should always result in a call to setFocusObject(),
+ // triggering a reset() which will update all the properties based on the new
+ // focus object. We try to detect code paths that fail this assertion and smooth
+ // over the situation by doing a manual update of the focus object.
+ if (qApp->focusObject() != m_imeState.focusObject && updatedProperties != Qt::ImQueryAll) {
+ qWarning() << "stale focus object" << m_imeState.focusObject << ", doing manual update";
+ setFocusObject(qApp->focusObject());
+ return;
+ }
+
// Mask for properties that we are interested in and see if any of them changed
updatedProperties &= (Qt::ImEnabled | Qt::ImHints | Qt::ImQueryInput | Qt::ImEnterKeyType | Qt::ImPlatformData);
- qImDebug() << "fw =" << qApp->focusWindow() << "fo =" << qApp->focusObject();
-
// Perform update first, so we can trust the value of inputMethodAccepted()
Qt::InputMethodQueries changedProperties = m_imeState.update(updatedProperties);
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index e5b4d6da85..fbf167b514 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -61,6 +61,7 @@
#include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h>
#include <QtClipboardSupport/private/qmacmime_p.h>
#include <QDir>
+#include <QOperatingSystemVersion>
#import <AudioToolbox/AudioServices.h>
@@ -119,7 +120,7 @@ QIOSIntegration::QIOSIntegration()
m_touchDevice = new QTouchDevice;
m_touchDevice->setType(QTouchDevice::TouchScreen);
QTouchDevice::Capabilities touchCapabilities = QTouchDevice::Position | QTouchDevice::NormalizedPosition;
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_9_0) {
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9)) {
if (mainScreen.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
touchCapabilities |= QTouchDevice::Pressure;
}
diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm
index 50d5442f17..4f0c667861 100644
--- a/src/plugins/platforms/ios/qiosmessagedialog.mm
+++ b/src/plugins/platforms/ios/qiosmessagedialog.mm
@@ -39,6 +39,7 @@
#import <UIKit/UIKit.h>
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/qwindow.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
@@ -109,7 +110,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win
if (m_alertController // Ensure that the dialog is not showing already
|| !options() // Some message dialogs don't have options (QErrorMessage)
|| windowModality == Qt::NonModal // We can only do modal dialogs
- || QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) // API limitation
+ || QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) // API limitation
return false;
m_alertController = [[UIAlertController
diff --git a/src/plugins/platforms/ios/qiosoptionalplugininterface.h b/src/plugins/platforms/ios/qiosoptionalplugininterface.h
index bcb8978e02..3f74e41c83 100644
--- a/src/plugins/platforms/ios/qiosoptionalplugininterface.h
+++ b/src/plugins/platforms/ios/qiosoptionalplugininterface.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index c518f9111d..3514bf63bb 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -45,6 +45,7 @@
#include "qiosapplicationdelegate.h"
#include "qiosviewcontroller.h"
#include "quiview.h"
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/private/qwindow_p.h>
#include <private/qcoregraphics_p.h>
@@ -274,7 +275,7 @@ void QIOSScreen::updateProperties()
if (m_uiScreen == [UIScreen mainScreen]) {
Qt::ScreenOrientation statusBarOrientation = toQtScreenOrientation(UIDeviceOrientation([UIApplication sharedApplication].statusBarOrientation));
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) {
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
// On iOS < 8.0 the UIScreen geometry is always in portait, and the system applies
// the screen rotation to the root view-controller's view instead of directly to the
// screen, like iOS 8 and above does.
@@ -302,7 +303,7 @@ void QIOSScreen::updateProperties()
if (m_geometry != previousGeometry) {
QRectF physicalGeometry;
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0) {
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 8)) {
// We can't use the primaryOrientation of screen(), as we haven't reported the new geometry yet
Qt::ScreenOrientation primaryOrientation = m_geometry.width() >= m_geometry.height() ?
Qt::LandscapeOrientation : Qt::PortraitOrientation;
@@ -406,10 +407,11 @@ qreal QIOSScreen::devicePixelRatio() const
Qt::ScreenOrientation QIOSScreen::nativeOrientation() const
{
CGRect nativeBounds =
-#if !defined(Q_OS_TVOS) && QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_8_0)
- QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_8_0 ? m_uiScreen.nativeBounds :
-#endif
+#if defined(Q_OS_IOS)
+ m_uiScreen.nativeBounds;
+#else
m_uiScreen.bounds;
+#endif
// All known iOS devices have a native orientation of portrait, but to
// be on the safe side we compare the width and height of the bounds.
diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.h b/src/plugins/platforms/ios/qiostextinputoverlay.h
index 2f01993b19..9ed3a9b271 100644
--- a/src/plugins/platforms/ios/qiostextinputoverlay.h
+++ b/src/plugins/platforms/ios/qiostextinputoverlay.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm
index 238d7addf6..78f84729da 100644
--- a/src/plugins/platforms/ios/qiostextinputoverlay.mm
+++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -219,7 +225,7 @@ static void executeBlockWithoutAnimation(Block block)
borderLayer.borderColor = [[UIColor lightGrayColor] CGColor];
[self addSublayer:borderLayer];
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_7_0) {
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 7)) {
// [UIView snapshotViewAfterScreenUpdates:] is available since iOS 7.0.
// Just silently ignore showing the loupe for older versions.
self.hidden = YES;
@@ -267,7 +273,7 @@ static void executeBlockWithoutAnimation(Block block)
- (void)display
{
- if (QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_7_0)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion(QOperatingSystemVersion::IOS, 7))
return;
// Take a snapshow of the target view, magnify the area around the focal
diff --git a/src/plugins/platforms/ios/quiview.mm b/src/plugins/platforms/ios/quiview.mm
index 2a1444e9e5..9966bd50a3 100644
--- a/src/plugins/platforms/ios/quiview.mm
+++ b/src/plugins/platforms/ios/quiview.mm
@@ -48,6 +48,7 @@
#include "qiosmenu.h"
#endif
+#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qwindow_p.h>
#include <qpa/qwindowsysteminterface_p.h>
@@ -208,18 +209,23 @@
- (BOOL)becomeFirstResponder
{
- FirstResponderCandidate firstResponderCandidate(self);
+ {
+ // Scope for the duration of becoming first responder only, as the window
+ // activation event may trigger new responders, which we don't want to be
+ // blocked by this guard.
+ FirstResponderCandidate firstResponderCandidate(self);
- qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
- << "first:" << [UIResponder currentFirstResponder];
+ qImDebug() << "win:" << m_qioswindow->window() << "self:" << self
+ << "first:" << [UIResponder currentFirstResponder];
- if (![super becomeFirstResponder]) {
- qImDebug() << m_qioswindow->window()
- << "was not allowed to become first responder";
- return NO;
- }
+ if (![super becomeFirstResponder]) {
+ qImDebug() << m_qioswindow->window()
+ << "was not allowed to become first responder";
+ return NO;
+ }
- qImDebug() << m_qioswindow->window() << "became first responder";
+ qImDebug() << m_qioswindow->window() << "became first responder";
+ }
if (qGuiApp->focusWindow() != m_qioswindow->window())
QWindowSystemInterface::handleWindowActivated<QWindowSystemInterface::SynchronousDelivery>(m_qioswindow->window());
@@ -291,7 +297,7 @@
QTouchDevice *touchDevice = QIOSIntegration::instance()->touchDevice();
QTouchDevice::Capabilities touchCapabilities = touchDevice->capabilities();
- if (QSysInfo::MacintoshVersion >= QSysInfo::MV_IOS_9_0) {
+ if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::IOS, 9)) {
if (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)
touchCapabilities |= QTouchDevice::Pressure;
else
diff --git a/src/plugins/platforms/linuxfb/linuxfb.pro b/src/plugins/platforms/linuxfb/linuxfb.pro
index e2fa31211d..d3a4476f80 100644
--- a/src/plugins/platforms/linuxfb/linuxfb.pro
+++ b/src/plugins/platforms/linuxfb/linuxfb.pro
@@ -10,8 +10,18 @@ QT += \
qtHaveModule(input_support-private): \
QT += input_support-private
-SOURCES = main.cpp qlinuxfbintegration.cpp qlinuxfbscreen.cpp
-HEADERS = qlinuxfbintegration.h qlinuxfbscreen.h
+SOURCES = main.cpp \
+ qlinuxfbintegration.cpp \
+ qlinuxfbscreen.cpp
+
+HEADERS = qlinuxfbintegration.h \
+ qlinuxfbscreen.h
+
+qtHaveModule(kms_support-private) {
+ QT += kms_support-private
+ SOURCES += qlinuxfbdrmscreen.cpp
+ HEADERS += qlinuxfbdrmscreen.h
+}
OTHER_FILES += linuxfb.json
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
new file mode 100644
index 0000000000..2ca251c4af
--- /dev/null
+++ b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.cpp
@@ -0,0 +1,412 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// Experimental DRM dumb buffer backend.
+//
+// TODO:
+// Multiscreen: QWindow-QScreen(-output) association. Needs some reorg (device cannot be owned by screen)
+// Find card via devicediscovery like in eglfs_kms.
+// Mode restore like QEglFSKmsInterruptHandler.
+// Formats other then 32 bpp?
+// grabWindow
+
+#include "qlinuxfbdrmscreen.h"
+#include <QLoggingCategory>
+#include <QGuiApplication>
+#include <QPainter>
+#include <QtFbSupport/private/qfbcursor_p.h>
+#include <QtFbSupport/private/qfbwindow_p.h>
+#include <QtKmsSupport/private/qkmsdevice_p.h>
+#include <QtCore/private/qcore_unix_p.h>
+#include <sys/mman.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_LOGGING_CATEGORY(qLcFbDrm, "qt.qpa.fb")
+
+static const int BUFFER_COUNT = 2;
+
+class QLinuxFbDevice : public QKmsDevice
+{
+public:
+ struct Framebuffer {
+ Framebuffer() : handle(0), pitch(0), size(0), fb(0), p(MAP_FAILED) { }
+ uint32_t handle;
+ uint32_t pitch;
+ uint64_t size;
+ uint32_t fb;
+ void *p;
+ QImage wrapper;
+ };
+
+ struct Output {
+ Output() : backFb(0), flipped(false) { }
+ QKmsOutput kmsOutput;
+ Framebuffer fb[BUFFER_COUNT];
+ QRegion dirty[BUFFER_COUNT];
+ int backFb;
+ bool flipped;
+ QSize currentRes() const {
+ const drmModeModeInfo &modeInfo(kmsOutput.modes[kmsOutput.mode]);
+ return QSize(modeInfo.hdisplay, modeInfo.vdisplay);
+ }
+ };
+
+ QLinuxFbDevice(QKmsScreenConfig *screenConfig);
+
+ bool open() override;
+ void close() override;
+
+ void createFramebuffers();
+ void destroyFramebuffers();
+ void setMode();
+
+ void swapBuffers(Output *output);
+
+ int outputCount() const { return m_outputs.count(); }
+ Output *output(int idx) { return &m_outputs[idx]; }
+
+private:
+ void *nativeDisplay() const override;
+ QPlatformScreen *createScreen(const QKmsOutput &output) override;
+ void registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings) override;
+
+ bool createFramebuffer(Output *output, int bufferIdx);
+ void destroyFramebuffer(Output *output, int bufferIdx);
+
+ static void pageFlipHandler(int fd, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec, void *user_data);
+
+ QVector<Output> m_outputs;
+};
+
+QLinuxFbDevice::QLinuxFbDevice(QKmsScreenConfig *screenConfig)
+ : QKmsDevice(screenConfig, QStringLiteral("/dev/dri/card0"))
+{
+}
+
+bool QLinuxFbDevice::open()
+{
+ int fd = qt_safe_open(devicePath().toLocal8Bit().constData(), O_RDWR | O_CLOEXEC);
+ if (fd == -1) {
+ qErrnoWarning("Could not open DRM device %s", qPrintable(devicePath()));
+ return false;
+ }
+
+ uint64_t hasDumbBuf = 0;
+ if (drmGetCap(fd, DRM_CAP_DUMB_BUFFER, &hasDumbBuf) == -1 || !hasDumbBuf) {
+ qWarning("Dumb buffers not supported");
+ qt_safe_close(fd);
+ return false;
+ }
+
+ setFd(fd);
+
+ qCDebug(qLcFbDrm, "DRM device %s opened", qPrintable(devicePath()));
+
+ return true;
+}
+
+void QLinuxFbDevice::close()
+{
+ for (Output &output : m_outputs)
+ output.kmsOutput.cleanup(this); // restore mode
+
+ m_outputs.clear();
+
+ if (fd() != -1) {
+ qCDebug(qLcFbDrm, "Closing DRM device");
+ qt_safe_close(fd());
+ setFd(-1);
+ }
+}
+
+void *QLinuxFbDevice::nativeDisplay() const
+{
+ Q_UNREACHABLE();
+ return nullptr;
+}
+
+QPlatformScreen *QLinuxFbDevice::createScreen(const QKmsOutput &output)
+{
+ qCDebug(qLcFbDrm, "Got a new output: %s", qPrintable(output.name));
+ Output o;
+ o.kmsOutput = output;
+ m_outputs.append(o);
+ return nullptr; // no platformscreen, we are not a platform plugin
+}
+
+void QLinuxFbDevice::registerScreen(QPlatformScreen *screen,
+ bool isPrimary,
+ const QPoint &virtualPos,
+ const QList<QPlatformScreen *> &virtualSiblings)
+{
+ Q_UNUSED(screen);
+ Q_UNUSED(isPrimary);
+ Q_UNUSED(virtualPos);
+ Q_UNUSED(virtualSiblings);
+ Q_UNREACHABLE();
+}
+
+bool QLinuxFbDevice::createFramebuffer(QLinuxFbDevice::Output *output, int bufferIdx)
+{
+ const QSize size = output->currentRes();
+ const uint32_t w = size.width();
+ const uint32_t h = size.height();
+ drm_mode_create_dumb creq = {
+ h,
+ w,
+ 32,
+ 0, 0, 0, 0
+ };
+ if (drmIoctl(fd(), DRM_IOCTL_MODE_CREATE_DUMB, &creq) == -1) {
+ qErrnoWarning(errno, "Failed to create dumb buffer");
+ return false;
+ }
+
+ Framebuffer &fb(output->fb[bufferIdx]);
+ fb.handle = creq.handle;
+ fb.pitch = creq.pitch;
+ fb.size = creq.size;
+ qCDebug(qLcFbDrm, "Got a dumb buffer for size %dx%d, handle %u, pitch %u, size %u",
+ w, h, fb.handle, fb.pitch, (uint) fb.size);
+
+ if (drmModeAddFB(fd(), w, h, 24, 32, fb.pitch, fb.handle, &fb.fb) == -1) {
+ qErrnoWarning(errno, "Failed to add FB");
+ return false;
+ }
+
+ drm_mode_map_dumb mreq = {
+ fb.handle,
+ 0, 0
+ };
+ if (drmIoctl(fd(), DRM_IOCTL_MODE_MAP_DUMB, &mreq) == -1) {
+ qErrnoWarning(errno, "Failed to map dumb buffer");
+ return false;
+ }
+ fb.p = mmap(0, fb.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd(), mreq.offset);
+ if (fb.p == MAP_FAILED) {
+ qErrnoWarning(errno, "Failed to mmap dumb buffer");
+ return false;
+ }
+
+ qCDebug(qLcFbDrm, "FB is %u, mapped at %p", fb.fb, fb.p);
+ memset(fb.p, 0, fb.size);
+
+ fb.wrapper = QImage(static_cast<uchar *>(fb.p), w, h, fb.pitch, QImage::Format_ARGB32);
+
+ return true;
+}
+
+void QLinuxFbDevice::createFramebuffers()
+{
+ for (Output &output : m_outputs) {
+ for (int i = 0; i < BUFFER_COUNT; ++i) {
+ if (!createFramebuffer(&output, i))
+ return;
+ }
+ output.backFb = 0;
+ output.flipped = false;
+ }
+}
+
+void QLinuxFbDevice::destroyFramebuffer(QLinuxFbDevice::Output *output, int bufferIdx)
+{
+ Framebuffer &fb(output->fb[bufferIdx]);
+ if (fb.p != MAP_FAILED)
+ munmap(fb.p, fb.size);
+ if (fb.fb) {
+ if (drmModeRmFB(fd(), fb.fb) == -1)
+ qErrnoWarning("Failed to remove fb");
+ }
+ if (fb.handle) {
+ drm_mode_destroy_dumb dreq = { fb.handle };
+ if (drmIoctl(fd(), DRM_IOCTL_MODE_DESTROY_DUMB, &dreq) == -1)
+ qErrnoWarning(errno, "Failed to destroy dumb buffer %u", fb.handle);
+ }
+ fb = Framebuffer();
+}
+
+void QLinuxFbDevice::destroyFramebuffers()
+{
+ for (Output &output : m_outputs) {
+ for (int i = 0; i < BUFFER_COUNT; ++i)
+ destroyFramebuffer(&output, i);
+ }
+}
+
+void QLinuxFbDevice::setMode()
+{
+ for (Output &output : m_outputs) {
+ drmModeModeInfo &modeInfo(output.kmsOutput.modes[output.kmsOutput.mode]);
+ if (drmModeSetCrtc(fd(), output.kmsOutput.crtc_id, output.fb[0].fb, 0, 0,
+ &output.kmsOutput.connector_id, 1, &modeInfo) == -1) {
+ qErrnoWarning(errno, "Failed to set mode");
+ return;
+ }
+
+ output.kmsOutput.mode_set = true; // have cleanup() to restore the mode
+ output.kmsOutput.setPowerState(this, QPlatformScreen::PowerStateOn);
+ }
+}
+
+void QLinuxFbDevice::pageFlipHandler(int fd, unsigned int sequence,
+ unsigned int tv_sec, unsigned int tv_usec,
+ void *user_data)
+{
+ Q_UNUSED(fd);
+ Q_UNUSED(sequence);
+ Q_UNUSED(tv_sec);
+ Q_UNUSED(tv_usec);
+
+ Output *output = static_cast<Output *>(user_data);
+ output->backFb = (output->backFb + 1) % BUFFER_COUNT;
+}
+
+void QLinuxFbDevice::swapBuffers(Output *output)
+{
+ Framebuffer &fb(output->fb[output->backFb]);
+ if (drmModePageFlip(fd(), output->kmsOutput.crtc_id, fb.fb, DRM_MODE_PAGE_FLIP_EVENT, output) == -1) {
+ qErrnoWarning(errno, "Page flip failed");
+ return;
+ }
+
+ const int fbIdx = output->backFb;
+ while (output->backFb == fbIdx) {
+ drmEventContext drmEvent = {
+ DRM_EVENT_CONTEXT_VERSION,
+ nullptr,
+ pageFlipHandler
+ };
+ // Blocks until there is something to read on the drm fd
+ // and calls back pageFlipHandler once the flip completes.
+ drmHandleEvent(fd(), &drmEvent);
+ }
+}
+
+QLinuxFbDrmScreen::QLinuxFbDrmScreen(const QStringList &args)
+ : m_screenConfig(nullptr),
+ m_device(nullptr)
+{
+ Q_UNUSED(args);
+}
+
+QLinuxFbDrmScreen::~QLinuxFbDrmScreen()
+{
+ if (m_device) {
+ m_device->destroyFramebuffers();
+ m_device->close();
+ delete m_device;
+ }
+ delete m_screenConfig;
+}
+
+bool QLinuxFbDrmScreen::initialize()
+{
+ m_screenConfig = new QKmsScreenConfig;
+ m_device = new QLinuxFbDevice(m_screenConfig);
+ if (!m_device->open())
+ return false;
+
+ // Discover outputs. Calls back Device::createScreen().
+ m_device->createScreens();
+ // Now off to dumb buffer specifics.
+ m_device->createFramebuffers();
+ // Do the modesetting.
+ m_device->setMode();
+
+ QLinuxFbDevice::Output *output(m_device->output(0));
+
+ mGeometry = QRect(QPoint(0, 0), output->currentRes());
+ mDepth = 32;
+ mFormat = QImage::Format_ARGB32;
+ mPhysicalSize = output->kmsOutput.physical_size;
+ qCDebug(qLcFbDrm) << mGeometry << mPhysicalSize;
+
+ QFbScreen::initializeCompositor();
+
+ mCursor = new QFbCursor(this);
+
+ return true;
+}
+
+QRegion QLinuxFbDrmScreen::doRedraw()
+{
+ const QRegion dirty = QFbScreen::doRedraw();
+ if (dirty.isEmpty())
+ return dirty;
+
+ QLinuxFbDevice::Output *output(m_device->output(0));
+
+ for (int i = 0; i < BUFFER_COUNT; ++i)
+ output->dirty[i] += dirty;
+
+ if (output->fb[output->backFb].wrapper.isNull())
+ return dirty;
+
+ QPainter pntr(&output->fb[output->backFb].wrapper);
+ // Image has alpha but no need for blending at this stage.
+ // Do not waste time with the default SourceOver.
+ pntr.setCompositionMode(QPainter::CompositionMode_Source);
+ for (const QRect &rect : qAsConst(output->dirty[output->backFb]))
+ pntr.drawImage(rect, mScreenImage, rect);
+ pntr.end();
+
+ output->dirty[output->backFb] = QRegion();
+
+ m_device->swapBuffers(output);
+
+ return dirty;
+}
+
+QPixmap QLinuxFbDrmScreen::grabWindow(WId wid, int x, int y, int width, int height) const
+{
+ Q_UNUSED(wid);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+
+ return QPixmap();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
new file mode 100644
index 0000000000..50a9576798
--- /dev/null
+++ b/src/plugins/platforms/linuxfb/qlinuxfbdrmscreen.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QLINUXFBDRMSCREEN_H
+#define QLINUXFBDRMSCREEN_H
+
+#include <QtFbSupport/private/qfbscreen_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class QKmsScreenConfig;
+class QLinuxFbDevice;
+
+class QLinuxFbDrmScreen : public QFbScreen
+{
+ Q_OBJECT
+public:
+ QLinuxFbDrmScreen(const QStringList &args);
+ ~QLinuxFbDrmScreen();
+
+ bool initialize() override;
+ QRegion doRedraw() override;
+ QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
+
+private:
+ QKmsScreenConfig *m_screenConfig;
+ QLinuxFbDevice *m_device;
+};
+
+QT_END_NAMESPACE
+
+#endif // QLINUXFBDRMSCREEN_H
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
index c1c235588e..ce193bdf90 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
@@ -39,6 +39,9 @@
#include "qlinuxfbintegration.h"
#include "qlinuxfbscreen.h"
+#if QT_CONFIG(kms)
+#include "qlinuxfbdrmscreen.h"
+#endif
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
#include <QtServiceSupport/private/qgenericunixservices_p.h>
@@ -69,10 +72,16 @@
QT_BEGIN_NAMESPACE
QLinuxFbIntegration::QLinuxFbIntegration(const QStringList &paramList)
- : m_fontDb(new QGenericUnixFontDatabase),
+ : m_primaryScreen(nullptr),
+ m_fontDb(new QGenericUnixFontDatabase),
m_services(new QGenericUnixServices)
{
- m_primaryScreen = new QLinuxFbScreen(paramList);
+#if QT_CONFIG(kms)
+ if (qEnvironmentVariableIntValue("QT_QPA_FB_DRM") != 0)
+ m_primaryScreen = new QLinuxFbDrmScreen(paramList);
+#endif
+ if (!m_primaryScreen)
+ m_primaryScreen = new QLinuxFbScreen(paramList);
}
QLinuxFbIntegration::~QLinuxFbIntegration()
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
index e48a1bae28..9934a8cd54 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbintegration.h
@@ -46,7 +46,7 @@
QT_BEGIN_NAMESPACE
class QAbstractEventDispatcher;
-class QLinuxFbScreen;
+class QFbScreen;
class QFbVtHandler;
class QLinuxFbIntegration : public QPlatformIntegration, public QPlatformNativeInterface
@@ -74,7 +74,7 @@ public:
private:
void createInputHandlers();
- QLinuxFbScreen *m_primaryScreen;
+ QFbScreen *m_primaryScreen;
QPlatformInputContext *m_inputContext;
QScopedPointer<QPlatformFontDatabase> m_fontDb;
QScopedPointer<QPlatformServices> m_services;
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index 246c959fd3..dc7ea08dc5 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -414,7 +414,7 @@ QRegion QLinuxFbScreen::doRedraw()
mBlitter->setCompositionMode(QPainter::CompositionMode_Source);
for (const QRect &rect : touched)
- mBlitter->drawImage(rect, *mScreenImage, rect);
+ mBlitter->drawImage(rect, mScreenImage, rect);
return touched;
}
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
index 1e98191569..c7ce455e6a 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.h
@@ -54,11 +54,11 @@ public:
QLinuxFbScreen(const QStringList &args);
~QLinuxFbScreen();
- bool initialize();
+ bool initialize() override;
- QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
+ QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
- QRegion doRedraw() Q_DECL_OVERRIDE;
+ QRegion doRedraw() override;
private:
QStringList mArgs;
diff --git a/src/plugins/platforms/minimal/qminimalintegration.cpp b/src/plugins/platforms/minimal/qminimalintegration.cpp
index 03c72502cb..aa0037f187 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.cpp
+++ b/src/plugins/platforms/minimal/qminimalintegration.cpp
@@ -44,12 +44,19 @@
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformwindow.h>
-#if defined(Q_OS_WIN)
#include <QtFontDatabaseSupport/private/qbasicfontdatabase_p.h>
+#if defined(Q_OS_WINRT)
+# include <QtFontDatabaseSupport/private/qwinrtfontdatabase_p.h>
+#elif defined(Q_OS_WIN)
+# include <QtFontDatabaseSupport/private/qwindowsfontdatabase_p.h>
+# if QT_CONFIG(freetype)
+# include <QtFontDatabaseSupport/private/qwindowsfontdatabase_ft_p.h>
+# endif
+#elif defined(Q_OS_DARWIN)
+# include <QtFontDatabaseSupport/private/qcoretextfontdatabase_p.h>
#elif QT_CONFIG(fontconfig)
-#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
-#else
-#include <qpa/qplatformfontdatabase.h>
+# include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
+# include <qpa/qplatformfontdatabase.h>
#endif
#if !defined(Q_OS_WIN)
@@ -70,6 +77,8 @@ static inline unsigned parseOptions(const QStringList &paramList)
for (const QString &param : paramList) {
if (param == QLatin1String("enable_fonts"))
options |= QMinimalIntegration::EnableFonts;
+ else if (param == QLatin1String("freetype"))
+ options |= QMinimalIntegration::FreeTypeFontDatabase;
}
return options;
}
@@ -117,12 +126,23 @@ public:
QPlatformFontDatabase *QMinimalIntegration::fontDatabase() const
{
- if (m_options & EnableFonts) {
+ if (!m_fontDatabase && (m_options & EnableFonts)) {
#if QT_CONFIG(fontconfig)
- if (!m_fontDatabase)
- m_fontDatabase = new QGenericUnixFontDatabase;
+ m_fontDatabase = new QGenericUnixFontDatabase;
+#elif defined(Q_OS_WINRT)
+ m_fontDatabase = new QWinRTFontDatabase;
+#elif defined(Q_OS_WIN)
+ if (m_options & FreeTypeFontDatabase) {
+# if QT_CONFIG(freetype)
+ m_fontDatabase = new QWindowsFontDatabaseFT;
+# endif // freetype
+ } else {
+ m_fontDatabase = new QWindowsFontDatabase;
+ }
+#elif defined(Q_OS_DARWIN)
+ m_fontDatabase = new QCoreTextFontDatabase;
#else
- return QPlatformIntegration::fontDatabase();
+ m_fontDatabase = QPlatformIntegration::fontDatabase();
#endif
}
if (!m_fontDatabase)
diff --git a/src/plugins/platforms/minimal/qminimalintegration.h b/src/plugins/platforms/minimal/qminimalintegration.h
index 755664d14d..eaa2f228c5 100644
--- a/src/plugins/platforms/minimal/qminimalintegration.h
+++ b/src/plugins/platforms/minimal/qminimalintegration.h
@@ -67,7 +67,8 @@ class QMinimalIntegration : public QPlatformIntegration
public:
enum Options { // Options to be passed on command line or determined from environment
DebugBackingStore = 0x1,
- EnableFonts = 0x2
+ EnableFonts = 0x2,
+ FreeTypeFontDatabase = 0x4
};
explicit QMinimalIntegration(const QStringList &parameters);
diff --git a/src/plugins/platforms/minimalegl/minimalegl.pro b/src/plugins/platforms/minimalegl/minimalegl.pro
index 88466e7f36..b7dde9069f 100644
--- a/src/plugins/platforms/minimalegl/minimalegl.pro
+++ b/src/plugins/platforms/minimalegl/minimalegl.pro
@@ -14,14 +14,17 @@ DEFINES += QT_EGL_NO_X11
SOURCES = main.cpp \
qminimaleglintegration.cpp \
qminimaleglwindow.cpp \
- qminimaleglbackingstore.cpp \
qminimaleglscreen.cpp
HEADERS = qminimaleglintegration.h \
qminimaleglwindow.h \
- qminimaleglbackingstore.h \
qminimaleglscreen.h
+qtConfig(opengl) {
+ SOURCES += qminimaleglbackingstore.cpp
+ HEADERS += qminimaleglbackingstore.h
+}
+
CONFIG += egl
OTHER_FILES += \
diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp
index c564e1e431..81512b1561 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.cpp
@@ -40,8 +40,9 @@
#include "qminimaleglintegration.h"
#include "qminimaleglwindow.h"
-#include "qminimaleglbackingstore.h"
-
+#ifndef QT_NO_OPENGL
+# include "qminimaleglbackingstore.h"
+#endif
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
#if defined(Q_OS_UNIX)
@@ -127,13 +128,18 @@ QPlatformBackingStore *QMinimalEglIntegration::createPlatformBackingStore(QWindo
#ifdef QEGL_EXTRA_DEBUG
qWarning("QMinimalEglIntegration::createWindowSurface %p\n", window);
#endif
+#ifndef QT_NO_OPENGL
return new QMinimalEglBackingStore(window);
+#else
+ return nullptr;
+#endif
}
-
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QMinimalEglIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
return static_cast<QMinimalEglScreen *>(context->screen()->handle())->platformContext();
}
+#endif
QPlatformFontDatabase *QMinimalEglIntegration::fontDatabase() const
{
diff --git a/src/plugins/platforms/minimalegl/qminimaleglintegration.h b/src/plugins/platforms/minimalegl/qminimaleglintegration.h
index 529e89f85a..d0ab75bd3c 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglintegration.h
+++ b/src/plugins/platforms/minimalegl/qminimaleglintegration.h
@@ -55,8 +55,9 @@ public:
QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
-
+#endif
QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
index d3d091fab7..0175d2dbdd 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
+++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.cpp
@@ -41,7 +41,9 @@
#include "qminimaleglwindow.h"
#include <QtEglSupport/private/qeglconvenience_p.h>
-#include <QtEglSupport/private/qeglplatformcontext_p.h>
+#ifndef QT_NO_OPENGL
+# include <QtEglSupport/private/qeglplatformcontext_p.h>
+#endif
#ifdef Q_OPENKODE
#include <KD/kd.h>
@@ -52,6 +54,8 @@ QT_BEGIN_NAMESPACE
// #define QEGL_EXTRA_DEBUG
+#ifndef QT_NO_OPENGL
+
class QMinimalEglContext : public QEGLPlatformContext
{
public:
@@ -68,6 +72,8 @@ public:
}
};
+#endif
+
QMinimalEglScreen::QMinimalEglScreen(EGLNativeDisplayType display)
: m_depth(32)
, m_format(QImage::Format_Invalid)
@@ -161,9 +167,10 @@ void QMinimalEglScreen::createAndSetPlatformContext()
}
// qWarning("Created surface %dx%d\n", w, h);
+#ifndef QT_NO_OPENGL
QEGLPlatformContext *platformContext = new QMinimalEglContext(platformFormat, 0, m_dpy);
m_platformContext = platformContext;
-
+#endif
EGLint w,h; // screen size detection
eglQuerySurface(m_dpy, m_surface, EGL_WIDTH, &w);
eglQuerySurface(m_dpy, m_surface, EGL_HEIGHT, &h);
@@ -191,6 +198,7 @@ QImage::Format QMinimalEglScreen::format() const
createAndSetPlatformContext();
return m_format;
}
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QMinimalEglScreen::platformContext() const
{
if (!m_platformContext) {
@@ -199,5 +207,5 @@ QPlatformOpenGLContext *QMinimalEglScreen::platformContext() const
}
return m_platformContext;
}
-
+#endif
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/minimalegl/qminimaleglscreen.h b/src/plugins/platforms/minimalegl/qminimaleglscreen.h
index ba605835a8..24098b8127 100644
--- a/src/plugins/platforms/minimalegl/qminimaleglscreen.h
+++ b/src/plugins/platforms/minimalegl/qminimaleglscreen.h
@@ -59,9 +59,9 @@ public:
QRect geometry() const Q_DECL_OVERRIDE;
int depth() const Q_DECL_OVERRIDE;
QImage::Format format() const Q_DECL_OVERRIDE;
-
+#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *platformContext() const;
-
+#endif
EGLSurface surface() const { return m_surface; }
private:
diff --git a/src/plugins/platforms/mirclient/mirclient.pro b/src/plugins/platforms/mirclient/mirclient.pro
index 0ba63601a9..d2da7e6ca0 100644
--- a/src/plugins/platforms/mirclient/mirclient.pro
+++ b/src/plugins/platforms/mirclient/mirclient.pro
@@ -5,6 +5,9 @@ QT += \
theme_support-private eventdispatcher_support-private \
fontdatabase_support-private egl_support-private
+qtHaveModule(linuxaccessibility_support-private): \
+ QT += linuxaccessibility_support-private
+
DEFINES += MESA_EGL_NO_X11_HEADERS
# CONFIG += c++11 # only enables C++0x
QMAKE_CXXFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -std=c++11 -Werror -Wall
@@ -13,9 +16,12 @@ QMAKE_LFLAGS += -std=c++11 -Wl,-no-undefined
QMAKE_USE_PRIVATE += mirclient
SOURCES = \
+ qmirclientappstatecontroller.cpp \
qmirclientbackingstore.cpp \
qmirclientclipboard.cpp \
qmirclientcursor.cpp \
+ qmirclientdebugextension.cpp \
+ qmirclientdesktopwindow.cpp \
qmirclientglcontext.cpp \
qmirclientinput.cpp \
qmirclientintegration.cpp \
@@ -23,13 +29,17 @@ SOURCES = \
qmirclientplatformservices.cpp \
qmirclientplugin.cpp \
qmirclientscreen.cpp \
+ qmirclientscreenobserver.cpp \
qmirclienttheme.cpp \
qmirclientwindow.cpp
HEADERS = \
+ qmirclientappstatecontroller.h \
qmirclientbackingstore.h \
qmirclientclipboard.h \
qmirclientcursor.h \
+ qmirclientdebugextension.h \
+ qmirclientdesktopwindow.h \
qmirclientglcontext.h \
qmirclientinput.h \
qmirclientintegration.h \
@@ -39,9 +49,17 @@ HEADERS = \
qmirclientplatformservices.h \
qmirclientplugin.h \
qmirclientscreen.h \
+ qmirclientscreenobserver.h \
qmirclienttheme.h \
qmirclientwindow.h
+# libxkbcommon
+!qtConfig(xkbcommon-system) {
+ include(../../../3rdparty/xkbcommon.pri)
+} else {
+ QMAKE_USE += xkbcommon
+}
+
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = MirServerIntegrationPlugin
!equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = -
diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp
new file mode 100644
index 0000000000..69fc9b7aa7
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientappstatecontroller.h"
+
+#include <qpa/qwindowsysteminterface.h>
+
+/*
+ * QMirClientAppStateController - updates Qt's QApplication::applicationState property.
+ *
+ * Tries to avoid active-inactive-active invocations using a timer. The rapid state
+ * change can confuse some applications.
+ */
+
+QMirClientAppStateController::QMirClientAppStateController()
+ : m_suspended(false)
+ , m_lastActive(true)
+{
+ m_inactiveTimer.setSingleShot(true);
+ m_inactiveTimer.setInterval(10);
+ QObject::connect(&m_inactiveTimer, &QTimer::timeout, []()
+ {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ });
+}
+
+void QMirClientAppStateController::setSuspended()
+{
+ m_inactiveTimer.stop();
+ if (!m_suspended) {
+ m_suspended = true;
+
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
+ }
+}
+
+void QMirClientAppStateController::setResumed()
+{
+ m_inactiveTimer.stop();
+ if (m_suspended) {
+ m_suspended = false;
+
+ if (m_lastActive) {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
+ } else {
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
+ }
+ }
+}
+
+void QMirClientAppStateController::setWindowFocused(bool focused)
+{
+ if (m_suspended) {
+ return;
+ }
+
+ if (focused) {
+ m_inactiveTimer.stop();
+ QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
+ } else {
+ m_inactiveTimer.start();
+ }
+
+ m_lastActive = focused;
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h
new file mode 100644
index 0000000000..b3aa0022d9
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientappstatecontroller.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTAPPSTATECONTROLLER_H
+#define QMIRCLIENTAPPSTATECONTROLLER_H
+
+#include <QTimer>
+
+class QMirClientAppStateController
+{
+public:
+ QMirClientAppStateController();
+
+ void setSuspended();
+ void setResumed();
+
+ void setWindowFocused(bool focused);
+
+private:
+ bool m_suspended;
+ bool m_lastActive;
+ QTimer m_inactiveTimer;
+};
+
+#endif // QMIRCLIENTAPPSTATECONTROLLER_H
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
index a4bb8864ab..51363619d9 100644
--- a/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientbackingstore.cpp
@@ -61,6 +61,7 @@ QMirClientBackingStore::QMirClientBackingStore(QWindow* window)
QMirClientBackingStore::~QMirClientBackingStore()
{
+ mContext->makeCurrent(window()); // needed as QOpenGLTexture destructor assumes current context
}
void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const QPoint& offset)
@@ -76,7 +77,6 @@ void QMirClientBackingStore::flush(QWindow* window, const QRegion& region, const
mBlitter->create();
mBlitter->bind();
- mBlitter->setRedBlueSwizzle(true);
mBlitter->blit(mTexture->textureId(), QMatrix4x4(), QOpenGLTextureBlitter::OriginTopLeft);
mBlitter->release();
@@ -137,7 +137,9 @@ void QMirClientBackingStore::beginPaint(const QRegion& region)
void QMirClientBackingStore::resize(const QSize& size, const QRegion& /*staticContents*/)
{
- mImage = QImage(size, QImage::Format_RGB32);
+ mImage = QImage(size, QImage::Format_RGBA8888);
+
+ mContext->makeCurrent(window());
if (mTexture->isCreated())
mTexture->destroy();
@@ -147,3 +149,9 @@ QPaintDevice* QMirClientBackingStore::paintDevice()
{
return &mImage;
}
+
+QImage QMirClientBackingStore::toImage() const
+{
+ // used by QPlatformBackingStore::composeAndFlush
+ return mImage;
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientbackingstore.h b/src/plugins/platforms/mirclient/qmirclientbackingstore.h
index 0c75e182ff..7644c77df2 100644
--- a/src/plugins/platforms/mirclient/qmirclientbackingstore.h
+++ b/src/plugins/platforms/mirclient/qmirclientbackingstore.h
@@ -58,6 +58,7 @@ public:
void flush(QWindow* window, const QRegion& region, const QPoint& offset) override;
void resize(const QSize& size, const QRegion& staticContents) override;
QPaintDevice* paintDevice() override;
+ QImage toImage() const override;
protected:
void updateTexture();
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
index 4dff339f21..b9fc9b3b42 100644
--- a/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientclipboard.cpp
@@ -39,41 +39,36 @@
#include "qmirclientclipboard.h"
+#include "qmirclientlogging.h"
+#include "qmirclientwindow.h"
+#include <QDBusPendingCallWatcher>
+#include <QGuiApplication>
+#include <QSignalBlocker>
#include <QtCore/QMimeData>
#include <QtCore/QStringList>
-#include <QDBusInterface>
-#include <QDBusPendingCallWatcher>
-#include <QDBusPendingReply>
-
-// FIXME(loicm) The clipboard data format is not defined by Ubuntu Platform API
-// which makes it impossible to have non-Qt applications communicate with Qt
-// applications through the clipboard API. The solution would be to have
-// Ubuntu Platform define the data format or propose an API that supports
-// embedding different mime types in the clipboard.
-// Data format:
-// number of mime types (sizeof(int))
-// data layout ((4 * sizeof(int)) * number of mime types)
-// mime type string offset (sizeof(int))
-// mime type string size (sizeof(int))
-// data offset (sizeof(int))
-// data size (sizeof(int))
-// data (n bytes)
+// content-hub
+#include <com/ubuntu/content/hub.h>
-namespace {
-
-const int maxFormatsCount = 16;
-const int maxBufferSize = 4 * 1024 * 1024; // 4 Mb
-
-}
+// get this cumbersome nested namespace out of the way
+using namespace com::ubuntu::content;
QMirClientClipboard::QMirClientClipboard()
: mMimeData(new QMimeData)
- , mIsOutdated(true)
- , mUpdatesDisabled(false)
- , mDBusSetupDone(false)
+ , mContentHub(Hub::Client::instance())
{
+ connect(mContentHub, &Hub::pasteboardChanged, this, [this]() {
+ if (mClipboardState == QMirClientClipboard::SyncedClipboard) {
+ mClipboardState = QMirClientClipboard::OutdatedClipboard;
+ emitChanged(QClipboard::Clipboard);
+ }
+ });
+
+ connect(qGuiApp, &QGuiApplication::applicationStateChanged,
+ this, &QMirClientClipboard::onApplicationStateChanged);
+
+ requestMimeData();
}
QMirClientClipboard::~QMirClientClipboard()
@@ -81,236 +76,106 @@ QMirClientClipboard::~QMirClientClipboard()
delete mMimeData;
}
-void QMirClientClipboard::requestDBusClipboardContents()
+QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode)
{
- if (!mDBusSetupDone) {
- setupDBus();
- }
-
- if (!mPendingGetContentsCall.isNull())
- return;
+ if (mode != QClipboard::Clipboard)
+ return nullptr;
- QDBusPendingCall pendingCall = mDBusClipboard->asyncCall(QStringLiteral("GetContents"));
+ // Blocks dataChanged() signal from being emitted. Makes no sense to emit it from
+ // inside the data getter.
+ const QSignalBlocker blocker(this);
- mPendingGetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
+ if (mClipboardState == OutdatedClipboard) {
+ updateMimeData();
+ } else if (mClipboardState == SyncingClipboard) {
+ mPasteReply->waitForFinished();
+ }
- QObject::connect(mPendingGetContentsCall.data(), &QDBusPendingCallWatcher::finished,
- this, &QMirClientClipboard::onDBusClipboardGetContentsFinished);
+ return mMimeData;
}
-void QMirClientClipboard::onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher* call)
+void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
{
- Q_ASSERT(call == mPendingGetContentsCall.data());
+ QWindow *focusWindow = QGuiApplication::focusWindow();
+ if (focusWindow && mode == QClipboard::Clipboard && mimeData != nullptr) {
+ QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
- QDBusPendingReply<QByteArray> reply = *call;
- if (Q_UNLIKELY(reply.isError())) {
- qCritical("QMirClientClipboard - Failed to get system clipboard contents via D-Bus. %s, %s",
- qPrintable(reply.error().name()), qPrintable(reply.error().message()));
- // TODO: Might try again later a number of times...
- } else {
- QByteArray serializedMimeData = reply.argumentAt<0>();
- updateMimeData(serializedMimeData);
- }
- call->deleteLater();
-}
+ QDBusPendingCall reply = mContentHub->createPaste(surfaceId, *mimeData);
-void QMirClientClipboard::onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher *call)
-{
- QDBusPendingReply<void> reply = *call;
- if (Q_UNLIKELY(reply.isError())) {
- qCritical("QMirClientClipboard - Failed to set the system clipboard contents via D-Bus. %s, %s",
- qPrintable(reply.error().name()), qPrintable(reply.error().message()));
- // TODO: Might try again later a number of times...
- }
- call->deleteLater();
-}
-
-void QMirClientClipboard::updateMimeData(const QByteArray &serializedMimeData)
-{
- if (mUpdatesDisabled)
- return;
+ // Don't care whether it succeeded
+ QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
+ connect(watcher, &QDBusPendingCallWatcher::finished,
+ watcher, &QObject::deleteLater);
- QMimeData *newMimeData = deserializeMimeData(serializedMimeData);
- if (newMimeData) {
- delete mMimeData;
- mMimeData = newMimeData;
- mIsOutdated = false;
+ mMimeData = mimeData;
+ mClipboardState = SyncedClipboard;
emitChanged(QClipboard::Clipboard);
- } else {
- qWarning("QMirClientClipboard - Got invalid serialized mime data. Ignoring it.");
}
}
-void QMirClientClipboard::setupDBus()
-{
- QDBusConnection dbusConnection = QDBusConnection::sessionBus();
-
- bool ok = dbusConnection.connect(
- QStringLiteral("com.canonical.QtMir"),
- QStringLiteral("/com/canonical/QtMir/Clipboard"),
- QStringLiteral("com.canonical.QtMir.Clipboard"),
- QStringLiteral("ContentsChanged"),
- this, SLOT(updateMimeData(QByteArray)));
- if (Q_UNLIKELY(!ok))
- qCritical("QMirClientClipboard - Failed to connect to ContentsChanged signal form the D-Bus system clipboard.");
-
- mDBusClipboard = new QDBusInterface(QStringLiteral("com.canonical.QtMir"),
- QStringLiteral("/com/canonical/QtMir/Clipboard"),
- QStringLiteral("com.canonical.QtMir.Clipboard"),
- dbusConnection);
-
- mDBusSetupDone = true;
-}
-
-QByteArray QMirClientClipboard::serializeMimeData(QMimeData *mimeData) const
+bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const
{
- Q_ASSERT(mimeData != nullptr);
-
- const QStringList formats = mimeData->formats();
- const int formatCount = qMin(formats.size(), maxFormatsCount);
- const int headerSize = sizeof(int) + (formatCount * 4 * sizeof(int));
- int bufferSize = headerSize;
-
- for (int i = 0; i < formatCount; i++)
- bufferSize += formats[i].size() + mimeData->data(formats[i]).size();
-
- QByteArray serializedMimeData;
- if (bufferSize <= maxBufferSize) {
- // Serialize data.
- serializedMimeData.resize(bufferSize);
- {
- char *buffer = serializedMimeData.data();
- int* header = reinterpret_cast<int*>(serializedMimeData.data());
- int offset = headerSize;
- header[0] = formatCount;
- for (int i = 0; i < formatCount; i++) {
- const QByteArray data = mimeData->data(formats[i]);
- const int formatOffset = offset;
- const int formatSize = formats[i].size();
- const int dataOffset = offset + formatSize;
- const int dataSize = data.size();
- memcpy(&buffer[formatOffset], formats[i].toLatin1().data(), formatSize);
- memcpy(&buffer[dataOffset], data.data(), dataSize);
- header[i*4+1] = formatOffset;
- header[i*4+2] = formatSize;
- header[i*4+3] = dataOffset;
- header[i*4+4] = dataSize;
- offset += formatSize + dataSize;
- }
- }
- } else {
- qWarning("QMirClientClipboard: Not sending contents (%d bytes) to the global clipboard as it's"
- " bigger than the maximum allowed size of %d bytes", bufferSize, maxBufferSize);
- }
-
- return serializedMimeData;
+ return mode == QClipboard::Clipboard;
}
-QMimeData *QMirClientClipboard::deserializeMimeData(const QByteArray &serializedMimeData) const
+bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const
{
- if (static_cast<std::size_t>(serializedMimeData.size()) < sizeof(int)) {
- // Data is invalid
- return nullptr;
- }
-
- QMimeData *mimeData = new QMimeData;
-
- const char* const buffer = serializedMimeData.constData();
- const int* const header = reinterpret_cast<const int*>(serializedMimeData.constData());
-
- const int count = qMin(header[0], maxFormatsCount);
-
- for (int i = 0; i < count; i++) {
- const int formatOffset = header[i*4+1];
- const int formatSize = header[i*4+2];
- const int dataOffset = header[i*4+3];
- const int dataSize = header[i*4+4];
-
- if (formatOffset + formatSize <= serializedMimeData.size()
- && dataOffset + dataSize <= serializedMimeData.size()) {
-
- QString mimeType = QString::fromLatin1(&buffer[formatOffset], formatSize);
- QByteArray mimeDataBytes(&buffer[dataOffset], dataSize);
-
- mimeData->setData(mimeType, mimeDataBytes);
- }
- }
-
- return mimeData;
+ Q_UNUSED(mode);
+ return false;
}
-QMimeData* QMirClientClipboard::mimeData(QClipboard::Mode mode)
+void QMirClientClipboard::onApplicationStateChanged(Qt::ApplicationState state)
{
- if (mode != QClipboard::Clipboard)
- return nullptr;
-
- if (mIsOutdated && mPendingGetContentsCall.isNull()) {
- requestDBusClipboardContents();
+ if (state == Qt::ApplicationActive) {
+ // Only focused or active applications might be allowed to paste, so we probably
+ // missed changes in the clipboard while we were hidden, inactive or, more importantly,
+ // suspended.
+ requestMimeData();
}
-
- // Return whatever we have at the moment instead of blocking until we have something.
- //
- // This might be called during app startup just for the sake of checking if some
- // "Paste" UI control should be enabled or not.
- // We will emit QClipboard::changed() once we finally have something.
- return mMimeData;
}
-void QMirClientClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode)
+void QMirClientClipboard::updateMimeData()
{
- if (mode != QClipboard::Clipboard)
+ if (qGuiApp->applicationState() != Qt::ApplicationActive) {
+ // Don't even bother asking as content-hub would probably ignore our request (and should).
return;
-
- if (!mPendingGetContentsCall.isNull()) {
- // Ignore whatever comes from the system clipboard as we are going to change it anyway
- QObject::disconnect(mPendingGetContentsCall.data(), 0, this, 0);
- mUpdatesDisabled = true;
- mPendingGetContentsCall->waitForFinished();
- mUpdatesDisabled = false;
- delete mPendingGetContentsCall.data();
}
- if (mimeData != nullptr) {
- QByteArray serializedMimeData = serializeMimeData(mimeData);
- if (!serializedMimeData.isEmpty()) {
- setDBusClipboardContents(serializedMimeData);
- }
+ delete mMimeData;
- mMimeData = mimeData;
+ QWindow *focusWindow = QGuiApplication::focusWindow();
+ if (focusWindow) {
+ QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
+ mMimeData = mContentHub->latestPaste(surfaceId);
+ mClipboardState = SyncedClipboard;
emitChanged(QClipboard::Clipboard);
}
}
-bool QMirClientClipboard::supportsMode(QClipboard::Mode mode) const
-{
- return mode == QClipboard::Clipboard;
-}
-
-bool QMirClientClipboard::ownsMode(QClipboard::Mode mode) const
+void QMirClientClipboard::requestMimeData()
{
- Q_UNUSED(mode);
- return false;
-}
-
-void QMirClientClipboard::setDBusClipboardContents(const QByteArray &clipboardContents)
-{
- if (!mDBusSetupDone) {
- setupDBus();
+ if (qGuiApp->applicationState() != Qt::ApplicationActive) {
+ // Don't even bother asking as content-hub would probably ignore our request (and should).
+ return;
}
- if (!mPendingSetContentsCall.isNull()) {
- // Ignore any previous set call as we are going to overwrite it anyway
- QObject::disconnect(mPendingSetContentsCall.data(), 0, this, 0);
- mUpdatesDisabled = true;
- mPendingSetContentsCall->waitForFinished();
- mUpdatesDisabled = false;
- delete mPendingSetContentsCall.data();
+ QWindow *focusWindow = QGuiApplication::focusWindow();
+ if (!focusWindow) {
+ return;
}
- QDBusPendingCall pendingCall = mDBusClipboard->asyncCall(QStringLiteral("SetContents"), clipboardContents);
-
- mPendingSetContentsCall = new QDBusPendingCallWatcher(pendingCall, this);
+ QString surfaceId = static_cast<QMirClientWindow*>(focusWindow->handle())->persistentSurfaceId();
+ QDBusPendingCall reply = mContentHub->requestLatestPaste(surfaceId);
+ mClipboardState = SyncingClipboard;
- QObject::connect(mPendingSetContentsCall.data(), &QDBusPendingCallWatcher::finished,
- this, &QMirClientClipboard::onDBusClipboardSetContentsFinished);
+ mPasteReply = new QDBusPendingCallWatcher(reply, this);
+ connect(mPasteReply, &QDBusPendingCallWatcher::finished,
+ this, [this]() {
+ delete mMimeData;
+ mMimeData = mContentHub->paste(*mPasteReply);
+ mClipboardState = SyncedClipboard;
+ mPasteReply->deleteLater();
+ mPasteReply = nullptr;
+ emitChanged(QClipboard::Clipboard);
+ });
}
diff --git a/src/plugins/platforms/mirclient/qmirclientclipboard.h b/src/plugins/platforms/mirclient/qmirclientclipboard.h
index 1394498320..09e9bcdf38 100644
--- a/src/plugins/platforms/mirclient/qmirclientclipboard.h
+++ b/src/plugins/platforms/mirclient/qmirclientclipboard.h
@@ -45,7 +45,15 @@
#include <QMimeData>
#include <QPointer>
-class QDBusInterface;
+
+namespace com {
+ namespace ubuntu {
+ namespace content {
+ class Hub;
+ }
+ }
+}
+
class QDBusPendingCallWatcher;
class QMirClientClipboard : public QObject, public QPlatformClipboard
@@ -61,31 +69,24 @@ public:
bool supportsMode(QClipboard::Mode mode) const override;
bool ownsMode(QClipboard::Mode mode) const override;
- void requestDBusClipboardContents();
-
private Q_SLOTS:
- void onDBusClipboardGetContentsFinished(QDBusPendingCallWatcher*);
- void onDBusClipboardSetContentsFinished(QDBusPendingCallWatcher*);
- void updateMimeData(const QByteArray &serializedMimeData);
+ void onApplicationStateChanged(Qt::ApplicationState state);
private:
- void setupDBus();
-
- QByteArray serializeMimeData(QMimeData *mimeData) const;
- QMimeData *deserializeMimeData(const QByteArray &serializedMimeData) const;
-
- void setDBusClipboardContents(const QByteArray &clipboardContents);
+ void updateMimeData();
+ void requestMimeData();
QMimeData *mMimeData;
- bool mIsOutdated;
- QPointer<QDBusInterface> mDBusClipboard;
+ enum {
+ OutdatedClipboard, // Our mimeData is outdated, need to fetch latest from ContentHub
+ SyncingClipboard, // Our mimeData is outdated and we are waiting for ContentHub to reply with the latest paste
+ SyncedClipboard // Our mimeData is in sync with what ContentHub has
+ } mClipboardState{OutdatedClipboard};
- QPointer<QDBusPendingCallWatcher> mPendingGetContentsCall;
- QPointer<QDBusPendingCallWatcher> mPendingSetContentsCall;
+ com::ubuntu::content::Hub *mContentHub;
- bool mUpdatesDisabled;
- bool mDBusSetupDone;
+ QDBusPendingCallWatcher *mPasteReply{nullptr};
};
#endif // QMIRCLIENTCLIPBOARD_H
diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.cpp b/src/plugins/platforms/mirclient/qmirclientcursor.cpp
index a0da3fdd77..812cde95c6 100644
--- a/src/plugins/platforms/mirclient/qmirclientcursor.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientcursor.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 Canonical, Ltd.
+** Copyright (C) 2015-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -45,35 +45,41 @@
#include <mir_toolkit/mir_client_library.h>
+Q_LOGGING_CATEGORY(mirclientCursor, "qt.qpa.mirclient.cursor", QtWarningMsg)
+
QMirClientCursor::QMirClientCursor(MirConnection *connection)
: mConnection(connection)
{
- mShapeToCursorName[Qt::ArrowCursor] = "left_ptr";
+ /*
+ * TODO: Add the missing cursors to Mir (LP: #1388987)
+ * Those are the ones without a mir_ prefix, which are X11 cursors
+ * and won't be understood by any shell other than Unity8.
+ */
+ mShapeToCursorName[Qt::ArrowCursor] = mir_arrow_cursor_name;
mShapeToCursorName[Qt::UpArrowCursor] = "up_arrow";
- mShapeToCursorName[Qt::CrossCursor] = "cross";
- mShapeToCursorName[Qt::WaitCursor] = "watch";
- mShapeToCursorName[Qt::IBeamCursor] = "xterm";
- mShapeToCursorName[Qt::SizeVerCursor] = "size_ver";
- mShapeToCursorName[Qt::SizeHorCursor] = "size_hor";
- mShapeToCursorName[Qt::SizeBDiagCursor] = "size_bdiag";
- mShapeToCursorName[Qt::SizeFDiagCursor] = "size_fdiag";
- mShapeToCursorName[Qt::SizeAllCursor] = "size_all";
- mShapeToCursorName[Qt::BlankCursor] = "blank";
- mShapeToCursorName[Qt::SplitVCursor] = "split_v";
- mShapeToCursorName[Qt::SplitHCursor] = "split_h";
- mShapeToCursorName[Qt::PointingHandCursor] = "hand";
+ mShapeToCursorName[Qt::CrossCursor] = mir_crosshair_cursor_name;
+ mShapeToCursorName[Qt::WaitCursor] = mir_busy_cursor_name;
+ mShapeToCursorName[Qt::IBeamCursor] = mir_caret_cursor_name;
+ mShapeToCursorName[Qt::SizeVerCursor] = mir_vertical_resize_cursor_name;
+ mShapeToCursorName[Qt::SizeHorCursor] = mir_horizontal_resize_cursor_name;
+ mShapeToCursorName[Qt::SizeBDiagCursor] = mir_diagonal_resize_bottom_to_top_cursor_name;
+ mShapeToCursorName[Qt::SizeFDiagCursor] = mir_diagonal_resize_top_to_bottom_cursor_name;
+ mShapeToCursorName[Qt::SizeAllCursor] = mir_omnidirectional_resize_cursor_name;
+ mShapeToCursorName[Qt::BlankCursor] = mir_disabled_cursor_name;
+ mShapeToCursorName[Qt::SplitVCursor] = mir_vsplit_resize_cursor_name;
+ mShapeToCursorName[Qt::SplitHCursor] = mir_hsplit_resize_cursor_name;
+ mShapeToCursorName[Qt::PointingHandCursor] = mir_pointing_hand_cursor_name;
mShapeToCursorName[Qt::ForbiddenCursor] = "forbidden";
mShapeToCursorName[Qt::WhatsThisCursor] = "whats_this";
mShapeToCursorName[Qt::BusyCursor] = "left_ptr_watch";
- mShapeToCursorName[Qt::OpenHandCursor] = "openhand";
- mShapeToCursorName[Qt::ClosedHandCursor] = "closedhand";
+ mShapeToCursorName[Qt::OpenHandCursor] = mir_open_hand_cursor_name;
+ mShapeToCursorName[Qt::ClosedHandCursor] = mir_closed_hand_cursor_name;
mShapeToCursorName[Qt::DragCopyCursor] = "dnd-copy";
mShapeToCursorName[Qt::DragMoveCursor] = "dnd-move";
mShapeToCursorName[Qt::DragLinkCursor] = "dnd-link";
}
namespace {
-#if !defined(QT_NO_DEBUG)
const char *qtCursorShapeToStr(Qt::CursorShape shape)
{
switch (shape) {
@@ -127,7 +133,6 @@ const char *qtCursorShapeToStr(Qt::CursorShape shape)
return "???";
}
}
-#endif // !defined(QT_NO_DEBUG)
} // anonymous namespace
void QMirClientCursor::changeCursor(QCursor *windowCursor, QWindow *window)
@@ -144,7 +149,7 @@ void QMirClientCursor::changeCursor(QCursor *windowCursor, QWindow *window)
if (windowCursor) {
- DLOG("[ubuntumirclient QPA] changeCursor shape=%s, window=%p\n", qtCursorShapeToStr(windowCursor->shape()), window);
+ qCDebug(mirclientCursor, "changeCursor shape=%s, window=%p", qtCursorShapeToStr(windowCursor->shape()), window);
if (!windowCursor->pixmap().isNull()) {
configureMirCursorWithPixmapQCursor(surface, *windowCursor);
} else if (windowCursor->shape() == Qt::BitmapCursor) {
diff --git a/src/plugins/platforms/mirclient/qmirclientcursor.h b/src/plugins/platforms/mirclient/qmirclientcursor.h
index 4ecc3d97ee..c5de23b272 100644
--- a/src/plugins/platforms/mirclient/qmirclientcursor.h
+++ b/src/plugins/platforms/mirclient/qmirclientcursor.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2015 Canonical, Ltd.
+** Copyright (C) 2015-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp b/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp
new file mode 100644
index 0000000000..9aa934083d
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientdebugextension.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientdebugextension.h"
+
+#include "qmirclientlogging.h"
+
+// mir client debug
+#include <mir_toolkit/debug/surface.h>
+
+Q_LOGGING_CATEGORY(mirclientDebug, "qt.qpa.mirclient.debug")
+
+QMirClientDebugExtension::QMirClientDebugExtension()
+ : m_mirclientDebug(QStringLiteral("mirclient-debug-extension"), 1)
+ , m_mapper(nullptr)
+{
+ qCDebug(mirclientDebug) << "NOTICE: Loading mirclient-debug-extension";
+ m_mapper = (MapperPrototype) m_mirclientDebug.resolve("mir_debug_surface_coords_to_screen");
+
+ if (!m_mirclientDebug.isLoaded()) {
+ qCWarning(mirclientDebug) << "ERROR: mirclient-debug-extension failed to load:"
+ << m_mirclientDebug.errorString();
+ } else if (!m_mapper) {
+ qCWarning(mirclientDebug) << "ERROR: unable to find required symbols in mirclient-debug-extension:"
+ << m_mirclientDebug.errorString();
+ }
+}
+
+QPoint QMirClientDebugExtension::mapSurfacePointToScreen(MirSurface *surface, const QPoint &point)
+{
+ if (!m_mapper) {
+ return point;
+ }
+
+ QPoint mappedPoint;
+ bool status = m_mapper(surface, point.x(), point.y(), &mappedPoint.rx(), &mappedPoint.ry());
+ if (status) {
+ return mappedPoint;
+ } else {
+ return point;
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientdebugextension.h b/src/plugins/platforms/mirclient/qmirclientdebugextension.h
new file mode 100644
index 0000000000..0596561d77
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientdebugextension.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTDEBUGEXTENSION_H
+#define QMIRCLIENTDEBUGEXTENSION_H
+
+#include <QPoint>
+#include <QLibrary>
+struct MirSurface;
+
+typedef bool (*MapperPrototype)(MirSurface* surface, int x, int y, int* screenX, int* screenY);
+
+
+class QMirClientDebugExtension
+{
+public:
+ QMirClientDebugExtension();
+
+ QPoint mapSurfacePointToScreen(MirSurface *, const QPoint &point);
+
+private:
+ QLibrary m_mirclientDebug;
+ MapperPrototype m_mapper;
+};
+
+#endif // QMIRCLIENTDEBUGEXTENSION_H
diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp
new file mode 100644
index 0000000000..123f805c25
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientdesktopwindow.h"
+
+// local
+#include "qmirclientlogging.h"
+
+QMirClientDesktopWindow::QMirClientDesktopWindow(QWindow *window)
+ : QPlatformWindow(window)
+{
+ qCDebug(mirclient, "QMirClientDesktopWindow(window=%p)", window);
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h
new file mode 100644
index 0000000000..3ba54db826
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientdesktopwindow.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTDESKTOPWINDOW_H
+#define QMIRCLIENTDESKTOPWINDOW_H
+
+#include <qpa/qplatformwindow.h>
+
+// TODO Implement it. For now it's just an empty, dummy class.
+class QMirClientDesktopWindow : public QPlatformWindow
+{
+public:
+ QMirClientDesktopWindow(QWindow*);
+};
+
+#endif // QMIRCLIENTDESKTOPWINDOW_H
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
index 38eb0a4609..fc7d90d5ec 100644
--- a/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientglcontext.cpp
@@ -39,123 +39,94 @@
#include "qmirclientglcontext.h"
-#include "qmirclientwindow.h"
#include "qmirclientlogging.h"
+#include "qmirclientwindow.h"
+
+#include <QOpenGLFramebufferObject>
#include <QtEglSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglpbuffer_p.h>
#include <QtGui/private/qopenglcontext_p.h>
-#include <dlfcn.h>
-
-#if !defined(QT_NO_DEBUG)
-static void printOpenGLESConfig() {
- static bool once = true;
- if (once) {
- const char* string = (const char*) glGetString(GL_VENDOR);
- LOG("OpenGL ES vendor: %s", string);
- string = (const char*) glGetString(GL_RENDERER);
- LOG("OpenGL ES renderer: %s", string);
- string = (const char*) glGetString(GL_VERSION);
- LOG("OpenGL ES version: %s", string);
- string = (const char*) glGetString(GL_SHADING_LANGUAGE_VERSION);
- LOG("OpenGL ES Shading Language version: %s", string);
- string = (const char*) glGetString(GL_EXTENSIONS);
- LOG("OpenGL ES extensions: %s", string);
- once = false;
- }
-}
-#endif
-static EGLenum api_in_use()
+Q_LOGGING_CATEGORY(mirclientGraphics, "qt.qpa.mirclient.graphics", QtWarningMsg)
+
+namespace {
+
+void printEglConfig(EGLDisplay display, EGLConfig config)
{
-#ifdef QTUBUNTU_USE_OPENGL
- return EGL_OPENGL_API;
-#else
- return EGL_OPENGL_ES_API;
-#endif
+ Q_ASSERT(display != EGL_NO_DISPLAY);
+ Q_ASSERT(config != nullptr);
+
+ const char *string = eglQueryString(display, EGL_VENDOR);
+ qCDebug(mirclientGraphics, "EGL vendor: %s", string);
+
+ string = eglQueryString(display, EGL_VERSION);
+ qCDebug(mirclientGraphics, "EGL version: %s", string);
+
+ string = eglQueryString(display, EGL_EXTENSIONS);
+ qCDebug(mirclientGraphics, "EGL extensions: %s", string);
+
+ qCDebug(mirclientGraphics, "EGL configuration attributes:");
+ q_printEglConfig(display, config);
}
-QMirClientOpenGLContext::QMirClientOpenGLContext(QMirClientScreen* screen, QMirClientOpenGLContext* share)
+} // anonymous namespace
+
+QMirClientOpenGLContext::QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
+ EGLDisplay display)
+ : QEGLPlatformContext(format, share, display, 0)
{
- ASSERT(screen != NULL);
- mEglDisplay = screen->eglDisplay();
- mScreen = screen;
-
- // Create an OpenGL ES 2 context.
- QVector<EGLint> attribs;
- attribs.append(EGL_CONTEXT_CLIENT_VERSION);
- attribs.append(2);
- attribs.append(EGL_NONE);
- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
-
- mEglContext = eglCreateContext(mEglDisplay, screen->eglConfig(), share ? share->eglContext() : EGL_NO_CONTEXT,
- attribs.constData());
- DASSERT(mEglContext != EGL_NO_CONTEXT);
+ if (mirclientGraphics().isDebugEnabled()) {
+ printEglConfig(display, eglConfig());
+ }
}
-QMirClientOpenGLContext::~QMirClientOpenGLContext()
+static bool needsFBOReadBackWorkaround()
{
- ASSERT(eglDestroyContext(mEglDisplay, mEglContext) == EGL_TRUE);
+ static bool set = false;
+ static bool needsWorkaround = false;
+
+ if (Q_UNLIKELY(!set)) {
+ const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ needsWorkaround = qstrncmp(rendererString, "Mali-400", 8) == 0
+ || qstrncmp(rendererString, "Mali-T7", 7) == 0
+ || qstrncmp(rendererString, "PowerVR Rogue G6200", 19) == 0;
+ set = true;
+ }
+
+ return needsWorkaround;
}
bool QMirClientOpenGLContext::makeCurrent(QPlatformSurface* surface)
{
- DASSERT(surface->surface()->surfaceType() == QSurface::OpenGLSurface);
- EGLSurface eglSurface = static_cast<QMirClientWindow*>(surface)->eglSurface();
-#if defined(QT_NO_DEBUG)
- eglBindAPI(api_in_use());
- eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext);
-#else
- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
- ASSERT(eglMakeCurrent(mEglDisplay, eglSurface, eglSurface, mEglContext) == EGL_TRUE);
- printOpenGLESConfig();
-#endif
-
- // When running on the emulator, shaders will be compiled using a thin wrapper around the desktop drivers.
- // These wrappers might not support the precision qualifiers, so set the workaround flag to true.
- const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
- if (rendererString != 0 && qstrncmp(rendererString, "Android Emulator", 16) == 0) {
+ const bool ret = QEGLPlatformContext::makeCurrent(surface);
+
+ if (Q_LIKELY(ret)) {
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
- ctx_d->workaround_missingPrecisionQualifiers = true;
+ if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaround()) {
+ ctx_d->workaround_brokenFBOReadBack = true;
+ }
}
-
- return true;
+ return ret;
}
-void QMirClientOpenGLContext::doneCurrent()
+// Following method used internally in the base class QEGLPlatformContext to access
+// the egl surface of a QPlatformSurface/QMirClientWindow
+EGLSurface QMirClientOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
{
-#if defined(QT_NO_DEBUG)
- eglBindAPI(api_in_use());
- eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-#else
- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
- ASSERT(eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) == EGL_TRUE);
-#endif
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ return static_cast<QMirClientWindow *>(surface)->eglSurface();
+ } else {
+ return static_cast<QEGLPbuffer *>(surface)->pbuffer();
+ }
}
void QMirClientOpenGLContext::swapBuffers(QPlatformSurface* surface)
{
- QMirClientWindow *ubuntuWindow = static_cast<QMirClientWindow*>(surface);
-
- EGLSurface eglSurface = ubuntuWindow->eglSurface();
-#if defined(QT_NO_DEBUG)
- eglBindAPI(api_in_use());
- eglSwapBuffers(mEglDisplay, eglSurface);
-#else
- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
- ASSERT(eglSwapBuffers(mEglDisplay, eglSurface) == EGL_TRUE);
-#endif
-
- ubuntuWindow->onSwapBuffersDone();
-}
+ QEGLPlatformContext::swapBuffers(surface);
-QFunctionPointer QMirClientOpenGLContext::getProcAddress(const char *procName)
-{
-#if defined(QT_NO_DEBUG)
- eglBindAPI(api_in_use());
-#else
- ASSERT(eglBindAPI(api_in_use()) == EGL_TRUE);
-#endif
- QFunctionPointer proc = (QFunctionPointer) eglGetProcAddress(procName);
- if (!proc)
- proc = (QFunctionPointer) dlsym(RTLD_DEFAULT, procName);
- return proc;
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ // notify window on swap completion
+ auto platformWindow = static_cast<QMirClientWindow *>(surface);
+ platformWindow->onSwapBuffersDone();
+ }
}
diff --git a/src/plugins/platforms/mirclient/qmirclientglcontext.h b/src/plugins/platforms/mirclient/qmirclientglcontext.h
index eac0b78c4e..92331a6fb1 100644
--- a/src/plugins/platforms/mirclient/qmirclientglcontext.h
+++ b/src/plugins/platforms/mirclient/qmirclientglcontext.h
@@ -42,28 +42,22 @@
#define QMIRCLIENTGLCONTEXT_H
#include <qpa/qplatformopenglcontext.h>
-#include "qmirclientscreen.h"
+#include <QtEglSupport/private/qeglplatformcontext_p.h>
-class QMirClientOpenGLContext : public QPlatformOpenGLContext
+#include <EGL/egl.h>
+
+class QMirClientOpenGLContext : public QEGLPlatformContext
{
public:
- QMirClientOpenGLContext(QMirClientScreen* screen, QMirClientOpenGLContext* share);
- virtual ~QMirClientOpenGLContext();
-
- // QPlatformOpenGLContext methods.
- QSurfaceFormat format() const override { return mScreen->surfaceFormat(); }
- void swapBuffers(QPlatformSurface* surface) override;
- bool makeCurrent(QPlatformSurface* surface) override;
- void doneCurrent() override;
- bool isValid() const override { return mEglContext != EGL_NO_CONTEXT; }
- QFunctionPointer getProcAddress(const char *procName) override;
+ QMirClientOpenGLContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share,
+ EGLDisplay display);
- EGLContext eglContext() const { return mEglContext; }
+ // QEGLPlatformContext methods.
+ void swapBuffers(QPlatformSurface *surface) final;
+ bool makeCurrent(QPlatformSurface *surface) final;
-private:
- QMirClientScreen* mScreen;
- EGLContext mEglContext;
- EGLDisplay mEglDisplay;
+protected:
+ EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface) final;
};
#endif // QMIRCLIENTGLCONTEXT_H
diff --git a/src/plugins/platforms/mirclient/qmirclientinput.cpp b/src/plugins/platforms/mirclient/qmirclientinput.cpp
index b3b21ae0e3..ea13f3cc17 100644
--- a/src/plugins/platforms/mirclient/qmirclientinput.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientinput.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -48,21 +48,23 @@
#include "qmirclientorientationchangeevent_p.h"
// Qt
-#if !defined(QT_NO_DEBUG)
#include <QtCore/QThread>
-#endif
#include <QtCore/qglobal.h>
#include <QtCore/QCoreApplication>
-#include <private/qguiapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatforminputcontext.h>
#include <qpa/qwindowsysteminterface.h>
+#include <QTextCodec>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-keysyms.h>
#include <mir_toolkit/mir_client_library.h>
-#define LOG_EVENTS 0
+Q_LOGGING_CATEGORY(mirclientInput, "qt.qpa.mirclient.input", QtWarningMsg)
+
+namespace
+{
// XKB Keysyms which do not map directly to Qt types (i.e. Unicode points)
static const uint32_t KeyTable[] = {
@@ -134,6 +136,27 @@ static const uint32_t KeyTable[] = {
XKB_KEY_MultipleCandidate, Qt::Key_MultipleCandidate,
XKB_KEY_PreviousCandidate, Qt::Key_PreviousCandidate,
+ // dead keys
+ XKB_KEY_dead_grave, Qt::Key_Dead_Grave,
+ XKB_KEY_dead_acute, Qt::Key_Dead_Acute,
+ XKB_KEY_dead_circumflex, Qt::Key_Dead_Circumflex,
+ XKB_KEY_dead_tilde, Qt::Key_Dead_Tilde,
+ XKB_KEY_dead_macron, Qt::Key_Dead_Macron,
+ XKB_KEY_dead_breve, Qt::Key_Dead_Breve,
+ XKB_KEY_dead_abovedot, Qt::Key_Dead_Abovedot,
+ XKB_KEY_dead_diaeresis, Qt::Key_Dead_Diaeresis,
+ XKB_KEY_dead_abovering, Qt::Key_Dead_Abovering,
+ XKB_KEY_dead_doubleacute, Qt::Key_Dead_Doubleacute,
+ XKB_KEY_dead_caron, Qt::Key_Dead_Caron,
+ XKB_KEY_dead_cedilla, Qt::Key_Dead_Cedilla,
+ XKB_KEY_dead_ogonek, Qt::Key_Dead_Ogonek,
+ XKB_KEY_dead_iota, Qt::Key_Dead_Iota,
+ XKB_KEY_dead_voiced_sound, Qt::Key_Dead_Voiced_Sound,
+ XKB_KEY_dead_semivoiced_sound, Qt::Key_Dead_Semivoiced_Sound,
+ XKB_KEY_dead_belowdot, Qt::Key_Dead_Belowdot,
+ XKB_KEY_dead_hook, Qt::Key_Dead_Hook,
+ XKB_KEY_dead_horn, Qt::Key_Dead_Horn,
+
XKB_KEY_Mode_switch, Qt::Key_Mode_switch,
XKB_KEY_script_switch, Qt::Key_Mode_switch,
XKB_KEY_XF86AudioRaiseVolume, Qt::Key_VolumeUp,
@@ -144,14 +167,37 @@ static const uint32_t KeyTable[] = {
0, 0
};
-class QMirClientEvent : public QEvent
+Qt::WindowState mirSurfaceStateToWindowState(MirSurfaceState state)
+{
+ switch (state) {
+ case mir_surface_state_fullscreen:
+ return Qt::WindowFullScreen;
+ case mir_surface_state_maximized:
+ case mir_surface_state_vertmaximized:
+ case mir_surface_state_horizmaximized:
+ return Qt::WindowMaximized;
+ case mir_surface_state_minimized:
+ return Qt::WindowMinimized;
+ case mir_surface_state_hidden:
+ // We should be handling this state separately.
+ Q_ASSERT(false);
+ case mir_surface_state_restored:
+ case mir_surface_state_unknown:
+ default:
+ return Qt::WindowNoState;
+ }
+}
+
+} // namespace
+
+class UbuntuEvent : public QEvent
{
public:
- QMirClientEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type)
+ UbuntuEvent(QMirClientWindow* window, const MirEvent *event, QEvent::Type type)
: QEvent(type), window(window) {
nativeEvent = mir_event_ref(event);
}
- ~QMirClientEvent()
+ ~UbuntuEvent()
{
mir_event_unref(nativeEvent);
}
@@ -166,7 +212,7 @@ QMirClientInput::QMirClientInput(QMirClientClientIntegration* integration)
, mEventFilterType(static_cast<QMirClientNativeInterface*>(
integration->nativeInterface())->genericEventFilterType())
, mEventType(static_cast<QEvent::Type>(QEvent::registerEventType()))
- , mLastFocusedWindow(nullptr)
+ , mLastInputWindow(nullptr)
{
// Initialize touch device.
mTouchDevice = new QTouchDevice;
@@ -182,42 +228,47 @@ QMirClientInput::~QMirClientInput()
// Qt will take care of deleting mTouchDevice.
}
-#if (LOG_EVENTS != 0)
static const char* nativeEventTypeToStr(MirEventType t)
{
switch (t)
{
case mir_event_type_key:
- return "mir_event_type_key";
+ return "key";
case mir_event_type_motion:
- return "mir_event_type_motion";
+ return "motion";
case mir_event_type_surface:
- return "mir_event_type_surface";
+ return "surface";
case mir_event_type_resize:
- return "mir_event_type_resize";
+ return "resize";
case mir_event_type_prompt_session_state_change:
- return "mir_event_type_prompt_session_state_change";
+ return "prompt_session_state_change";
case mir_event_type_orientation:
- return "mir_event_type_orientation";
+ return "orientation";
case mir_event_type_close_surface:
- return "mir_event_type_close_surface";
+ return "close_surface";
case mir_event_type_input:
- return "mir_event_type_input";
+ return "input";
+ case mir_event_type_keymap:
+ return "keymap";
+ case mir_event_type_input_configuration:
+ return "input_configuration";
+ case mir_event_type_surface_output:
+ return "surface_output";
+ case mir_event_type_input_device_state:
+ return "input_device_state";
default:
- DLOG("Invalid event type %d", t);
- return "invalid";
+ return "unknown";
}
}
-#endif // LOG_EVENTS != 0
void QMirClientInput::customEvent(QEvent* event)
{
- DASSERT(QThread::currentThread() == thread());
- QMirClientEvent* ubuntuEvent = static_cast<QMirClientEvent*>(event);
+ Q_ASSERT(QThread::currentThread() == thread());
+ UbuntuEvent* ubuntuEvent = static_cast<UbuntuEvent*>(event);
const MirEvent *nativeEvent = ubuntuEvent->nativeEvent;
if ((ubuntuEvent->window == nullptr) || (ubuntuEvent->window->window() == nullptr)) {
- qWarning("Attempted to deliver an event to a non-existent window, ignoring.");
+ qCWarning(mirclient) << "Attempted to deliver an event to a non-existent window, ignoring.";
return;
}
@@ -226,13 +277,11 @@ void QMirClientInput::customEvent(QEvent* event)
if (QWindowSystemInterface::handleNativeEvent(
ubuntuEvent->window->window(), mEventFilterType,
const_cast<void *>(static_cast<const void *>(nativeEvent)), &result) == true) {
- DLOG("event filtered out by native interface");
+ qCDebug(mirclient, "event filtered out by native interface");
return;
}
- #if (LOG_EVENTS != 0)
- LOG("QMirClientInput::customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
- #endif
+ qCDebug(mirclientInput, "customEvent(type=%s)", nativeEventTypeToStr(mir_event_get_type(nativeEvent)));
// Event dispatching.
switch (mir_event_get_type(nativeEvent))
@@ -242,43 +291,30 @@ void QMirClientInput::customEvent(QEvent* event)
break;
case mir_event_type_resize:
{
- Q_ASSERT(ubuntuEvent->window->screen() == mIntegration->screen());
-
auto resizeEvent = mir_event_get_resize_event(nativeEvent);
- mIntegration->screen()->handleWindowSurfaceResize(
- mir_resize_event_get_width(resizeEvent),
- mir_resize_event_get_height(resizeEvent));
+ // Enable workaround for Screen rotation
+ auto const targetWindow = ubuntuEvent->window;
+ if (targetWindow) {
+ auto const screen = static_cast<QMirClientScreen*>(targetWindow->screen());
+ if (screen) {
+ screen->handleWindowSurfaceResize(
+ mir_resize_event_get_width(resizeEvent),
+ mir_resize_event_get_height(resizeEvent));
+ }
- ubuntuEvent->window->handleSurfaceResized(mir_resize_event_get_width(resizeEvent),
- mir_resize_event_get_height(resizeEvent));
+ targetWindow->handleSurfaceResized(
+ mir_resize_event_get_width(resizeEvent),
+ mir_resize_event_get_height(resizeEvent));
+ }
break;
}
case mir_event_type_surface:
- {
- auto surfaceEvent = mir_event_get_surface_event(nativeEvent);
- if (mir_surface_event_get_attribute(surfaceEvent) == mir_surface_attrib_focus) {
- const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused;
- // Mir may have sent a pair of focus lost/gained events, so we need to "peek" into the queue
- // so that we don't deactivate windows prematurely.
- if (focused) {
- mPendingFocusGainedEvents--;
- ubuntuEvent->window->handleSurfaceFocused();
- QWindowSystemInterface::handleWindowActivated(ubuntuEvent->window->window(), Qt::ActiveWindowFocusReason);
-
- // NB: Since processing of system events is queued, never check qGuiApp->applicationState()
- // as it might be outdated. Always call handleApplicationStateChanged() with the latest
- // state regardless.
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
-
- } else if (!mPendingFocusGainedEvents) {
- DLOG("[ubuntumirclient QPA] No windows have focus");
- QWindowSystemInterface::handleWindowActivated(nullptr, Qt::ActiveWindowFocusReason);
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
- }
- }
+ handleSurfaceEvent(ubuntuEvent->window, mir_event_get_surface_event(nativeEvent));
+ break;
+ case mir_event_type_surface_output:
+ handleSurfaceOutputEvent(ubuntuEvent->window, mir_event_get_surface_output_event(nativeEvent));
break;
- }
case mir_event_type_orientation:
dispatchOrientationEvent(ubuntuEvent->window->window(), mir_event_get_orientation_event(nativeEvent));
break;
@@ -286,7 +322,7 @@ void QMirClientInput::customEvent(QEvent* event)
QWindowSystemInterface::handleCloseEvent(ubuntuEvent->window->window());
break;
default:
- DLOG("unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
+ qCDebug(mirclient, "unhandled event type: %d", static_cast<int>(mir_event_get_type(nativeEvent)));
}
}
@@ -294,22 +330,11 @@ void QMirClientInput::postEvent(QMirClientWindow *platformWindow, const MirEvent
{
QWindow *window = platformWindow->window();
- const auto eventType = mir_event_get_type(event);
- if (mir_event_type_surface == eventType) {
- auto surfaceEvent = mir_event_get_surface_event(event);
- if (mir_surface_attrib_focus == mir_surface_event_get_attribute(surfaceEvent)) {
- const bool focused = mir_surface_event_get_attribute_value(surfaceEvent) == mir_surface_focused;
- if (focused) {
- mPendingFocusGainedEvents++;
- }
- }
- }
-
- QCoreApplication::postEvent(this, new QMirClientEvent(
+ QCoreApplication::postEvent(this, new UbuntuEvent(
platformWindow, event, mEventType));
if ((window->flags().testFlag(Qt::WindowTransparentForInput)) && window->parent()) {
- QCoreApplication::postEvent(this, new QMirClientEvent(
+ QCoreApplication::postEvent(this, new UbuntuEvent(
static_cast<QMirClientWindow*>(platformWindow->QPlatformWindow::parent()),
event, mEventType));
}
@@ -365,15 +390,17 @@ void QMirClientInput::dispatchTouchEvent(QMirClientWindow *window, const MirInpu
switch (touch_action)
{
case mir_touch_action_down:
- mLastFocusedWindow = window;
+ mLastInputWindow = window;
touchPoint.state = Qt::TouchPointPressed;
break;
case mir_touch_action_up:
touchPoint.state = Qt::TouchPointReleased;
break;
case mir_touch_action_change:
- default:
touchPoint.state = Qt::TouchPointMoved;
+ break;
+ default:
+ Q_UNREACHABLE();
}
touchPoints.append(touchPoint);
@@ -384,22 +411,26 @@ void QMirClientInput::dispatchTouchEvent(QMirClientWindow *window, const MirInpu
mTouchDevice, touchPoints);
}
-static uint32_t translateKeysym(uint32_t sym, char *string, size_t size)
-{
- Q_UNUSED(size);
- string[0] = '\0';
+static uint32_t translateKeysym(uint32_t sym, const QString &text) {
+ int code = 0;
- if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35)
+ QTextCodec *systemCodec = QTextCodec::codecForLocale();
+ if (sym < 128 || (sym < 256 && systemCodec->mibEnum() == 4)) {
+ // upper-case key, if known
+ code = isprint((int)sym) ? toupper((int)sym) : 0;
+ } else if (sym >= XKB_KEY_F1 && sym <= XKB_KEY_F35) {
return Qt::Key_F1 + (int(sym) - XKB_KEY_F1);
-
- for (int i = 0; KeyTable[i]; i += 2) {
- if (sym == KeyTable[i])
- return KeyTable[i + 1];
+ } else if (text.length() == 1 && text.unicode()->unicode() > 0x1f
+ && text.unicode()->unicode() != 0x7f
+ && !(sym >= XKB_KEY_dead_grave && sym <= XKB_KEY_dead_currency)) {
+ code = text.unicode()->toUpper().unicode();
+ } else {
+ for (int i = 0; KeyTable[i]; i += 2)
+ if (sym == KeyTable[i])
+ code = KeyTable[i + 1];
}
- string[0] = sym;
- string[1] = '\0';
- return toupper(sym);
+ return code;
}
namespace
@@ -413,12 +444,15 @@ Qt::KeyboardModifiers qt_modifiers_from_mir(MirInputEventModifiers modifiers)
if (modifiers & mir_input_event_modifier_ctrl) {
q_modifiers |= Qt::ControlModifier;
}
- if (modifiers & mir_input_event_modifier_alt) {
+ if (modifiers & mir_input_event_modifier_alt_left) {
q_modifiers |= Qt::AltModifier;
}
if (modifiers & mir_input_event_modifier_meta) {
q_modifiers |= Qt::MetaModifier;
}
+ if (modifiers & mir_input_event_modifier_alt_right) {
+ q_modifiers |= Qt::GroupSwitchModifier;
+ }
return q_modifiers;
}
}
@@ -429,34 +463,43 @@ void QMirClientInput::dispatchKeyEvent(QMirClientWindow *window, const MirInputE
ulong timestamp = mir_input_event_get_event_time(event) / 1000000;
xkb_keysym_t xk_sym = mir_keyboard_event_key_code(key_event);
+ quint32 scan_code = mir_keyboard_event_scan_code(key_event);
+ quint32 native_modifiers = mir_keyboard_event_modifiers(key_event);
// Key modifier and unicode index mapping.
- auto modifiers = qt_modifiers_from_mir(mir_keyboard_event_modifiers(key_event));
+ auto modifiers = qt_modifiers_from_mir(native_modifiers);
MirKeyboardAction action = mir_keyboard_event_action(key_event);
QEvent::Type keyType = action == mir_keyboard_action_up
? QEvent::KeyRelease : QEvent::KeyPress;
if (action == mir_keyboard_action_down)
- mLastFocusedWindow = window;
+ mLastInputWindow = window;
- char s[2];
- int sym = translateKeysym(xk_sym, s, sizeof(s));
- QString text = QString::fromLatin1(s);
+ QString text;
+ QVarLengthArray<char, 32> chars(32);
+ {
+ int result = xkb_keysym_to_utf8(xk_sym, chars.data(), chars.size());
+
+ if (result > 0) {
+ text = QString::fromUtf8(chars.constData());
+ }
+ }
+ int sym = translateKeysym(xk_sym, text);
bool is_auto_rep = action == mir_keyboard_action_repeat;
QPlatformInputContext *context = QGuiApplicationPrivate::platformIntegration()->inputContext();
if (context) {
- QKeyEvent qKeyEvent(keyType, sym, modifiers, text, is_auto_rep);
+ QKeyEvent qKeyEvent(keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
qKeyEvent.setTimestamp(timestamp);
if (context->filterEvent(&qKeyEvent)) {
- DLOG("key event filtered out by input context");
+ qCDebug(mirclient, "key event filtered out by input context");
return;
}
}
- QWindowSystemInterface::handleKeyEvent(window->window(), timestamp, keyType, sym, modifiers, text, is_auto_rep);
+ QWindowSystemInterface::handleExtendedKeyEvent(window->window(), timestamp, keyType, sym, modifiers, scan_code, xk_sym, native_modifiers, text, is_auto_rep);
}
namespace
@@ -481,14 +524,17 @@ Qt::MouseButtons extract_buttons(const MirPointerEvent *pev)
void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, const MirInputEvent *ev)
{
- auto window = platformWindow->window();
- auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
+ const auto window = platformWindow->window();
+ const auto timestamp = mir_input_event_get_event_time(ev) / 1000000;
+
+ const auto pev = mir_input_event_get_pointer_event(ev);
+ const auto action = mir_pointer_event_action(pev);
+
+ const auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
+ const auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
+ mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
- auto pev = mir_input_event_get_pointer_event(ev);
- auto action = mir_pointer_event_action(pev);
- auto localPoint = QPointF(mir_pointer_event_axis_value(pev, mir_pointer_axis_x),
- mir_pointer_event_axis_value(pev, mir_pointer_axis_y));
- auto modifiers = qt_modifiers_from_mir(mir_pointer_event_modifiers(pev));
+ mLastInputWindow = platformWindow;
switch (action) {
case mir_pointer_action_button_up:
@@ -499,7 +545,8 @@ void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, con
const float vDelta = mir_pointer_event_axis_value(pev, mir_pointer_axis_vscroll);
if (hDelta != 0 || vDelta != 0) {
- const QPoint angleDelta = QPoint(hDelta * 15, vDelta * 15);
+ // QWheelEvent::DefaultDeltasPerStep = 120 but doesn't exist on vivid
+ const QPoint angleDelta(120 * hDelta, 120 * vDelta);
QWindowSystemInterface::handleWheelEvent(window, timestamp, localPoint, window->position() + localPoint,
QPoint(), angleDelta, modifiers, Qt::ScrollUpdate);
}
@@ -515,42 +562,32 @@ void QMirClientInput::dispatchPointerEvent(QMirClientWindow *platformWindow, con
QWindowSystemInterface::handleLeaveEvent(window);
break;
default:
- DLOG("Unrecognized pointer event");
+ Q_UNREACHABLE();
}
}
-#if (LOG_EVENTS != 0)
static const char* nativeOrientationDirectionToStr(MirOrientation orientation)
{
switch (orientation) {
case mir_orientation_normal:
return "Normal";
- break;
case mir_orientation_left:
return "Left";
- break;
case mir_orientation_inverted:
return "Inverted";
- break;
case mir_orientation_right:
return "Right";
- break;
- default:
- return "INVALID!";
}
+ Q_UNREACHABLE();
}
-#endif
void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrientationEvent *event)
{
MirOrientation mir_orientation = mir_orientation_event_get_direction(event);
- #if (LOG_EVENTS != 0)
- // Orientation event logging.
- LOG("ORIENTATION direction: %s", nativeOrientationDirectionToStr(mir_orientation));
- #endif
+ qCDebug(mirclientInput, "orientation direction: %s", nativeOrientationDirectionToStr(mir_orientation));
if (!window->screen()) {
- DLOG("Window has no associated screen, dropping orientation event");
+ qCDebug(mirclient, "Window has no associated screen, dropping orientation event");
return;
}
@@ -569,7 +606,7 @@ void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrienta
orientation = OrientationChangeEvent::RightUp;
break;
default:
- DLOG("No such orientation %d", mir_orientation);
+ qCDebug(mirclient, "No such orientation %d", mir_orientation);
return;
}
@@ -581,3 +618,61 @@ void QMirClientInput::dispatchOrientationEvent(QWindow *window, const MirOrienta
new OrientationChangeEvent(OrientationChangeEvent::mType, orientation));
}
+void QMirClientInput::handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event)
+{
+ auto surfaceEventAttribute = mir_surface_event_get_attribute(event);
+
+ switch (surfaceEventAttribute) {
+ case mir_surface_attrib_focus: {
+ window->handleSurfaceFocusChanged(
+ mir_surface_event_get_attribute_value(event) == mir_surface_focused);
+ break;
+ }
+ case mir_surface_attrib_visibility: {
+ window->handleSurfaceExposeChange(
+ mir_surface_event_get_attribute_value(event) == mir_surface_visibility_exposed);
+ break;
+ }
+ // Remaining attributes are ones client sets for server, and server should not override them
+ case mir_surface_attrib_state: {
+ MirSurfaceState state = static_cast<MirSurfaceState>(mir_surface_event_get_attribute_value(event));
+
+ if (state == mir_surface_state_hidden) {
+ window->handleSurfaceVisibilityChanged(false);
+ } else {
+ // it's visible!
+ window->handleSurfaceVisibilityChanged(true);
+ window->handleSurfaceStateChanged(mirSurfaceStateToWindowState(state));
+ }
+ break;
+ }
+ case mir_surface_attrib_type:
+ case mir_surface_attrib_swapinterval:
+ case mir_surface_attrib_dpi:
+ case mir_surface_attrib_preferred_orientation:
+ case mir_surface_attribs:
+ break;
+ }
+}
+
+void QMirClientInput::handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event)
+{
+ const uint32_t outputId = mir_surface_output_event_get_output_id(event);
+ const int dpi = mir_surface_output_event_get_dpi(event);
+ const MirFormFactor formFactor = mir_surface_output_event_get_form_factor(event);
+ const float scale = mir_surface_output_event_get_scale(event);
+
+ const auto screenObserver = mIntegration->screenObserver();
+ QMirClientScreen *screen = screenObserver->findScreenWithId(outputId);
+ if (!screen) {
+ qCWarning(mirclient) << "Mir notified window" << window->window() << "on an unknown screen with id" << outputId;
+ return;
+ }
+
+ screenObserver->handleScreenPropertiesChange(screen, dpi, formFactor, scale);
+ window->handleScreenPropertiesChange(formFactor, scale);
+
+ if (window->screen() != screen) {
+ QWindowSystemInterface::handleWindowScreenChanged(window->window(), screen->screen());
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientinput.h b/src/plugins/platforms/mirclient/qmirclientinput.h
index 3600ae7ece..263cb5e54e 100644
--- a/src/plugins/platforms/mirclient/qmirclientinput.h
+++ b/src/plugins/platforms/mirclient/qmirclientinput.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -43,7 +43,6 @@
// Qt
#include <qpa/qwindowsysteminterface.h>
-#include <QAtomicInt>
#include <mir_toolkit/mir_client_library.h>
@@ -63,7 +62,7 @@ public:
void postEvent(QMirClientWindow* window, const MirEvent *event);
QMirClientClientIntegration* integration() const { return mIntegration; }
- QMirClientWindow *lastFocusedWindow() const {return mLastFocusedWindow; }
+ QMirClientWindow *lastInputWindow() const {return mLastInputWindow; }
protected:
void dispatchKeyEvent(QMirClientWindow *window, const MirInputEvent *event);
@@ -72,6 +71,8 @@ protected:
void dispatchInputEvent(QMirClientWindow *window, const MirInputEvent *event);
void dispatchOrientationEvent(QWindow* window, const MirOrientationEvent *event);
+ void handleSurfaceEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceEvent *event);
+ void handleSurfaceOutputEvent(const QPointer<QMirClientWindow> &window, const MirSurfaceOutputEvent *event);
private:
QMirClientClientIntegration* mIntegration;
@@ -79,8 +80,7 @@ private:
const QByteArray mEventFilterType;
const QEvent::Type mEventType;
- QMirClientWindow *mLastFocusedWindow;
- QAtomicInt mPendingFocusGainedEvents;
+ QMirClientWindow *mLastInputWindow;
};
#endif // QMIRCLIENTINPUT_H
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.cpp b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
index 2c8740f070..eef96ee3de 100644
--- a/src/plugins/platforms/mirclient/qmirclientintegration.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientintegration.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -42,6 +42,8 @@
#include "qmirclientintegration.h"
#include "qmirclientbackingstore.h"
#include "qmirclientclipboard.h"
+#include "qmirclientdebugextension.h"
+#include "qmirclientdesktopwindow.h"
#include "qmirclientglcontext.h"
#include "qmirclientinput.h"
#include "qmirclientlogging.h"
@@ -51,56 +53,62 @@
#include "qmirclientwindow.h"
// Qt
+#include <QFileInfo>
#include <QGuiApplication>
-#include <private/qguiapplication_p.h>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatforminputcontextfactory_p.h>
#include <qpa/qplatforminputcontext.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglpbuffer_p.h>
#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
+#ifndef QT_NO_ACCESSIBILITY
+#include <qpa/qplatformaccessibility.h>
+#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE
+#include <QtLinuxAccessibilitySupport/private/bridge_p.h>
+#endif
+#endif
+
#include <QOpenGLContext>
+#include <QOffscreenSurface>
// platform-api
#include <ubuntu/application/lifecycle_delegate.h>
#include <ubuntu/application/id.h>
#include <ubuntu/application/options.h>
-static void resumedCallback(const UApplicationOptions *options, void* context)
+static void resumedCallback(const UApplicationOptions */*options*/, void* context)
{
- Q_UNUSED(options)
- Q_UNUSED(context)
- DASSERT(context != NULL);
- if (qGuiApp->focusWindow()) {
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
- } else {
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationInactive);
- }
+ auto integration = static_cast<QMirClientClientIntegration*>(context);
+ integration->appStateController()->setResumed();
}
-static void aboutToStopCallback(UApplicationArchive *archive, void* context)
+static void aboutToStopCallback(UApplicationArchive */*archive*/, void* context)
{
- Q_UNUSED(archive)
- DASSERT(context != NULL);
- QMirClientClientIntegration* integration = static_cast<QMirClientClientIntegration*>(context);
- QPlatformInputContext *inputContext = integration->inputContext();
+ auto integration = static_cast<QMirClientClientIntegration*>(context);
+ auto inputContext = integration->inputContext();
if (inputContext) {
inputContext->hideInputPanel();
} else {
- qWarning("QMirClientClientIntegration aboutToStopCallback(): no input context");
+ qCWarning(mirclient) << "aboutToStopCallback(): no input context";
}
- QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
+ integration->appStateController()->setSuspended();
}
-QMirClientClientIntegration::QMirClientClientIntegration()
+QMirClientClientIntegration::QMirClientClientIntegration(int argc, char **argv)
: QPlatformIntegration()
- , mNativeInterface(new QMirClientNativeInterface)
+ , mNativeInterface(new QMirClientNativeInterface(this))
, mFontDb(new QGenericUnixFontDatabase)
, mServices(new QMirClientPlatformServices)
- , mClipboard(new QMirClientClipboard)
+ , mAppStateController(new QMirClientAppStateController)
, mScaleFactor(1.0)
{
- setupOptions();
- setupDescription();
+ {
+ QStringList args = QCoreApplication::arguments();
+ setupOptions(args);
+ QByteArray sessionName = generateSessionName(args);
+ setupDescription(sessionName);
+ }
// Create new application instance
mInstance = u_application_instance_new_from_description_with_options(mDesc, mOptions);
@@ -110,19 +118,48 @@ QMirClientClientIntegration::QMirClientClientIntegration()
"running, and the correct socket is being used and is accessible. The shell may have\n"
"rejected the incoming connection, so check its log file");
- mNativeInterface->setMirConnection(u_application_instance_get_mir_connection(mInstance));
+ mMirConnection = u_application_instance_get_mir_connection(mInstance);
+
+ // Choose the default surface format suited to the Mir platform
+ QSurfaceFormat defaultFormat;
+ defaultFormat.setRedBufferSize(8);
+ defaultFormat.setGreenBufferSize(8);
+ defaultFormat.setBlueBufferSize(8);
+ QSurfaceFormat::setDefaultFormat(defaultFormat);
+
+ // Initialize EGL.
+ mEglNativeDisplay = mir_connection_get_egl_native_display(mMirConnection);
+ ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
+ ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
+
+ // Has debug mode been requsted, either with "-testability" switch or QT_LOAD_TESTABILITY env var
+ bool testability = qEnvironmentVariableIsSet("QT_LOAD_TESTABILITY");
+ for (int i=1; !testability && i<argc; i++) {
+ if (strcmp(argv[i], "-testability") == 0) {
+ testability = true;
+ }
+ }
+ if (testability) {
+ mDebugExtension.reset(new QMirClientDebugExtension);
+ }
+}
- // Create default screen.
- screenAdded(new QMirClientScreen(u_application_instance_get_mir_connection(mInstance)));
+void QMirClientClientIntegration::initialize()
+{
+ // Init the ScreenObserver
+ mScreenObserver.reset(new QMirClientScreenObserver(mMirConnection));
+ connect(mScreenObserver.data(), &QMirClientScreenObserver::screenAdded,
+ [this](QMirClientScreen *screen) { this->screenAdded(screen); });
+ connect(mScreenObserver.data(), &QMirClientScreenObserver::screenRemoved,
+ this, &QMirClientClientIntegration::destroyScreen);
+
+ Q_FOREACH (auto screen, mScreenObserver->screens()) {
+ screenAdded(screen);
+ }
// Initialize input.
- if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_INPUT")) {
- mInput = new QMirClientInput(this);
- mInputContext = QPlatformInputContextFactory::create();
- } else {
- mInput = nullptr;
- mInputContext = nullptr;
- }
+ mInput = new QMirClientInput(this);
+ mInputContext = QPlatformInputContextFactory::create();
// compute the scale factor
const int defaultGridUnit = 8;
@@ -140,10 +177,9 @@ QMirClientClientIntegration::QMirClientClientIntegration()
QMirClientClientIntegration::~QMirClientClientIntegration()
{
+ eglTerminate(mEglDisplay);
delete mInput;
delete mInputContext;
- for (QScreen *screen : QGuiApplication::screens())
- QPlatformIntegration::destroyScreen(screen->handle());
delete mServices;
}
@@ -152,9 +188,8 @@ QPlatformServices *QMirClientClientIntegration::services() const
return mServices;
}
-void QMirClientClientIntegration::setupOptions()
+void QMirClientClientIntegration::setupOptions(QStringList &args)
{
- QStringList args = QCoreApplication::arguments();
int argc = args.size() + 1;
char **argv = new char*[argc];
for (int i = 0; i < argc - 1; i++)
@@ -168,10 +203,11 @@ void QMirClientClientIntegration::setupOptions()
delete [] argv;
}
-void QMirClientClientIntegration::setupDescription()
+void QMirClientClientIntegration::setupDescription(QByteArray &sessionName)
{
mDesc = u_application_description_new();
- UApplicationId* id = u_application_id_new_from_stringn("QtUbuntu", 8);
+
+ UApplicationId* id = u_application_id_new_from_stringn(sessionName.data(), sessionName.count());
u_application_description_set_application_id(mDesc, id);
UApplicationLifecycleDelegate* delegate = u_application_lifecycle_delegate_new();
@@ -181,43 +217,66 @@ void QMirClientClientIntegration::setupDescription()
u_application_description_set_application_lifecycle_delegate(mDesc, delegate);
}
-QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
+QByteArray QMirClientClientIntegration::generateSessionName(QStringList &args)
{
- return const_cast<QMirClientClientIntegration*>(this)->createPlatformWindow(window);
+ // Try to come up with some meaningful session name to uniquely identify this session,
+ // helping with shell debugging
+
+ if (args.count() == 0) {
+ return QByteArray("QtUbuntu");
+ } if (args[0].contains("qmlscene")) {
+ return generateSessionNameFromQmlFile(args);
+ } else {
+ // use the executable name
+ QFileInfo fileInfo(args[0]);
+ return fileInfo.fileName().toLocal8Bit();
+ }
}
-QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window)
+QByteArray QMirClientClientIntegration::generateSessionNameFromQmlFile(QStringList &args)
{
- return new QMirClientWindow(window, mClipboard, screen(),
- mInput, u_application_instance_get_mir_connection(mInstance));
+ Q_FOREACH (QString arg, args) {
+ if (arg.endsWith(".qml")) {
+ QFileInfo fileInfo(arg);
+ return fileInfo.fileName().toLocal8Bit();
+ }
+ }
+
+ // give up
+ return "qmlscene";
}
-QMirClientScreen *QMirClientClientIntegration::screen() const
+QPlatformWindow* QMirClientClientIntegration::createPlatformWindow(QWindow* window) const
{
- return static_cast<QMirClientScreen *>(QGuiApplication::primaryScreen()->handle());
+ if (window->type() == Qt::Desktop) {
+ // Desktop windows should not be backed up by a mir surface as they don't draw anything (nor should).
+ return new QMirClientDesktopWindow(window);
+ } else {
+ return new QMirClientWindow(window, mInput, mNativeInterface, mAppStateController.data(),
+ mEglDisplay, mMirConnection, mDebugExtension.data());
+ }
}
bool QMirClientClientIntegration::hasCapability(QPlatformIntegration::Capability cap) const
{
switch (cap) {
- case ThreadedPixmaps:
- return true;
-
- case OpenGL:
- return true;
-
- case ApplicationState:
- return true;
-
case ThreadedOpenGL:
if (qEnvironmentVariableIsEmpty("QTUBUNTU_NO_THREADED_OPENGL")) {
return true;
} else {
- DLOG("ubuntumirclient: disabled threaded OpenGL");
+ qCDebug(mirclient, "disabled threaded OpenGL");
return false;
}
+
+ case ThreadedPixmaps:
+ case OpenGL:
+ case ApplicationState:
case MultipleWindows:
case NonFullScreenWindows:
+#if QT_VERSION > QT_VERSION_CHECK(5, 5, 0)
+ case SwitchableWidgetComposition:
+#endif
+ case RasterGLSurface: // needed for QQuickWidget
return true;
default:
return QPlatformIntegration::hasCapability(cap);
@@ -237,14 +296,25 @@ QPlatformBackingStore* QMirClientClientIntegration::createPlatformBackingStore(Q
QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
QOpenGLContext* context) const
{
- return const_cast<QMirClientClientIntegration*>(this)->createPlatformOpenGLContext(context);
-}
-
-QPlatformOpenGLContext* QMirClientClientIntegration::createPlatformOpenGLContext(
- QOpenGLContext* context)
-{
- return new QMirClientOpenGLContext(static_cast<QMirClientScreen*>(context->screen()->handle()),
- static_cast<QMirClientOpenGLContext*>(context->shareHandle()));
+ QSurfaceFormat format(context->format());
+
+ auto platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay);
+ if (!platformContext->isValid()) {
+ // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
+ // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
+ // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to
+ // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
+ // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
+ static const bool isMesa = QString(eglQueryString(mEglDisplay, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
+ if (isMesa) {
+ qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
+ format.setMajorVersion(1);
+ format.setMinorVersion(4);
+ delete platformContext;
+ platformContext = new QMirClientOpenGLContext(format, context->shareHandle(), mEglDisplay);
+ }
+ }
+ return platformContext;
}
QStringList QMirClientClientIntegration::themeNames() const
@@ -277,10 +347,65 @@ QVariant QMirClientClientIntegration::styleHint(StyleHint hint) const
QPlatformClipboard* QMirClientClientIntegration::clipboard() const
{
- return mClipboard.data();
+ static QPlatformClipboard *clipboard = nullptr;
+ if (!clipboard) {
+ clipboard = new QMirClientClipboard;
+ }
+ return clipboard;
}
QPlatformNativeInterface* QMirClientClientIntegration::nativeInterface() const
{
return mNativeInterface;
}
+
+QPlatformOffscreenSurface *QMirClientClientIntegration::createPlatformOffscreenSurface(
+ QOffscreenSurface *surface) const
+{
+ return new QEGLPbuffer(mEglDisplay, surface->requestedFormat(), surface);
+}
+
+void QMirClientClientIntegration::destroyScreen(QMirClientScreen *screen)
+{
+ // FIXME: on deleting a screen while a Window is on it, Qt will automatically
+ // move the window to the primaryScreen(). This will trigger a screenChanged
+ // signal, causing things like QQuickScreenAttached to re-fetch screen properties
+ // like DPI and physical size. However this is crashing, as Qt is calling virtual
+ // functions on QPlatformScreen, for reasons unclear. As workaround, move window
+ // to primaryScreen() before deleting the screen. Might be QTBUG-38650
+
+ QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ if (screen != primaryScreen->handle()) {
+ uint32_t movedWindowCount = 0;
+ Q_FOREACH (QWindow *w, QGuiApplication::topLevelWindows()) {
+ if (w->screen()->handle() == screen) {
+ QWindowSystemInterface::handleWindowScreenChanged(w, primaryScreen);
+ ++movedWindowCount;
+ }
+ }
+ if (movedWindowCount > 0) {
+ QWindowSystemInterface::flushWindowSystemEvents();
+ }
+ }
+
+ qCDebug(mirclient) << "Removing Screen with id" << screen->mirOutputId() << "and geometry" << screen->geometry();
+#if QT_VERSION < QT_VERSION_CHECK(5, 5, 0)
+ delete screen;
+#else
+ QPlatformIntegration::destroyScreen(screen);
+#endif
+}
+
+#ifndef QT_NO_ACCESSIBILITY
+QPlatformAccessibility *QMirClientClientIntegration::accessibility() const
+{
+#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE)
+ if (!mAccessibility) {
+ Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QMirClientIntegration",
+ "Initializing accessibility without event-dispatcher!");
+ mAccessibility.reset(new QSpiAccessibleBridge());
+ }
+#endif
+ return mAccessibility.data();
+}
+#endif
diff --git a/src/plugins/platforms/mirclient/qmirclientintegration.h b/src/plugins/platforms/mirclient/qmirclientintegration.h
index 97317a310a..035117f4da 100644
--- a/src/plugins/platforms/mirclient/qmirclientintegration.h
+++ b/src/plugins/platforms/mirclient/qmirclientintegration.h
@@ -44,20 +44,28 @@
#include <qpa/qplatformintegration.h>
#include <QSharedPointer>
+#include "qmirclientappstatecontroller.h"
#include "qmirclientplatformservices.h"
+#include "qmirclientscreenobserver.h"
// platform-api
#include <ubuntu/application/description.h>
#include <ubuntu/application/instance.h>
-class QMirClientClipboard;
+#include <EGL/egl.h>
+
+class QMirClientDebugExtension;
class QMirClientInput;
class QMirClientNativeInterface;
class QMirClientScreen;
+class MirConnection;
+
+class QMirClientClientIntegration : public QObject, public QPlatformIntegration
+{
+ Q_OBJECT
-class QMirClientClientIntegration : public QPlatformIntegration {
public:
- QMirClientClientIntegration();
+ QMirClientClientIntegration(int argc, char **argv);
virtual ~QMirClientClientIntegration();
// QPlatformIntegration methods.
@@ -74,14 +82,26 @@ public:
QPlatformWindow* createPlatformWindow(QWindow* window) const override;
QPlatformInputContext* inputContext() const override { return mInputContext; }
QPlatformClipboard* clipboard() const override;
+ void initialize() override;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const override;
+ QPlatformAccessibility *accessibility() const override;
+
+ // New methods.
+ MirConnection *mirConnection() const { return mMirConnection; }
+ EGLDisplay eglDisplay() const { return mEglDisplay; }
+ EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
+ QMirClientAppStateController *appStateController() const { return mAppStateController.data(); }
+ QMirClientScreenObserver *screenObserver() const { return mScreenObserver.data(); }
+ QMirClientDebugExtension *debugExtension() const { return mDebugExtension.data(); }
- QPlatformOpenGLContext* createPlatformOpenGLContext(QOpenGLContext* context);
- QPlatformWindow* createPlatformWindow(QWindow* window);
- QMirClientScreen* screen() const;
+private Q_SLOTS:
+ void destroyScreen(QMirClientScreen *screen);
private:
- void setupOptions();
- void setupDescription();
+ void setupOptions(QStringList &args);
+ void setupDescription(QByteArray &sessionName);
+ static QByteArray generateSessionName(QStringList &args);
+ static QByteArray generateSessionNameFromQmlFile(QStringList &args);
QMirClientNativeInterface* mNativeInterface;
QPlatformFontDatabase* mFontDb;
@@ -90,13 +110,22 @@ private:
QMirClientInput* mInput;
QPlatformInputContext* mInputContext;
- QSharedPointer<QMirClientClipboard> mClipboard;
+ mutable QScopedPointer<QPlatformAccessibility> mAccessibility;
+ QScopedPointer<QMirClientDebugExtension> mDebugExtension;
+ QScopedPointer<QMirClientScreenObserver> mScreenObserver;
+ QScopedPointer<QMirClientAppStateController> mAppStateController;
qreal mScaleFactor;
+ MirConnection *mMirConnection;
+
// Platform API stuff
UApplicationOptions* mOptions;
UApplicationDescription* mDesc;
UApplicationInstance* mInstance;
+
+ // EGL related
+ EGLDisplay mEglDisplay{EGL_NO_DISPLAY};
+ EGLNativeDisplayType mEglNativeDisplay;
};
#endif // QMIRCLIENTINTEGRATION_H
diff --git a/src/plugins/platforms/mirclient/qmirclientlogging.h b/src/plugins/platforms/mirclient/qmirclientlogging.h
index 0eb3adbdc7..4921864ced 100644
--- a/src/plugins/platforms/mirclient/qmirclientlogging.h
+++ b/src/plugins/platforms/mirclient/qmirclientlogging.h
@@ -41,23 +41,15 @@
#ifndef QMIRCLIENTLOGGING_H
#define QMIRCLIENTLOGGING_H
-// Logging and assertion macros.
-#define LOG(...) qDebug(__VA_ARGS__)
-#define LOG_IF(cond,...) do { if (cond) qDebug(__VA_ARGS__); } while (0)
+#include <QLoggingCategory>
+
#define ASSERT(cond) ((!(cond)) ? qt_assert(#cond,__FILE__,__LINE__) : qt_noop())
-#define NOT_REACHED() qt_assert("Not reached!",__FILE__,__LINE__)
-// Logging and assertion macros are compiled out for release builds.
-#if !defined(QT_NO_DEBUG)
-#define DLOG(...) LOG(__VA_ARGS__)
-#define DLOG_IF(cond,...) LOG_IF((cond), __VA_ARGS__)
-#define DASSERT(cond) ASSERT((cond))
-#define DNOT_REACHED() NOT_REACHED()
-#else
-#define DLOG(...) qt_noop()
-#define DLOG_IF(cond,...) qt_noop()
-#define DASSERT(cond) qt_noop()
-#define DNOT_REACHED() qt_noop()
-#endif
+Q_DECLARE_LOGGING_CATEGORY(mirclient)
+Q_DECLARE_LOGGING_CATEGORY(mirclientBufferSwap)
+Q_DECLARE_LOGGING_CATEGORY(mirclientInput)
+Q_DECLARE_LOGGING_CATEGORY(mirclientGraphics)
+Q_DECLARE_LOGGING_CATEGORY(mirclientCursor)
+Q_DECLARE_LOGGING_CATEGORY(mirclientDebug)
#endif // QMIRCLIENTLOGGING_H
diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
index 033df6ba11..b85e6fedfa 100644
--- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientnativeinterface.cpp
@@ -42,32 +42,36 @@
#include "qmirclientnativeinterface.h"
#include "qmirclientscreen.h"
#include "qmirclientglcontext.h"
+#include "qmirclientwindow.h"
// Qt
-#include <private/qguiapplication_p.h>
+#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qscreen.h>
#include <QtCore/QMap>
-class QMirClientResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType>
+class UbuntuResourceMap : public QMap<QByteArray, QMirClientNativeInterface::ResourceType>
{
public:
- QMirClientResourceMap()
+ UbuntuResourceMap()
: QMap<QByteArray, QMirClientNativeInterface::ResourceType>() {
insert("egldisplay", QMirClientNativeInterface::EglDisplay);
insert("eglcontext", QMirClientNativeInterface::EglContext);
insert("nativeorientation", QMirClientNativeInterface::NativeOrientation);
insert("display", QMirClientNativeInterface::Display);
insert("mirconnection", QMirClientNativeInterface::MirConnection);
+ insert("mirsurface", QMirClientNativeInterface::MirSurface);
+ insert("scale", QMirClientNativeInterface::Scale);
+ insert("formfactor", QMirClientNativeInterface::FormFactor);
}
};
-Q_GLOBAL_STATIC(QMirClientResourceMap, ubuntuResourceMap)
+Q_GLOBAL_STATIC(UbuntuResourceMap, ubuntuResourceMap)
-QMirClientNativeInterface::QMirClientNativeInterface()
- : mGenericEventFilterType(QByteArrayLiteral("Event"))
+QMirClientNativeInterface::QMirClientNativeInterface(const QMirClientClientIntegration *integration)
+ : mIntegration(integration)
+ , mGenericEventFilterType(QByteArrayLiteral("Event"))
, mNativeOrientation(nullptr)
- , mMirConnection(nullptr)
{
}
@@ -88,7 +92,7 @@ void* QMirClientNativeInterface::nativeResourceForIntegration(const QByteArray &
const ResourceType resourceType = ubuntuResourceMap()->value(lowerCaseResource);
if (resourceType == QMirClientNativeInterface::MirConnection) {
- return mMirConnection;
+ return mIntegration->mirConnection();
} else {
return nullptr;
}
@@ -119,14 +123,11 @@ void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resou
if (!ubuntuResourceMap()->contains(kLowerCaseResource))
return NULL;
const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
- if (kResourceType == QMirClientNativeInterface::EglDisplay) {
- if (window) {
- return static_cast<QMirClientScreen*>(window->screen()->handle())->eglDisplay();
- } else {
- return static_cast<QMirClientScreen*>(
- QGuiApplication::primaryScreen()->handle())->eglDisplay();
- }
- } else if (kResourceType == QMirClientNativeInterface::NativeOrientation) {
+
+ switch (kResourceType) {
+ case EglDisplay:
+ return mIntegration->eglDisplay();
+ case NativeOrientation:
// Return the device's native screen orientation.
if (window) {
QMirClientScreen *ubuntuScreen = static_cast<QMirClientScreen*>(window->screen()->handle());
@@ -136,8 +137,19 @@ void* QMirClientNativeInterface::nativeResourceForWindow(const QByteArray& resou
mNativeOrientation = new Qt::ScreenOrientation(platformScreen->nativeOrientation());
}
return mNativeOrientation;
- } else {
- return NULL;
+ case MirSurface:
+ if (window) {
+ auto ubuntuWindow = static_cast<QMirClientWindow*>(window->handle());
+ if (ubuntuWindow) {
+ return ubuntuWindow->mirSurface();
+ } else {
+ return nullptr;
+ }
+ } else {
+ return nullptr;
+ }
+ default:
+ return nullptr;
}
}
@@ -147,10 +159,59 @@ void* QMirClientNativeInterface::nativeResourceForScreen(const QByteArray& resou
if (!ubuntuResourceMap()->contains(kLowerCaseResource))
return NULL;
const ResourceType kResourceType = ubuntuResourceMap()->value(kLowerCaseResource);
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ auto ubuntuScreen = static_cast<QMirClientScreen*>(screen->handle());
if (kResourceType == QMirClientNativeInterface::Display) {
- if (!screen)
- screen = QGuiApplication::primaryScreen();
- return static_cast<QMirClientScreen*>(screen->handle())->eglNativeDisplay();
+ return mIntegration->eglNativeDisplay();
+ // Changes to the following properties are emitted via the QMirClientNativeInterface::screenPropertyChanged
+ // signal fired by QMirClientScreen. Connect to this signal for these properties updates.
+ // WARNING: code highly thread unsafe!
+ } else if (kResourceType == QMirClientNativeInterface::Scale) {
+ // In application code, read with:
+ // float scale = *reinterpret_cast<float*>(nativeResourceForScreen("scale", screen()));
+ return &ubuntuScreen->mScale;
+ } else if (kResourceType == QMirClientNativeInterface::FormFactor) {
+ return &ubuntuScreen->mFormFactor;
} else
return NULL;
}
+
+// Changes to these properties are emitted via the QMirClientNativeInterface::windowPropertyChanged
+// signal fired by QMirClientWindow. Connect to this signal for these properties updates.
+QVariantMap QMirClientNativeInterface::windowProperties(QPlatformWindow *window) const
+{
+ QVariantMap propertyMap;
+ auto w = static_cast<QMirClientWindow*>(window);
+ if (w) {
+ propertyMap.insert("scale", w->scale());
+ propertyMap.insert("formFactor", w->formFactor());
+ }
+ return propertyMap;
+}
+
+QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name) const
+{
+ auto w = static_cast<QMirClientWindow*>(window);
+ if (!w) {
+ return QVariant();
+ }
+
+ if (name == QStringLiteral("scale")) {
+ return w->scale();
+ } else if (name == QStringLiteral("formFactor")) {
+ return w->formFactor();
+ } else {
+ return QVariant();
+ }
+}
+
+QVariant QMirClientNativeInterface::windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const
+{
+ QVariant returnVal = windowProperty(window, name);
+ if (!returnVal.isValid()) {
+ return defaultValue;
+ } else {
+ return returnVal;
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
index 78a440e956..eb601de301 100644
--- a/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
+++ b/src/plugins/platforms/mirclient/qmirclientnativeinterface.h
@@ -43,11 +43,16 @@
#include <qpa/qplatformnativeinterface.h>
+#include "qmirclientintegration.h"
+
+class QPlatformScreen;
+
class QMirClientNativeInterface : public QPlatformNativeInterface {
+ Q_OBJECT
public:
- enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection };
+ enum ResourceType { EglDisplay, EglContext, NativeOrientation, Display, MirConnection, MirSurface, Scale, FormFactor };
- QMirClientNativeInterface();
+ QMirClientNativeInterface(const QMirClientClientIntegration *integration);
~QMirClientNativeInterface();
// QPlatformNativeInterface methods.
@@ -59,14 +64,20 @@ public:
void* nativeResourceForScreen(const QByteArray& resourceString,
QScreen* screen) override;
+ QVariantMap windowProperties(QPlatformWindow *window) const override;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name) const override;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override;
+
// New methods.
const QByteArray& genericEventFilterType() const { return mGenericEventFilterType; }
- void setMirConnection(void *mirConnection) { mMirConnection = mirConnection; }
+
+Q_SIGNALS: // New signals
+ void screenPropertyChanged(QPlatformScreen *screen, const QString &propertyName);
private:
+ const QMirClientClientIntegration *mIntegration;
const QByteArray mGenericEventFilterType;
Qt::ScreenOrientation* mNativeOrientation;
- void *mMirConnection;
};
#endif // QMIRCLIENTNATIVEINTERFACE_H
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.cpp b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
index 6899d70f2e..fc44edfe40 100644
--- a/src/plugins/platforms/mirclient/qmirclientplugin.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientplugin.cpp
@@ -40,12 +40,16 @@
#include "qmirclientplugin.h"
#include "qmirclientintegration.h"
+#include "qmirclientlogging.h"
-QPlatformIntegration* QMirClientIntegrationPlugin::create(const QString &system,
- const QStringList &)
+Q_LOGGING_CATEGORY(mirclient, "qt.qpa.mirclient", QtWarningMsg)
+
+QPlatformIntegration *QMirClientIntegrationPlugin::create(const QString &system,
+ const QStringList &/*paramList*/,
+ int &argc, char **argv)
{
if (system.toLower() == QLatin1String("mirclient")) {
- return new QMirClientClientIntegration;
+ return new QMirClientClientIntegration(argc, argv);
} else {
return 0;
}
diff --git a/src/plugins/platforms/mirclient/qmirclientplugin.h b/src/plugins/platforms/mirclient/qmirclientplugin.h
index c91f2d1924..207d97b5af 100644
--- a/src/plugins/platforms/mirclient/qmirclientplugin.h
+++ b/src/plugins/platforms/mirclient/qmirclientplugin.h
@@ -49,7 +49,8 @@ class QMirClientIntegrationPlugin : public QPlatformIntegrationPlugin
Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "mirclient.json")
public:
- QPlatformIntegration* create(const QString&, const QStringList&);
+ QPlatformIntegration *create(const QString &system, const QStringList &paramList,
+ int &argc, char **argv) override;
};
#endif // QMIRCLIENTPLUGIN_H
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.cpp b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
index 0a2253e9e2..cc8db830aa 100644
--- a/src/plugins/platforms/mirclient/qmirclientscreen.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientscreen.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -42,11 +42,12 @@
#include "qmirclientscreen.h"
#include "qmirclientlogging.h"
#include "qmirclientorientationchangeevent_p.h"
+#include "qmirclientnativeinterface.h"
#include <mir_toolkit/mir_client_library.h>
// Qt
-#include <QCoreApplication>
+#include <QGuiApplication>
#include <QtCore/qmath.h>
#include <QScreen>
#include <QThread>
@@ -55,9 +56,7 @@
#include <memory>
-static const int kSwapInterval = 1;
-
-#if !defined(QT_NO_DEBUG)
+static const int overrideDevicePixelRatio = qgetenv("QT_DEVICE_PIXEL_RATIO").toInt();
static const char *orientationToStr(Qt::ScreenOrientation orientation) {
switch (orientation) {
@@ -71,173 +70,33 @@ static const char *orientationToStr(Qt::ScreenOrientation orientation) {
return "inverted portrait";
case Qt::InvertedLandscapeOrientation:
return "inverted landscape";
- default:
- return "INVALID!";
}
+ Q_UNREACHABLE();
}
-static void printEglConfig(EGLDisplay display, EGLConfig config) {
- DASSERT(display != EGL_NO_DISPLAY);
- DASSERT(config != nullptr);
- static const struct { const EGLint attrib; const char* name; } kAttribs[] = {
- { EGL_BUFFER_SIZE, "EGL_BUFFER_SIZE" },
- { EGL_ALPHA_SIZE, "EGL_ALPHA_SIZE" },
- { EGL_BLUE_SIZE, "EGL_BLUE_SIZE" },
- { EGL_GREEN_SIZE, "EGL_GREEN_SIZE" },
- { EGL_RED_SIZE, "EGL_RED_SIZE" },
- { EGL_DEPTH_SIZE, "EGL_DEPTH_SIZE" },
- { EGL_STENCIL_SIZE, "EGL_STENCIL_SIZE" },
- { EGL_CONFIG_CAVEAT, "EGL_CONFIG_CAVEAT" },
- { EGL_CONFIG_ID, "EGL_CONFIG_ID" },
- { EGL_LEVEL, "EGL_LEVEL" },
- { EGL_MAX_PBUFFER_HEIGHT, "EGL_MAX_PBUFFER_HEIGHT" },
- { EGL_MAX_PBUFFER_PIXELS, "EGL_MAX_PBUFFER_PIXELS" },
- { EGL_MAX_PBUFFER_WIDTH, "EGL_MAX_PBUFFER_WIDTH" },
- { EGL_NATIVE_RENDERABLE, "EGL_NATIVE_RENDERABLE" },
- { EGL_NATIVE_VISUAL_ID, "EGL_NATIVE_VISUAL_ID" },
- { EGL_NATIVE_VISUAL_TYPE, "EGL_NATIVE_VISUAL_TYPE" },
- { EGL_SAMPLES, "EGL_SAMPLES" },
- { EGL_SAMPLE_BUFFERS, "EGL_SAMPLE_BUFFERS" },
- { EGL_SURFACE_TYPE, "EGL_SURFACE_TYPE" },
- { EGL_TRANSPARENT_TYPE, "EGL_TRANSPARENT_TYPE" },
- { EGL_TRANSPARENT_BLUE_VALUE, "EGL_TRANSPARENT_BLUE_VALUE" },
- { EGL_TRANSPARENT_GREEN_VALUE, "EGL_TRANSPARENT_GREEN_VALUE" },
- { EGL_TRANSPARENT_RED_VALUE, "EGL_TRANSPARENT_RED_VALUE" },
- { EGL_BIND_TO_TEXTURE_RGB, "EGL_BIND_TO_TEXTURE_RGB" },
- { EGL_BIND_TO_TEXTURE_RGBA, "EGL_BIND_TO_TEXTURE_RGBA" },
- { EGL_MIN_SWAP_INTERVAL, "EGL_MIN_SWAP_INTERVAL" },
- { EGL_MAX_SWAP_INTERVAL, "EGL_MAX_SWAP_INTERVAL" },
- { -1, NULL }
- };
- const char* string = eglQueryString(display, EGL_VENDOR);
- LOG("EGL vendor: %s", string);
- string = eglQueryString(display, EGL_VERSION);
- LOG("EGL version: %s", string);
- string = eglQueryString(display, EGL_EXTENSIONS);
- LOG("EGL extensions: %s", string);
- LOG("EGL configuration attibutes:");
- for (int index = 0; kAttribs[index].attrib != -1; index++) {
- EGLint value;
- if (eglGetConfigAttrib(display, config, kAttribs[index].attrib, &value))
- LOG(" %s: %d", kAttribs[index].name, static_cast<int>(value));
- }
-}
-#endif
-
-
const QEvent::Type OrientationChangeEvent::mType =
static_cast<QEvent::Type>(QEvent::registerEventType());
-static const MirDisplayOutput *find_active_output(
- const MirDisplayConfiguration *conf)
-{
- const MirDisplayOutput *output = NULL;
- for (uint32_t d = 0; d < conf->num_outputs; d++)
- {
- const MirDisplayOutput *out = conf->outputs + d;
-
- if (out->used &&
- out->connected &&
- out->num_modes &&
- out->current_mode < out->num_modes)
- {
- output = out;
- break;
- }
- }
-
- return output;
-}
-QMirClientScreen::QMirClientScreen(MirConnection *connection)
- : mFormat(QImage::Format_RGB32)
+QMirClientScreen::QMirClientScreen(const MirOutput *output, MirConnection *connection)
+ : mDevicePixelRatio(1.0)
+ , mFormat(QImage::Format_RGB32)
, mDepth(32)
+ , mDpi{0}
+ , mFormFactor{mir_form_factor_unknown}
+ , mScale{1.0}
, mOutputId(0)
- , mSurfaceFormat()
- , mEglDisplay(EGL_NO_DISPLAY)
- , mEglConfig(nullptr)
, mCursor(connection)
{
- // Initialize EGL.
- ASSERT(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
-
- mEglNativeDisplay = mir_connection_get_egl_native_display(connection);
- ASSERT((mEglDisplay = eglGetDisplay(mEglNativeDisplay)) != EGL_NO_DISPLAY);
- ASSERT(eglInitialize(mEglDisplay, nullptr, nullptr) == EGL_TRUE);
-
- // Configure EGL buffers format.
- mSurfaceFormat.setRedBufferSize(8);
- mSurfaceFormat.setGreenBufferSize(8);
- mSurfaceFormat.setBlueBufferSize(8);
- mSurfaceFormat.setAlphaBufferSize(8);
- mSurfaceFormat.setDepthBufferSize(24);
- mSurfaceFormat.setStencilBufferSize(8);
- if (!qEnvironmentVariableIsEmpty("QTUBUNTU_MULTISAMPLE")) {
- mSurfaceFormat.setSamples(4);
- DLOG("ubuntumirclient: setting MSAA to 4 samples");
- }
-#ifdef QTUBUNTU_USE_OPENGL
- mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGL);
-#else
- mSurfaceFormat.setRenderableType(QSurfaceFormat::OpenGLES);
-#endif
- mEglConfig = q_configFromGLFormat(mEglDisplay, mSurfaceFormat, true);
-
- #if !defined(QT_NO_DEBUG)
- printEglConfig(mEglDisplay, mEglConfig);
- #endif
-
- // Set vblank swap interval.
- int swapInterval = kSwapInterval;
- QByteArray swapIntervalString = qgetenv("QTUBUNTU_SWAPINTERVAL");
- if (!swapIntervalString.isEmpty()) {
- bool ok;
- swapInterval = swapIntervalString.toInt(&ok);
- if (!ok)
- swapInterval = kSwapInterval;
- }
- DLOG("ubuntumirclient: setting swap interval to %d", swapInterval);
- eglSwapInterval(mEglDisplay, swapInterval);
-
- // Get screen resolution.
- auto configDeleter = [](MirDisplayConfiguration *config) { mir_display_config_destroy(config); };
- using configUp = std::unique_ptr<MirDisplayConfiguration, decltype(configDeleter)>;
- configUp displayConfig(mir_connection_create_display_config(connection), configDeleter);
- ASSERT(displayConfig != nullptr);
-
- auto const displayOutput = find_active_output(displayConfig.get());
- ASSERT(displayOutput != nullptr);
-
- mOutputId = displayOutput->output_id;
-
- mPhysicalSize = QSizeF(displayOutput->physical_width_mm, displayOutput->physical_height_mm);
- DLOG("ubuntumirclient: screen physical size: %.2fx%.2f", mPhysicalSize.width(), mPhysicalSize.height());
-
- const MirDisplayMode *mode = &displayOutput->modes[displayOutput->current_mode];
- const int kScreenWidth = mode->horizontal_resolution;
- const int kScreenHeight = mode->vertical_resolution;
- DASSERT(kScreenWidth > 0 && kScreenHeight > 0);
-
- DLOG("ubuntumirclient: screen resolution: %dx%d", kScreenWidth, kScreenHeight);
-
- mGeometry = QRect(0, 0, kScreenWidth, kScreenHeight);
-
- DLOG("QQMirClientScreen::QQMirClientScreen (this=%p)", this);
-
- // Set the default orientation based on the initial screen dimmensions.
- mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
-
- // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
- mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+ setMirOutput(output);
}
QMirClientScreen::~QMirClientScreen()
{
- eglTerminate(mEglDisplay);
}
void QMirClientScreen::customEvent(QEvent* event) {
- DASSERT(QThread::currentThread() == thread());
+ Q_ASSERT(QThread::currentThread() == thread());
OrientationChangeEvent* oReadingEvent = static_cast<OrientationChangeEvent*>(event);
switch (oReadingEvent->mOrientation) {
@@ -261,14 +120,10 @@ void QMirClientScreen::customEvent(QEvent* event) {
Qt::InvertedLandscapeOrientation : Qt::InvertedPortraitOrientation;
break;
}
- default: {
- DLOG("QMirClientScreen::customEvent - Unknown orientation.");
- return;
- }
}
// Raise the event signal so that client apps know the orientation changed
- DLOG("QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
+ qCDebug(mirclient, "QMirClientScreen::customEvent - handling orientation change to %s", orientationToStr(mCurrentOrientation));
QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
}
@@ -289,7 +144,7 @@ void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeig
mGeometry.setWidth(currGeometry.height());
mGeometry.setHeight(currGeometry.width());
- DLOG("QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
+ qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new screen geometry (w=%d, h=%d)",
mGeometry.width(), mGeometry.height());
QWindowSystemInterface::handleScreenGeometryChange(screen(),
mGeometry /* newGeometry */,
@@ -300,7 +155,108 @@ void QMirClientScreen::handleWindowSurfaceResize(int windowWidth, int windowHeig
} else {
mCurrentOrientation = Qt::LandscapeOrientation;
}
- DLOG("QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
+ qCDebug(mirclient, "QMirClientScreen::handleWindowSurfaceResize - new orientation %s",orientationToStr(mCurrentOrientation));
QWindowSystemInterface::handleScreenOrientationChange(screen(), mCurrentOrientation);
}
}
+
+void QMirClientScreen::setMirOutput(const MirOutput *output)
+{
+ // Physical screen size (in mm)
+ mPhysicalSize.setWidth(mir_output_get_physical_width_mm(output));
+ mPhysicalSize.setHeight(mir_output_get_physical_height_mm(output));
+
+ // Pixel Format
+// mFormat = qImageFormatFromMirPixelFormat(mir_output_get_current_pixel_format(output)); // GERRY: TODO
+
+ // Pixel depth
+ mDepth = 8 * MIR_BYTES_PER_PIXEL(mir_output_get_current_pixel_format(output));
+
+ // Mode = Resolution & refresh rate
+ const MirOutputMode *mode = mir_output_get_current_mode(output);
+ mNativeGeometry.setX(mir_output_get_position_x(output));
+ mNativeGeometry.setY(mir_output_get_position_y(output));
+ mNativeGeometry.setWidth(mir_output_mode_get_width(mode));
+ mNativeGeometry.setHeight(mir_output_mode_get_height(mode));
+
+ mRefreshRate = mir_output_mode_get_refresh_rate(mode);
+
+ // UI scale & DPR
+ mScale = mir_output_get_scale_factor(output);
+ if (overrideDevicePixelRatio > 0) {
+ mDevicePixelRatio = overrideDevicePixelRatio;
+ } else {
+ mDevicePixelRatio = 1.0; // FIXME - need to determine suitable DPR for the specified scale
+ }
+
+ mFormFactor = mir_output_get_form_factor(output);
+
+ mOutputId = mir_output_get_id(output);
+
+ mGeometry.setX(mNativeGeometry.x());
+ mGeometry.setY(mNativeGeometry.y());
+ mGeometry.setWidth(mNativeGeometry.width());
+ mGeometry.setHeight(mNativeGeometry.height());
+
+ // Set the default orientation based on the initial screen dimensions.
+ mNativeOrientation = (mGeometry.width() >= mGeometry.height()) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+
+ // If it's a landscape device (i.e. some tablets), start in landscape, otherwise portrait
+ mCurrentOrientation = (mNativeOrientation == Qt::LandscapeOrientation) ? Qt::LandscapeOrientation : Qt::PortraitOrientation;
+}
+
+void QMirClientScreen::updateMirOutput(const MirOutput *output)
+{
+ auto oldRefreshRate = mRefreshRate;
+ auto oldScale = mScale;
+ auto oldFormFactor = mFormFactor;
+ auto oldGeometry = mGeometry;
+
+ setMirOutput(output);
+
+ // Emit change signals in particular order
+ if (oldGeometry != mGeometry) {
+ QWindowSystemInterface::handleScreenGeometryChange(screen(),
+ mGeometry /* newGeometry */,
+ mGeometry /* newAvailableGeometry */);
+ }
+
+ if (!qFuzzyCompare(mRefreshRate, oldRefreshRate)) {
+ QWindowSystemInterface::handleScreenRefreshRateChange(screen(), mRefreshRate);
+ }
+
+ auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface());
+ if (!qFuzzyCompare(mScale, oldScale)) {
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("scale"));
+ }
+ if (mFormFactor != oldFormFactor) {
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor"));
+ }
+}
+
+void QMirClientScreen::setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi)
+{
+ if (mDpi != dpi) {
+ mDpi = dpi;
+ QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(), dpi, dpi);
+ }
+
+ auto nativeInterface = static_cast<QMirClientNativeInterface *>(qGuiApp->platformNativeInterface());
+ if (!qFuzzyCompare(mScale, scale)) {
+ mScale = scale;
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("scale"));
+ }
+ if (mFormFactor != formFactor) {
+ mFormFactor = formFactor;
+ nativeInterface->screenPropertyChanged(this, QStringLiteral("formFactor"));
+ }
+}
+
+QDpi QMirClientScreen::logicalDpi() const
+{
+ if (mDpi > 0) {
+ return QDpi(mDpi, mDpi);
+ } else {
+ return QPlatformScreen::logicalDpi();
+ }
+}
diff --git a/src/plugins/platforms/mirclient/qmirclientscreen.h b/src/plugins/platforms/mirclient/qmirclientscreen.h
index b050836ada..b31cba1964 100644
--- a/src/plugins/platforms/mirclient/qmirclientscreen.h
+++ b/src/plugins/platforms/mirclient/qmirclientscreen.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -43,17 +43,19 @@
#include <qpa/qplatformscreen.h>
#include <QSurfaceFormat>
-#include <EGL/egl.h>
+
+#include <mir_toolkit/common.h> // just for MirFormFactor enum
#include "qmirclientcursor.h"
struct MirConnection;
+struct MirOutput;
class QMirClientScreen : public QObject, public QPlatformScreen
{
Q_OBJECT
public:
- QMirClientScreen(MirConnection *connection);
+ QMirClientScreen(const MirOutput *output, MirConnection *connection);
virtual ~QMirClientScreen();
// QPlatformScreen methods.
@@ -62,34 +64,43 @@ public:
QRect geometry() const override { return mGeometry; }
QRect availableGeometry() const override { return mGeometry; }
QSizeF physicalSize() const override { return mPhysicalSize; }
+ qreal devicePixelRatio() const override { return mDevicePixelRatio; }
+ QDpi logicalDpi() const override;
Qt::ScreenOrientation nativeOrientation() const override { return mNativeOrientation; }
Qt::ScreenOrientation orientation() const override { return mNativeOrientation; }
QPlatformCursor *cursor() const override { return const_cast<QMirClientCursor*>(&mCursor); }
- // New methods.
- QSurfaceFormat surfaceFormat() const { return mSurfaceFormat; }
- EGLDisplay eglDisplay() const { return mEglDisplay; }
- EGLConfig eglConfig() const { return mEglConfig; }
- EGLNativeDisplayType eglNativeDisplay() const { return mEglNativeDisplay; }
+ // Additional Screen properties from Mir
+ int mirOutputId() const { return mOutputId; }
+ MirFormFactor formFactor() const { return mFormFactor; }
+ float scale() const { return mScale; }
+
+ // Internally used methods
+ void updateMirOutput(const MirOutput *output);
+ void setAdditionalMirDisplayProperties(float scale, MirFormFactor formFactor, int dpi);
void handleWindowSurfaceResize(int width, int height);
- uint32_t mirOutputId() const { return mOutputId; }
// QObject methods.
void customEvent(QEvent* event) override;
private:
- QRect mGeometry;
+ void setMirOutput(const MirOutput *output);
+
+ QRect mGeometry, mNativeGeometry;
QSizeF mPhysicalSize;
+ qreal mDevicePixelRatio;
Qt::ScreenOrientation mNativeOrientation;
Qt::ScreenOrientation mCurrentOrientation;
QImage::Format mFormat;
int mDepth;
- uint32_t mOutputId;
- QSurfaceFormat mSurfaceFormat;
- EGLDisplay mEglDisplay;
- EGLConfig mEglConfig;
- EGLNativeDisplayType mEglNativeDisplay;
+ int mDpi;
+ qreal mRefreshRate;
+ MirFormFactor mFormFactor;
+ float mScale;
+ int mOutputId;
QMirClientCursor mCursor;
+
+ friend class QMirClientNativeInterface;
};
#endif // QMIRCLIENTSCREEN_H
diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp b/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp
new file mode 100644
index 0000000000..792aeca351
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientscreenobserver.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qmirclientscreenobserver.h"
+#include "qmirclientscreen.h"
+#include "qmirclientwindow.h"
+#include "qmirclientlogging.h"
+
+// Qt
+#include <QMetaObject>
+#include <QPointer>
+
+// Mir
+#include <mirclient/mir_toolkit/mir_connection.h>
+#include <mirclient/mir_toolkit/mir_display_configuration.h>
+
+#include <memory>
+
+namespace {
+ static void displayConfigurationChangedCallback(MirConnection */*connection*/, void* context)
+ {
+ ASSERT(context != NULL);
+ QMirClientScreenObserver *observer = static_cast<QMirClientScreenObserver *>(context);
+ QMetaObject::invokeMethod(observer, "update");
+ }
+
+ const char *mirFormFactorToStr(MirFormFactor formFactor)
+ {
+ switch (formFactor) {
+ case mir_form_factor_unknown: return "unknown";
+ case mir_form_factor_phone: return "phone";
+ case mir_form_factor_tablet: return "tablet";
+ case mir_form_factor_monitor: return "monitor";
+ case mir_form_factor_tv: return "tv";
+ case mir_form_factor_projector: return "projector";
+ }
+ Q_UNREACHABLE();
+ }
+} // anonymous namespace
+
+QMirClientScreenObserver::QMirClientScreenObserver(MirConnection *mirConnection)
+ : mMirConnection(mirConnection)
+{
+ mir_connection_set_display_config_change_callback(mirConnection, ::displayConfigurationChangedCallback, this);
+ update();
+}
+
+void QMirClientScreenObserver::update()
+{
+ // Wrap MirDisplayConfiguration to always delete when out of scope
+ auto configDeleter = [](MirDisplayConfig *config) { mir_display_config_release(config); };
+ using configUp = std::unique_ptr<MirDisplayConfig, decltype(configDeleter)>;
+ configUp displayConfig(mir_connection_create_display_configuration(mMirConnection), configDeleter);
+
+ // Mir only tells us something changed, it is up to us to figure out what.
+ QList<QMirClientScreen*> newScreenList;
+ QList<QMirClientScreen*> oldScreenList = mScreenList;
+ mScreenList.clear();
+
+ for (int i = 0; i < mir_display_config_get_num_outputs(displayConfig.get()); i++) {
+ const MirOutput *output = mir_display_config_get_output(displayConfig.get(), i);
+ if (mir_output_is_enabled(output)) {
+ QMirClientScreen *screen = findScreenWithId(oldScreenList, mir_output_get_id(output));
+ if (screen) { // we've already set up this display before
+ screen->updateMirOutput(output);
+ oldScreenList.removeAll(screen);
+ } else {
+ // new display, so create QMirClientScreen for it
+ screen = new QMirClientScreen(output, mMirConnection);
+ newScreenList.append(screen);
+ qCDebug(mirclient) << "Added Screen with id" << mir_output_get_id(output)
+ << "and geometry" << screen->geometry();
+ }
+ mScreenList.append(screen);
+ }
+ }
+
+ // Announce old & unused Screens, should be deleted by the slot
+ Q_FOREACH (const auto screen, oldScreenList) {
+ Q_EMIT screenRemoved(screen);
+ }
+
+ /*
+ * Mir's MirDisplayOutput does not include formFactor or scale for some reason, but Qt
+ * will want that information on creating the QScreen. Only way we get that info is when
+ * Mir positions a Window on that Screen. See "handleScreenPropertiesChange" method
+ */
+
+ // Announce new Screens
+ Q_FOREACH (const auto screen, newScreenList) {
+ Q_EMIT screenAdded(screen);
+ }
+
+ qCDebug(mirclient) << "=======================================";
+ for (auto screen: mScreenList) {
+ qCDebug(mirclient) << screen << "- id:" << screen->mirOutputId()
+ << "geometry:" << screen->geometry()
+ << "form factor:" << mirFormFactorToStr(screen->formFactor())
+ << "scale:" << screen->scale();
+ }
+ qCDebug(mirclient) << "=======================================";
+}
+
+QMirClientScreen *QMirClientScreenObserver::findScreenWithId(int id)
+{
+ return findScreenWithId(mScreenList, id);
+}
+
+QMirClientScreen *QMirClientScreenObserver::findScreenWithId(const QList<QMirClientScreen *> &list, int id)
+{
+ Q_FOREACH (const auto screen, list) {
+ if (screen->mirOutputId() == id) {
+ return screen;
+ }
+ }
+ return nullptr;
+}
+
+void QMirClientScreenObserver::handleScreenPropertiesChange(QMirClientScreen *screen, int dpi,
+ MirFormFactor formFactor, float scale)
+{
+ screen->setAdditionalMirDisplayProperties(scale, formFactor, dpi);
+}
+
diff --git a/src/plugins/platforms/mirclient/qmirclientscreenobserver.h b/src/plugins/platforms/mirclient/qmirclientscreenobserver.h
new file mode 100644
index 0000000000..ad927319c1
--- /dev/null
+++ b/src/plugins/platforms/mirclient/qmirclientscreenobserver.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Canonical, Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#ifndef QMIRCLIENTSCREENOBSERVER_H
+#define QMIRCLIENTSCREENOBSERVER_H
+
+#include <QObject>
+
+#include <mir_toolkit/mir_connection.h>
+
+class QMirClientScreen;
+
+class QMirClientScreenObserver : public QObject
+{
+ Q_OBJECT
+
+public:
+ QMirClientScreenObserver(MirConnection *connection);
+
+ QList<QMirClientScreen*> screens() const { return mScreenList; }
+ QMirClientScreen *findScreenWithId(int id);
+
+ void handleScreenPropertiesChange(QMirClientScreen *screen, int dpi,
+ MirFormFactor formFactor, float scale);
+
+Q_SIGNALS:
+ void screenAdded(QMirClientScreen *screen);
+ void screenRemoved(QMirClientScreen *screen);
+
+private Q_SLOTS:
+ void update();
+
+private:
+ QMirClientScreen *findScreenWithId(const QList<QMirClientScreen *> &list, int id);
+ void removeScreen(QMirClientScreen *screen);
+
+ MirConnection *mMirConnection;
+ QList<QMirClientScreen*> mScreenList;
+};
+
+#endif // QMIRCLIENTSCREENOBSERVER_H
diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.cpp b/src/plugins/platforms/mirclient/qmirclientwindow.cpp
index 60b9cd7900..adc8ae652a 100644
--- a/src/plugins/platforms/mirclient/qmirclientwindow.cpp
+++ b/src/plugins/platforms/mirclient/qmirclientwindow.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -40,26 +40,33 @@
// Local
#include "qmirclientwindow.h"
-#include "qmirclientclipboard.h"
+#include "qmirclientdebugextension.h"
+#include "qmirclientnativeinterface.h"
#include "qmirclientinput.h"
+#include "qmirclientintegration.h"
#include "qmirclientscreen.h"
#include "qmirclientlogging.h"
#include <mir_toolkit/mir_client_library.h>
+#include <mir_toolkit/version.h>
// Qt
#include <qpa/qwindowsysteminterface.h>
#include <QMutexLocker>
#include <QSize>
#include <QtMath>
+#include <QtEglSupport/private/qeglconvenience_p.h>
// Platform API
#include <ubuntu/application/instance.h>
#include <EGL/egl.h>
+Q_LOGGING_CATEGORY(mirclientBufferSwap, "qt.qpa.mirclient.bufferSwap", QtWarningMsg)
+
namespace
{
+const Qt::WindowType LowChromeWindowHint = (Qt::WindowType)0x00800000;
// FIXME: this used to be defined by platform-api, but it's been removed in v3. Change ubuntu-keyboard to use
// a different enum for window roles.
@@ -87,40 +94,110 @@ EGLNativeWindowType nativeWindowFor(MirSurface *surf)
return reinterpret_cast<EGLNativeWindowType>(mir_buffer_stream_get_egl_native_window(stream));
}
-MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
+const char *qtWindowStateToStr(Qt::WindowState state)
{
switch (state) {
case Qt::WindowNoState:
- return mir_surface_state_restored;
+ return "NoState";
case Qt::WindowFullScreen:
- return mir_surface_state_fullscreen;
+ return "FullScreen";
case Qt::WindowMaximized:
- return mir_surface_state_maximized;
+ return "Maximized";
case Qt::WindowMinimized:
- return mir_surface_state_minimized;
- default:
- LOG("Unexpected Qt::WindowState: %d", state);
- return mir_surface_state_restored;
+ return "Minimized";
+ case Qt::WindowActive:
+ return "Active";
}
+ Q_UNREACHABLE();
}
-#if !defined(QT_NO_DEBUG)
-const char *qtWindowStateToStr(Qt::WindowState state)
+const char *mirSurfaceStateToStr(MirSurfaceState surfaceState)
+{
+ switch (surfaceState) {
+ case mir_surface_state_unknown: return "unknown";
+ case mir_surface_state_restored: return "restored";
+ case mir_surface_state_minimized: return "minimized";
+ case mir_surface_state_maximized: return "vertmaximized";
+ case mir_surface_state_vertmaximized: return "vertmaximized";
+ case mir_surface_state_fullscreen: return "fullscreen";
+ case mir_surface_state_horizmaximized: return "horizmaximized";
+ case mir_surface_state_hidden: return "hidden";
+ case mir_surface_states: Q_UNREACHABLE();
+ }
+ Q_UNREACHABLE();
+}
+
+const char *mirPixelFormatToStr(MirPixelFormat pixelFormat)
+{
+ switch (pixelFormat) {
+ case mir_pixel_format_invalid: return "invalid";
+ case mir_pixel_format_abgr_8888: return "ABGR8888";
+ case mir_pixel_format_xbgr_8888: return "XBGR8888";
+ case mir_pixel_format_argb_8888: return "ARGB8888";
+ case mir_pixel_format_xrgb_8888: return "XRGB8888";
+ case mir_pixel_format_bgr_888: return "BGR888";
+ case mir_pixel_format_rgb_888: return "RGB888";
+ case mir_pixel_format_rgb_565: return "RGB565";
+ case mir_pixel_format_rgba_5551: return "RGBA5551";
+ case mir_pixel_format_rgba_4444: return "RGBA4444";
+ case mir_pixel_formats: Q_UNREACHABLE();
+ }
+ Q_UNREACHABLE();
+}
+
+const char *mirSurfaceTypeToStr(MirSurfaceType type)
+{
+ switch (type) {
+ case mir_surface_type_normal: return "Normal"; /**< AKA "regular" */
+ case mir_surface_type_utility: return "Utility"; /**< AKA "floating regular" */
+ case mir_surface_type_dialog: return "Dialog";
+ case mir_surface_type_gloss: return "Gloss";
+ case mir_surface_type_freestyle: return "Freestyle";
+ case mir_surface_type_menu: return "Menu";
+ case mir_surface_type_inputmethod: return "Input Method"; /**< AKA "OSK" or handwriting etc. */
+ case mir_surface_type_satellite: return "Satellite"; /**< AKA "toolbox"/"toolbar" */
+ case mir_surface_type_tip: return "Tip"; /**< AKA "tooltip" */
+ case mir_surface_types: Q_UNREACHABLE();
+ }
+ return "";
+}
+
+MirSurfaceState qtWindowStateToMirSurfaceState(Qt::WindowState state)
{
switch (state) {
case Qt::WindowNoState:
- return "NoState";
+ case Qt::WindowActive:
+ return mir_surface_state_restored;
case Qt::WindowFullScreen:
- return "FullScreen";
+ return mir_surface_state_fullscreen;
case Qt::WindowMaximized:
- return "Maximized";
+ return mir_surface_state_maximized;
case Qt::WindowMinimized:
- return "Minimized";
+ return mir_surface_state_minimized;
+ }
+ return mir_surface_state_unknown; // should never be reached
+}
+
+MirSurfaceType qtWindowTypeToMirSurfaceType(Qt::WindowType type)
+{
+ switch (type & Qt::WindowType_Mask) {
+ case Qt::Dialog:
+ return mir_surface_type_dialog;
+ case Qt::Sheet:
+ case Qt::Drawer:
+ return mir_surface_type_utility;
+ case Qt::Popup:
+ case Qt::Tool:
+ return mir_surface_type_menu;
+ case Qt::ToolTip:
+ return mir_surface_type_tip;
+ case Qt::SplashScreen:
+ return mir_surface_type_freestyle;
+ case Qt::Window:
default:
- return "!?";
+ return mir_surface_type_normal;
}
}
-#endif
WId makeId()
{
@@ -128,14 +205,6 @@ WId makeId()
return id++;
}
-MirPixelFormat defaultPixelFormatFor(MirConnection *connection)
-{
- MirPixelFormat format;
- unsigned int nformats;
- mir_connection_get_available_surface_formats(connection, &format, 1, &nformats);
- return format;
-}
-
UAUiWindowRole roleFor(QWindow *window)
{
QVariant roleVariant = window->property("role");
@@ -155,52 +224,93 @@ QMirClientWindow *transientParentFor(QWindow *window)
return parent ? static_cast<QMirClientWindow *>(parent->handle()) : nullptr;
}
-Spec makeSurfaceSpec(QWindow *window, QMirClientInput *input, MirConnection *connection)
-{
- const auto geom = window->geometry();
- const int width = geom.width() > 0 ? geom.width() : 1;
- const int height = geom.height() > 0 ? geom.height() : 1;
- const auto pixelFormat = defaultPixelFormatFor(connection);
-
- if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating input method surface (width=%d, height=%d", window, width, height);
- return Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)};
- }
-
- const Qt::WindowType type = window->type();
- if (type == Qt::Popup) {
- auto parent = transientParentFor(window);
- if (parent == nullptr) {
- //NOTE: We cannot have a parentless popup -
- //try using the last surface to receive input as that will most likely be
- //the one that caused this popup to be created
- parent = input->lastFocusedWindow();
- }
- if (parent) {
- auto pos = geom.topLeft();
- pos -= parent->geometry().topLeft();
- MirRectangle location{pos.x(), pos.y(), 0, 0};
- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating menu surface(width:%d, height:%d)", window, width, height);
- return Spec{mir_connection_create_spec_for_menu(
- connection, width, height, pixelFormat, parent->mirSurface(),
- &location, mir_edge_attachment_any)};
- } else {
- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - cannot create a menu without a parent!", window);
- }
- } else if (type == Qt::Dialog) {
- auto parent = transientParentFor(window);
- if (parent) {
- // Modal dialog
- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating modal dialog (width=%d, height=%d", window, width, height);
- return Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent->mirSurface())};
- } else {
- // TODO: do Qt parentless dialogs have the same semantics as mir?
- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating parentless dialog (width=%d, height=%d)", window, width, height);
- return Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)};
- }
- }
- DLOG("[ubuntumirclient QPA] makeSurfaceSpec(window=%p) - creating normal surface(type=0x%x, width=%d, height=%d)", window, type, width, height);
- return Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)};
+bool requiresParent(const MirSurfaceType type)
+{
+ switch (type) {
+ case mir_surface_type_dialog: //FIXME - not quite what the specification dictates, but is what Mir's api dictates
+ case mir_surface_type_utility:
+ case mir_surface_type_gloss:
+ case mir_surface_type_menu:
+ case mir_surface_type_satellite:
+ case mir_surface_type_tip:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool requiresParent(const Qt::WindowType type)
+{
+ return requiresParent(qtWindowTypeToMirSurfaceType(type));
+}
+
+bool isMovable(const Qt::WindowType type)
+{
+ auto mirType = qtWindowTypeToMirSurfaceType(type);
+ switch (mirType) {
+ case mir_surface_type_menu:
+ case mir_surface_type_tip:
+ return true;
+ default:
+ return false;
+ }
+}
+
+Spec makeSurfaceSpec(QWindow *window, MirPixelFormat pixelFormat, QMirClientWindow *parentWindowHandle,
+ MirConnection *connection)
+{
+ const auto geometry = window->geometry();
+ const int width = geometry.width() > 0 ? geometry.width() : 1;
+ const int height = geometry.height() > 0 ? geometry.height() : 1;
+ auto type = qtWindowTypeToMirSurfaceType(window->type());
+
+ if (U_ON_SCREEN_KEYBOARD_ROLE == roleFor(window)) {
+ type = mir_surface_type_inputmethod;
+ }
+
+ MirRectangle location{geometry.x(), geometry.y(), 0, 0};
+ MirSurface *parent = nullptr;
+ if (parentWindowHandle) {
+ parent = parentWindowHandle->mirSurface();
+ // Qt uses absolute positioning, but Mir positions surfaces relative to parent.
+ location.top -= parentWindowHandle->geometry().top();
+ location.left -= parentWindowHandle->geometry().left();
+ }
+
+ Spec spec;
+
+ switch (type) {
+ case mir_surface_type_menu:
+ spec = Spec{mir_connection_create_spec_for_menu(connection, width, height, pixelFormat, parent,
+ &location, mir_edge_attachment_any)};
+ break;
+ case mir_surface_type_dialog:
+ spec = Spec{mir_connection_create_spec_for_modal_dialog(connection, width, height, pixelFormat, parent)};
+ break;
+ case mir_surface_type_utility:
+ spec = Spec{mir_connection_create_spec_for_dialog(connection, width, height, pixelFormat)};
+ break;
+ case mir_surface_type_tip:
+#if MIR_CLIENT_VERSION < MIR_VERSION_NUMBER(3, 4, 0)
+ spec = Spec{mir_connection_create_spec_for_tooltip(connection, width, height, pixelFormat, parent,
+ &location)};
+#else
+ spec = Spec{mir_connection_create_spec_for_tip(connection, width, height, pixelFormat, parent,
+ &location, mir_edge_attachment_any)};
+#endif
+ break;
+ case mir_surface_type_inputmethod:
+ spec = Spec{mir_connection_create_spec_for_input_method(connection, width, height, pixelFormat)};
+ break;
+ default:
+ spec = Spec{mir_connection_create_spec_for_normal_surface(connection, width, height, pixelFormat)};
+ break;
+ }
+
+ qCDebug(mirclient, "makeSurfaceSpec(window=%p): %s spec (type=0x%x, position=(%d, %d)px, size=(%dx%d)px)",
+ window, mirSurfaceTypeToStr(type), window->type(), location.left, location.top, width, height);
+
+ return std::move(spec);
}
void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSize& maxSize, const QSize& increment)
@@ -221,16 +331,30 @@ void setSizingConstraints(MirSurfaceSpec *spec, const QSize& minSize, const QSiz
}
}
-MirSurface *createMirSurface(QWindow *window, QMirClientScreen *screen, QMirClientInput *input, MirConnection *connection)
+MirSurface *createMirSurface(QWindow *window, int mirOutputId, QMirClientWindow *parentWindowHandle,
+ MirPixelFormat pixelFormat, MirConnection *connection,
+ mir_surface_event_callback inputCallback, void *inputContext)
{
- auto spec = makeSurfaceSpec(window, input, connection);
+ auto spec = makeSurfaceSpec(window, pixelFormat, parentWindowHandle, connection);
+
+ // Install event handler as early as possible
+ mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
+
const auto title = window->title().toUtf8();
mir_surface_spec_set_name(spec.get(), title.constData());
setSizingConstraints(spec.get(), window->minimumSize(), window->maximumSize(), window->sizeIncrement());
if (window->windowState() == Qt::WindowFullScreen) {
- mir_surface_spec_set_fullscreen_on_output(spec.get(), screen->mirOutputId());
+ mir_surface_spec_set_fullscreen_on_output(spec.get(), mirOutputId);
+ }
+
+ if (window->flags() & LowChromeWindowHint) {
+ mir_surface_spec_set_shell_chrome(spec.get(), mir_shell_chrome_low);
+ }
+
+ if (!window->isVisible()) {
+ mir_surface_spec_set_state(spec.get(), mir_surface_state_hidden);
}
auto surface = mir_surface_create_sync(spec.get());
@@ -238,83 +362,45 @@ MirSurface *createMirSurface(QWindow *window, QMirClientScreen *screen, QMirClie
return surface;
}
-// FIXME - in order to work around https://bugs.launchpad.net/mir/+bug/1346633
-// we need to guess the panel height (3GU)
-int panelHeight()
-{
- if (qEnvironmentVariableIsSet("QT_MIRCLIENT_IGNORE_PANEL"))
- return 0;
- const int defaultGridUnit = 8;
- int gridUnit = defaultGridUnit;
- QByteArray gridUnitString = qgetenv("GRID_UNIT_PX");
- if (!gridUnitString.isEmpty()) {
- bool ok;
- gridUnit = gridUnitString.toInt(&ok);
- if (!ok) {
- gridUnit = defaultGridUnit;
+QMirClientWindow *getParentIfNecessary(QWindow *window, QMirClientInput *input)
+{
+ QMirClientWindow *parentWindowHandle = nullptr;
+ if (requiresParent(window->type())) {
+ parentWindowHandle = transientParentFor(window);
+ if (parentWindowHandle == nullptr) {
+ // NOTE: Mir requires this surface have a parent. Try using the last surface to receive input as that will
+ // most likely be the one that caused this surface to be created
+ parentWindowHandle = input->lastInputWindow();
}
}
- return gridUnit * 3;
+ return parentWindowHandle;
}
-} //namespace
-
-class QMirClientSurface
+MirPixelFormat disableAlphaBufferIfPossible(MirPixelFormat pixelFormat)
{
-public:
- QMirClientSurface(QMirClientWindow *platformWindow, QMirClientScreen *screen, QMirClientInput *input, MirConnection *connection)
- : mWindow(platformWindow->window())
- , mPlatformWindow(platformWindow)
- , mInput(input)
- , mConnection(connection)
- , mMirSurface(createMirSurface(mWindow, screen, input, connection))
- , mEglDisplay(screen->eglDisplay())
- , mEglSurface(eglCreateWindowSurface(mEglDisplay, screen->eglConfig(), nativeWindowFor(mMirSurface), nullptr))
- , mVisible(false)
- , mNeedsRepaint(false)
- , mParented(mWindow->transientParent() || mWindow->parent())
- , mWindowState(mWindow->windowState())
-
- {
- mir_surface_set_event_handler(mMirSurface, surfaceEventCallback, this);
-
- // Window manager can give us a final size different from what we asked for
- // so let's check what we ended up getting
- MirSurfaceParameters parameters;
- mir_surface_get_parameters(mMirSurface, &parameters);
-
- auto geom = mWindow->geometry();
- geom.setWidth(parameters.width);
- geom.setHeight(parameters.height);
- if (mWindowState == Qt::WindowFullScreen) {
- geom.setY(0);
- } else {
- geom.setY(panelHeight());
- }
+ switch (pixelFormat) {
+ case mir_pixel_format_abgr_8888:
+ return mir_pixel_format_xbgr_8888;
+ case mir_pixel_format_argb_8888:
+ return mir_pixel_format_xrgb_8888;
+ default: // can do nothing, leave it alone
+ return pixelFormat;
+ }
+}
+} //namespace
- // Assume that the buffer size matches the surface size at creation time
- mBufferSize = geom.size();
- platformWindow->QPlatformWindow::setGeometry(geom);
- QWindowSystemInterface::handleGeometryChange(mWindow, geom);
- DLOG("[ubuntumirclient QPA] created surface at (%d, %d) with size (%d, %d), title '%s', role: '%d'\n",
- geom.x(), geom.y(), geom.width(), geom.height(), mWindow->title().toUtf8().constData(), roleFor(mWindow));
- }
- ~QMirClientSurface()
- {
- if (mEglSurface != EGL_NO_SURFACE)
- eglDestroySurface(mEglDisplay, mEglSurface);
- if (mMirSurface)
- mir_surface_release_sync(mMirSurface);
- }
+class UbuntuSurface
+{
+public:
+ UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection);
+ ~UbuntuSurface();
- QMirClientSurface(QMirClientSurface const&) = delete;
- QMirClientSurface& operator=(QMirClientSurface const&) = delete;
+ UbuntuSurface(const UbuntuSurface &) = delete;
+ UbuntuSurface& operator=(const UbuntuSurface &) = delete;
- void resize(const QSize& newSize);
- void setState(Qt::WindowState newState);
- void setVisible(bool state);
+ void updateGeometry(const QRect &newGeometry);
void updateTitle(const QString& title);
void setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment);
@@ -322,76 +408,151 @@ public:
void handleSurfaceResized(int width, int height);
int needsRepaint() const;
+ MirSurfaceState state() const { return mir_surface_get_state(mMirSurface); }
+ void setState(MirSurfaceState state);
+
+ MirSurfaceType type() const { return mir_surface_get_type(mMirSurface); }
+
+ void setShellChrome(MirShellChrome shellChrome);
+
EGLSurface eglSurface() const { return mEglSurface; }
MirSurface *mirSurface() const { return mMirSurface; }
+ void setSurfaceParent(MirSurface*);
+ bool hasParent() const { return mParented; }
+
+ QSurfaceFormat format() const { return mFormat; }
+
+ bool mNeedsExposeCatchup;
+
+ QString persistentSurfaceId();
+
private:
static void surfaceEventCallback(MirSurface* surface, const MirEvent *event, void* context);
void postEvent(const MirEvent *event);
- void updateSurface();
QWindow * const mWindow;
QMirClientWindow * const mPlatformWindow;
QMirClientInput * const mInput;
MirConnection * const mConnection;
+ QMirClientWindow * mParentWindowHandle{nullptr};
- MirSurface * const mMirSurface;
+ MirSurface* mMirSurface;
const EGLDisplay mEglDisplay;
- const EGLSurface mEglSurface;
+ EGLSurface mEglSurface;
- bool mVisible;
bool mNeedsRepaint;
bool mParented;
- Qt::WindowState mWindowState;
QSize mBufferSize;
+ QSurfaceFormat mFormat;
+ MirPixelFormat mPixelFormat;
QMutex mTargetSizeMutex;
QSize mTargetSize;
+ MirShellChrome mShellChrome;
+ QString mPersistentIdStr;
};
-void QMirClientSurface::resize(const QSize& size)
-{
- DLOG("[ubuntumirclient QPA] resize(window=%p, width=%d, height=%d)", mWindow, size.width(), size.height());
-
- if (mWindowState == Qt::WindowFullScreen || mWindowState == Qt::WindowMaximized) {
- DLOG("[ubuntumirclient QPA] resize(window=%p) - not resizing, window is maximized or fullscreen", mWindow);
- return;
+UbuntuSurface::UbuntuSurface(QMirClientWindow *platformWindow, EGLDisplay display, QMirClientInput *input, MirConnection *connection)
+ : mWindow(platformWindow->window())
+ , mPlatformWindow(platformWindow)
+ , mInput(input)
+ , mConnection(connection)
+ , mEglDisplay(display)
+ , mNeedsRepaint(false)
+ , mParented(mWindow->transientParent() || mWindow->parent())
+ , mFormat(mWindow->requestedFormat())
+ , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
+{
+ // Have Qt choose most suitable EGLConfig for the requested surface format, and update format to reflect it
+ EGLConfig config = q_configFromGLFormat(display, mFormat, true);
+ if (config == 0) {
+ // Older Intel Atom-based devices only support OpenGL 1.4 compatibility profile but by default
+ // QML asks for at least OpenGL 2.0. The XCB GLX backend ignores this request and returns a
+ // 1.4 context, but the XCB EGL backend tries to honor it, and fails. The 1.4 context appears to
+ // have sufficient capabilities on MESA (i915) to render correctly however. So reduce the default
+ // requested OpenGL version to 1.0 to ensure EGL will give us a working context (lp:1549455).
+ static const bool isMesa = QString(eglQueryString(display, EGL_VENDOR)).contains(QStringLiteral("Mesa"));
+ if (isMesa) {
+ qCDebug(mirclientGraphics, "Attempting to choose OpenGL 1.4 context which may suit Mesa");
+ mFormat.setMajorVersion(1);
+ mFormat.setMinorVersion(4);
+ config = q_configFromGLFormat(display, mFormat, true);
+ }
+ }
+ if (config == 0) {
+ qCritical() << "Qt failed to choose a suitable EGLConfig to suit the surface format" << mFormat;
}
- if (size.isEmpty()) {
- DLOG("[ubuntumirclient QPA] resize(window=%p) - not resizing, size is empty", mWindow);
- return;
+ mFormat = q_glFormatFromConfig(display, config, mFormat);
+
+ // Have Mir decide the pixel format most suited to the chosen EGLConfig. This is the only way
+ // Mir will know what EGLConfig has been chosen - it cannot deduce it from the buffers.
+ mPixelFormat = mir_connection_get_egl_pixel_format(connection, display, config);
+ // But the chosen EGLConfig might have an alpha buffer enabled, even if not requested by the client.
+ // If that's the case, try to edit the chosen pixel format in order to disable the alpha buffer.
+ // This is an optimization for the compositor, as it can avoid blending this surface.
+ if (mWindow->requestedFormat().alphaBufferSize() < 0) {
+ mPixelFormat = disableAlphaBufferIfPossible(mPixelFormat);
}
- Spec spec{mir_connection_create_spec_for_changes(mConnection)};
- mir_surface_spec_set_width(spec.get(), size.width());
- mir_surface_spec_set_height(spec.get(), size.height());
- mir_surface_apply_spec(mMirSurface, spec.get());
+ const auto outputId = static_cast<QMirClientScreen *>(mWindow->screen()->handle())->mirOutputId();
+
+ mParentWindowHandle = getParentIfNecessary(mWindow, input);
+
+ mMirSurface = createMirSurface(mWindow, outputId, mParentWindowHandle, mPixelFormat, connection, surfaceEventCallback, this);
+ mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);
+
+ mNeedsExposeCatchup = mir_surface_get_visibility(mMirSurface) == mir_surface_visibility_occluded;
+
+ // Window manager can give us a final size different from what we asked for
+ // so let's check what we ended up getting
+ MirSurfaceParameters parameters;
+ mir_surface_get_parameters(mMirSurface, &parameters);
+
+ auto geom = mWindow->geometry();
+ geom.setWidth(parameters.width);
+ geom.setHeight(parameters.height);
+
+ // Assume that the buffer size matches the surface size at creation time
+ mBufferSize = geom.size();
+ platformWindow->QPlatformWindow::setGeometry(geom);
+ QWindowSystemInterface::handleGeometryChange(mWindow, geom);
+
+ qCDebug(mirclient) << "Created surface with geometry:" << geom << "title:" << mWindow->title()
+ << "role:" << roleFor(mWindow);
+ qCDebug(mirclientGraphics)
+ << "Requested format:" << mWindow->requestedFormat()
+ << "\nActual format:" << mFormat
+ << "with associated Mir pixel format:" << mirPixelFormatToStr(mPixelFormat);
}
-void QMirClientSurface::setState(Qt::WindowState newState)
+UbuntuSurface::~UbuntuSurface()
{
- mir_wait_for(mir_surface_set_state(mMirSurface, qtWindowStateToMirSurfaceState(newState)));
- mWindowState = newState;
+ if (mEglSurface != EGL_NO_SURFACE)
+ eglDestroySurface(mEglDisplay, mEglSurface);
+ if (mMirSurface) {
+ mir_surface_release_sync(mMirSurface);
+ }
}
-void QMirClientSurface::setVisible(bool visible)
+void UbuntuSurface::updateGeometry(const QRect &newGeometry)
{
- if (mVisible == visible)
- return;
-
- mVisible = visible;
+ qCDebug(mirclient,"updateGeometry(window=%p, width=%d, height=%d)", mWindow,
+ newGeometry.width(), newGeometry.height());
- if (mVisible)
- updateSurface();
-
- // TODO: Use the new mir_surface_state_hidden state instead of mir_surface_state_minimized.
- // Will have to change qtmir and unity8 for that.
- const auto newState = visible ? qtWindowStateToMirSurfaceState(mWindowState) : mir_surface_state_minimized;
- mir_wait_for(mir_surface_set_state(mMirSurface, newState));
+ Spec spec;
+ if (isMovable(mWindow->type())) {
+ spec = Spec{makeSurfaceSpec(mWindow, mPixelFormat, mParentWindowHandle, mConnection)};
+ } else {
+ spec = Spec{mir_connection_create_spec_for_changes(mConnection)};
+ mir_surface_spec_set_width(spec.get(), newGeometry.width());
+ mir_surface_spec_set_height(spec.get(), newGeometry.height());
+ }
+ mir_surface_apply_spec(mMirSurface, spec.get());
}
-void QMirClientSurface::updateTitle(const QString& newTitle)
+void UbuntuSurface::updateTitle(const QString& newTitle)
{
const auto title = newTitle.toUtf8();
Spec spec{mir_connection_create_spec_for_changes(mConnection)};
@@ -399,14 +560,14 @@ void QMirClientSurface::updateTitle(const QString& newTitle)
mir_surface_apply_spec(mMirSurface, spec.get());
}
-void QMirClientSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment)
+void UbuntuSurface::setSizingConstraints(const QSize& minSize, const QSize& maxSize, const QSize& increment)
{
Spec spec{mir_connection_create_spec_for_changes(mConnection)};
::setSizingConstraints(spec.get(), minSize, maxSize, increment);
mir_surface_apply_spec(mMirSurface, spec.get());
}
-void QMirClientSurface::handleSurfaceResized(int width, int height)
+void UbuntuSurface::handleSurfaceResized(int width, int height)
{
QMutexLocker lock(&mTargetSizeMutex);
@@ -419,7 +580,7 @@ void QMirClientSurface::handleSurfaceResized(int width, int height)
mNeedsRepaint = mTargetSize.width() == width && mTargetSize.height() == height;
}
-int QMirClientSurface::needsRepaint() const
+int UbuntuSurface::needsRepaint() const
{
if (mNeedsRepaint) {
if (mTargetSize != mBufferSize) {
@@ -436,12 +597,26 @@ int QMirClientSurface::needsRepaint() const
return 0;
}
-void QMirClientSurface::onSwapBuffersDone()
+void UbuntuSurface::setState(MirSurfaceState state)
+{
+ mir_wait_for(mir_surface_set_state(mMirSurface, state));
+}
+
+void UbuntuSurface::setShellChrome(MirShellChrome chrome)
+{
+ if (chrome != mShellChrome) {
+ auto spec = Spec{mir_connection_create_spec_for_changes(mConnection)};
+ mir_surface_spec_set_shell_chrome(spec.get(), chrome);
+ mir_surface_apply_spec(mMirSurface, spec.get());
+
+ mShellChrome = chrome;
+ }
+}
+
+void UbuntuSurface::onSwapBuffersDone()
{
-#if !defined(QT_NO_DEBUG)
static int sFrameNumber = 0;
++sFrameNumber;
-#endif
EGLint eglSurfaceWidth = -1;
EGLint eglSurfaceHeight = -1;
@@ -452,7 +627,7 @@ void QMirClientSurface::onSwapBuffersDone()
if (validSize && (mBufferSize.width() != eglSurfaceWidth || mBufferSize.height() != eglSurfaceHeight)) {
- DLOG("[ubuntumirclient QPA] onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)",
+ qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - size changed (%d, %d) => (%d, %d)",
mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height(), eglSurfaceWidth, eglSurfaceHeight);
mBufferSize.rwidth() = eglSurfaceWidth;
@@ -464,23 +639,21 @@ void QMirClientSurface::onSwapBuffersDone()
mPlatformWindow->QPlatformWindow::setGeometry(newGeometry);
QWindowSystemInterface::handleGeometryChange(mWindow, newGeometry);
} else {
-#if 0
- DLOG("[ubuntumirclient QPA] onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
+ qCDebug(mirclientBufferSwap, "onSwapBuffersDone(window=%p) [%d] - buffer size (%d,%d)",
mWindow, sFrameNumber, mBufferSize.width(), mBufferSize.height());
-#endif
}
}
-void QMirClientSurface::surfaceEventCallback(MirSurface *surface, const MirEvent *event, void* context)
+void UbuntuSurface::surfaceEventCallback(MirSurface *surface, const MirEvent *event, void* context)
{
Q_UNUSED(surface);
Q_ASSERT(context != nullptr);
- auto s = static_cast<QMirClientSurface *>(context);
+ auto s = static_cast<UbuntuSurface *>(context);
s->postEvent(event);
}
-void QMirClientSurface::postEvent(const MirEvent *event)
+void UbuntuSurface::postEvent(const MirEvent *event)
{
if (mir_event_type_resize == mir_event_get_type(event)) {
// TODO: The current event queue just accumulates all resize events;
@@ -490,7 +663,7 @@ void QMirClientSurface::postEvent(const MirEvent *event)
const auto resizeEvent = mir_event_get_resize_event(event);
const auto width = mir_resize_event_get_width(resizeEvent);
const auto height = mir_resize_event_get_height(resizeEvent);
- DLOG("[ubuntumirclient QPA] resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height);
+ qCDebug(mirclient, "resizeEvent(window=%p, width=%d, height=%d)", mWindow, width, height);
QMutexLocker lock(&mTargetSizeMutex);
mTargetSize.rwidth() = width;
@@ -500,44 +673,57 @@ void QMirClientSurface::postEvent(const MirEvent *event)
mInput->postEvent(mPlatformWindow, event);
}
-void QMirClientSurface::updateSurface()
+void UbuntuSurface::setSurfaceParent(MirSurface* parent)
{
- DLOG("[ubuntumirclient QPA] updateSurface(window=%p)", mWindow);
+ qCDebug(mirclient, "setSurfaceParent(window=%p)", mWindow);
- if (!mParented && mWindow->type() == Qt::Dialog) {
- // The dialog may have been parented after creation time
- // so morph it into a modal dialog
- auto parent = transientParentFor(mWindow);
- if (parent) {
- DLOG("[ubuntumirclient QPA] updateSurface(window=%p) dialog now parented", mWindow);
- mParented = true;
- Spec spec{mir_connection_create_spec_for_changes(mConnection)};
- mir_surface_spec_set_parent(spec.get(), parent->mirSurface());
- mir_surface_apply_spec(mMirSurface, spec.get());
- }
+ mParented = true;
+ Spec spec{mir_connection_create_spec_for_changes(mConnection)};
+ mir_surface_spec_set_parent(spec.get(), parent);
+ mir_surface_apply_spec(mMirSurface, spec.get());
+}
+
+QString UbuntuSurface::persistentSurfaceId()
+{
+ if (mPersistentIdStr.isEmpty()) {
+ MirPersistentId* mirPermaId = mir_surface_request_persistent_id_sync(mMirSurface);
+ mPersistentIdStr = mir_persistent_id_as_string(mirPermaId);
+ mir_persistent_id_release(mirPermaId);
}
+ return mPersistentIdStr;
}
-QMirClientWindow::QMirClientWindow(QWindow *w, const QSharedPointer<QMirClientClipboard> &clipboard, QMirClientScreen *screen,
- QMirClientInput *input, MirConnection *connection)
+QMirClientWindow::QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface *native,
+ QMirClientAppStateController *appState, EGLDisplay eglDisplay,
+ MirConnection *mirConnection, QMirClientDebugExtension *debugExt)
: QObject(nullptr)
, QPlatformWindow(w)
, mId(makeId())
- , mClipboard(clipboard)
- , mSurface(new QMirClientSurface{this, screen, input, connection})
+ , mWindowState(w->windowState())
+ , mWindowFlags(w->flags())
+ , mWindowVisible(false)
+ , mAppStateController(appState)
+ , mDebugExtention(debugExt)
+ , mNativeInterface(native)
+ , mSurface(new UbuntuSurface{this, eglDisplay, input, mirConnection})
+ , mScale(1.0)
+ , mFormFactor(mir_form_factor_unknown)
{
- DLOG("[ubuntumirclient QPA] QMirClientWindow(window=%p, screen=%p, input=%p, surf=%p)", w, screen, input, mSurface.get());
+ mWindowExposed = mSurface->mNeedsExposeCatchup == false;
+
+ qCDebug(mirclient, "QMirClientWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'",
+ w, w->screen()->handle(), input, mSurface.get(), qPrintable(window()->title()), roleFor(window()));
}
QMirClientWindow::~QMirClientWindow()
{
- DLOG("[ubuntumirclient QPA] ~QMirClientWindow(window=%p)", this);
+ qCDebug(mirclient, "~QMirClientWindow(window=%p)", this);
}
void QMirClientWindow::handleSurfaceResized(int width, int height)
{
QMutexLocker lock(&mMutex);
- DLOG("[ubuntumirclient QPA] handleSurfaceResize(window=%p, width=%d, height=%d)", window(), width, height);
+ qCDebug(mirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), width, height);
mSurface->handleSurfaceResized(width, height);
@@ -547,88 +733,140 @@ void QMirClientWindow::handleSurfaceResized(int width, int height)
// updated size but it still needs re-rendering so another redraw may be needed.
// A mir API to drop the currently held buffer would help here, so that we wouldn't have to redraw twice
auto const numRepaints = mSurface->needsRepaint();
- DLOG("[ubuntumirclient QPA] handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
+ lock.unlock();
+ qCDebug(mirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
for (int i = 0; i < numRepaints; i++) {
- DLOG("[ubuntumirclient QPA] handleSurfaceResize(window=%p) repainting width=%d, height=%d", window(), geometry().size().width(), geometry().size().height());
+ qCDebug(mirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height());
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
}
-void QMirClientWindow::handleSurfaceFocused()
+void QMirClientWindow::handleSurfaceExposeChange(bool exposed)
{
- DLOG("[ubuntumirclient QPA] handleSurfaceFocused(window=%p)", window());
+ QMutexLocker lock(&mMutex);
+ qCDebug(mirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false");
+
+ mSurface->mNeedsExposeCatchup = false;
+ if (mWindowExposed == exposed) return;
+ mWindowExposed = exposed;
- // System clipboard contents might have changed while this window was unfocused and without
- // this process getting notified about it because it might have been suspended (due to
- // application lifecycle policies), thus unable to listen to any changes notified through
- // D-Bus.
- // Therefore let's ensure we are up to date with the system clipboard now that we are getting
- // focused again.
- mClipboard->requestDBusClipboardContents();
+ lock.unlock();
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
+}
+
+void QMirClientWindow::handleSurfaceFocusChanged(bool focused)
+{
+ qCDebug(mirclient, "handleSurfaceFocusChanged(window=%p, focused=%d)", window(), focused);
+ if (focused) {
+ mAppStateController->setWindowFocused(true);
+ QWindowSystemInterface::handleWindowActivated(window(), Qt::ActiveWindowFocusReason);
+ } else {
+ mAppStateController->setWindowFocused(false);
+ }
+}
+
+void QMirClientWindow::handleSurfaceVisibilityChanged(bool visible)
+{
+ qCDebug(mirclient, "handleSurfaceVisibilityChanged(window=%p, visible=%d)", window(), visible);
+
+ if (mWindowVisible == visible) return;
+ mWindowVisible = visible;
+
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
+}
+
+void QMirClientWindow::handleSurfaceStateChanged(Qt::WindowState state)
+{
+ qCDebug(mirclient, "handleSurfaceStateChanged(window=%p, %s)", window(), qtWindowStateToStr(state));
+
+ if (mWindowState == state) return;
+ mWindowState = state;
+
+ QWindowSystemInterface::handleWindowStateChanged(window(), state);
}
void QMirClientWindow::setWindowState(Qt::WindowState state)
{
QMutexLocker lock(&mMutex);
- DLOG("[ubuntumirclient QPA] setWindowState(window=%p, %s)", this, qtWindowStateToStr(state));
- mSurface->setState(state);
+ qCDebug(mirclient, "setWindowState(window=%p, %s)", this, qtWindowStateToStr(state));
+
+ if (mWindowState == state) return;
+ mWindowState = state;
+
+ lock.unlock();
+ updateSurfaceState();
+}
+
+void QMirClientWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ QMutexLocker lock(&mMutex);
+ qCDebug(mirclient, "setWindowFlags(window=%p, 0x%x)", this, (int)flags);
- updatePanelHeightHack(state);
+ if (mWindowFlags == flags) return;
+ mWindowFlags = flags;
+
+ mSurface->setShellChrome(mWindowFlags & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal);
}
-/*
- FIXME: Mir does not let clients know the position of their windows in the virtual
- desktop space. So we have this ugly hack that assumes a phone situation where the
- window is always on the top-left corner, right below the indicators panel if not
- in fullscreen.
- */
-void QMirClientWindow::updatePanelHeightHack(Qt::WindowState state)
+QRect QMirClientWindow::geometry() const
{
- if (state == Qt::WindowFullScreen && geometry().y() != 0) {
- QRect newGeometry = geometry();
- newGeometry.setY(0);
- QPlatformWindow::setGeometry(newGeometry);
- QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
- } else if (geometry().y() == 0) {
- QRect newGeometry = geometry();
- newGeometry.setY(panelHeight());
- QPlatformWindow::setGeometry(newGeometry);
- QWindowSystemInterface::handleGeometryChange(window(), newGeometry);
+ if (mDebugExtention) {
+ auto geom = QPlatformWindow::geometry();
+ geom.moveTopLeft(mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), QPoint(0,0)));
+ return geom;
+ } else {
+ return QPlatformWindow::geometry();
}
}
void QMirClientWindow::setGeometry(const QRect& rect)
{
QMutexLocker lock(&mMutex);
- DLOG("[ubuntumirclient QPA] setGeometry (window=%p, x=%d, y=%d, width=%d, height=%d)",
- window(), rect.x(), rect.y(), rect.width(), rect.height());
- //NOTE: mir surfaces cannot be moved by the client so ignore the topLeft coordinates
- const auto newSize = rect.size();
- auto newGeometry = geometry();
- newGeometry.setSize(newSize);
- QPlatformWindow::setGeometry(newGeometry);
+ if (window()->windowState() == Qt::WindowFullScreen || window()->windowState() == Qt::WindowMaximized) {
+ qCDebug(mirclient, "setGeometry(window=%p) - not resizing, window is maximized or fullscreen", window());
+ return;
+ }
+
+ qCDebug(mirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)",
+ window(), rect.x(), rect.y(), rect.width(), rect.height());
+ // Immediately update internal geometry so Qt believes position updated
+ QRect newPosition(geometry());
+ newPosition.moveTo(rect.topLeft());
+ QPlatformWindow::setGeometry(newPosition);
- mSurface->resize(newSize);
+ mSurface->updateGeometry(rect);
+ // Note: don't call handleGeometryChange here, wait to see what Mir replies with.
}
void QMirClientWindow::setVisible(bool visible)
{
QMutexLocker lock(&mMutex);
- DLOG("[ubuntumirclient QPA] setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false");
-
- mSurface->setVisible(visible);
- const QRect& exposeRect = visible ? QRect(QPoint(), geometry().size()) : QRect();
+ qCDebug(mirclient, "setVisible (window=%p, visible=%s)", window(), visible ? "true" : "false");
+
+ if (mWindowVisible == visible) return;
+ mWindowVisible = visible;
+
+ if (visible) {
+ if (!mSurface->hasParent() && window()->type() == Qt::Dialog) {
+ // The dialog may have been parented after creation time
+ // so morph it into a modal dialog
+ auto parent = transientParentFor(window());
+ if (parent) {
+ mSurface->setSurfaceParent(parent->mirSurface());
+ }
+ }
+ }
lock.unlock();
- QWindowSystemInterface::handleExposeEvent(window(), exposeRect);
- QWindowSystemInterface::flushWindowSystemEvents();
+ updateSurfaceState();
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
void QMirClientWindow::setWindowTitle(const QString& title)
{
QMutexLocker lock(&mMutex);
- DLOG("[ubuntumirclient QPA] setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData());
+ qCDebug(mirclient, "setWindowTitle(window=%p) title=%s)", window(), title.toUtf8().constData());
mSurface->updateTitle(title);
}
@@ -636,13 +874,33 @@ void QMirClientWindow::propagateSizeHints()
{
QMutexLocker lock(&mMutex);
const auto win = window();
- DLOG("[ubuntumirclient QPA] propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)",
- win, win->minimumSize().width(), win->minimumSize().height(),
- win->maximumSize().width(), win->maximumSize().height(),
- win->sizeIncrement().width(), win->sizeIncrement().height());
+ qCDebug(mirclient, "propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)",
+ win, win->minimumSize().width(), win->minimumSize().height(),
+ win->maximumSize().width(), win->maximumSize().height(),
+ win->sizeIncrement().width(), win->sizeIncrement().height());
mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement());
}
+bool QMirClientWindow::isExposed() const
+{
+ // mNeedsExposeCatchup because we need to render a frame to get the expose surface event from mir.
+ return mWindowVisible && (mWindowExposed || (mSurface && mSurface->mNeedsExposeCatchup));
+}
+
+QSurfaceFormat QMirClientWindow::format() const
+{
+ return mSurface->format();
+}
+
+QPoint QMirClientWindow::mapToGlobal(const QPoint &pos) const
+{
+ if (mDebugExtention) {
+ return mDebugExtention->mapSurfacePointToScreen(mSurface->mirSurface(), pos);
+ } else {
+ return pos;
+ }
+}
+
void* QMirClientWindow::eglSurface() const
{
return mSurface->eglSurface();
@@ -662,4 +920,43 @@ void QMirClientWindow::onSwapBuffersDone()
{
QMutexLocker lock(&mMutex);
mSurface->onSwapBuffersDone();
+
+ if (mSurface->mNeedsExposeCatchup) {
+ mSurface->mNeedsExposeCatchup = false;
+ mWindowExposed = false;
+
+ lock.unlock();
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
+ }
+}
+
+void QMirClientWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale)
+{
+ // Update the scale & form factor native-interface properties for the windows affected
+ // as there is no convenient way to emit signals for those custom properties on a QScreen
+ if (formFactor != mFormFactor) {
+ mFormFactor = formFactor;
+ Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("formFactor"));
+ }
+
+ if (!qFuzzyCompare(scale, mScale)) {
+ mScale = scale;
+ Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale"));
+ }
+}
+
+void QMirClientWindow::updateSurfaceState()
+{
+ QMutexLocker lock(&mMutex);
+ MirSurfaceState newState = mWindowVisible ? qtWindowStateToMirSurfaceState(mWindowState) :
+ mir_surface_state_hidden;
+ qCDebug(mirclient, "updateSurfaceState (window=%p, surfaceState=%s)", window(), mirSurfaceStateToStr(newState));
+ if (newState != mSurface->state()) {
+ mSurface->setState(newState);
+ }
+}
+
+QString QMirClientWindow::persistentSurfaceId()
+{
+ return mSurface->persistentSurfaceId();
}
diff --git a/src/plugins/platforms/mirclient/qmirclientwindow.h b/src/plugins/platforms/mirclient/qmirclientwindow.h
index 025976c130..324e7691ff 100644
--- a/src/plugins/platforms/mirclient/qmirclientwindow.h
+++ b/src/plugins/platforms/mirclient/qmirclientwindow.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Canonical, Ltd.
+** Copyright (C) 2014-2016 Canonical, Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@@ -45,44 +45,74 @@
#include <QSharedPointer>
#include <QMutex>
+#include <mir_toolkit/common.h> // needed only for MirFormFactor enum
+
#include <memory>
-class QMirClientClipboard;
+#include <EGL/egl.h>
+
+class QMirClientAppStateController;
+class QMirClientDebugExtension;
+class QMirClientNativeInterface;
class QMirClientInput;
class QMirClientScreen;
-class QMirClientSurface;
-struct MirConnection;
+class UbuntuSurface;
struct MirSurface;
+class MirConnection;
class QMirClientWindow : public QObject, public QPlatformWindow
{
Q_OBJECT
public:
- QMirClientWindow(QWindow *w, const QSharedPointer<QMirClientClipboard> &clipboard, QMirClientScreen *screen,
- QMirClientInput *input, MirConnection *mirConnection);
+ QMirClientWindow(QWindow *w, QMirClientInput *input, QMirClientNativeInterface* native,
+ QMirClientAppStateController *appState, EGLDisplay eglDisplay,
+ MirConnection *mirConnection, QMirClientDebugExtension *debugExt);
virtual ~QMirClientWindow();
// QPlatformWindow methods.
WId winId() const override;
+ QRect geometry() const override;
void setGeometry(const QRect&) override;
void setWindowState(Qt::WindowState state) override;
+ void setWindowFlags(Qt::WindowFlags flags) override;
void setVisible(bool visible) override;
void setWindowTitle(const QString &title) override;
void propagateSizeHints() override;
+ bool isExposed() const override;
+
+ QPoint mapToGlobal(const QPoint &pos) const override;
+ QSurfaceFormat format() const override;
+
+ // Additional Window properties exposed by NativeInterface
+ MirFormFactor formFactor() const { return mFormFactor; }
+ float scale() const { return mScale; }
// New methods.
void *eglSurface() const;
MirSurface *mirSurface() const;
void handleSurfaceResized(int width, int height);
- void handleSurfaceFocused();
+ void handleSurfaceExposeChange(bool exposed);
+ void handleSurfaceFocusChanged(bool focused);
+ void handleSurfaceVisibilityChanged(bool visible);
+ void handleSurfaceStateChanged(Qt::WindowState state);
void onSwapBuffersDone();
+ void handleScreenPropertiesChange(MirFormFactor formFactor, float scale);
+ QString persistentSurfaceId();
private:
- void updatePanelHeightHack(Qt::WindowState);
+ void updateSurfaceState();
mutable QMutex mMutex;
const WId mId;
- const QSharedPointer<QMirClientClipboard> mClipboard;
- std::unique_ptr<QMirClientSurface> mSurface;
+ Qt::WindowState mWindowState;
+ Qt::WindowFlags mWindowFlags;
+ bool mWindowVisible;
+ bool mWindowExposed;
+ QMirClientAppStateController *mAppStateController;
+ QMirClientDebugExtension *mDebugExtention;
+ QMirClientNativeInterface *mNativeInterface;
+ std::unique_ptr<UbuntuSurface> mSurface;
+ float mScale;
+ MirFormFactor mFormFactor;
};
#endif // QMIRCLIENTWINDOW_H
diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro
index 2a6e059243..9ccc2b54b9 100644
--- a/src/plugins/platforms/platforms.pro
+++ b/src/plugins/platforms/platforms.pro
@@ -36,7 +36,7 @@ qtConfig(directfb) {
qtConfig(linuxfb): SUBDIRS += linuxfb
-unix:!android:!darwin: SUBDIRS += vnc
+qtConfig(vnc): SUBDIRS += vnc
freebsd {
SUBDIRS += bsdfb
diff --git a/src/plugins/platforms/qnx/qnx.pro b/src/plugins/platforms/qnx/qnx.pro
index 9da3d6811b..0b052adf0f 100644
--- a/src/plugins/platforms/qnx/qnx.pro
+++ b/src/plugins/platforms/qnx/qnx.pro
@@ -7,8 +7,6 @@ QT += \
# Uncomment this to build with support for IMF once it becomes available in the BBNDK
#CONFIG += qqnx_imf
-CONFIG += qqnx_screeneventthread
-
# Uncomment these to enable debugging output for various aspects of the plugin
#DEFINES += QQNXBUFFER_DEBUG
#DEFINES += QQNXBUTTON_DEBUG
@@ -47,7 +45,8 @@ SOURCES = main.cpp \
qqnxservices.cpp \
qqnxcursor.cpp \
qqnxrasterwindow.cpp \
- qqnxglobal.cpp
+ qqnxglobal.cpp \
+ qqnxscreeneventthread.cpp
HEADERS = main.h \
qqnxbuffer.h \
@@ -67,13 +66,8 @@ HEADERS = main.h \
qqnxrasterwindow.h \
qqnxscreeneventfilter.h \
qqnxglobal.h \
- qqnxlgmon.h
-
-CONFIG(qqnx_screeneventthread) {
- DEFINES += QQNX_SCREENEVENTTHREAD
- SOURCES += qqnxscreeneventthread.cpp
- HEADERS += qqnxscreeneventthread.h
-}
+ qqnxlgmon.h \
+ qqnxscreeneventthread.h
LIBS += -lscreen
diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp
index 7229d7d2a8..eee0581709 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.cpp
+++ b/src/plugins/platforms/qnx/qqnxintegration.cpp
@@ -40,9 +40,7 @@
#include "qqnxglobal.h"
#include "qqnxintegration.h"
-#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
-#endif
#include "qqnxnativeinterface.h"
#include "qqnxrasterbackingstore.h"
#include "qqnxscreen.h"
@@ -125,9 +123,7 @@ static inline QQnxIntegration::Options parseOptions(const QStringList &paramList
QQnxIntegration::QQnxIntegration(const QStringList &paramList)
: QPlatformIntegration()
-#if defined(QQNX_SCREENEVENTTHREAD)
, m_screenEventThread(0)
-#endif
, m_navigatorEventHandler(new QQnxNavigatorEventHandler())
, m_virtualKeyboard(0)
#if defined(QQNX_PPS)
@@ -169,10 +165,8 @@ QQnxIntegration::QQnxIntegration(const QStringList &paramList)
#endif
// Create/start event thread
-#if defined(QQNX_SCREENEVENTTHREAD)
m_screenEventThread = new QQnxScreenEventThread(ms_screenContext, m_screenEventHandler);
m_screenEventThread->start();
-#endif
#if defined(QQNX_PPS)
// Create/start the keyboard class.
@@ -235,10 +229,8 @@ QQnxIntegration::~QQnxIntegration()
#endif
delete m_navigatorEventHandler;
-#if defined(QQNX_SCREENEVENTTHREAD)
// Stop/destroy screen event thread
delete m_screenEventThread;
-#endif
// In case the event-dispatcher was never transferred to QCoreApplication
delete m_eventDispatcher;
diff --git a/src/plugins/platforms/qnx/qqnxintegration.h b/src/plugins/platforms/qnx/qqnxintegration.h
index 6f2af82100..b2008baa0c 100644
--- a/src/plugins/platforms/qnx/qqnxintegration.h
+++ b/src/plugins/platforms/qnx/qqnxintegration.h
@@ -48,9 +48,7 @@
QT_BEGIN_NAMESPACE
-#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
-#endif
class QQnxFileDialogHelper;
class QQnxNativeInterface;
class QQnxWindow;
@@ -142,9 +140,7 @@ private:
static void removeWindow(screen_window_t qnxWindow);
static screen_context_t ms_screenContext;
-#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_screenEventThread;
-#endif
QQnxNavigatorEventHandler *m_navigatorEventHandler;
QQnxAbstractVirtualKeyboard *m_virtualKeyboard;
#if defined(QQNX_PPS)
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
index beda6e1a49..5d230e2145 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp
@@ -40,9 +40,7 @@
#include "qqnxglobal.h"
#include "qqnxscreeneventhandler.h"
-#if defined(QQNX_SCREENEVENTTHREAD)
#include "qqnxscreeneventthread.h"
-#endif
#include "qqnxintegration.h"
#include "qqnxkeytranslator.h"
#include "qqnxscreen.h"
@@ -67,9 +65,7 @@ QQnxScreenEventHandler::QQnxScreenEventHandler(QQnxIntegration *integration)
, m_lastButtonState(Qt::NoButton)
, m_lastMouseWindow(0)
, m_touchDevice(0)
-#if defined(QQNX_SCREENEVENTTHREAD)
, m_eventThread(0)
-#endif
, m_focusLostTimer(-1)
{
// Create a touch device
@@ -198,7 +194,6 @@ void QQnxScreenEventHandler::injectKeyboardEvent(int flags, int sym, int modifie
}
}
-#if defined(QQNX_SCREENEVENTTHREAD)
void QQnxScreenEventHandler::setScreenEventThread(QQnxScreenEventThread *eventThread)
{
m_eventThread = eventThread;
@@ -233,7 +228,6 @@ void QQnxScreenEventHandler::processEventsFromScreenThread()
m_eventThread->unlock();
}
-#endif
void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event)
{
diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
index 80798a8a2d..d872f9b9aa 100644
--- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
+++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.h
@@ -48,9 +48,7 @@ QT_BEGIN_NAMESPACE
class QQnxIntegration;
class QQnxScreenEventFilter;
-#if defined(QQNX_SCREENEVENTTHREAD)
class QQnxScreenEventThread;
-#endif
class QQnxScreenEventHandler : public QObject
{
@@ -66,9 +64,7 @@ public:
static void injectKeyboardEvent(int flags, int sym, int mod, int scan, int cap);
-#if defined(QQNX_SCREENEVENTTHREAD)
void setScreenEventThread(QQnxScreenEventThread *eventThread);
-#endif
Q_SIGNALS:
void newWindowCreated(void *window);
@@ -77,10 +73,8 @@ Q_SIGNALS:
protected:
void timerEvent(QTimerEvent *event) override;
-#if defined(QQNX_SCREENEVENTTHREAD)
private Q_SLOTS:
void processEventsFromScreenThread();
-#endif
private:
void handleKeyboardEvent(screen_event_t event);
@@ -105,9 +99,7 @@ private:
QTouchDevice *m_touchDevice;
QWindowSystemInterface::TouchPoint m_touchPoints[MaximumTouchPoints];
QList<QQnxScreenEventFilter*> m_eventFilters;
-#if defined(QQNX_SCREENEVENTTHREAD)
QQnxScreenEventThread *m_eventThread;
-#endif
int m_focusLostTimer;
};
diff --git a/src/plugins/platforms/vnc/main.cpp b/src/plugins/platforms/vnc/main.cpp
index 6ee8bf1ec6..3ec0f0b78d 100644
--- a/src/plugins/platforms/vnc/main.cpp
+++ b/src/plugins/platforms/vnc/main.cpp
@@ -48,7 +48,7 @@ class QVncIntegrationPlugin : public QPlatformIntegrationPlugin
Q_OBJECT
Q_PLUGIN_METADATA(IID QPlatformIntegrationFactoryInterface_iid FILE "vnc.json")
public:
- QPlatformIntegration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE;
+ QPlatformIntegration *create(const QString&, const QStringList&) override;
};
QPlatformIntegration* QVncIntegrationPlugin::create(const QString& system, const QStringList& paramList)
diff --git a/src/plugins/platforms/vnc/qvnc.cpp b/src/plugins/platforms/vnc/qvnc.cpp
index a45bb1c19c..fa65e8c9a4 100644
--- a/src/plugins/platforms/vnc/qvnc.cpp
+++ b/src/plugins/platforms/vnc/qvnc.cpp
@@ -531,13 +531,12 @@ void QRfbRawEncoder::write()
socket->flush();
}
+#if QT_CONFIG(cursor)
QVncClientCursor::QVncClientCursor()
{
-#ifndef QT_NO_CURSOR
QWindow *w = QGuiApplication::focusWindow();
QCursor c = w ? w->cursor() : QCursor(Qt::ArrowCursor);
changeCursor(&c, 0);
-#endif
}
QVncClientCursor::~QVncClientCursor()
@@ -587,7 +586,6 @@ void QVncClientCursor::write(QVncClient *client) const
void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
{
Q_UNUSED(window);
-#ifndef QT_NO_CURSOR
const Qt::CursorShape shape = widgetCursor ? widgetCursor->shape() : Qt::ArrowCursor;
if (shape == Qt::BitmapCursor) {
@@ -601,9 +599,6 @@ void QVncClientCursor::changeCursor(QCursor *widgetCursor, QWindow *window)
cursor = *platformImage.image();
hotspot = platformImage.hotspot();
}
-#else // !QT_NO_CURSOR
- Q_UNUSED(widgetCursor);
-#endif
for (auto client : clients)
client->setDirtyCursor();
}
@@ -619,6 +614,7 @@ uint QVncClientCursor::removeClient(QVncClient *client)
clients.removeOne(client);
return clients.count();
}
+#endif // QT_CONFIG(cursor)
QVncServer::QVncServer(QVncScreen *screen, quint16 port)
: qvnc_screen(screen)
diff --git a/src/plugins/platforms/vnc/qvnc_p.h b/src/plugins/platforms/vnc/qvnc_p.h
index 1c44cd1569..338fae9f87 100644
--- a/src/plugins/platforms/vnc/qvnc_p.h
+++ b/src/plugins/platforms/vnc/qvnc_p.h
@@ -95,7 +95,7 @@ public:
QVncDirtyMapOptimized(QVncScreen *screen) : QVncDirtyMap(screen) {}
~QVncDirtyMapOptimized() {}
- void setDirty(int x, int y, bool force = false);
+ void setDirty(int x, int y, bool force = false) override;
};
@@ -216,7 +216,7 @@ class QRfbRawEncoder : public QRfbEncoder
public:
QRfbRawEncoder(QVncClient *s) : QRfbEncoder(s) {}
- void write();
+ void write() override;
private:
QByteArray buffer;
@@ -364,6 +364,7 @@ private:
friend class QRfbMultiColorHextile<SRC>;
};
+#if QT_CONFIG(cursor)
class QVncClientCursor : public QPlatformCursor
{
public:
@@ -372,7 +373,7 @@ public:
void write(QVncClient *client) const;
- void changeCursor(QCursor *widgetCursor, QWindow *window);
+ void changeCursor(QCursor *widgetCursor, QWindow *window) override;
void addClient(QVncClient *client);
uint removeClient(QVncClient *client);
@@ -381,7 +382,7 @@ public:
QPoint hotspot;
QVector<QVncClient *> clients;
};
-
+#endif // QT_CONFIG(cursor)
class QVncServer : public QObject
{
diff --git a/src/plugins/platforms/vnc/qvncclient.cpp b/src/plugins/platforms/vnc/qvncclient.cpp
index 58dcfc9b51..9dfe873927 100644
--- a/src/plugins/platforms/vnc/qvncclient.cpp
+++ b/src/plugins/platforms/vnc/qvncclient.cpp
@@ -425,14 +425,14 @@ void QVncClient::checkUpdate()
{
if (!m_wantUpdate)
return;
-
+#if QT_CONFIG(cursor)
if (m_dirtyCursor) {
m_server->screen()->clientCursor->write(this);
m_dirtyCursor = false;
m_wantUpdate = false;
return;
}
-
+#endif
if (!m_dirtyRegion.isEmpty()) {
if (m_encoder)
m_encoder->write();
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
index 293ff54376..34a6a6b941 100644
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ b/src/plugins/platforms/vnc/qvncintegration.h
@@ -55,19 +55,19 @@ public:
QVncIntegration(const QStringList &paramList);
~QVncIntegration();
- void initialize() Q_DECL_OVERRIDE;
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ void initialize() override;
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
- QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const override;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
- QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const override;
- QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QPlatformServices *services() const Q_DECL_OVERRIDE;
- QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE { return m_inputContext; }
+ QPlatformFontDatabase *fontDatabase() const override;
+ QPlatformServices *services() const override;
+ QPlatformInputContext *inputContext() const override { return m_inputContext; }
- QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+ QPlatformNativeInterface *nativeInterface() const override;
QList<QPlatformScreen *> screens() const;
diff --git a/src/plugins/platforms/vnc/qvncscreen.cpp b/src/plugins/platforms/vnc/qvncscreen.cpp
index 64f1bc0bf7..cd43ce4e69 100644
--- a/src/plugins/platforms/vnc/qvncscreen.cpp
+++ b/src/plugins/platforms/vnc/qvncscreen.cpp
@@ -58,8 +58,10 @@ QVncScreen::QVncScreen(const QStringList &args)
QVncScreen::~QVncScreen()
{
+#if QT_CONFIG(cursor)
if (clientCursor)
delete clientCursor;
+#endif
}
bool QVncScreen::initialize()
@@ -120,17 +122,21 @@ QRegion QVncScreen::doRedraw()
return touched;
}
+
void QVncScreen::enableClientCursor(QVncClient *client)
{
+#if QT_CONFIG(cursor)
delete mCursor;
mCursor = nullptr;
if (!clientCursor)
clientCursor = new QVncClientCursor();
clientCursor->addClient(client);
+#endif
}
void QVncScreen::disableClientCursor(QVncClient *client)
{
+#if QT_CONFIG(cursor)
uint clientCount = clientCursor->removeClient(client);
if (clientCount == 0) {
delete clientCursor;
@@ -138,11 +144,16 @@ void QVncScreen::disableClientCursor(QVncClient *client)
}
mCursor = new QFbCursor(this);
+#endif
}
QPlatformCursor *QVncScreen::cursor() const
{
+#if QT_CONFIG(cursor)
return mCursor ? static_cast<QPlatformCursor *>(mCursor) : static_cast<QPlatformCursor *>(clientCursor);
+#else
+ return nullptr;
+#endif
}
// grabWindow() grabs "from the screen" not from the backingstores.
@@ -151,10 +162,10 @@ QPixmap QVncScreen::grabWindow(WId wid, int x, int y, int width, int height) con
{
if (!wid) {
if (width < 0)
- width = mScreenImage->width() - x;
+ width = mScreenImage.width() - x;
if (height < 0)
- height = mScreenImage->height() - y;
- return QPixmap::fromImage(*mScreenImage).copy(x, y, width, height);
+ height = mScreenImage.height() - y;
+ return QPixmap::fromImage(mScreenImage).copy(x, y, width, height);
}
QFbWindow *window = windowForId(wid);
@@ -166,7 +177,7 @@ QPixmap QVncScreen::grabWindow(WId wid, int x, int y, int width, int height) con
height = geom.height() - y;
QRect rect(geom.topLeft() + QPoint(x, y), QSize(width, height));
rect &= window->geometry();
- return QPixmap::fromImage(*mScreenImage).copy(rect);
+ return QPixmap::fromImage(mScreenImage).copy(rect);
}
return QPixmap();
@@ -188,5 +199,10 @@ bool QVncScreen::swapBytes() const
}
#endif
+QFbScreen::Flags QVncScreen::flags() const
+{
+ return QFbScreen::DontForceFirstWindowToFullScreen;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvncscreen.h b/src/plugins/platforms/vnc/qvncscreen.h
index 0b42c3c7ea..e69aa90d41 100644
--- a/src/plugins/platforms/vnc/qvncscreen.h
+++ b/src/plugins/platforms/vnc/qvncscreen.h
@@ -59,16 +59,18 @@ public:
QVncScreen(const QStringList &args);
~QVncScreen();
- bool initialize();
+ bool initialize() override;
- QPixmap grabWindow(WId wid, int x, int y, int width, int height) const Q_DECL_OVERRIDE;
+ QPixmap grabWindow(WId wid, int x, int y, int width, int height) const override;
- QRegion doRedraw() Q_DECL_OVERRIDE;
- QImage *image() const { return mScreenImage; }
+ QRegion doRedraw() override;
+ QImage *image() { return &mScreenImage; }
void enableClientCursor(QVncClient *client);
void disableClientCursor(QVncClient *client);
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE;
+ QPlatformCursor *cursor() const override;
+
+ Flags flags() const override;
void clearDirty() { dirtyRegion = QRegion(); }
@@ -84,7 +86,9 @@ public:
QRegion dirtyRegion;
int refreshRate = 30;
QVncServer *vncServer = 0;
+#if QT_CONFIG(cursor)
QVncClientCursor *clientCursor = 0;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h
index e035e3924a..8621e93120 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h
@@ -53,7 +53,7 @@ class QWindowsAccessibility : public QPlatformAccessibility
public:
QWindowsAccessibility();
static bool handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult);
- void notifyAccessibilityUpdate(QAccessibleEvent *event) Q_DECL_OVERRIDE;
+ void notifyAccessibilityUpdate(QAccessibleEvent *event) override;
static IAccessible *wrap(QAccessibleInterface *acc);
static QWindow *windowHelper(const QAccessibleInterface *iface);
};
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 85aab84c2c..25b1577772 100644
--- a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -1052,11 +1052,24 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BS
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR value)
{
QAccessibleInterface *accessible = accessibleInterface();
accessibleDebugClientCalls(accessible);
- return DISP_E_MEMBERNOTFOUND;
+
+ if (!accessible || !accessible->isValid()) {
+ return E_FAIL;
+ }
+
+ QString qstrValue = QString::fromWCharArray(value);
+
+ if (accessible->valueInterface()) {
+ accessible->valueInterface()->setCurrentValue(qstrValue);
+ } else {
+ accessible->setText(QAccessible::Value, qstrValue);
+ }
+
+ return S_OK;
}
// moz: [important]
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index dd99e674ec..69f4a54d05 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -114,6 +114,18 @@
"features": [
"disable_desktopgl"
]
- }
+ },
+ {
+ "id": 10,
+ "description": "Intel(R) HD Graphics IronLake (Arrandale) crashes on makeCurrent QTBUG-53888",
+ "vendor_id": "0x8086",
+ "device_id": [ "0x0046" ],
+ "os": {
+ "type": "win"
+ },
+ "features": [
+ "disable_desktopgl"
+ ]
+ }
]
}
diff --git a/src/plugins/platforms/windows/qtwindowsglobal.h b/src/plugins/platforms/windows/qtwindowsglobal.h
index ec6a8f62ae..a5c05bf1a3 100644
--- a/src/plugins/platforms/windows/qtwindowsglobal.h
+++ b/src/plugins/platforms/windows/qtwindowsglobal.h
@@ -56,6 +56,10 @@
# define WM_GESTURE 0x0119
#endif
+#ifndef WM_DPICHANGED
+# define WM_DPICHANGED 0x02E0
+#endif
+
QT_BEGIN_NAMESPACE
namespace QtWindows
@@ -96,12 +100,14 @@ enum WindowsEventType // Simplify event types
FocusInEvent = WindowEventFlag + 17,
FocusOutEvent = WindowEventFlag + 18,
WhatsThisEvent = WindowEventFlag + 19,
+ DpiChangedEvent = WindowEventFlag + 21,
MouseEvent = MouseEventFlag + 1,
MouseWheelEvent = MouseEventFlag + 2,
CursorEvent = MouseEventFlag + 3,
TouchEvent = TouchEventFlag + 1,
NonClientMouseEvent = NonClientEventFlag + MouseEventFlag + 1,
NonClientHitTest = NonClientEventFlag + 2,
+ NonClientCreate = NonClientEventFlag + 3,
KeyEvent = KeyEventFlag + 1,
KeyDownEvent = KeyEventFlag + KeyDownEventFlag + 1,
KeyboardLayoutChangeEvent = KeyEventFlag + 2,
@@ -177,6 +183,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
return QtWindows::HideEvent;
case WM_SIZE:
return QtWindows::ResizeEvent;
+ case WM_NCCREATE:
+ return QtWindows::NonClientCreate;
case WM_NCCALCSIZE:
return QtWindows::CalculateSize;
case WM_NCHITTEST:
@@ -263,6 +271,8 @@ inline QtWindows::WindowsEventType windowsEventType(UINT message, WPARAM wParamI
#endif
case WM_GESTURE:
return QtWindows::GestureEvent;
+ case WM_DPICHANGED:
+ return QtWindows::DpiChangedEvent;
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.h b/src/plugins/platforms/windows/qwindowsbackingstore.h
index 46a7fcc676..9e62266697 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.h
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.h
@@ -57,15 +57,15 @@ public:
QWindowsBackingStore(QWindow *window);
~QWindowsBackingStore();
- QPaintDevice *paintDevice() Q_DECL_OVERRIDE;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) Q_DECL_OVERRIDE;
- void resize(const QSize &size, const QRegion &r) Q_DECL_OVERRIDE;
- bool scroll(const QRegion &area, int dx, int dy) Q_DECL_OVERRIDE;
- void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
+ QPaintDevice *paintDevice() override;
+ void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
+ void resize(const QSize &size, const QRegion &r) override;
+ bool scroll(const QRegion &area, int dx, int dy) override;
+ void beginPaint(const QRegion &) override;
HDC getDC() const;
- QImage toImage() const Q_DECL_OVERRIDE;
+ QImage toImage() const override;
private:
QScopedPointer<QWindowsNativeImage> m_image;
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.cpp b/src/plugins/platforms/windows/qwindowsclipboard.cpp
index d4a7e27762..01191a7dc1 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.cpp
+++ b/src/plugins/platforms/windows/qwindowsclipboard.cpp
@@ -81,7 +81,7 @@ static QDebug operator<<(QDebug d, const QMimeData *mimeData)
d << "QMimeData(";
if (mimeData) {
const QStringList formats = mimeData->formats();
- d << "formats=" << formats.join(QStringLiteral(", "));
+ d << "formats=" << formats.join(QLatin1String(", "));
if (mimeData->hasText())
d << ", text=" << mimeData->text();
if (mimeData->hasHtml())
@@ -149,8 +149,7 @@ static void cleanClipboardPostRoutine()
QWindowsClipboard *QWindowsClipboard::m_instance = 0;
-QWindowsClipboard::QWindowsClipboard() :
- m_data(0), m_clipboardViewer(0), m_nextClipboardViewer(0), m_formatListenerRegistered(false)
+QWindowsClipboard::QWindowsClipboard()
{
QWindowsClipboard::m_instance = this;
qAddPostRoutine(cleanClipboardPostRoutine);
@@ -322,7 +321,7 @@ void QWindowsClipboard::setMimeData(QMimeData *mimeData, QClipboard::Mode mode)
const HRESULT src = OleSetClipboard(m_data);
if (src != S_OK) {
QString mimeDataFormats = mimeData ?
- mimeData->formats().join(QStringLiteral(", ")) : QString(QStringLiteral("NULL"));
+ mimeData->formats().join(QLatin1String(", ")) : QString(QStringLiteral("NULL"));
qErrnoWarning("OleSetClipboard: Failed to set mime data (%s) on clipboard: %s",
qPrintable(mimeDataFormats),
QWindowsContext::comErrorString(src).constData());
diff --git a/src/plugins/platforms/windows/qwindowsclipboard.h b/src/plugins/platforms/windows/qwindowsclipboard.h
index 992d34d492..4f3e7437f6 100644
--- a/src/plugins/platforms/windows/qwindowsclipboard.h
+++ b/src/plugins/platforms/windows/qwindowsclipboard.h
@@ -52,8 +52,8 @@ class QWindowsClipboardRetrievalMimeData : public QWindowsInternalMimeData {
public:
protected:
- IDataObject *retrieveDataObject() const Q_DECL_OVERRIDE;
- void releaseDataObject(IDataObject *) const Q_DECL_OVERRIDE;
+ IDataObject *retrieveDataObject() const override;
+ void releaseDataObject(IDataObject *) const override;
};
class QWindowsClipboard : public QPlatformClipboard
@@ -64,10 +64,10 @@ public:
void registerViewer(); // Call in initialization, when context is up.
void cleanup();
- QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
- void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) Q_DECL_OVERRIDE;
- bool supportsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
- bool ownsMode(QClipboard::Mode mode) const Q_DECL_OVERRIDE;
+ QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override;
+ void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard) override;
+ bool supportsMode(QClipboard::Mode mode) const override;
+ bool ownsMode(QClipboard::Mode mode) const override;
inline bool clipboardViewerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result);
@@ -85,10 +85,10 @@ private:
static QWindowsClipboard *m_instance;
QWindowsClipboardRetrievalMimeData m_retrievalData;
- QWindowsOleDataObject *m_data;
- HWND m_clipboardViewer;
- HWND m_nextClipboardViewer;
- bool m_formatListenerRegistered;
+ QWindowsOleDataObject *m_data = nullptr;
+ HWND m_clipboardViewer = 0;
+ HWND m_nextClipboardViewer = 0;
+ bool m_formatListenerRegistered = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index bb9ed730a3..5745fc6d19 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -68,6 +68,7 @@
#include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtCore/QDebug>
+#include <QtCore/QOperatingSystemVersion>
#include <QtCore/QSysInfo>
#include <QtCore/QScopedArrayPointer>
#include <QtCore/private/qsystemlibrary_p.h>
@@ -127,6 +128,28 @@ static inline QWindowsSessionManager *platformSessionManager() {
}
#endif
+static inline int windowDpiAwareness(HWND hwnd)
+{
+ return QWindowsContext::user32dll.getWindowDpiAwarenessContext && QWindowsContext::user32dll.getWindowDpiAwarenessContext
+ ? QWindowsContext::user32dll.getAwarenessFromDpiAwarenessContext(QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd))
+ : -1;
+}
+
+// Note: This only works within WM_NCCREATE
+static bool enableNonClientDpiScaling(HWND hwnd)
+{
+ bool result = false;
+ if (QWindowsContext::user32dll.enableNonClientDpiScaling && windowDpiAwareness(hwnd) == 2) {
+ result = QWindowsContext::user32dll.enableNonClientDpiScaling(hwnd) != FALSE;
+ if (!result) {
+ const DWORD errorCode = GetLastError();
+ qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)",
+ hwnd, errorCode);
+ }
+ }
+ return result;
+}
+
/*!
\class QWindowsUser32DLL
\brief Struct that contains dynamically resolved symbols of User32.dll.
@@ -142,14 +165,6 @@ static inline QWindowsSessionManager *platformSessionManager() {
\internal
\ingroup qt-lighthouse-win
*/
-QWindowsUser32DLL::QWindowsUser32DLL() :
- isTouchWindow(0),
- registerTouchWindow(0), unregisterTouchWindow(0),
- getTouchInputInfo(0), closeTouchInputHandle(0), setProcessDPIAware(0),
- addClipboardFormatListener(0), removeClipboardFormatListener(0),
- getDisplayAutoRotationPreferences(0), setDisplayAutoRotationPreferences(0)
-{
-}
void QWindowsUser32DLL::init()
{
@@ -161,6 +176,12 @@ void QWindowsUser32DLL::init()
getDisplayAutoRotationPreferences = (GetDisplayAutoRotationPreferences)library.resolve("GetDisplayAutoRotationPreferences");
setDisplayAutoRotationPreferences = (SetDisplayAutoRotationPreferences)library.resolve("SetDisplayAutoRotationPreferences");
+
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10) { // Appears in 10.0.14393, October 2016
+ enableNonClientDpiScaling = (EnableNonClientDpiScaling)library.resolve("EnableNonClientDpiScaling");
+ getWindowDpiAwarenessContext = (GetWindowDpiAwarenessContext)library.resolve("GetWindowDpiAwarenessContext");
+ getAwarenessFromDpiAwarenessContext = (GetAwarenessFromDpiAwarenessContext)library.resolve("GetAwarenessFromDpiAwarenessContext");
+ }
}
bool QWindowsUser32DLL::initTouch()
@@ -176,16 +197,9 @@ bool QWindowsUser32DLL::initTouch()
return isTouchWindow && registerTouchWindow && unregisterTouchWindow && getTouchInputInfo && closeTouchInputHandle;
}
-QWindowsShcoreDLL::QWindowsShcoreDLL()
- : getProcessDpiAwareness(0)
- , setProcessDpiAwareness(0)
- , getDpiForMonitor(0)
-{
-}
-
void QWindowsShcoreDLL::init()
{
- if (QSysInfo::windowsVersion() < QSysInfo::WV_WINDOWS8_1)
+ if (QOperatingSystemVersion::current() < QOperatingSystemVersion::Windows8_1)
return;
QSystemLibrary library(QStringLiteral("SHCore"));
getProcessDpiAwareness = (GetProcessDpiAwareness)library.resolve("GetProcessDpiAwareness");
@@ -211,14 +225,13 @@ QWindowsContext *QWindowsContext::m_instance = 0;
typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash;
struct QWindowsContextPrivate {
-
QWindowsContextPrivate();
- unsigned m_systemInfo;
+ unsigned m_systemInfo = 0;
QSet<QString> m_registeredWindowClassNames;
HandleBaseWindowHash m_windows;
- HDC m_displayContext;
- int m_defaultDPI;
+ HDC m_displayContext = 0;
+ int m_defaultDPI = 96;
QWindowsKeyMapper m_keyMapper;
QWindowsMouseHandler m_mouseHandler;
QWindowsMimeConverter m_mimeConverter;
@@ -229,15 +242,13 @@ struct QWindowsContextPrivate {
#endif
const HRESULT m_oleInitializeResult;
const QByteArray m_eventType;
- QWindow *m_lastActiveWindow;
- bool m_asyncExpose;
+ QWindow *m_lastActiveWindow = nullptr;
+ bool m_asyncExpose = false;
};
QWindowsContextPrivate::QWindowsContextPrivate()
- : m_systemInfo(0)
- , m_oleInitializeResult(OleInitialize(NULL))
+ : m_oleInitializeResult(OleInitialize(NULL))
, m_eventType(QByteArrayLiteral("windows_generic_MSG"))
- , m_lastActiveWindow(0), m_asyncExpose(0)
{
QWindowsContext::user32dll.init();
QWindowsContext::shcoredll.init();
@@ -379,6 +390,11 @@ void QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreat
d->m_creationContext = ctx;
}
+QSharedPointer<QWindowCreationContext> QWindowsContext::windowCreationContext() const
+{
+ return d->m_creationContext;
+}
+
int QWindowsContext::defaultDPI() const
{
return d->m_defaultDPI;
@@ -807,7 +823,9 @@ static inline QWindowsInputContext *windowsInputContext()
bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
QtWindows::WindowsEventType et,
- WPARAM wParam, LPARAM lParam, LRESULT *result)
+ WPARAM wParam, LPARAM lParam,
+ LRESULT *result,
+ QWindowsWindow **platformWindowPtr)
{
*result = 0;
@@ -838,6 +856,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
}
QWindowsWindow *platformWindow = findPlatformWindow(hwnd);
+ *platformWindowPtr = platformWindow;
if (platformWindow) {
filterResult = 0;
if (QWindowSystemInterface::handleNativeEvent(platformWindow->window(), d->m_eventType, &msg, &filterResult)) {
@@ -919,6 +938,10 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
case QtWindows::MoveEvent:
d->m_creationContext->obtainedGeometry.moveTo(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
return true;
+ case QtWindows::NonClientCreate:
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS10 && d->m_creationContext->window->isTopLevel())
+ enableNonClientDpiScaling(msg.hwnd);
+ return false;
case QtWindows::CalculateSize:
return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->customMargins, msg, result);
case QtWindows::GeometryChangingEvent:
@@ -1026,9 +1049,6 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
case QtWindows::ThemeChanged: {
// Switch from Aero to Classic changes margins.
- const Qt::WindowFlags flags = platformWindow->window()->flags();
- if ((flags & Qt::WindowType_Mask) != Qt::Desktop && !(flags & Qt::FramelessWindowHint))
- platformWindow->setFlag(QWindowsWindow::FrameDirty);
if (QWindowsTheme *theme = QWindowsTheme::instance())
theme->windowsThemeChanged(platformWindow->window());
return true;
@@ -1068,6 +1088,15 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
#endif
} break;
+ case QtWindows::DpiChangedEvent: {
+ platformWindow->setFlag(QWindowsWindow::WithinDpiChanged);
+ const RECT *prcNewWindow = reinterpret_cast<RECT *>(lParam);
+ SetWindowPos(hwnd, NULL, prcNewWindow->left, prcNewWindow->top,
+ prcNewWindow->right - prcNewWindow->left,
+ prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
+ platformWindow->clearFlag(QWindowsWindow::WithinDpiChanged);
+ return true;
+ }
#if !defined(QT_NO_SESSIONMANAGER)
case QtWindows::QueryEndSessionApplicationEvent: {
QWindowsSessionManager *sessionManager = platformSessionManager();
@@ -1201,6 +1230,37 @@ QTouchDevice *QWindowsContext::touchDevice() const
return d->m_mouseHandler.touchDevice();
}
+static inline bool isEmptyRect(const RECT &rect)
+{
+ return rect.right - rect.left == 0 && rect.bottom - rect.top == 0;
+}
+
+static inline QMargins marginsFromRects(const RECT &frame, const RECT &client)
+{
+ return QMargins(client.left - frame.left, client.top - frame.top,
+ frame.right - client.right, frame.bottom - client.bottom);
+}
+
+static RECT rectFromNcCalcSize(UINT message, WPARAM wParam, LPARAM lParam, int n)
+{
+ RECT result = {0, 0, 0, 0};
+ if (message == WM_NCCALCSIZE && wParam)
+ result = reinterpret_cast<const NCCALCSIZE_PARAMS *>(lParam)->rgrc[n];
+ return result;
+}
+
+static inline bool isMinimized(HWND hwnd)
+{
+ WINDOWPLACEMENT windowPlacement;
+ windowPlacement.length = sizeof(WINDOWPLACEMENT);
+ return GetWindowPlacement(hwnd, &windowPlacement) && windowPlacement.showCmd == SW_SHOWMINIMIZED;
+}
+
+static inline bool isTopLevel(HWND hwnd)
+{
+ return (GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILD) == 0;
+}
+
/*!
\brief Windows functions for actual windows.
@@ -1214,7 +1274,9 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
{
LRESULT result;
const QtWindows::WindowsEventType et = windowsEventType(message, wParam, lParam);
- const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result);
+ QWindowsWindow *platformWindow = nullptr;
+ const RECT ncCalcSizeFrame = rectFromNcCalcSize(message, wParam, lParam, 0);
+ const bool handled = QWindowsContext::instance()->windowsProc(hwnd, message, et, wParam, lParam, &result, &platformWindow);
if (QWindowsContext::verbose > 1 && lcQpaEvents().isDebugEnabled()) {
if (const char *eventName = QWindowsGuiEventDispatcher::windowsMessageName(message)) {
qCDebug(lcQpaEvents) << "EVENT: hwd=" << hwnd << eventName << hex << "msg=0x" << message
@@ -1224,6 +1286,24 @@ extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND hwnd, UINT message, WPAR
}
if (!handled)
result = DefWindowProc(hwnd, message, wParam, lParam);
+
+ // Capture WM_NCCALCSIZE on top level windows and obtain the window margins by
+ // subtracting the rectangles before and after processing. This will correctly
+ // capture client code overriding the message and allow for per-monitor margins
+ // for High DPI (QTBUG-53255, QTBUG-40578).
+ if (message == WM_NCCALCSIZE && !isEmptyRect(ncCalcSizeFrame) && isTopLevel(hwnd) && !isMinimized(hwnd)) {
+ const QMargins margins =
+ marginsFromRects(ncCalcSizeFrame, rectFromNcCalcSize(message, wParam, lParam, 0));
+ if (margins.left() >= 0) {
+ if (platformWindow) {
+ platformWindow->setFrameMargins(margins);
+ } else {
+ const QSharedPointer<QWindowCreationContext> ctx = QWindowsContext::instance()->windowCreationContext();
+ if (!ctx.isNull())
+ ctx->margins = margins;
+ }
+ }
+ }
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowscontext.h b/src/plugins/platforms/windows/qwindowscontext.h
index 9dfde67797..b50010321b 100644
--- a/src/plugins/platforms/windows/qwindowscontext.h
+++ b/src/plugins/platforms/windows/qwindowscontext.h
@@ -80,7 +80,6 @@ class QTouchDevice;
struct QWindowsUser32DLL
{
- QWindowsUser32DLL();
inline void init();
inline bool initTouch();
@@ -94,30 +93,36 @@ struct QWindowsUser32DLL
typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND);
typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *);
typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD);
+ typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND);
+ typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND);
+ typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int);
// Touch functions from Windows 7 onwards (also for use with Q_CC_MSVC).
- IsTouchWindow isTouchWindow;
- RegisterTouchWindow registerTouchWindow;
- UnregisterTouchWindow unregisterTouchWindow;
- GetTouchInputInfo getTouchInputInfo;
- CloseTouchInputHandle closeTouchInputHandle;
+ IsTouchWindow isTouchWindow = nullptr;
+ RegisterTouchWindow registerTouchWindow = nullptr;
+ UnregisterTouchWindow unregisterTouchWindow = nullptr;
+ GetTouchInputInfo getTouchInputInfo = nullptr;
+ CloseTouchInputHandle closeTouchInputHandle = nullptr;
// Windows Vista onwards
- SetProcessDPIAware setProcessDPIAware;
+ SetProcessDPIAware setProcessDPIAware = nullptr;
// Clipboard listeners are present on Windows Vista onwards
// but missing in MinGW 4.9 stub libs. Can be removed in MinGW 5.
- AddClipboardFormatListener addClipboardFormatListener;
- RemoveClipboardFormatListener removeClipboardFormatListener;
+ AddClipboardFormatListener addClipboardFormatListener = nullptr;
+ RemoveClipboardFormatListener removeClipboardFormatListener = nullptr;
// Rotation API
- GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences;
- SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences;
+ GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences = nullptr;
+ SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences = nullptr;
+
+ EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr;
+ GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr;
+ GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr;
};
// Shell scaling library (Windows 8.1 onwards)
struct QWindowsShcoreDLL {
- QWindowsShcoreDLL();
void init();
inline bool isValid() const { return getProcessDpiAwareness && setProcessDpiAwareness && getDpiForMonitor; }
@@ -125,9 +130,9 @@ struct QWindowsShcoreDLL {
typedef HRESULT (WINAPI *SetProcessDpiAwareness)(int);
typedef HRESULT (WINAPI *GetDpiForMonitor)(HMONITOR,int,UINT *,UINT *);
- GetProcessDpiAwareness getProcessDpiAwareness;
- SetProcessDpiAwareness setProcessDpiAwareness;
- GetDpiForMonitor getDpiForMonitor;
+ GetProcessDpiAwareness getProcessDpiAwareness = nullptr;
+ SetProcessDpiAwareness setProcessDpiAwareness = nullptr;
+ GetDpiForMonitor getDpiForMonitor = nullptr;
};
class QWindowsContext
@@ -181,12 +186,14 @@ public:
inline bool windowsProc(HWND hwnd, UINT message,
QtWindows::WindowsEventType et,
- WPARAM wParam, LPARAM lParam, LRESULT *result);
+ WPARAM wParam, LPARAM lParam, LRESULT *result,
+ QWindowsWindow **platformWindowPtr);
QWindow *keyGrabber() const;
void setKeyGrabber(QWindow *hwnd);
void setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx);
+ QSharedPointer<QWindowCreationContext> windowCreationContext() const;
void setTabletAbsoluteRange(int a);
void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness);
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index 6fff5f9ab1..df2e22733b 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -104,9 +104,9 @@ public:
explicit QWindowsCursor(const QPlatformScreen *screen);
- void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE;
- QPoint pos() const Q_DECL_OVERRIDE;
- void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
+ void changeCursor(QCursor * widgetCursor, QWindow * widget) override;
+ QPoint pos() const override;
+ void setPos(const QPoint &pos) override;
static HCURSOR createPixmapCursor(QPixmap pixmap, const QPoint &hotSpot, qreal scaleFactor = 1);
static HCURSOR createPixmapCursor(const PixmapCursor &pc, qreal scaleFactor = 1) { return createPixmapCursor(pc.pixmap, pc.hotSpot, scaleFactor); }
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
index 8f1358de6c..f4527bcc60 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp
@@ -66,9 +66,11 @@
#include <QtCore/QMutexLocker>
#include <QtCore/QUuid>
#include <QtCore/QRegularExpression>
+#include <QtCore/QTemporaryFile>
#include <QtCore/private/qsystemlibrary_p.h>
#include <algorithm>
+#include <vector>
#include <QtCore/qt_windows.h>
@@ -212,15 +214,6 @@ private:
*/
template <class BaseClass>
-QWindowsDialogHelperBase<BaseClass>::QWindowsDialogHelperBase() :
- m_nativeDialog(0),
- m_ownerWindow(0),
- m_timerId(0),
- m_thread(0)
-{
-}
-
-template <class BaseClass>
void QWindowsDialogHelperBase<BaseClass>::cleanupThread()
{
if (m_thread) { // Thread may be running if the dialog failed to close.
@@ -549,11 +542,11 @@ public:
IFACEMETHODIMP OnOverwrite(IFileDialog *, IShellItem *, FDE_OVERWRITE_RESPONSE *) { return S_OK; }
QWindowsNativeFileDialogEventHandler(QWindowsNativeFileDialogBase *nativeFileDialog) :
- m_ref(1), m_nativeFileDialog(nativeFileDialog) {}
+ m_nativeFileDialog(nativeFileDialog) {}
virtual ~QWindowsNativeFileDialogEventHandler() {}
private:
- long m_ref;
+ long m_ref = 1;
QWindowsNativeFileDialogBase *m_nativeFileDialog;
};
@@ -570,6 +563,235 @@ IFileDialogEvents *QWindowsNativeFileDialogEventHandler::create(QWindowsNativeFi
}
/*!
+ \class QWindowsShellItem
+ \brief Wrapper for IShellItem
+
+ \sa QWindowsNativeFileDialogBase
+ \internal
+ \ingroup qt-lighthouse-win
+*/
+class QWindowsShellItem
+{
+public:
+ typedef std::vector<IShellItem *> IShellItems;
+
+ explicit QWindowsShellItem(IShellItem *item);
+
+ SFGAOF attributes() const { return m_attributes; }
+ QString normalDisplay() const // base name, usually
+ { return displayName(m_item, SIGDN_NORMALDISPLAY); }
+ QString desktopAbsoluteParsing() const
+ { return displayName(m_item, SIGDN_DESKTOPABSOLUTEPARSING); }
+ QString path() const; // Only set for 'FileSystem' (SFGAO_FILESYSTEM) items
+ QUrl url() const;
+
+ bool isFileSystem() const { return (m_attributes & SFGAO_FILESYSTEM) != 0; }
+ bool isDir() const { return (m_attributes & SFGAO_FOLDER) != 0; }
+ // Copy using IFileOperation
+ bool canCopy() const { return (m_attributes & SFGAO_CANCOPY) != 0; }
+ // Supports IStream
+ bool canStream() const { return (m_attributes & SFGAO_STREAM) != 0; }
+
+ bool copyData(QIODevice *out);
+
+ static IShellItems itemsFromItemArray(IShellItemArray *items);
+
+#ifndef QT_NO_DEBUG_STREAM
+ void format(QDebug &d) const;
+#endif
+
+private:
+ static QString displayName(IShellItem *item, SIGDN mode);
+ static QString libraryItemDefaultSaveFolder(IShellItem *item);
+ QUrl urlValue() const;
+
+ IShellItem *m_item;
+ SFGAOF m_attributes;
+};
+
+QWindowsShellItem::QWindowsShellItem(IShellItem *item)
+ : m_item(item)
+ , m_attributes(0)
+{
+ if (FAILED(item->GetAttributes(SFGAO_CAPABILITYMASK | SFGAO_DISPLAYATTRMASK | SFGAO_CONTENTSMASK | SFGAO_STORAGECAPMASK, &m_attributes)))
+ m_attributes = 0;
+}
+
+QString QWindowsShellItem::path() const
+{
+ if (isFileSystem())
+ return QDir::cleanPath(QWindowsShellItem::displayName(m_item, SIGDN_FILESYSPATH));
+ // Check for a "Library" item (Windows 7)
+ if (QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7 && isDir())
+ return QWindowsShellItem::libraryItemDefaultSaveFolder(m_item);
+ return QString();
+}
+
+QUrl QWindowsShellItem::urlValue() const // plain URL as returned by SIGDN_URL, not set for all items
+{
+ QUrl result;
+ const QString urlString = displayName(m_item, SIGDN_URL);
+ if (!urlString.isEmpty()) {
+ const QUrl parsed = QUrl(urlString);
+ if (parsed.isValid()) {
+ result = parsed;
+ } else {
+ qWarning("%s: Unable to decode URL \"%s\": %s", __FUNCTION__,
+ qPrintable(urlString), qPrintable(parsed.errorString()));
+ }
+ }
+ return result;
+}
+
+QUrl QWindowsShellItem::url() const
+{
+ // Prefer file if existent to avoid any misunderstandings about UNC shares
+ const QString fsPath = path();
+ if (!fsPath.isEmpty())
+ return QUrl::fromLocalFile(fsPath);
+ const QUrl urlV = urlValue();
+ if (urlV.isValid())
+ return urlV;
+ // Last resort: encode the absolute desktop parsing id as data URL
+ const QString data = QStringLiteral("data:text/plain;base64,")
+ + QLatin1String(desktopAbsoluteParsing().toLatin1().toBase64());
+ return QUrl(data);
+}
+
+QString QWindowsShellItem::displayName(IShellItem *item, SIGDN mode)
+{
+ LPWSTR name = nullptr;
+ QString result;
+ if (SUCCEEDED(item->GetDisplayName(mode, &name))) {
+ result = QString::fromWCharArray(name);
+ CoTaskMemFree(name);
+ }
+ return result;
+}
+
+QWindowsShellItem::IShellItems QWindowsShellItem::itemsFromItemArray(IShellItemArray *items)
+{
+ IShellItems result;
+ DWORD itemCount = 0;
+ if (FAILED(items->GetCount(&itemCount)) || itemCount == 0)
+ return result;
+ result.reserve(itemCount);
+ for (DWORD i = 0; i < itemCount; ++i) {
+ IShellItem *item = nullptr;
+ if (SUCCEEDED(items->GetItemAt(i, &item)))
+ result.push_back(item);
+ }
+ return result;
+}
+
+bool QWindowsShellItem::copyData(QIODevice *out)
+{
+ if (!canCopy() || !canStream())
+ return false;
+ IStream *istream = nullptr;
+ HRESULT hr = m_item->BindToHandler(NULL, BHID_Stream, IID_PPV_ARGS(&istream));
+ if (FAILED(hr))
+ return false;
+ enum : ULONG { bufSize = 102400 };
+ char buffer[bufSize];
+ ULONG bytesRead;
+ forever {
+ bytesRead = 0;
+ hr = istream->Read(buffer, bufSize, &bytesRead); // S_FALSE: EOF reached
+ if ((hr == S_OK || hr == S_FALSE) && bytesRead)
+ out->write(buffer, bytesRead);
+ else
+ break;
+ }
+ istream->Release();
+ return hr == S_OK || hr == S_FALSE;
+}
+
+// Helper for "Libraries": collections of folders appearing from Windows 7
+// on, visible in the file dialogs.
+
+// Load a library from a IShellItem (sanitized copy of the inline function
+// SHLoadLibraryFromItem from ShObjIdl.h, which does not exist for MinGW).
+static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode)
+{
+ // ID symbols present from Windows 7 on:
+ static const CLSID classId_ShellLibrary = {0xd9b3211d, 0xe57f, 0x4426, {0xaa, 0xef, 0x30, 0xa8, 0x6, 0xad, 0xd3, 0x97}};
+ static const IID iId_IShellLibrary = {0x11a66efa, 0x382e, 0x451a, {0x92, 0x34, 0x1e, 0xe, 0x12, 0xef, 0x30, 0x85}};
+
+ IShellLibrary *helper = nullptr;
+ IShellLibrary *result = nullptr;
+ if (SUCCEEDED(CoCreateInstance(classId_ShellLibrary, NULL, CLSCTX_INPROC_SERVER, iId_IShellLibrary, reinterpret_cast<void **>(&helper))))
+ if (SUCCEEDED(helper->LoadLibraryFromItem(libraryItem, mode)))
+ helper->QueryInterface(iId_IShellLibrary, reinterpret_cast<void **>(&result));
+ if (helper)
+ helper->Release();
+ return result;
+}
+
+// Return default save folders of a library-type item.
+QString QWindowsShellItem::libraryItemDefaultSaveFolder(IShellItem *item)
+{
+ QString result;
+ if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) {
+ IShellItem *item = Q_NULLPTR;
+ if (SUCCEEDED(library->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, reinterpret_cast<void **>(&item)))) {
+ result = QDir::cleanPath(QWindowsShellItem::displayName(item, SIGDN_FILESYSPATH));
+ item->Release();
+ }
+ library->Release();
+ }
+ return result;
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+void QWindowsShellItem::format(QDebug &d) const
+{
+ d << "attributes=0x" << hex << attributes() << dec;
+ if (isFileSystem())
+ d << " [filesys]";
+ if (isDir())
+ d << " [dir]";
+ if (canStream())
+ d << " [stream]";
+ if (canCopy())
+ d << " [copyable]";
+ d << ", normalDisplay=\"" << normalDisplay()
+ << "\", desktopAbsoluteParsing=\"" << desktopAbsoluteParsing() << '"';
+ const QString pathS = path();
+ if (!pathS.isEmpty())
+ d << ", path=\"" << pathS << '"';
+ const QUrl urlV = urlValue();
+ if (urlV.isValid())
+ d << "\", url=" << urlV;
+}
+
+QDebug operator<<(QDebug d, const QWindowsShellItem &i)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "QShellItem(";
+ i.format(d);
+ d << ')';
+ return d;
+}
+
+QDebug operator<<(QDebug d, IShellItem *i)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "IShellItem(" << static_cast<const void *>(i);
+ if (i) {
+ d << ", ";
+ QWindowsShellItem(i).format(d);
+ }
+ d << ')';
+ return d;
+}
+#endif // !QT_NO_DEBUG_STREAM
+
+/*!
\class QWindowsNativeFileDialogBase
\brief Windows native file dialog wrapper around IFileOpenDialog, IFileSaveDialog.
@@ -590,12 +812,12 @@ public:
inline static QWindowsNativeFileDialogBase *create(QFileDialogOptions::AcceptMode am, const QWindowsFileDialogSharedData &data);
- void setWindowTitle(const QString &title) Q_DECL_OVERRIDE;
+ void setWindowTitle(const QString &title) override;
inline void setMode(QFileDialogOptions::FileMode mode, QFileDialogOptions::AcceptMode acceptMode, QFileDialogOptions::FileDialogOptions options);
inline void setDirectory(const QUrl &directory);
inline void updateDirectory() { setDirectory(m_data.directory()); }
inline QString directory() const;
- void doExec(HWND owner = 0) Q_DECL_OVERRIDE;
+ void doExec(HWND owner = 0) override;
virtual void setNameFilters(const QStringList &f);
inline void selectNameFilter(const QString &filter);
inline void updateSelectedNameFilter() { selectNameFilter(m_data.selectedNameFilter()); }
@@ -624,36 +846,31 @@ signals:
void filterSelected(const QString & filter);
public slots:
- void close() Q_DECL_OVERRIDE;
+ void close() override;
protected:
explicit QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data);
bool init(const CLSID &clsId, const IID &iid);
void setDefaultSuffixSys(const QString &s);
inline IFileDialog * fileDialog() const { return m_fileDialog; }
- static QString itemPath(IShellItem *item);
- static QList<QUrl> libraryItemFolders(IShellItem *item);
- static QString libraryItemDefaultSaveFolder(IShellItem *item);
- static int itemPaths(IShellItemArray *items, QList<QUrl> *fileResult = 0);
static IShellItem *shellItem(const QUrl &url);
const QWindowsFileDialogSharedData &data() const { return m_data; }
QWindowsFileDialogSharedData &data() { return m_data; }
private:
- IFileDialog *m_fileDialog;
- IFileDialogEvents *m_dialogEvents;
- DWORD m_cookie;
+ IFileDialog *m_fileDialog = nullptr;
+ IFileDialogEvents *m_dialogEvents = nullptr;
+ DWORD m_cookie = 0;
QStringList m_nameFilters;
- bool m_hideFiltersDetails;
- bool m_hasDefaultSuffix;
+ bool m_hideFiltersDetails = false;
+ bool m_hasDefaultSuffix = false;
QWindowsFileDialogSharedData m_data;
QString m_title;
};
QWindowsNativeFileDialogBase::QWindowsNativeFileDialogBase(const QWindowsFileDialogSharedData &data) :
- m_fileDialog(0), m_dialogEvents(0), m_cookie(0), m_hideFiltersDetails(false),
- m_hasDefaultSuffix(false), m_data(data)
+ m_data(data)
{
}
@@ -753,7 +970,7 @@ QString QWindowsNativeFileDialogBase::directory() const
QString result;
IShellItem *item = 0;
if (m_fileDialog && SUCCEEDED(m_fileDialog->GetFolder(&item)) && item) {
- result = QWindowsNativeFileDialogBase::itemPath(item);
+ result = QWindowsShellItem(item).path();
item->Release();
}
return result;
@@ -807,113 +1024,6 @@ void QWindowsNativeFileDialogBase::setMode(QFileDialogOptions::FileMode mode,
qErrnoWarning("%s: SetOptions() failed", __FUNCTION__);
}
-#if defined(__IShellLibrary_INTERFACE_DEFINED__) // Windows SDK 7
-
-// Helper for "Libraries": collections of folders appearing from Windows 7
-// on, visible in the file dialogs.
-
-// Load a library from a IShellItem (sanitized copy of the inline function
-// SHLoadLibraryFromItem from ShObjIdl.h, which does not exist for MinGW).
-static IShellLibrary *sHLoadLibraryFromItem(IShellItem *libraryItem, DWORD mode)
-{
- // ID symbols present from Windows 7 on:
- static const CLSID classId_ShellLibrary = {0xd9b3211d, 0xe57f, 0x4426, {0xaa, 0xef, 0x30, 0xa8, 0x6, 0xad, 0xd3, 0x97}};
- static const IID iId_IShellLibrary = {0x11a66efa, 0x382e, 0x451a, {0x92, 0x34, 0x1e, 0xe, 0x12, 0xef, 0x30, 0x85}};
-
- IShellLibrary *helper = 0;
- IShellLibrary *result = 0;
- if (SUCCEEDED(CoCreateInstance(classId_ShellLibrary, NULL, CLSCTX_INPROC_SERVER, iId_IShellLibrary, reinterpret_cast<void **>(&helper))))
- if (SUCCEEDED(helper->LoadLibraryFromItem(libraryItem, mode)))
- helper->QueryInterface(iId_IShellLibrary, reinterpret_cast<void **>(&result));
- if (helper)
- helper->Release();
- return result;
-}
-
-// Return all folders of a library-type item.
-QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *item)
-{
- QList<QUrl> result;
- if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) {
- IShellItemArray *itemArray = 0;
- if (SUCCEEDED(library->GetFolders(LFF_FORCEFILESYSTEM, IID_IShellItemArray, reinterpret_cast<void **>(&itemArray)))) {
- QWindowsNativeFileDialogBase::itemPaths(itemArray, &result);
- itemArray->Release();
- }
- library->Release();
- }
- return result;
-}
-
-// Return default save folders of a library-type item.
-QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *item)
-{
- QString result;
- if (IShellLibrary *library = sHLoadLibraryFromItem(item, STGM_READ | STGM_SHARE_DENY_WRITE)) {
- IShellItem *item = 0;
- if (SUCCEEDED(library->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, reinterpret_cast<void **>(&item)))) {
- result = QWindowsNativeFileDialogBase::itemPath(item);
- item->Release();
- }
- library->Release();
- }
- return result;
-}
-
-#else // __IShellLibrary_INTERFACE_DEFINED__
-
-QList<QUrl> QWindowsNativeFileDialogBase::libraryItemFolders(IShellItem *)
-{
- return QList<QUrl>();
-}
-
-QString QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(IShellItem *)
-{
- return QString();
-}
-
-#endif // !__IShellLibrary_INTERFACE_DEFINED__
-
-QString QWindowsNativeFileDialogBase::itemPath(IShellItem *item)
-{
- SFGAOF attributes = 0;
- // Check whether it has a file system representation?
- if (FAILED(item->GetAttributes(SFGAO_FILESYSTEM, &attributes)))
- return QString();
- if (attributes & SFGAO_FILESYSTEM) {
- LPWSTR name = 0;
- QString result;
- if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &name))) {
- result = QDir::cleanPath(QString::fromWCharArray(name));
- CoTaskMemFree(name);
- }
- return result;
- }
- // Check for a "Library" item
- if ((QSysInfo::windowsVersion() & QSysInfo::WV_NT_based) && QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS7)
- return QWindowsNativeFileDialogBase::libraryItemDefaultSaveFolder(item);
- return QString();
-}
-
-int QWindowsNativeFileDialogBase::itemPaths(IShellItemArray *items,
- QList<QUrl> *result /* = 0 */)
-{
- DWORD itemCount = 0;
- if (result)
- result->clear();
- if (FAILED(items->GetCount(&itemCount)))
- return 0;
- if (result && itemCount) {
- result->reserve(itemCount);
- for (DWORD i = 0; i < itemCount; ++i) {
- IShellItem *item = 0;
- if (SUCCEEDED(items->GetItemAt(i, &item)))
- result->push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
- }
- }
- return itemCount;
-}
-
// Split a list of name filters into description and actual filters
struct FilterSpec
{
@@ -1011,6 +1121,13 @@ void QWindowsNativeFileDialogBase::setDefaultSuffixSys(const QString &s)
m_fileDialog->SetDefaultExtension(wSuffix);
}
+static inline IFileDialog2 *getFileDialog2(IFileDialog *fileDialog)
+{
+ IFileDialog2 *result;
+ return SUCCEEDED(fileDialog->QueryInterface(IID_IFileDialog2, reinterpret_cast<void **>(&result)))
+ ? result : nullptr;
+}
+
void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel l, const QString &text)
{
wchar_t *wText = const_cast<wchar_t *>(reinterpret_cast<const wchar_t *>(text.utf16()));
@@ -1021,8 +1138,13 @@ void QWindowsNativeFileDialogBase::setLabelText(QFileDialogOptions::DialogLabel
case QFileDialogOptions::Accept:
m_fileDialog->SetOkButtonLabel(wText);
break;
- case QFileDialogOptions::LookIn:
case QFileDialogOptions::Reject:
+ if (IFileDialog2 *dialog2 = getFileDialog2(m_fileDialog)) {
+ dialog2->SetCancelButtonLabel(wText);
+ dialog2->Release();
+ }
+ break;
+ case QFileDialogOptions::LookIn:
case QFileDialogOptions::FileType:
case QFileDialogOptions::DialogLabelCount:
break;
@@ -1067,7 +1189,7 @@ void QWindowsNativeFileDialogBase::selectNameFilter(const QString &filter)
if (index < 0) {
qWarning("%s: Invalid parameter '%s' not found in '%s'.",
__FUNCTION__, qPrintable(filter),
- qPrintable(m_nameFilters.join(QStringLiteral(", "))));
+ qPrintable(m_nameFilters.join(QLatin1String(", "))));
return;
}
m_fileDialog->SetFileTypeIndex(index + 1); // one-based.
@@ -1087,7 +1209,7 @@ QString QWindowsNativeFileDialogBase::selectedNameFilter() const
void QWindowsNativeFileDialogBase::onFolderChange(IShellItem *item)
{
if (item) {
- const QUrl directory = QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item));
+ const QUrl directory = QWindowsShellItem(item).url();
m_data.setDirectory(directory);
emit directoryEntered(directory);
}
@@ -1165,9 +1287,9 @@ class QWindowsNativeSaveFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeSaveFileDialog(const QWindowsFileDialogSharedData &data)
: QWindowsNativeFileDialogBase(data) {}
- void setNameFilters(const QStringList &f) Q_DECL_OVERRIDE;
- QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- QList<QUrl> dialogResult() const Q_DECL_OVERRIDE;
+ void setNameFilters(const QStringList &f) override;
+ QList<QUrl> selectedFiles() const override;
+ QList<QUrl> dialogResult() const override;
};
// Return the first suffix from the name filter "Foo files (*.foo;*.bar)" -> "foo".
@@ -1210,7 +1332,7 @@ QList<QUrl> QWindowsNativeSaveFileDialog::dialogResult() const
QList<QUrl> result;
IShellItem *item = 0;
if (SUCCEEDED(fileDialog()->GetResult(&item)) && item)
- result.push_back(QUrl::fromLocalFile(QWindowsNativeFileDialogBase::itemPath(item)));
+ result.append(QWindowsShellItem(item).url());
return result;
}
@@ -1220,7 +1342,7 @@ QList<QUrl> QWindowsNativeSaveFileDialog::selectedFiles() const
IShellItem *item = 0;
const HRESULT hr = fileDialog()->GetCurrentSelection(&item);
if (SUCCEEDED(hr) && item) {
- result.push_back(QUrl::fromLocalFile(QWindowsNativeSaveFileDialog::itemPath(item)));
+ result.append(QWindowsShellItem(item).url());
item->Release();
}
return result;
@@ -1241,20 +1363,69 @@ class QWindowsNativeOpenFileDialog : public QWindowsNativeFileDialogBase
public:
explicit QWindowsNativeOpenFileDialog(const QWindowsFileDialogSharedData &data) :
QWindowsNativeFileDialogBase(data) {}
- QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- QList<QUrl> dialogResult() const Q_DECL_OVERRIDE;
+ QList<QUrl> selectedFiles() const override;
+ QList<QUrl> dialogResult() const override;
private:
inline IFileOpenDialog *openFileDialog() const
{ return static_cast<IFileOpenDialog *>(fileDialog()); }
};
+// Helpers for managing a list of temporary copies of items with no
+// file system representation (SFGAO_FILESYSTEM unset, for example devices
+// using MTP) returned by IFileOpenDialog. This emulates the behavior
+// of the Win32 API GetOpenFileName() used in Qt 4 (QTBUG-57070).
+
+Q_GLOBAL_STATIC(QStringList, temporaryItemCopies)
+
+static void cleanupTemporaryItemCopies()
+{
+ for (const QString &file : qAsConst(*temporaryItemCopies()))
+ QFile::remove(file);
+}
+
+static QString createTemporaryItemCopy(QWindowsShellItem &qItem)
+{
+ if (!qItem.canCopy() || !qItem.canStream())
+ return QString();
+ QString pattern = qItem.normalDisplay();
+ const int lastDot = pattern.lastIndexOf(QLatin1Char('.'));
+ const QString placeHolder = QStringLiteral("_XXXXXX");
+ if (lastDot >= 0)
+ pattern.insert(lastDot, placeHolder);
+ else
+ pattern.append(placeHolder);
+
+ QTemporaryFile targetFile(QDir::tempPath() + QLatin1Char('/') + pattern);
+ targetFile.setAutoRemove(false);
+ if (!targetFile.open() || !qItem.copyData(&targetFile))
+ return QString();
+ const QString result = targetFile.fileName();
+ if (temporaryItemCopies()->isEmpty())
+ qAddPostRoutine(cleanupTemporaryItemCopies);
+ temporaryItemCopies()->append(result);
+ return result;
+}
+
QList<QUrl> QWindowsNativeOpenFileDialog::dialogResult() const
{
QList<QUrl> result;
IShellItemArray *items = 0;
- if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items)
- QWindowsNativeFileDialogBase::itemPaths(items, &result);
+ if (SUCCEEDED(openFileDialog()->GetResults(&items)) && items) {
+ for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) {
+ QWindowsShellItem qItem(item);
+ const QString path = qItem.path();
+ if (path.isEmpty()) {
+ const QString temporaryCopy = createTemporaryItemCopy(qItem);
+ if (temporaryCopy.isEmpty())
+ qWarning() << "Unable to create a local copy of" << qItem;
+ else
+ result.append(QUrl::fromLocalFile(temporaryCopy));
+ } else {
+ result.append(qItem.url());
+ }
+ }
+ }
return result;
}
@@ -1263,8 +1434,16 @@ QList<QUrl> QWindowsNativeOpenFileDialog::selectedFiles() const
QList<QUrl> result;
IShellItemArray *items = 0;
const HRESULT hr = openFileDialog()->GetSelectedItems(&items);
- if (SUCCEEDED(hr) && items)
- QWindowsNativeFileDialogBase::itemPaths(items, &result);
+ if (SUCCEEDED(hr) && items) {
+ for (IShellItem *item : QWindowsShellItem::itemsFromItemArray(items)) {
+ const QWindowsShellItem qItem(item);
+ const QUrl url = qItem.url();
+ if (url.isValid())
+ result.append(url);
+ else
+ qWarning().nospace() << __FUNCTION__<< ": Unable to obtain URL of " << qItem;
+ }
+ }
return result;
}
@@ -1309,19 +1488,19 @@ class QWindowsFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFileDi
{
public:
QWindowsFileDialogHelper() {}
- virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; }
- virtual bool defaultNameFilterDisables() const Q_DECL_OVERRIDE
+ bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const override { return false; }
+ bool defaultNameFilterDisables() const override
{ return false; }
- virtual void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
- virtual QUrl directory() const Q_DECL_OVERRIDE;
- virtual void selectFile(const QUrl &filename) Q_DECL_OVERRIDE;
- virtual QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- virtual void setFilter() Q_DECL_OVERRIDE;
- virtual void selectNameFilter(const QString &filter) Q_DECL_OVERRIDE;
- virtual QString selectedNameFilter() const Q_DECL_OVERRIDE;
+ void setDirectory(const QUrl &directory) override;
+ QUrl directory() const override;
+ void selectFile(const QUrl &filename) override;
+ QList<QUrl> selectedFiles() const override;
+ void setFilter() override;
+ void selectNameFilter(const QString &filter) override;
+ QString selectedNameFilter() const override;
private:
- QWindowsNativeDialogBase *createNativeDialog() Q_DECL_OVERRIDE;
+ QWindowsNativeDialogBase *createNativeDialog() override;
inline QWindowsNativeFileDialogBase *nativeFileDialog() const
{ return static_cast<QWindowsNativeFileDialogBase *>(nativeDialog()); }
@@ -1357,6 +1536,8 @@ QWindowsNativeDialogBase *QWindowsFileDialogHelper::createNativeDialog()
result->setLabelText(QFileDialogOptions::FileName, opts->labelText(QFileDialogOptions::FileName));
if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept))
result->setLabelText(QFileDialogOptions::Accept, opts->labelText(QFileDialogOptions::Accept));
+ if (opts->isLabelExplicitlySet(QFileDialogOptions::Reject))
+ result->setLabelText(QFileDialogOptions::Reject, opts->labelText(QFileDialogOptions::Reject));
result->updateDirectory();
result->updateSelectedNameFilter();
const QList<QUrl> initialSelection = opts->initiallySelectedFiles();
@@ -1447,13 +1628,13 @@ public:
static QWindowsXpNativeFileDialog *create(const OptionsPtr &options, const QWindowsFileDialogSharedData &data);
- void setWindowTitle(const QString &t) Q_DECL_OVERRIDE { m_title = t; }
- void doExec(HWND owner = 0) Q_DECL_OVERRIDE;
+ void setWindowTitle(const QString &t) override { m_title = t; }
+ void doExec(HWND owner = 0) override;
int existingDirCallback(HWND hwnd, UINT uMsg, LPARAM lParam);
public slots:
- void close() Q_DECL_OVERRIDE {}
+ void close() override {}
private:
typedef BOOL (APIENTRY *PtrGetOpenFileNameW)(LPOPENFILENAMEW);
@@ -1689,19 +1870,19 @@ class QWindowsXpFileDialogHelper : public QWindowsDialogHelperBase<QPlatformFile
{
public:
QWindowsXpFileDialogHelper() {}
- bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const Q_DECL_OVERRIDE { return false; }
- bool defaultNameFilterDisables() const Q_DECL_OVERRIDE
+ bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const override { return false; }
+ bool defaultNameFilterDisables() const override
{ return true; }
- void setDirectory(const QUrl &directory) Q_DECL_OVERRIDE;
- QUrl directory() const Q_DECL_OVERRIDE;
- void selectFile(const QUrl &url) Q_DECL_OVERRIDE;
- QList<QUrl> selectedFiles() const Q_DECL_OVERRIDE;
- void setFilter() Q_DECL_OVERRIDE {}
- void selectNameFilter(const QString &) Q_DECL_OVERRIDE;
- QString selectedNameFilter() const Q_DECL_OVERRIDE;
+ void setDirectory(const QUrl &directory) override;
+ QUrl directory() const override;
+ void selectFile(const QUrl &url) override;
+ QList<QUrl> selectedFiles() const override;
+ void setFilter() override {}
+ void selectNameFilter(const QString &) override;
+ QString selectedNameFilter() const override;
private:
- QWindowsNativeDialogBase *createNativeDialog() Q_DECL_OVERRIDE;
+ QWindowsNativeDialogBase *createNativeDialog() override;
inline QWindowsXpNativeFileDialog *nativeFileDialog() const
{ return static_cast<QWindowsXpNativeFileDialog *>(nativeDialog()); }
@@ -1773,13 +1954,13 @@ public:
explicit QWindowsNativeColorDialog(const SharedPointerColor &color);
- void setWindowTitle(const QString &) Q_DECL_OVERRIDE {}
+ void setWindowTitle(const QString &) override {}
public slots:
- void close() Q_DECL_OVERRIDE {}
+ void close() override {}
private:
- void doExec(HWND owner = 0) Q_DECL_OVERRIDE;
+ void doExec(HWND owner = 0) override;
COLORREF m_customColors[CustomColorCount];
QPlatformDialogHelper::DialogCode m_code;
diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.h b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
index b3101a1419..55f112c57a 100644
--- a/src/plugins/platforms/windows/qwindowsdialoghelpers.h
+++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.h
@@ -69,19 +69,19 @@ public:
typedef QSharedPointer<QWindowsNativeDialogBase> QWindowsNativeDialogBasePtr;
~QWindowsDialogHelperBase() { cleanupThread(); }
- void exec() Q_DECL_OVERRIDE;
+ void exec() override;
bool show(Qt::WindowFlags windowFlags,
- Qt::WindowModality windowModality,
- QWindow *parent) Q_DECL_OVERRIDE;
- void hide() Q_DECL_OVERRIDE;
+ Qt::WindowModality windowModality,
+ QWindow *parent) override;
+ void hide() override;
virtual bool supportsNonModalDialog(const QWindow * /* parent */ = 0) const { return true; }
protected:
- QWindowsDialogHelperBase();
+ QWindowsDialogHelperBase() {}
QWindowsNativeDialogBase *nativeDialog() const;
inline bool hasNativeDialog() const { return m_nativeDialog; }
- void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
+ void timerEvent(QTimerEvent *) override;
private:
virtual QWindowsNativeDialogBase *createNativeDialog() = 0;
@@ -91,9 +91,9 @@ private:
void cleanupThread();
QWindowsNativeDialogBasePtr m_nativeDialog;
- HWND m_ownerWindow;
- int m_timerId;
- QThread *m_thread;
+ HWND m_ownerWindow = 0;
+ int m_timerId = 0;
+ QThread *m_thread = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index 26a5131927..550415e889 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -84,7 +84,7 @@ public:
void setPixmap(const QPixmap &p);
protected:
- void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE
+ void paintEvent(QPaintEvent *) override
{
QPainter painter(this);
painter.drawPixmap(0, 0, m_pixmap);
@@ -190,6 +190,20 @@ static inline Qt::KeyboardModifiers toQtKeyboardModifiers(DWORD keyState)
return modifiers;
}
+static inline Qt::MouseButtons toQtMouseButtons(DWORD keyState)
+{
+ Qt::MouseButtons buttons = Qt::NoButton;
+
+ if (keyState & MK_LBUTTON)
+ buttons |= Qt::LeftButton;
+ if (keyState & MK_RBUTTON)
+ buttons |= Qt::RightButton;
+ if (keyState & MK_MBUTTON)
+ buttons |= Qt::MidButton;
+
+ return buttons;
+}
+
/*!
\class QWindowsOleDropSource
\brief Implementation of IDropSource
@@ -405,16 +419,7 @@ QWindowsOleDropSource::QueryContinueDrag(BOOL fEscapePressed, DWORD grfKeyState)
break;
}
- // grfKeyState is broken on CE & some Windows XP versions,
- // therefore we need to check the state manually
- if ((GetAsyncKeyState(VK_LBUTTON) == 0)
- && (GetAsyncKeyState(VK_MBUTTON) == 0)
- && (GetAsyncKeyState(VK_RBUTTON) == 0)) {
- hr = ResultFromScode(DRAGDROP_S_DROP);
- break;
- }
-
- const Qt::MouseButtons buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ const Qt::MouseButtons buttons = toQtMouseButtons(grfKeyState);
if (m_currentButtons == Qt::NoButton) {
m_currentButtons = buttons;
} else {
@@ -489,8 +494,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
\ingroup qt-lighthouse-win
*/
-QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) :
- m_refs(1), m_window(w), m_chosenEffect(0), m_lastKeyState(0)
+QWindowsOleDropTarget::QWindowsOleDropTarget(QWindow *w) : m_window(w)
{
qCDebug(lcQpaMime) << __FUNCTION__ << this << w;
}
@@ -538,7 +542,7 @@ void QWindowsOleDropTarget::handleDrag(QWindow *window, DWORD grfKeyState,
QWindowsDrag *windowsDrag = QWindowsDrag::instance();
const Qt::DropActions actions = translateToQDragDropActions(*pdwEffect);
QGuiApplicationPrivate::modifier_buttons = toQtKeyboardModifiers(grfKeyState);
- QGuiApplicationPrivate::mouse_buttons = QWindowsMouseHandler::keyStateToMouseButtons(grfKeyState);
+ QGuiApplicationPrivate::mouse_buttons = toQtMouseButtons(grfKeyState);
const QPlatformDragQtResponse response =
QWindowSystemInterface::handleDrag(window, windowsDrag->dropData(), m_lastPoint, actions);
@@ -682,10 +686,7 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
bool QWindowsDrag::m_canceled = false;
-QWindowsDrag::QWindowsDrag() :
- m_dropDataObject(0), m_cachedDropTargetHelper(0)
-{
-}
+QWindowsDrag::QWindowsDrag() = default;
QWindowsDrag::~QWindowsDrag()
{
diff --git a/src/plugins/platforms/windows/qwindowsdrag.h b/src/plugins/platforms/windows/qwindowsdrag.h
index e81bc7dc61..983f3a67b4 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.h
+++ b/src/plugins/platforms/windows/qwindowsdrag.h
@@ -54,7 +54,7 @@ class QPlatformScreen;
class QWindowsDropMimeData : public QWindowsInternalMimeData {
public:
QWindowsDropMimeData() {}
- IDataObject *retrieveDataObject() const Q_DECL_OVERRIDE;
+ IDataObject *retrieveDataObject() const override;
};
class QWindowsOleDropTarget : public IDropTarget
@@ -77,12 +77,12 @@ public:
private:
void handleDrag(QWindow *window, DWORD grfKeyState, const QPoint &, LPDWORD pdwEffect);
- ULONG m_refs;
+ ULONG m_refs = 1;
QWindow *const m_window;
QRect m_answerRect;
QPoint m_lastPoint;
- DWORD m_chosenEffect;
- DWORD m_lastKeyState;
+ DWORD m_chosenEffect = 0;
+ DWORD m_lastKeyState = 0;
};
class QWindowsDrag : public QPlatformDrag
@@ -91,12 +91,12 @@ public:
QWindowsDrag();
virtual ~QWindowsDrag();
- QMimeData *platformDropData() Q_DECL_OVERRIDE { return &m_dropData; }
+ QMimeData *platformDropData() override { return &m_dropData; }
- Qt::DropAction drag(QDrag *drag) Q_DECL_OVERRIDE;
+ Qt::DropAction drag(QDrag *drag) override;
static QWindowsDrag *instance();
- void cancelDrag() Q_DECL_OVERRIDE { QWindowsDrag::m_canceled = true; }
+ void cancelDrag() override { QWindowsDrag::m_canceled = true; }
static bool isCanceled() { return QWindowsDrag::m_canceled; }
IDataObject *dropDataObject() const { return m_dropDataObject; }
@@ -110,9 +110,9 @@ private:
static bool m_canceled;
QWindowsDropMimeData m_dropData;
- IDataObject *m_dropDataObject;
+ IDataObject *m_dropDataObject = nullptr;
- IDropTargetHelper* m_cachedDropTargetHelper;
+ IDropTargetHelper* m_cachedDropTargetHelper = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp
index a4738dc100..4632c9c157 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp
@@ -384,8 +384,6 @@ QWindowsEGLContext::QWindowsEGLContext(QWindowsEGLStaticContext *staticContext,
QPlatformOpenGLContext *share)
: m_staticContext(staticContext)
, m_eglDisplay(staticContext->display())
- , m_api(EGL_OPENGL_ES_API)
- , m_swapInterval(-1)
{
if (!m_staticContext)
return;
diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h
index 48a19f81e5..47878a7169 100644
--- a/src/plugins/platforms/windows/qwindowseglcontext.h
+++ b/src/plugins/platforms/windows/qwindowseglcontext.h
@@ -117,12 +117,12 @@ public:
EGLDisplay display() const { return m_display; }
- QWindowsOpenGLContext *createContext(QOpenGLContext *context) Q_DECL_OVERRIDE;
- void *moduleHandle() const Q_DECL_OVERRIDE { return libGLESv2.moduleHandle(); }
- QOpenGLContext::OpenGLModuleType moduleType() const Q_DECL_OVERRIDE { return QOpenGLContext::LibGLES; }
+ QWindowsOpenGLContext *createContext(QOpenGLContext *context) override;
+ void *moduleHandle() const override { return libGLESv2.moduleHandle(); }
+ QOpenGLContext::OpenGLModuleType moduleType() const override { return QOpenGLContext::LibGLES; }
- void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) Q_DECL_OVERRIDE;
- void destroyWindowSurface(void *nativeSurface) Q_DECL_OVERRIDE;
+ void *createWindowSurface(void *nativeWindow, void *nativeConfig, int *err) override;
+ void destroyWindowSurface(void *nativeSurface) override;
QSurfaceFormat formatFromConfig(EGLDisplay display, EGLConfig config, const QSurfaceFormat &referenceFormat);
@@ -145,18 +145,18 @@ public:
QPlatformOpenGLContext *share);
~QWindowsEGLContext();
- bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- void doneCurrent() Q_DECL_OVERRIDE;
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE;
+ bool makeCurrent(QPlatformSurface *surface) override;
+ void doneCurrent() override;
+ void swapBuffers(QPlatformSurface *surface) override;
+ QFunctionPointer getProcAddress(const char *procName) override;
- QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- bool isSharing() const Q_DECL_OVERRIDE { return m_shareContext != EGL_NO_CONTEXT; }
- bool isValid() const Q_DECL_OVERRIDE { return m_eglContext != EGL_NO_CONTEXT; }
+ QSurfaceFormat format() const override { return m_format; }
+ bool isSharing() const override { return m_shareContext != EGL_NO_CONTEXT; }
+ bool isValid() const override { return m_eglContext != EGL_NO_CONTEXT; }
- void *nativeContext() const Q_DECL_OVERRIDE { return m_eglContext; }
- void *nativeDisplay() const Q_DECL_OVERRIDE { return m_eglDisplay; }
- void *nativeConfig() const Q_DECL_OVERRIDE { return m_eglConfig; }
+ void *nativeContext() const override { return m_eglContext; }
+ void *nativeDisplay() const override { return m_eglDisplay; }
+ void *nativeConfig() const override { return m_eglConfig; }
private:
EGLConfig chooseConfig(const QSurfaceFormat &format);
@@ -167,8 +167,8 @@ private:
EGLDisplay m_eglDisplay;
EGLConfig m_eglConfig;
QSurfaceFormat m_format;
- EGLenum m_api;
- int m_swapInterval;
+ EGLenum m_api = EGL_OPENGL_ES_API;
+ int m_swapInterval = -1;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsgdiintegration.h b/src/plugins/platforms/windows/qwindowsgdiintegration.h
index 46af20a083..ec67a99bc9 100644
--- a/src/plugins/platforms/windows/qwindowsgdiintegration.h
+++ b/src/plugins/platforms/windows/qwindowsgdiintegration.h
@@ -51,9 +51,9 @@ public:
explicit QWindowsGdiIntegration(const QStringList &paramList);
virtual ~QWindowsGdiIntegration();
- QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const Q_DECL_OVERRIDE;
- QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformNativeInterface *nativeInterface() const override;
+ QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const override;
+ QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const override;
private:
QScopedPointer<QWindowsGdiIntegrationPrivate> d;
diff --git a/src/plugins/platforms/windows/qwindowsgdinativeinterface.h b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
index f0464bc823..c86d3cbb47 100644
--- a/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsgdinativeinterface.h
@@ -48,7 +48,7 @@ class QWindowsGdiNativeInterface : public QWindowsNativeInterface
{
Q_OBJECT
public:
- void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) Q_DECL_OVERRIDE;
+ void *nativeResourceForBackingStore(const QByteArray &resource, QBackingStore *bs) override;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.cpp b/src/plugins/platforms/windows/qwindowsglcontext.cpp
index c1eb664324..751807e897 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsglcontext.cpp
@@ -825,13 +825,6 @@ static inline QOpenGLContextData createDummyWindowOpenGLContextData()
\ingroup qt-lighthouse-win
*/
-QWindowsOpenGLContextFormat::QWindowsOpenGLContextFormat() :
- profile(QSurfaceFormat::NoProfile),
- version(0),
- options(0)
-{
-}
-
QWindowsOpenGLContextFormat QWindowsOpenGLContextFormat::current()
{
QWindowsOpenGLContextFormat result;
diff --git a/src/plugins/platforms/windows/qwindowsglcontext.h b/src/plugins/platforms/windows/qwindowsglcontext.h
index 048b22bbf7..dfaa428520 100644
--- a/src/plugins/platforms/windows/qwindowsglcontext.h
+++ b/src/plugins/platforms/windows/qwindowsglcontext.h
@@ -73,24 +73,23 @@ struct QWindowsOpenGLAdditionalFormat
struct QOpenGLContextData
{
QOpenGLContextData(HGLRC r, HWND h, HDC d) : renderingContext(r), hwnd(h), hdc(d) {}
- QOpenGLContextData() : renderingContext(0), hwnd(0), hdc(0) {}
+ QOpenGLContextData() {}
- HGLRC renderingContext;
- HWND hwnd;
- HDC hdc;
+ HGLRC renderingContext = 0;
+ HWND hwnd = 0;
+ HDC hdc = 0;
};
class QOpenGLStaticContext;
struct QWindowsOpenGLContextFormat
{
- QWindowsOpenGLContextFormat();
static QWindowsOpenGLContextFormat current();
void apply(QSurfaceFormat *format) const;
- QSurfaceFormat::OpenGLContextProfile profile;
- int version; //! majorVersion<<8 + minorVersion
- QSurfaceFormat::FormatOptions options;
+ QSurfaceFormat::OpenGLContextProfile profile = QSurfaceFormat::NoProfile;
+ int version = 0; //! majorVersion<<8 + minorVersion
+ QSurfaceFormat::FormatOptions options = 0;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -195,22 +194,22 @@ class QWindowsGLContext : public QWindowsOpenGLContext
public:
explicit QWindowsGLContext(QOpenGLStaticContext *staticContext, QOpenGLContext *context);
~QWindowsGLContext();
- bool isSharing() const Q_DECL_OVERRIDE { return m_context->shareHandle(); }
- bool isValid() const Q_DECL_OVERRIDE { return m_renderingContext && !m_lost; }
- QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_obtainedFormat; }
+ bool isSharing() const override { return m_context->shareHandle(); }
+ bool isValid() const override { return m_renderingContext && !m_lost; }
+ QSurfaceFormat format() const override { return m_obtainedFormat; }
- void swapBuffers(QPlatformSurface *surface) Q_DECL_OVERRIDE;
+ void swapBuffers(QPlatformSurface *surface) override;
- bool makeCurrent(QPlatformSurface *surface) Q_DECL_OVERRIDE;
- void doneCurrent() Q_DECL_OVERRIDE;
+ bool makeCurrent(QPlatformSurface *surface) override;
+ void doneCurrent() override;
typedef void (*GL_Proc) ();
- QFunctionPointer getProcAddress(const char *procName) Q_DECL_OVERRIDE;
+ QFunctionPointer getProcAddress(const char *procName) override;
HGLRC renderingContext() const { return m_renderingContext; }
- void *nativeContext() const Q_DECL_OVERRIDE { return m_renderingContext; }
+ void *nativeContext() const override { return m_renderingContext; }
private:
inline void releaseDCs();
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.cpp b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
index 8adbd494c4..e7ebf73d5d 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.cpp
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.cpp
@@ -166,15 +166,8 @@ Q_CORE_EXPORT QLocale qt_localeFromLCID(LCID id); // from qlocale_win.cpp
HIMC QWindowsInputContext::m_defaultContext = 0;
-QWindowsInputContext::CompositionContext::CompositionContext() :
- hwnd(0), haveCaret(false), position(0), isComposing(false),
- factor(1)
-{
-}
-
QWindowsInputContext::QWindowsInputContext() :
m_WM_MSIME_MOUSE(RegisterWindowMessage(L"MSIMEMouseOperation")),
- m_endCompositionRecursionGuard(false),
m_languageId(currentInputLanguageId()),
m_locale(qt_localeFromLCID(m_languageId))
{
diff --git a/src/plugins/platforms/windows/qwindowsinputcontext.h b/src/plugins/platforms/windows/qwindowsinputcontext.h
index a7fa2c4f94..617ef30cef 100644
--- a/src/plugins/platforms/windows/qwindowsinputcontext.h
+++ b/src/plugins/platforms/windows/qwindowsinputcontext.h
@@ -57,15 +57,13 @@ class QWindowsInputContext : public QPlatformInputContext
struct CompositionContext
{
- CompositionContext();
-
- HWND hwnd;
- bool haveCaret;
+ HWND hwnd = 0;
+ bool haveCaret = false;
QString composition;
- int position;
- bool isComposing;
+ int position = 0;
+ bool isComposing = false;
QPointer<QObject> focusObject;
- qreal factor;
+ qreal factor = 1;
};
public:
explicit QWindowsInputContext();
@@ -73,13 +71,13 @@ public:
static void setWindowsImeEnabled(QWindowsWindow *platformWindow, bool enabled);
- bool hasCapability(Capability capability) const Q_DECL_OVERRIDE;
- QLocale locale() const Q_DECL_OVERRIDE { return m_locale; }
+ bool hasCapability(Capability capability) const override;
+ QLocale locale() const override { return m_locale; }
- void reset() Q_DECL_OVERRIDE;
- void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
- void invokeAction(QInputMethod::Action, int cursorPosition) Q_DECL_OVERRIDE;
- void setFocusObject(QObject *object) Q_DECL_OVERRIDE;
+ void reset() override;
+ void update(Qt::InputMethodQueries) override;
+ void invokeAction(QInputMethod::Action, int cursorPosition) override;
+ void setFocusObject(QObject *object) override;
bool startComposition(HWND hwnd);
bool composition(HWND hwnd, LPARAM lParam);
@@ -104,7 +102,7 @@ private:
const DWORD m_WM_MSIME_MOUSE;
static HIMC m_defaultContext;
CompositionContext m_compositionContext;
- bool m_endCompositionRecursionGuard;
+ bool m_endCompositionRecursionGuard = false;
LCID m_languageId;
QLocale m_locale;
};
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 3f74fd5296..316f93e3ac 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -129,9 +129,9 @@ struct QWindowsIntegrationPrivate
explicit QWindowsIntegrationPrivate(const QStringList &paramList);
~QWindowsIntegrationPrivate();
- unsigned m_options;
+ unsigned m_options = 0;
QWindowsContext m_context;
- QPlatformFontDatabase *m_fontDatabase;
+ QPlatformFontDatabase *m_fontDatabase = nullptr;
#ifndef QT_NO_CLIPBOARD
QWindowsClipboard m_clipboard;
# ifndef QT_NO_DRAGANDDROP
@@ -209,8 +209,6 @@ static inline unsigned parseOptions(const QStringList &paramList,
}
QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList &paramList)
- : m_options(0)
- , m_fontDatabase(0)
{
Q_INIT_RESOURCE(openglblacklists);
@@ -306,24 +304,6 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
return result;
}
- if (window->type() == Qt::ForeignWindow) {
- const HWND hwnd = reinterpret_cast<HWND>(window->winId());
- if (!IsWindow(hwnd)) {
- qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd);
- return nullptr;
- }
- QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);
- const QRect obtainedGeometry = result->geometry();
- QScreen *screen = Q_NULLPTR;
- if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry))
- screen = pScreen->screen();
- if (screen && screen != window->screen())
- window->setScreen(screen);
- qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex
- << result->winId() << noshowbase << dec << obtainedGeometry << screen;
- return result;
- }
-
QWindowsWindowData requested;
requested.flags = window->flags();
requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
@@ -367,6 +347,25 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
return result;
}
+QPlatformWindow *QWindowsIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
+{
+ const HWND hwnd = reinterpret_cast<HWND>(nativeHandle);
+ if (!IsWindow(hwnd)) {
+ qWarning("Windows QPA: Invalid foreign window ID %p.", hwnd);
+ return nullptr;
+ }
+ QWindowsForeignWindow *result = new QWindowsForeignWindow(window, hwnd);
+ const QRect obtainedGeometry = result->geometry();
+ QScreen *screen = Q_NULLPTR;
+ if (const QPlatformScreen *pScreen = result->screenForGeometry(obtainedGeometry))
+ screen = pScreen->screen();
+ if (screen && screen != window->screen())
+ window->setScreen(screen);
+ qCDebug(lcQpaWindows) << "Foreign window:" << window << showbase << hex
+ << result->winId() << noshowbase << dec << obtainedGeometry << screen;
+ return result;
+}
+
// Overridden to return a QWindowsDirect2DWindow in Direct2D plugin.
QWindowsWindow *QWindowsIntegration::createPlatformWindowHelper(QWindow *window, const QWindowsWindowData &data) const
{
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index a668470993..607203829f 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -70,34 +70,35 @@ public:
explicit QWindowsIntegration(const QStringList &paramList);
virtual ~QWindowsIntegration();
- bool hasCapability(QPlatformIntegration::Capability cap) const Q_DECL_OVERRIDE;
+ bool hasCapability(QPlatformIntegration::Capability cap) const override;
- QPlatformWindow *createPlatformWindow(QWindow *window) const Q_DECL_OVERRIDE;
+ QPlatformWindow *createPlatformWindow(QWindow *window) const override;
+ QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
#ifndef QT_NO_OPENGL
- QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const Q_DECL_OVERRIDE;
- QOpenGLContext::OpenGLModuleType openGLModuleType() Q_DECL_OVERRIDE;
+ QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
+ QOpenGLContext::OpenGLModuleType openGLModuleType() override;
static QWindowsStaticOpenGLContext *staticOpenGLContext();
#endif
- QAbstractEventDispatcher *createEventDispatcher() const Q_DECL_OVERRIDE;
- void initialize() Q_DECL_OVERRIDE;
+ QAbstractEventDispatcher *createEventDispatcher() const override;
+ void initialize() override;
#ifndef QT_NO_CLIPBOARD
- QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE;
+ QPlatformClipboard *clipboard() const override;
# ifndef QT_NO_DRAGANDDROP
- QPlatformDrag *drag() const Q_DECL_OVERRIDE;
+ QPlatformDrag *drag() const override;
# endif
#endif // !QT_NO_CLIPBOARD
- QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
+ QPlatformInputContext *inputContext() const override;
#ifndef QT_NO_ACCESSIBILITY
- QPlatformAccessibility *accessibility() const Q_DECL_OVERRIDE;
+ QPlatformAccessibility *accessibility() const override;
#endif
- QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
- QStringList themeNames() const Q_DECL_OVERRIDE;
- QPlatformTheme *createPlatformTheme(const QString &name) const Q_DECL_OVERRIDE;
- QPlatformServices *services() const Q_DECL_OVERRIDE;
- QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE;
+ QPlatformFontDatabase *fontDatabase() const override;
+ QStringList themeNames() const override;
+ QPlatformTheme *createPlatformTheme(const QString &name) const override;
+ QPlatformServices *services() const override;
+ QVariant styleHint(StyleHint hint) const override;
- Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE;
- QList<int> possibleKeys(const QKeyEvent *e) const Q_DECL_OVERRIDE;
+ Qt::KeyboardModifiers queryKeyboardModifiers() const override;
+ QList<int> possibleKeys(const QKeyEvent *e) const override;
static QWindowsIntegration *instance() { return m_instance; }
@@ -106,10 +107,10 @@ public:
unsigned options() const;
- void beep() const Q_DECL_OVERRIDE;
+ void beep() const override;
#if !defined(QT_NO_SESSIONMANAGER)
- QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const Q_DECL_OVERRIDE;
+ QPlatformSessionManager *createPlatformSessionManager(const QString &id, const QString &key) const override;
#endif
protected:
diff --git a/src/plugins/platforms/windows/qwindowsinternalmimedata.h b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
index 4d775b1f21..a7df1ee6e0 100644
--- a/src/plugins/platforms/windows/qwindowsinternalmimedata.h
+++ b/src/plugins/platforms/windows/qwindowsinternalmimedata.h
@@ -52,9 +52,9 @@ class QDebug;
// Implementation in qwindowsclipboard.cpp.
class QWindowsInternalMimeData : public QInternalMimeData {
public:
- bool hasFormat_sys(const QString &mimetype) const Q_DECL_OVERRIDE;
- QStringList formats_sys() const Q_DECL_OVERRIDE;
- QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
+ bool hasFormat_sys(const QString &mimetype) const override;
+ QStringList formats_sys() const override;
+ QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const override;
protected:
virtual IDataObject *retrieveDataObject() const = 0;
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index b84b586f7c..24c2df86d4 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -144,13 +144,11 @@ struct KeyRecord {
static const int QT_MAX_KEY_RECORDINGS = 64; // User has LOTS of fingers...
struct KeyRecorder
{
- KeyRecorder() : nrecs(0) {}
-
inline KeyRecord *findKey(int code, bool remove);
inline void storeKey(int code, int ascii, int state, const QString& text);
inline void clearKeys();
- int nrecs;
+ int nrecs = 0;
KeyRecord deleted_record; // A copy of last entry removed from records[]
KeyRecord records[QT_MAX_KEY_RECORDINGS];
};
@@ -973,7 +971,8 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
state = state ^ Qt::ShiftModifier;
else if (code == Qt::Key_Alt)
state = state ^ Qt::AltModifier;
-
+ else if (code == 0 && modifiersIndex != 0)
+ code = keyLayout[vk_key].qtKey[0];
// If the bit 24 of lParm is set you received a enter,
// otherwise a Return. (This is the extended key bit)
if ((code == Qt::Key_Return) && (msg.lParam & 0x1000000))
diff --git a/src/plugins/platforms/windows/qwindowsmime.cpp b/src/plugins/platforms/windows/qwindowsmime.cpp
index 30d438a127..71fd12d71b 100644
--- a/src/plugins/platforms/windows/qwindowsmime.cpp
+++ b/src/plugins/platforms/windows/qwindowsmime.cpp
@@ -893,14 +893,14 @@ public:
QWindowsMimeHtml();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
- QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override;
+ QString mimeForFormat(const FORMATETC &formatetc) const override;
private:
int CF_HTML;
@@ -1025,14 +1025,14 @@ class QWindowsMimeImage : public QWindowsMime
public:
QWindowsMimeImage();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
- QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override;
+ QString mimeForFormat(const FORMATETC &formatetc) const override;
private:
bool hasOriginalDIBV5(IDataObject *pDataObj) const;
UINT CF_PNG;
@@ -1179,14 +1179,14 @@ public:
QBuiltInMimes();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
- QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override;
+ QString mimeForFormat(const FORMATETC &formatetc) const override;
private:
QMap<int, QString> outFormats;
@@ -1299,14 +1299,14 @@ public:
QLastResortMimes();
// for converting from Qt
- bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
- bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const Q_DECL_OVERRIDE;
- QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const Q_DECL_OVERRIDE;
+ bool canConvertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData) const override;
+ bool convertFromMime(const FORMATETC &formatetc, const QMimeData *mimeData, STGMEDIUM * pmedium) const override;
+ QVector<FORMATETC> formatsForMime(const QString &mimeType, const QMimeData *mimeData) const override;
// for converting to Qt
- bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const Q_DECL_OVERRIDE;
- QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const Q_DECL_OVERRIDE;
- QString mimeForFormat(const FORMATETC &formatetc) const Q_DECL_OVERRIDE;
+ bool canConvertToMime(const QString &mimeType, IDataObject *pDataObj) const override;
+ QVariant convertToMime(const QString &mime, IDataObject *pDataObj, QVariant::Type preferredType) const override;
+ QString mimeForFormat(const FORMATETC &formatetc) const override;
private:
QMap<int, QString> formats;
@@ -1496,9 +1496,7 @@ QString QLastResortMimes::mimeForFormat(const FORMATETC &formatetc) const
\sa QWindowsMime
*/
-QWindowsMimeConverter::QWindowsMimeConverter() : m_internalMimeCount(0)
-{
-}
+QWindowsMimeConverter::QWindowsMimeConverter() = default;
QWindowsMimeConverter::~QWindowsMimeConverter()
{
diff --git a/src/plugins/platforms/windows/qwindowsmime.h b/src/plugins/platforms/windows/qwindowsmime.h
index 4c0cbf9f31..1ed2aa933f 100644
--- a/src/plugins/platforms/windows/qwindowsmime.h
+++ b/src/plugins/platforms/windows/qwindowsmime.h
@@ -96,7 +96,7 @@ private:
void ensureInitialized() const;
mutable QList<QWindowsMime *> m_mimes;
- mutable int m_internalMimeCount;
+ mutable int m_internalMimeCount = 0;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index e4025fe60d..34c34fd28e 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -185,14 +185,7 @@ static inline QTouchDevice *createTouchDevice()
\ingroup qt-lighthouse-win
*/
-QWindowsMouseHandler::QWindowsMouseHandler() :
- m_windowUnderMouse(0),
- m_trackedWindow(0),
- m_touchDevice(Q_NULLPTR),
- m_leftButtonDown(false),
- m_previousCaptureWindow(0)
-{
-}
+QWindowsMouseHandler::QWindowsMouseHandler() = default;
QTouchDevice *QWindowsMouseHandler::ensureTouchDevice()
{
@@ -421,7 +414,7 @@ static bool isValidWheelReceiver(QWindow *candidate)
{
if (candidate) {
const QWindow *toplevel = QWindowsWindow::topLevelOf(candidate);
- if (toplevel->type() == Qt::ForeignWindow)
+ if (toplevel->handle() && toplevel->handle()->isForeignWindow())
return true;
if (const QWindowsWindow *ww = QWindowsWindow::windowsWindowOf(toplevel))
return !ww->testFlag(QWindowsWindow::BlockedByModal);
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h
index bd36d9f44c..86f18a0482 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.h
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.h
@@ -88,9 +88,9 @@ private:
QPointer<QWindow> m_trackedWindow;
QHash<DWORD, int> m_touchInputIDToTouchPointID;
QHash<int, QPointF> m_lastTouchPositions;
- QTouchDevice *m_touchDevice;
- bool m_leftButtonDown;
- QWindow *m_previousCaptureWindow;
+ QTouchDevice *m_touchDevice = nullptr;
+ bool m_leftButtonDown = false;
+ QWindow *m_previousCaptureWindow = nullptr;
};
Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam)
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index eaa6e45b9f..d750eef19d 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qwindowsnativeinterface.h"
+#include "qwindowsclipboard.h"
#include "qwindowswindow.h"
#include "qwindowscontext.h"
#include "qwindowscursor.h"
@@ -45,6 +46,7 @@
#include "qwindowsopengltester.h"
#include "qwindowsintegration.h"
#include "qwindowsmime.h"
+#include "qwin10helpers.h"
#include <QtGui/QWindow>
#include <QtGui/QOpenGLContext>
@@ -108,6 +110,7 @@ void *QWindowsNativeInterface::nativeResourceForWindow(const QByteArray &resourc
}
break;
case QWindow::OpenGLSurface:
+ case QWindow::OpenVGSurface:
break;
}
qWarning("%s: Invalid key '%s' requested.", __FUNCTION__, resource.constData());
@@ -252,14 +255,23 @@ QFont QWindowsNativeInterface::logFontToQFont(const void *logFont, int verticalD
return QWindowsFontDatabase::LOGFONT_to_QFont(*reinterpret_cast<const LOGFONT *>(logFont), verticalDpi);
}
+bool QWindowsNativeInterface::isTabletMode()
+{
+#if QT_CONFIG(clipboard)
+ if (const QWindowsClipboard *clipboard = QWindowsClipboard::instance())
+ return qt_windowsIsTabletMode(clipboard->clipboardViewer());
+#endif
+ return false;
+}
+
QFunctionPointer QWindowsNativeInterface::platformFunction(const QByteArray &function) const
{
if (function == QWindowsWindowFunctions::setTouchWindowTouchTypeIdentifier())
return QFunctionPointer(QWindowsWindow::setTouchWindowTouchTypeStatic);
else if (function == QWindowsWindowFunctions::setHasBorderInFullScreenIdentifier())
return QFunctionPointer(QWindowsWindow::setHasBorderInFullScreenStatic);
- else if (function == QWindowsWindowFunctions::setWindowActivationBehaviorIdentifier())
- return QFunctionPointer(QWindowsNativeInterface::setWindowActivationBehavior);
+ else if (function == QWindowsWindowFunctions::isTabletModeIdentifier())
+ return QFunctionPointer(QWindowsNativeInterface::isTabletMode);
return Q_NULLPTR;
}
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
index 9fc43ddcce..d085a4afb3 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -68,13 +68,13 @@ class QWindowsNativeInterface : public QPlatformNativeInterface
Q_PROPERTY(QVariant gpu READ gpu STORED false)
public:
- void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE;
+ void *nativeResourceForIntegration(const QByteArray &resource) override;
#ifndef QT_NO_OPENGL
- void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) override;
#endif
- void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) Q_DECL_OVERRIDE;
+ void *nativeResourceForWindow(const QByteArray &resource, QWindow *window) override;
#ifndef QT_NO_CURSOR
- void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) Q_DECL_OVERRIDE;
+ void *nativeResourceForCursor(const QByteArray &resource, const QCursor &cursor) override;
#endif
Q_INVOKABLE void *createMessageWindow(const QString &classNameTemplate,
const QString &windowName,
@@ -92,17 +92,19 @@ public:
QVariant gpu() const;
- QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE;
- QVariant windowProperty(QPlatformWindow *window, const QString &name) const Q_DECL_OVERRIDE;
- QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE;
- void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) Q_DECL_OVERRIDE;
+ QVariantMap windowProperties(QPlatformWindow *window) const override;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name) const override;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const override;
+ void setWindowProperty(QPlatformWindow *window, const QString &name, const QVariant &value) override;
static QWindowsWindowFunctions::WindowActivationBehavior windowActivationBehavior()
{ return QWindowsNativeInterface::m_windowActivationBehavior; }
static void setWindowActivationBehavior(QWindowsWindowFunctions::WindowActivationBehavior b)
{ QWindowsNativeInterface::m_windowActivationBehavior = b; }
- QFunctionPointer platformFunction(const QByteArray &function) const Q_DECL_OVERRIDE;
+ static bool isTabletMode();
+
+ QFunctionPointer platformFunction(const QByteArray &function) const override;
private:
static QWindowsWindowFunctions::WindowActivationBehavior m_windowActivationBehavior;
diff --git a/src/plugins/platforms/windows/qwindowsole.cpp b/src/plugins/platforms/windows/qwindowsole.cpp
index a1a8c0b499..9b71061aa5 100644
--- a/src/plugins/platforms/windows/qwindowsole.cpp
+++ b/src/plugins/platforms/windows/qwindowsole.cpp
@@ -74,9 +74,8 @@ QT_BEGIN_NAMESPACE
*/
QWindowsOleDataObject::QWindowsOleDataObject(QMimeData *mimeData) :
- m_refs(1), data(mimeData),
- CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT)),
- performedEffect(DROPEFFECT_NONE)
+ data(mimeData),
+ CF_PERFORMEDDROPEFFECT(RegisterClipboardFormat(CFSTR_PERFORMEDDROPEFFECT))
{
qCDebug(lcQpaMime) << __FUNCTION__ << mimeData->formats();
}
@@ -267,8 +266,7 @@ QWindowsOleDataObject::EnumDAdvise(LPENUMSTATDATA FAR*)
\ingroup qt-lighthouse-win
*/
-QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs) :
- m_dwRefs(1), m_nIndex(0), m_isNull(false)
+QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs)
{
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaMime) << __FUNCTION__ << fmtetcs;
@@ -285,8 +283,7 @@ QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<FORMATETC> &fmtetcs)
}
}
-QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs) :
- m_dwRefs(1), m_nIndex(0), m_isNull(false)
+QWindowsOleEnumFmtEtc::QWindowsOleEnumFmtEtc(const QVector<LPFORMATETC> &lpfmtetcs)
{
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaMime) << __FUNCTION__;
diff --git a/src/plugins/platforms/windows/qwindowsole.h b/src/plugins/platforms/windows/qwindowsole.h
index dc31c793e9..643011272b 100644
--- a/src/plugins/platforms/windows/qwindowsole.h
+++ b/src/plugins/platforms/windows/qwindowsole.h
@@ -82,10 +82,10 @@ public:
STDMETHOD(EnumDAdvise)(LPENUMSTATDATA FAR* ppenumAdvise);
private:
- ULONG m_refs;
+ ULONG m_refs = 1;
QPointer<QMimeData> data;
- int CF_PERFORMEDDROPEFFECT;
- DWORD performedEffect;
+ const int CF_PERFORMEDDROPEFFECT;
+ DWORD performedEffect = DROPEFFECT_NONE;
};
class QWindowsOleEnumFmtEtc : public IEnumFORMATETC
@@ -111,10 +111,10 @@ public:
private:
bool copyFormatEtc(LPFORMATETC dest, const FORMATETC *src) const;
- ULONG m_dwRefs;
- ULONG m_nIndex;
+ ULONG m_dwRefs = 1;
+ ULONG m_nIndex = 0;
QVector<LPFORMATETC> m_lpfmtetcs;
- bool m_isNull;
+ bool m_isNull = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 39e20b55d1..e3fec59dd5 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -51,16 +51,14 @@ class QVariant;
struct GpuDescription
{
- GpuDescription() : vendorId(0), deviceId(0), revision(0), subSysId(0) {}
-
static GpuDescription detect();
QString toString() const;
QVariant toVariant() const;
- uint vendorId;
- uint deviceId;
- uint revision;
- uint subSysId;
+ uint vendorId = 0;
+ uint deviceId = 0;
+ uint revision = 0;
+ uint subSysId = 0;
QVersionNumber driverVersion;
QByteArray driverName;
QByteArray description;
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index c70323c06f..24fb12d27a 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -56,13 +56,6 @@
QT_BEGIN_NAMESPACE
-QWindowsScreenData::QWindowsScreenData() :
- dpi(96, 96), depth(32), format(QImage::Format_ARGB32_Premultiplied),
- flags(VirtualDesktop), orientation(Qt::LandscapeOrientation),
- refreshRateHz(60)
-{
-}
-
static inline QDpi deviceDPI(HDC hdc)
{
return QDpi(GetDeviceCaps(hdc, LOGPIXELSX), GetDeviceCaps(hdc, LOGPIXELSY));
@@ -89,6 +82,7 @@ static bool monitorData(HMONITOR hMonitor, QWindowsScreenData *data)
if (GetMonitorInfo(hMonitor, &info) == FALSE)
return false;
+ data->hMonitor = hMonitor;
data->geometry = QRect(QPoint(info.rcMonitor.left, info.rcMonitor.top), QPoint(info.rcMonitor.right - 1, info.rcMonitor.bottom - 1));
data->availableGeometry = QRect(QPoint(info.rcWork.left, info.rcWork.top), QPoint(info.rcWork.right - 1, info.rcWork.bottom - 1));
data->name = QString::fromWCharArray(info.szDevice);
@@ -423,10 +417,7 @@ QPlatformScreen::SubpixelAntialiasingType QWindowsScreen::subpixelAntialiasingTy
\ingroup qt-lighthouse-win
*/
-QWindowsScreenManager::QWindowsScreenManager() :
- m_lastDepth(-1), m_lastHorizontalResolution(0), m_lastVerticalResolution(0)
-{
-}
+QWindowsScreenManager::QWindowsScreenManager() = default;
/*!
\brief Triggers synchronization of screens (WM_DISPLAYCHANGE).
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 02a9dc3bc3..9a8997326b 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -59,18 +59,17 @@ struct QWindowsScreenData
LockScreen = 0x4 // Temporary screen existing during user change, etc.
};
- QWindowsScreenData();
-
QRect geometry;
QRect availableGeometry;
- QDpi dpi;
+ QDpi dpi{96, 96};
QSizeF physicalSizeMM;
- int depth;
- QImage::Format format;
- unsigned flags;
+ int depth = 32;
+ QImage::Format format = QImage::Format_ARGB32_Premultiplied;
+ unsigned flags = VirtualDesktop;
QString name;
- Qt::ScreenOrientation orientation;
- qreal refreshRateHz;
+ Qt::ScreenOrientation orientation = Qt::LandscapeOrientation;
+ qreal refreshRateHz = 60;
+ HMONITOR hMonitor = nullptr;
};
class QWindowsScreen : public QPlatformScreen
@@ -82,23 +81,23 @@ public:
explicit QWindowsScreen(const QWindowsScreenData &data);
- QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
- QRect availableGeometry() const Q_DECL_OVERRIDE { return m_data.availableGeometry; }
- int depth() const Q_DECL_OVERRIDE { return m_data.depth; }
- QImage::Format format() const Q_DECL_OVERRIDE { return m_data.format; }
- QSizeF physicalSize() const Q_DECL_OVERRIDE { return m_data.physicalSizeMM; }
- QDpi logicalDpi() const Q_DECL_OVERRIDE { return m_data.dpi; }
- qreal pixelDensity() const Q_DECL_OVERRIDE;
- qreal devicePixelRatio() const Q_DECL_OVERRIDE { return 1.0; }
- qreal refreshRate() const Q_DECL_OVERRIDE { return m_data.refreshRateHz; }
- QString name() const Q_DECL_OVERRIDE { return m_data.name; }
- Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE { return m_data.orientation; }
- QList<QPlatformScreen *> virtualSiblings() const Q_DECL_OVERRIDE;
- QWindow *topLevelAt(const QPoint &point) const Q_DECL_OVERRIDE;
+ QRect geometry() const override { return m_data.geometry; }
+ QRect availableGeometry() const override { return m_data.availableGeometry; }
+ int depth() const override { return m_data.depth; }
+ QImage::Format format() const override { return m_data.format; }
+ QSizeF physicalSize() const override { return m_data.physicalSizeMM; }
+ QDpi logicalDpi() const override { return m_data.dpi; }
+ qreal pixelDensity() const override;
+ qreal devicePixelRatio() const override { return 1.0; }
+ qreal refreshRate() const override { return m_data.refreshRateHz; }
+ QString name() const override { return m_data.name; }
+ Qt::ScreenOrientation orientation() const override { return m_data.orientation; }
+ QList<QPlatformScreen *> virtualSiblings() const override;
+ QWindow *topLevelAt(const QPoint &point) const override;
static QWindow *windowAt(const QPoint &point, unsigned flags);
- QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const Q_DECL_OVERRIDE;
- QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const Q_DECL_OVERRIDE;
+ QPixmap grabWindow(WId window, int qX, int qY, int qWidth, int qHeight) const override;
+ QPlatformScreen::SubpixelAntialiasingType subpixelAntialiasingTypeHint() const override;
static Qt::ScreenOrientation orientationPreference();
static bool setOrientationPreference(Qt::ScreenOrientation o);
@@ -106,7 +105,7 @@ public:
inline void handleChanges(const QWindowsScreenData &newData);
#ifndef QT_NO_CURSOR
- QPlatformCursor *cursor() const Q_DECL_OVERRIDE { return m_cursor.data(); }
+ QPlatformCursor *cursor() const override { return m_cursor.data(); }
const CursorPtr &cursorPtr() const { return m_cursor; }
#else
QPlatformCursor *cursor() const { return 0; }
@@ -140,9 +139,9 @@ private:
void removeScreen(int index);
WindowsScreenList m_screens;
- int m_lastDepth;
- WORD m_lastHorizontalResolution;
- WORD m_lastVerticalResolution;
+ int m_lastDepth = -1;
+ WORD m_lastHorizontalResolution = 0;
+ WORD m_lastVerticalResolution = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.cpp b/src/plugins/platforms/windows/qwindowssessionmanager.cpp
index 2db9e44388..500fdc750c 100644
--- a/src/plugins/platforms/windows/qwindowssessionmanager.cpp
+++ b/src/plugins/platforms/windows/qwindowssessionmanager.cpp
@@ -44,9 +44,6 @@ QT_BEGIN_NAMESPACE
QWindowsSessionManager::QWindowsSessionManager(const QString &id, const QString &key)
: QPlatformSessionManager(id, key)
- , m_isActive(false)
- , m_blockUserInput(false)
- , m_canceled(false)
{
}
diff --git a/src/plugins/platforms/windows/qwindowssessionmanager.h b/src/plugins/platforms/windows/qwindowssessionmanager.h
index 25d0636650..4c4256f2b0 100644
--- a/src/plugins/platforms/windows/qwindowssessionmanager.h
+++ b/src/plugins/platforms/windows/qwindowssessionmanager.h
@@ -59,15 +59,15 @@ class QWindowsSessionManager : public QPlatformSessionManager
public:
explicit QWindowsSessionManager(const QString &id, const QString &key);
- bool allowsInteraction() Q_DECL_OVERRIDE;
- bool allowsErrorInteraction() Q_DECL_OVERRIDE;
+ bool allowsInteraction() override;
+ bool allowsErrorInteraction() override;
void blocksInteraction() { m_blockUserInput = true; }
bool isInteractionBlocked() const { return m_blockUserInput; }
- void release() Q_DECL_OVERRIDE;
+ void release() override;
- void cancel() Q_DECL_OVERRIDE;
+ void cancel() override;
void clearCancellation() { m_canceled = false; }
bool wasCanceled() const { return m_canceled; }
@@ -75,9 +75,9 @@ public:
bool isActive() const { return m_isActive;}
private:
- bool m_isActive;
- bool m_blockUserInput;
- bool m_canceled;
+ bool m_isActive = false;
+ bool m_blockUserInput = false;
+ bool m_canceled = false;
Q_DISABLE_COPY(QWindowsSessionManager)
};
diff --git a/src/plugins/platforms/windows/qwindowstabletsupport.h b/src/plugins/platforms/windows/qwindowstabletsupport.h
index 2c05dcddfc..97eceaf2cc 100644
--- a/src/plugins/platforms/windows/qwindowstabletsupport.h
+++ b/src/plugins/platforms/windows/qwindowstabletsupport.h
@@ -57,9 +57,6 @@ class QRect;
struct QWindowsWinTab32DLL
{
- QWindowsWinTab32DLL() : wTOpen(0), wTClose(0), wTInfo(0), wTEnable(0), wTOverlap(0), wTPacketsGet(0), wTGet(0),
- wTQueueSizeGet(0), wTQueueSizeSet(0) {}
-
bool init();
typedef HCTX (API *PtrWTOpen)(HWND, LPLOGCONTEXT, BOOL);
@@ -72,15 +69,15 @@ struct QWindowsWinTab32DLL
typedef int (API *PtrWTQueueSizeGet)(HCTX);
typedef BOOL (API *PtrWTQueueSizeSet)(HCTX, int);
- PtrWTOpen wTOpen;
- PtrWTClose wTClose;
- PtrWTInfo wTInfo;
- PtrWTEnable wTEnable;
- PtrWTOverlap wTOverlap;
- PtrWTPacketsGet wTPacketsGet;
- PtrWTGet wTGet;
- PtrWTQueueSizeGet wTQueueSizeGet;
- PtrWTQueueSizeSet wTQueueSizeSet;
+ PtrWTOpen wTOpen = nullptr;
+ PtrWTClose wTClose = nullptr;
+ PtrWTInfo wTInfo = nullptr;
+ PtrWTEnable wTEnable = nullptr;
+ PtrWTOverlap wTOverlap = nullptr;
+ PtrWTPacketsGet wTPacketsGet = nullptr;
+ PtrWTGet wTGet = nullptr;
+ PtrWTQueueSizeGet wTQueueSizeGet = nullptr;
+ PtrWTQueueSizeSet wTQueueSizeSet = nullptr;
};
struct QWindowsTabletDeviceData
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index ed12c8124e..4ae1a751e9 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -61,6 +61,9 @@
#include <QtCore/QTextStream>
#include <QtCore/QSysInfo>
#include <QtCore/QCache>
+#include <QtCore/QThread>
+#include <QtCore/QMutex>
+#include <QtCore/QWaitCondition>
#include <QtGui/QColor>
#include <QtGui/QPalette>
#include <QtGui/QGuiApplication>
@@ -127,40 +130,114 @@ static inline QColor getSysColor(int index)
// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system
// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the
// behavior by running it in a thread.
-class ShGetFileInfoFunction
+
+struct QShGetFileInfoParams
+{
+ QShGetFileInfoParams(const QString &fn, DWORD a, SHFILEINFO *i, UINT f, bool *r)
+ : fileName(fn), attributes(a), flags(f), info(i), result(r)
+ { }
+
+ const QString &fileName;
+ const DWORD attributes;
+ const UINT flags;
+ SHFILEINFO *const info;
+ bool *const result;
+};
+
+class QShGetFileInfoThread : public QThread
{
public:
- explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) :
- m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {}
+ explicit QShGetFileInfoThread()
+ : QThread(), m_params(nullptr)
+ {
+ connect(this, &QThread::finished, this, &QObject::deleteLater);
+ }
- void operator()() const
+ void run() override
{
+ m_init = CoInitializeEx(NULL, COINIT_MULTITHREADED);
+
+ QMutexLocker readyLocker(&m_readyMutex);
+ while (!m_cancelled.load()) {
+ if (!m_params && !m_cancelled.load()
+ && !m_readyCondition.wait(&m_readyMutex, 1000))
+ continue;
+
+ if (m_params) {
+ const QString fileName = m_params->fileName;
+ SHFILEINFO info;
#ifndef Q_OS_WINCE
- const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+ const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
#endif
- *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags);
+ const bool result = SHGetFileInfo(reinterpret_cast<const wchar_t *>(fileName.utf16()),
+ m_params->attributes, &info, sizeof(SHFILEINFO),
+ m_params->flags);
#ifndef Q_OS_WINCE
- SetErrorMode(oldErrorMode);
+ SetErrorMode(oldErrorMode);
#endif
+ m_doneMutex.lock();
+ if (!m_cancelled.load()) {
+ *m_params->result = result;
+ memcpy(m_params->info, &info, sizeof(SHFILEINFO));
+ }
+ m_params = nullptr;
+
+ m_doneCondition.wakeAll();
+ m_doneMutex.unlock();
+ }
+ }
+
+ if (m_init != S_FALSE)
+ CoUninitialize();
+ }
+
+ bool runWithParams(QShGetFileInfoParams *params, unsigned long timeOutMSecs)
+ {
+ QMutexLocker doneLocker(&m_doneMutex);
+
+ m_readyMutex.lock();
+ m_params = params;
+ m_readyCondition.wakeAll();
+ m_readyMutex.unlock();
+
+ return m_doneCondition.wait(&m_doneMutex, timeOutMSecs);
+ }
+
+ void cancel()
+ {
+ QMutexLocker doneLocker(&m_doneMutex);
+ m_cancelled.store(1);
+ m_readyCondition.wakeAll();
}
private:
- const wchar_t *m_fileName;
- const DWORD m_attributes;
- const UINT m_flags;
- SHFILEINFO *const m_info;
- bool *m_result;
+ HRESULT m_init;
+ QShGetFileInfoParams *m_params;
+ QAtomicInt m_cancelled;
+ QWaitCondition m_readyCondition;
+ QWaitCondition m_doneCondition;
+ QMutex m_readyMutex;
+ QMutex m_doneMutex;
};
-static bool shGetFileInfoBackground(QWindowsThreadPoolRunner &r,
- const wchar_t *fileName, DWORD attributes,
+static bool shGetFileInfoBackground(const QString &fileName, DWORD attributes,
SHFILEINFO *info, UINT flags,
unsigned long timeOutMSecs = 5000)
{
+ static QShGetFileInfoThread *getFileInfoThread = nullptr;
+ if (!getFileInfoThread) {
+ getFileInfoThread = new QShGetFileInfoThread;
+ getFileInfoThread->start();
+ }
+
bool result = false;
- if (!r.run(ShGetFileInfoFunction(fileName, attributes, info, flags, &result), timeOutMSecs)) {
- qWarning().noquote() << "ShGetFileInfoBackground() timed out for "
- << QString::fromWCharArray(fileName);
+ QShGetFileInfoParams params(fileName, attributes, info, flags, &result);
+ if (!getFileInfoThread->runWithParams(&params, timeOutMSecs)) {
+ // Cancel and reset getFileInfoThread. It'll
+ // be reinitialized the next time we get called.
+ getFileInfoThread->cancel();
+ getFileInfoThread = nullptr;
+ qWarning().noquote() << "SHGetFileInfo() timed out for " << fileName;
return false;
}
return result;
@@ -315,7 +392,6 @@ const char *QWindowsTheme::name = "windows";
QWindowsTheme *QWindowsTheme::m_instance = 0;
QWindowsTheme::QWindowsTheme()
- : m_threadPoolRunner(new QWindowsThreadPoolRunner)
{
m_instance = this;
std::fill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
@@ -718,10 +794,8 @@ static QPixmap pixmapFromShellImageList(int iImageList, const SHFILEINFO &info)
class QWindowsFileIconEngine : public QAbstractFileIconEngine
{
public:
- explicit QWindowsFileIconEngine(const QFileInfo &info,
- QPlatformTheme::IconOptions opts,
- const QSharedPointer<QWindowsThreadPoolRunner> &runner) :
- QAbstractFileIconEngine(info, opts), m_threadPoolRunner(runner) {}
+ explicit QWindowsFileIconEngine(const QFileInfo &info, QPlatformTheme::IconOptions opts) :
+ QAbstractFileIconEngine(info, opts) {}
QList<QSize> availableSizes(QIcon::Mode = QIcon::Normal, QIcon::State = QIcon::Off) const override
{ return QWindowsTheme::instance()->availableFileIconSizes(); }
@@ -729,9 +803,6 @@ public:
protected:
QString cacheKey() const override;
QPixmap filePixmap(const QSize &size, QIcon::Mode mode, QIcon::State) override;
-
-private:
- const QSharedPointer<QWindowsThreadPoolRunner> m_threadPoolRunner;
};
QString QWindowsFileIconEngine::cacheKey() const
@@ -797,10 +868,8 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon
SHGFI_ICON|iconSize|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX;
const bool val = cacheableDirIcon && useDefaultFolderIcon
- ? shGetFileInfoBackground(*m_threadPoolRunner.data(), L"dummy", FILE_ATTRIBUTE_DIRECTORY,
- &info, flags | SHGFI_USEFILEATTRIBUTES)
- : shGetFileInfoBackground(*m_threadPoolRunner.data(), reinterpret_cast<const wchar_t *>(filePath.utf16()), 0,
- &info, flags);
+ ? shGetFileInfoBackground(QString::fromWCharArray(L"dummy"), FILE_ATTRIBUTE_DIRECTORY, &info, flags | SHGFI_USEFILEATTRIBUTES)
+ : shGetFileInfoBackground(filePath, 0, &info, flags);
// Even if GetFileInfo returns a valid result, hIcon can be empty in some cases
if (val && info.hIcon) {
@@ -844,7 +913,7 @@ QPixmap QWindowsFileIconEngine::filePixmap(const QSize &size, QIcon::Mode, QIcon
QIcon QWindowsTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions) const
{
- return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions, m_threadPoolRunner));
+ return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions));
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 0384899efa..a3019ff6eb 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -40,7 +40,6 @@
#ifndef QWINDOWSTHEME_H
#define QWINDOWSTHEME_H
-#include "qwindowsthreadpoolrunner.h"
#include <qpa/qplatformtheme.h>
#include <QtCore/QSharedPointer>
@@ -58,15 +57,15 @@ public:
static QWindowsTheme *instance() { return m_instance; }
- bool usePlatformNativeDialog(DialogType type) const Q_DECL_OVERRIDE;
- QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const Q_DECL_OVERRIDE;
- QVariant themeHint(ThemeHint) const Q_DECL_OVERRIDE;
- const QPalette *palette(Palette type = SystemPalette) const Q_DECL_OVERRIDE
+ bool usePlatformNativeDialog(DialogType type) const override;
+ QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const override;
+ QVariant themeHint(ThemeHint) const override;
+ const QPalette *palette(Palette type = SystemPalette) const override
{ return m_palettes[type]; }
- const QFont *font(Font type = SystemFont) const Q_DECL_OVERRIDE
+ const QFont *font(Font type = SystemFont) const override
{ return m_fonts[type]; }
- QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const Q_DECL_OVERRIDE;
+ QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const override;
QIcon fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOptions iconOptions = 0) const override;
@@ -88,7 +87,6 @@ private:
static QWindowsTheme *m_instance;
QPalette *m_palettes[NPalettes];
QFont *m_fonts[NFonts];
- const QSharedPointer<QWindowsThreadPoolRunner> m_threadPoolRunner;
QList<QSize> m_fileIconSizes;
};
diff --git a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h
index 0361aa90f5..5601cc9305 100644
--- a/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h
+++ b/src/plugins/platforms/windows/qwindowsthreadpoolrunner.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -63,7 +69,7 @@ class QWindowsThreadPoolRunner
explicit Runnable(QMutex *m, QWaitCondition *c, RunnableFunction f)
: m_mutex(m), m_condition(c), m_function(f) {}
- void run() Q_DECL_OVERRIDE
+ void run() override
{
m_function();
m_mutex->lock();
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 48835f26a6..79dce2fc43 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -118,6 +118,35 @@ static QByteArray debugWinExStyle(DWORD exStyle)
return rc;
}
+static QByteArray debugWinSwpPos(UINT flags)
+{
+ QByteArray rc = "0x";
+ rc += QByteArray::number(flags, 16);
+ if (flags & SWP_FRAMECHANGED)
+ rc += " SWP_FRAMECHANGED";
+ if (flags & SWP_HIDEWINDOW)
+ rc += " SWP_HIDEWINDOW";
+ if (flags & SWP_NOACTIVATE)
+ rc += " SWP_NOACTIVATE";
+ if (flags & SWP_NOCOPYBITS)
+ rc += " SWP_NOCOPYBITS";
+ if (flags & SWP_NOMOVE)
+ rc += " SWP_NOMOVE";
+ if (flags & SWP_NOOWNERZORDER)
+ rc += " SWP_NOOWNERZORDER";
+ if (flags & SWP_NOREDRAW)
+ rc += " SWP_NOREDRAW";
+ if (flags & SWP_NOSENDCHANGING)
+ rc += " SWP_NOSENDCHANGING";
+ if (flags & SWP_NOSIZE)
+ rc += " SWP_NOSIZE";
+ if (flags & SWP_NOZORDER)
+ rc += " SWP_NOZORDER";
+ if (flags & SWP_SHOWWINDOW)
+ rc += " SWP_SHOWWINDOW";
+ return rc;
+}
+
static inline QSize qSizeOfRect(const RECT &rect)
{
return QSize(rect.right -rect.left, rect.bottom - rect.top);
@@ -141,8 +170,9 @@ QDebug operator<<(QDebug d, const RECT &r)
{
QDebugStateSaver saver(d);
d.nospace();
- d << "RECT: left/top=" << r.left << ',' << r.top
- << " right/bottom=" << r.right << ',' << r.bottom;
+ d << "RECT(left=" << r.left << ", top=" << r.top
+ << ", right=" << r.right << ", bottom=" << r.bottom
+ << " (" << r.right - r.left << 'x' << r.bottom - r.top << "))";
return d;
}
@@ -152,12 +182,23 @@ QDebug operator<<(QDebug d, const POINT &p)
return d;
}
+QDebug operator<<(QDebug d, const WINDOWPOS &wp)
+{
+ QDebugStateSaver saver(d);
+ d.nospace();
+ d.noquote();
+ d << "WINDOWPOS(flags=" << debugWinSwpPos(wp.flags) << ", hwnd="
+ << wp.hwnd << ", hwndInsertAfter=" << wp.hwndInsertAfter << ", x=" << wp.x
+ << ", y=" << wp.y << ", cx=" << wp.cx << ", cy=" << wp.cy << ')';
+ return d;
+}
+
QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p)
{
QDebugStateSaver saver(d);
d.nospace();
- d << "NCCALCSIZE_PARAMS " << qrectFromRECT(p.rgrc[0])
- << ' ' << qrectFromRECT(p.rgrc[1]) << ' ' << qrectFromRECT(p.rgrc[2]);
+ d << "NCCALCSIZE_PARAMS(rgrc=[" << p.rgrc[0] << ' ' << p.rgrc[1] << ' '
+ << p.rgrc[2] << "], lppos=" << *p.lppos << ')';
return d;
}
@@ -177,6 +218,7 @@ QDebug operator<<(QDebug d, const WINDOWPLACEMENT &wp)
{
QDebugStateSaver saver(d);
d.nospace();
+ d.noquote();
d << "WINDOWPLACEMENT(flags=0x" << hex << wp.flags << dec << ", showCmd="
<< wp.showCmd << ", ptMinPosition=" << wp.ptMinPosition << ", ptMaxPosition=" << wp.ptMaxPosition
<< ", rcNormalPosition=" << wp.rcNormalPosition;
@@ -939,9 +981,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
DWORD style_, DWORD exStyle_) :
geometryHint(w, cm), window(w), style(style_), exStyle(exStyle_),
requestedGeometry(geometry), obtainedGeometry(geometry),
- margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm),
- frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT),
- frameWidth(CW_USEDEFAULT), frameHeight(CW_USEDEFAULT)
+ margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm)
{
// Geometry of toplevels does not consider window frames.
// TODO: No concept of WA_wasMoved yet that would indicate a
@@ -994,17 +1034,8 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data) :
QWindowsBaseWindow(aWindow),
m_data(data),
- m_flags(WithinCreate),
- m_hdc(0),
- m_windowState(Qt::WindowNoState),
- m_opacity(1.0),
m_cursor(new CursorHandle),
- m_dropTarget(0),
- m_savedStyle(0),
- m_format(aWindow->requestedFormat()),
- m_iconSmall(0),
- m_iconBig(0),
- m_surface(0)
+ m_format(aWindow->requestedFormat())
{
// Clear the creation context as the window can be found in QWindowsContext's map.
QWindowsContext::instance()->setWindowCreationContext(QSharedPointer<QWindowCreationContext>());
@@ -1095,7 +1126,7 @@ void QWindowsWindow::updateDropSite(bool topLevel)
// if the parent window is a foreign window wrapped via QWindow::fromWinId, we need to enable the drop site
// on the first child window
const QWindow *parent = window()->parent();
- if (parent && (parent->type() == Qt::ForeignWindow))
+ if (parent && parent->handle() && parent->handle()->isForeignWindow())
parentIsEmbedded = true;
}
@@ -1216,18 +1247,14 @@ bool QWindowsWindow::isActive() const
return false;
}
-bool QWindowsWindow::isEmbedded(const QPlatformWindow *parentWindow) const
+bool QWindowsWindow::isAncestorOf(const QPlatformWindow *child) const
{
- if (parentWindow) {
- const QWindowsWindow *ww = static_cast<const QWindowsWindow *>(parentWindow);
- const HWND hwnd = ww->handle();
- if (!IsChild(hwnd, m_data.hwnd))
- return false;
- }
-
- if (!m_data.embedded && parent())
- return parent()->isEmbedded();
+ const QWindowsWindow *childWindow = static_cast<const QWindowsWindow *>(child);
+ return IsChild(m_data.hwnd, childWindow->handle());
+}
+bool QWindowsWindow::isEmbedded() const
+{
return m_data.embedded;
}
@@ -1471,18 +1498,22 @@ void QWindowsWindow::handleResized(int wParam)
case SIZE_MAXHIDE: // Some other window affected.
case SIZE_MAXSHOW:
return;
- case SIZE_MINIMIZED:
- handleWindowStateChange(Qt::WindowMinimized);
+ case SIZE_MINIMIZED: // QTBUG-53577, prevent state change events during programmatic state change
+ if (!testFlag(WithinSetStyle))
+ handleWindowStateChange(Qt::WindowMinimized);
return;
case SIZE_MAXIMIZED:
- handleWindowStateChange(Qt::WindowMaximized);
+ if (!testFlag(WithinSetStyle))
+ handleWindowStateChange(Qt::WindowMaximized);
handleGeometryChange();
break;
case SIZE_RESTORED:
- if (isFullScreen_sys())
- handleWindowStateChange(Qt::WindowFullScreen);
- else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
- handleWindowStateChange(Qt::WindowNoState);
+ if (!testFlag(WithinSetStyle)) {
+ if (isFullScreen_sys())
+ handleWindowStateChange(Qt::WindowFullScreen);
+ else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
+ handleWindowStateChange(Qt::WindowNoState);
+ }
handleGeometryChange();
break;
}
@@ -1490,9 +1521,6 @@ void QWindowsWindow::handleResized(int wParam)
void QWindowsWindow::handleGeometryChange()
{
- //Prevent recursive resizes for Windows CE
- if (testFlag(WithinSetStyle))
- return;
const QRect previousGeometry = m_data.geometry;
m_data.geometry = geometry_sys();
QPlatformWindow::setGeometry(m_data.geometry);
@@ -1505,10 +1533,16 @@ void QWindowsWindow::handleGeometryChange()
&& !(m_data.geometry.width() > previousGeometry.width() || m_data.geometry.height() > previousGeometry.height())) {
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
- if (previousGeometry.topLeft() != m_data.geometry.topLeft()) {
- QPlatformScreen *newScreen = screenForGeometry(m_data.geometry);
- if (newScreen != screen())
- QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
+ if (!parent() && previousGeometry.topLeft() != m_data.geometry.topLeft()) {
+ HMONITOR hMonitor = MonitorFromWindow(m_data.hwnd, MONITOR_DEFAULTTONULL);
+ QPlatformScreen *currentScreen = screen();
+ const auto screens = QWindowsContext::instance()->screenManager().screens();
+ auto newScreenIt = std::find_if(screens.begin(), screens.end(), [&](QWindowsScreen *s) {
+ return s->data().hMonitor == hMonitor
+ && s->data().flags & QWindowsScreenData::VirtualDesktop;
+ });
+ if (newScreenIt != screens.end() && *newScreenIt != currentScreen)
+ QWindowSystemInterface::handleWindowScreenChanged(window(), (*newScreenIt)->screen());
}
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
@@ -1588,7 +1622,8 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
if (message == WM_ERASEBKGND) // Backing store - ignored.
return true;
// Ignore invalid update bounding rectangles
- if (!GetUpdateRect(m_data.hwnd, 0, FALSE))
+ RECT updateRect;
+ if (!GetUpdateRect(m_data.hwnd, &updateRect, FALSE))
return false;
PAINTSTRUCT ps;
@@ -1612,7 +1647,7 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message,
// we still need to send isExposed=true, for compatibility.
// Our tests depend on it.
fireExpose(QRegion(qrectFromRECT(ps.rcPaint)), true);
- if (!QWindowsContext::instance()->asyncExpose())
+ if (qSizeOfRect(updateRect) == m_data.geometry.size() && !QWindowsContext::instance()->asyncExpose())
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
EndPaint(hwnd, &ps);
@@ -1659,7 +1694,6 @@ QWindowsWindowData QWindowsWindow::setWindowFlags_sys(Qt::WindowFlags wt,
QWindowsWindowData result = m_data;
result.flags = creationData.flags;
result.embedded = creationData.embedded;
- setFlag(FrameDirty);
return result;
}
@@ -1667,7 +1701,6 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowState state)
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window()
<< "\n from " << m_windowState << " to " << state;
- setFlag(FrameDirty);
m_windowState = state;
QWindowSystemInterface::handleWindowStateChanged(window(), state);
switch (state) {
@@ -1717,10 +1750,9 @@ bool QWindowsWindow::isFullScreen_sys() const
const QWindow *w = window();
if (!w->isTopLevel())
return false;
- const QScreen *screen = w->screen();
- if (!screen)
- screen = QGuiApplication::primaryScreen();
- return screen && geometry_sys() == QHighDpi::toNativePixels(screen->geometry(), w);
+ QRect geometry = geometry_sys();
+ QPlatformScreen *screen = screenForGeometry(geometry);
+ return screen && geometry == QHighDpi::toNativePixels(screen->geometry(), screen);
}
/*!
@@ -1744,8 +1776,6 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
const bool visible = isVisible();
- setFlag(FrameDirty);
-
if ((oldState == Qt::WindowFullScreen) != (newState == Qt::WindowFullScreen)) {
if (newState == Qt::WindowFullScreen) {
#ifndef Q_FLATTEN_EXPOSE
@@ -1794,6 +1824,13 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
newStyle |= WS_VISIBLE;
setStyle(newStyle);
+ const QScreen *screen = window()->screen();
+ if (!screen)
+ screen = QGuiApplication::primaryScreen();
+ // That area of the virtual desktop might not be covered by a screen anymore.
+ if (!screen->geometry().intersects(m_savedFrameGeometry))
+ m_savedFrameGeometry.moveTo(screen->geometry().topLeft());
+
UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
if (!m_savedFrameGeometry.isValid())
swpf |= SWP_NOSIZE | SWP_NOMOVE;
@@ -1839,7 +1876,6 @@ void QWindowsWindow::setStyle(unsigned s) const
{
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window() << debugWinStyle(s);
setFlag(WithinSetStyle);
- setFlag(FrameDirty);
SetWindowLongPtr(m_data.hwnd, GWL_STYLE, s);
clearFlag(WithinSetStyle);
}
@@ -1848,7 +1884,6 @@ void QWindowsWindow::setExStyle(unsigned s) const
{
qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << this << ' ' << window()
<< " 0x" << QByteArray::number(s, 16);
- setFlag(FrameDirty);
SetWindowLongPtr(m_data.hwnd, GWL_EXSTYLE, s);
}
@@ -1904,22 +1939,17 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const
return QWindowsWindow::handleGeometryChangingMessage(message, window(), margins);
}
-QMargins QWindowsWindow::frameMargins() const
+void QWindowsWindow::setFrameMargins(const QMargins &newMargins)
{
- // Frames are invalidated by style changes (window state, flags).
- // As they are also required for geometry calculations in resize
- // event sequences, introduce a dirty flag mechanism to be able
- // to cache results.
- if (testFlag(FrameDirty)) {
- // Always skip calculating style-dependent margins for windows claimed to be frameless.
- // This allows users to remove the margins by handling WM_NCCALCSIZE with WS_THICKFRAME set
- // to ensure Areo snap still works (QTBUG-40578).
- m_data.frame = m_data.flags & Qt::FramelessWindowHint
- ? QMargins(0, 0, 0, 0)
- : QWindowsGeometryHint::frame(style(), exStyle());
- clearFlag(FrameDirty);
+ if (m_data.frame != newMargins) {
+ qCDebug(lcQpaWindows) << __FUNCTION__ << window() << m_data.frame << "->" << newMargins;
+ m_data.frame = newMargins;
}
- return m_data.frame + m_data.customMargins;
+}
+
+QMargins QWindowsWindow::frameMargins() const
+{
+ return m_data.frame;
}
void QWindowsWindow::setOpacity(qreal level)
@@ -2091,8 +2121,12 @@ void QWindowsWindow::setFrameStrutEventsEnabled(bool enabled)
void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
{
- const QWindowsGeometryHint hint(window(), m_data.customMargins);
- hint.applyToMinMaxInfo(m_data.hwnd, mmi);
+ // We don't apply the min/max size hint as we change the dpi, because we did not adjust the
+ // QScreen of the window yet so we don't have the min/max with the right ratio
+ if (!testFlag(QWindowsWindow::WithinDpiChanged)) {
+ const QWindowsGeometryHint hint(window(), m_data.customMargins);
+ hint.applyToMinMaxInfo(m_data.hwnd, mmi);
+ }
if ((testFlag(WithinMaximize) || (window()->windowState() == Qt::WindowMinimized))
&& (m_data.flags & Qt::FramelessWindowHint)) {
@@ -2335,7 +2369,6 @@ void QWindowsWindow::setCustomMargins(const QMargins &newCustomMargins)
const QPoint topLeft = currentFrameGeometry.topLeft();
QRect newFrame = currentFrameGeometry.marginsRemoved(oldCustomMargins) + m_data.customMargins;
newFrame.moveTo(topLeft);
- setFlag(FrameDirty);
qCDebug(lcQpaWindows) << __FUNCTION__ << oldCustomMargins << "->" << newCustomMargins
<< currentFrameGeometry << "->" << newFrame;
SetWindowPos(m_data.hwnd, 0, newFrame.x(), newFrame.y(), newFrame.width(), newFrame.height(), SWP_NOZORDER | SWP_FRAMECHANGED);
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 924f242e6e..e541b110a6 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -89,22 +89,20 @@ struct QWindowCreationContext
QRect obtainedGeometry;
QMargins margins;
QMargins customMargins; // User-defined, additional frame for WM_NCCALCSIZE
- int frameX; // Passed on to CreateWindowEx(), including frame.
- int frameY;
- int frameWidth;
- int frameHeight;
+ int frameX = CW_USEDEFAULT; // Passed on to CreateWindowEx(), including frame.
+ int frameY = CW_USEDEFAULT;
+ int frameWidth = CW_USEDEFAULT;
+ int frameHeight = CW_USEDEFAULT;
};
struct QWindowsWindowData
{
- QWindowsWindowData() : hwnd(0), embedded(false) {}
-
Qt::WindowFlags flags;
QRect geometry;
QMargins frame; // Do not use directly for windows, see FrameDirty.
QMargins customMargins; // User-defined, additional frame for NCCALCSIZE
- HWND hwnd;
- bool embedded;
+ HWND hwnd = 0;
+ bool embedded = false;
static QWindowsWindowData create(const QWindow *w,
const QWindowsWindowData &parameters,
@@ -116,11 +114,11 @@ class QWindowsBaseWindow : public QPlatformWindow
public:
explicit QWindowsBaseWindow(QWindow *window) : QPlatformWindow(window) {}
- WId winId() const Q_DECL_OVERRIDE { return WId(handle()); }
- QRect geometry() const Q_DECL_OVERRIDE { return geometry_sys(); }
- QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMargins_sys(); }
- QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
- QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+ WId winId() const override { return WId(handle()); }
+ QRect geometry() const override { return geometry_sys(); }
+ QMargins frameMargins() const override { return frameMargins_sys(); }
+ QPoint mapToGlobal(const QPoint &pos) const override;
+ QPoint mapFromGlobal(const QPoint &pos) const override;
using QPlatformWindow::screenForGeometry;
@@ -152,11 +150,11 @@ public:
explicit QWindowsDesktopWindow(QWindow *window)
: QWindowsBaseWindow(window), m_hwnd(GetDesktopWindow()) {}
- QMargins frameMargins() const Q_DECL_OVERRIDE { return QMargins(); }
- bool isTopLevel() const Q_DECL_OVERRIDE { return true; }
+ QMargins frameMargins() const override { return QMargins(); }
+ bool isTopLevel() const override { return true; }
protected:
- HWND handle() const Q_DECL_OVERRIDE { return m_hwnd; }
+ HWND handle() const override { return m_hwnd; }
private:
const HWND m_hwnd;
@@ -167,15 +165,16 @@ class QWindowsForeignWindow : public QWindowsBaseWindow
public:
explicit QWindowsForeignWindow(QWindow *window, HWND hwnd);
- void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE;
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE { setGeometry_sys(rect); }
- void setVisible(bool visible) Q_DECL_OVERRIDE;
- void raise() Q_DECL_OVERRIDE { raise_sys(); }
- void lower() Q_DECL_OVERRIDE { lower_sys(); }
- void setWindowTitle(const QString &title) Q_DECL_OVERRIDE { setWindowTitle_sys(title); }
+ void setParent(const QPlatformWindow *window) override;
+ void setGeometry(const QRect &rect) override { setGeometry_sys(rect); }
+ void setVisible(bool visible) override;
+ void raise() override { raise_sys(); }
+ void lower() override { lower_sys(); }
+ void setWindowTitle(const QString &title) override { setWindowTitle_sys(title); }
+ bool isForeignWindow() const override { return true; }
protected:
- HWND handle() const Q_DECL_OVERRIDE { return m_hwnd; }
+ HWND handle() const override { return m_hwnd; }
private:
const HWND m_hwnd;
@@ -189,7 +188,6 @@ public:
{
AutoMouseCapture = 0x1, //! Automatic mouse capture on button press.
WithinSetParent = 0x2,
- FrameDirty = 0x4, //! Frame outdated by setStyle, recalculate in next query.
OpenGLSurface = 0x10,
OpenGL_ES2 = 0x20,
OpenGLDoubleBuffered = 0x40,
@@ -208,7 +206,8 @@ public:
MaximizeToFullScreen = 0x80000,
InputMethodDisabled = 0x100000,
Compositing = 0x200000,
- HasBorderInFullScreen = 0x400000
+ HasBorderInFullScreen = 0x400000,
+ WithinDpiChanged = 0x800000,
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
@@ -216,52 +215,54 @@ public:
using QPlatformWindow::screenForGeometry;
- QSurfaceFormat format() const Q_DECL_OVERRIDE { return m_format; }
- void setGeometry(const QRect &rect) Q_DECL_OVERRIDE;
- QRect geometry() const Q_DECL_OVERRIDE { return m_data.geometry; }
- QRect normalGeometry() const Q_DECL_OVERRIDE;
+ QSurfaceFormat format() const override { return m_format; }
+ void setGeometry(const QRect &rect) override;
+ QRect geometry() const override { return m_data.geometry; }
+ QRect normalGeometry() const override;
- void setVisible(bool visible) Q_DECL_OVERRIDE;
+ void setVisible(bool visible) override;
bool isVisible() const;
- bool isExposed() const Q_DECL_OVERRIDE { return testFlag(Exposed); }
- bool isActive() const Q_DECL_OVERRIDE;
- bool isEmbedded(const QPlatformWindow *parentWindow = 0) const Q_DECL_OVERRIDE;
- QPoint mapToGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
- QPoint mapFromGlobal(const QPoint &pos) const Q_DECL_OVERRIDE;
+ bool isExposed() const override { return testFlag(Exposed); }
+ bool isActive() const override;
+ bool isAncestorOf(const QPlatformWindow *child) const override;
+ bool isEmbedded() const override;
+ QPoint mapToGlobal(const QPoint &pos) const override;
+ QPoint mapFromGlobal(const QPoint &pos) const override;
- void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
- void setWindowState(Qt::WindowState state) Q_DECL_OVERRIDE;
+ void setWindowFlags(Qt::WindowFlags flags) override;
+ void setWindowState(Qt::WindowState state) override;
- void setParent(const QPlatformWindow *window) Q_DECL_OVERRIDE;
+ void setParent(const QPlatformWindow *window) override;
- void setWindowTitle(const QString &title) Q_DECL_OVERRIDE;
- void raise() Q_DECL_OVERRIDE { raise_sys(); }
- void lower() Q_DECL_OVERRIDE { lower_sys(); }
+ void setWindowTitle(const QString &title) override;
+ void raise() override { raise_sys(); }
+ void lower() override { lower_sys(); }
- void windowEvent(QEvent *event) Q_DECL_OVERRIDE;
+ void windowEvent(QEvent *event) override;
- void propagateSizeHints() Q_DECL_OVERRIDE;
+ void propagateSizeHints() override;
static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
- QMargins frameMargins() const Q_DECL_OVERRIDE;
+ QMargins frameMargins() const override;
+ void setFrameMargins(const QMargins &newMargins);
- void setOpacity(qreal level) Q_DECL_OVERRIDE;
- void setMask(const QRegion &region) Q_DECL_OVERRIDE;
+ void setOpacity(qreal level) override;
+ void setMask(const QRegion &region) override;
qreal opacity() const { return m_opacity; }
- void requestActivateWindow() Q_DECL_OVERRIDE;
+ void requestActivateWindow() override;
- bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE;
- bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
+ bool setKeyboardGrabEnabled(bool grab) override;
+ bool setMouseGrabEnabled(bool grab) override;
inline bool hasMouseCapture() const { return GetCapture() == m_data.hwnd; }
- bool startSystemResize(const QPoint &pos, Qt::Corner corner) Q_DECL_OVERRIDE;
+ bool startSystemResize(const QPoint &pos, Qt::Corner corner) override;
- void setFrameStrutEventsEnabled(bool enabled) Q_DECL_OVERRIDE;
- bool frameStrutEventsEnabled() const Q_DECL_OVERRIDE { return testFlag(FrameStrutEventsEnabled); }
+ void setFrameStrutEventsEnabled(bool enabled) override;
+ bool frameStrutEventsEnabled() const override { return testFlag(FrameStrutEventsEnabled); }
// QWindowsBaseWindow overrides
- HWND handle() const Q_DECL_OVERRIDE { return m_data.hwnd; }
- bool isTopLevel() const Q_DECL_OVERRIDE;
+ HWND handle() const override { return m_data.hwnd; }
+ bool isTopLevel() const override;
QMargins customMargins() const { return m_data.customMargins; }
void setCustomMargins(const QMargins &m);
@@ -301,14 +302,14 @@ public:
void setEnabled(bool enabled);
bool isEnabled() const;
- void setWindowIcon(const QIcon &icon) Q_DECL_OVERRIDE;
+ void setWindowIcon(const QIcon &icon) override;
void *surface(void *nativeConfig, int *err);
- void invalidateSurface() Q_DECL_OVERRIDE;
+ void invalidateSurface() override;
void aboutToMakeCurrent();
- void setAlertState(bool enabled) Q_DECL_OVERRIDE;
- bool isAlertState() const Q_DECL_OVERRIDE { return testFlag(AlertState); }
+ void setAlertState(bool enabled) override;
+ bool isAlertState() const override { return testFlag(AlertState); }
void alertWindow(int durationMs = 0);
void stopAlertWindow();
@@ -335,20 +336,20 @@ private:
void fireExpose(const QRegion &region, bool force=false);
mutable QWindowsWindowData m_data;
- mutable unsigned m_flags;
- HDC m_hdc;
- Qt::WindowState m_windowState;
- qreal m_opacity;
+ mutable unsigned m_flags = WithinCreate;
+ HDC m_hdc = 0;
+ Qt::WindowState m_windowState = Qt::WindowNoState;
+ qreal m_opacity = 1;
#ifndef QT_NO_CURSOR
CursorHandlePtr m_cursor;
#endif
- QWindowsOleDropTarget *m_dropTarget;
- unsigned m_savedStyle;
+ QWindowsOleDropTarget *m_dropTarget = nullptr;
+ unsigned m_savedStyle = 0;
QRect m_savedFrameGeometry;
const QSurfaceFormat m_format;
- HICON m_iconSmall;
- HICON m_iconBig;
- void *m_surface;
+ HICON m_iconSmall = 0;
+ HICON m_iconBig = 0;
+ void *m_surface = nullptr;
};
#ifndef QT_NO_DEBUG_STREAM
@@ -357,6 +358,7 @@ QDebug operator<<(QDebug d, const POINT &);
QDebug operator<<(QDebug d, const MINMAXINFO &i);
QDebug operator<<(QDebug d, const NCCALCSIZE_PARAMS &p);
QDebug operator<<(QDebug d, const WINDOWPLACEMENT &);
+QDebug operator<<(QDebug d, const WINDOWPOS &);
#endif // !QT_NO_DEBUG_STREAM
// ---------- QWindowsGeometryHint inline functions.
@@ -385,15 +387,14 @@ QPoint QWindowsGeometryHint::mapFromGlobal(const QWindow *w, const QPoint &p)
inline QWindowsWindow *QWindowsWindow::windowsWindowOf(const QWindow *w)
{
- QWindowsWindow *result = Q_NULLPTR;
- if (w) {
- const Qt::WindowType type = w->type();
- if (type != Qt::Desktop && type != Qt::ForeignWindow) {
- if (QPlatformWindow *pw = w->handle())
- result = static_cast<QWindowsWindow *>(pw);
- }
- }
- return result;
+ if (!w || !w->handle())
+ return nullptr;
+
+ const Qt::WindowType type = w->type();
+ if (type == Qt::Desktop || w->handle()->isForeignWindow())
+ return nullptr;
+
+ return static_cast<QWindowsWindow *>(w->handle());
}
void *QWindowsWindow::userDataOf(HWND hwnd)
diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri
index 20e0b81da9..7d3ecc8aa2 100644
--- a/src/plugins/platforms/windows/windows.pri
+++ b/src/plugins/platforms/windows/windows.pri
@@ -99,5 +99,5 @@ RESOURCES += $$PWD/openglblacklists.qrc
qtConfig(accessibility): include($$PWD/accessible/accessible.pri)
-DEFINES *= LIBEGL_NAME=$${LIBEGL_NAME}
-DEFINES *= LIBGLESV2_NAME=$${LIBGLESV2_NAME}
+DEFINES *= LIBEGL_NAME=$${LIBQTANGLE_NAME}
+DEFINES *= LIBGLESV2_NAME=$${LIBQTANGLE_NAME}
diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.cpp b/src/plugins/platforms/winrt/qwinrtclipboard.cpp
index 0a38b3df34..117cb515df 100644
--- a/src/plugins/platforms/winrt/qwinrtclipboard.cpp
+++ b/src/plugins/platforms/winrt/qwinrtclipboard.cpp
@@ -61,7 +61,6 @@ QT_BEGIN_NAMESPACE
QWinRTClipboard::QWinRTClipboard()
: m_mimeData(Q_NULLPTR)
{
-#ifndef Q_OS_WINPHONE
QEventDispatcherWinRT::runOnXamlThread([this]() {
HRESULT hr;
hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_Clipboard).Get(),
@@ -74,7 +73,6 @@ QWinRTClipboard::QWinRTClipboard()
return hr;
});
-#endif // !Q_OS_WINPHONE
}
QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
@@ -82,7 +80,6 @@ QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
if (!supportsMode(mode))
return nullptr;
-#ifndef Q_OS_WINPHONE
ComPtr<IDataPackageView> view;
HRESULT hr;
hr = m_nativeClipBoard->GetContent(&view);
@@ -114,9 +111,6 @@ QMimeData *QWinRTClipboard::mimeData(QClipboard::Mode mode)
m_mimeData->setText(text);
return m_mimeData;
-#else // Q_OS_WINPHONE
- return QPlatformClipboard::mimeData(mode);
-#endif // Q_OS_WINPHONE
}
// Inspired by QWindowsMimeText::convertFromMime
@@ -153,7 +147,6 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
if (!supportsMode(mode))
return;
-#ifndef Q_OS_WINPHONE
const bool newData = !m_mimeData || m_mimeData != data;
if (newData) {
if (m_mimeData)
@@ -178,18 +171,11 @@ void QWinRTClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
return S_OK;
});
RETURN_VOID_IF_FAILED("Could not set clipboard text.");
-#else // Q_OS_WINPHONE
- QPlatformClipboard::setMimeData(data, mode);
-#endif // Q_OS_WINPHONE
}
bool QWinRTClipboard::supportsMode(QClipboard::Mode mode) const
{
-#ifndef Q_OS_WINPHONE
return mode == QClipboard::Clipboard;
-#else
- return QPlatformClipboard::supportsMode(mode);
-#endif
}
HRESULT QWinRTClipboard::onContentChanged(IInspectable *, IInspectable *)
diff --git a/src/plugins/platforms/winrt/qwinrtclipboard.h b/src/plugins/platforms/winrt/qwinrtclipboard.h
index 2e3e2b834d..899fcbe730 100644
--- a/src/plugins/platforms/winrt/qwinrtclipboard.h
+++ b/src/plugins/platforms/winrt/qwinrtclipboard.h
@@ -45,7 +45,6 @@
#include <wrl.h>
-#ifndef Q_OS_WINPHONE
namespace ABI {
namespace Windows {
namespace ApplicationModel {
@@ -55,7 +54,6 @@ namespace ABI {
}
}
}
-#endif // !Q_OS_WINPHONE
QT_BEGIN_NAMESPACE
@@ -70,9 +68,7 @@ public:
HRESULT onContentChanged(IInspectable *, IInspectable *);
private:
-#ifndef Q_OS_WINPHONE
Microsoft::WRL::ComPtr<ABI::Windows::ApplicationModel::DataTransfer::IClipboardStatics> m_nativeClipBoard;
-#endif
QMimeData *m_mimeData;
};
diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp
index 89ebf7d26f..cf52816b65 100644
--- a/src/plugins/platforms/winrt/qwinrtdrag.cpp
+++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp
@@ -504,6 +504,8 @@ static HRESULT qt_drop(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventA
class QtDragEventHandler##name : public IDragEventHandler \
{ \
public: \
+ virtual ~QtDragEventHandler##name() {\
+ }\
STDMETHODIMP Invoke(IInspectable *sender, \
ABI::Windows::UI::Xaml::IDragEventArgs *e) \
{ \
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
index 417dbdc1db..62eacba89b 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.cpp
@@ -61,11 +61,9 @@ using namespace ABI::Windows::Foundation::Collections;
using namespace ABI::Windows::Storage;
using namespace ABI::Windows::Storage::Pickers;
-#ifndef Q_OS_WINPHONE
typedef IAsyncOperationCompletedHandler<StorageFile *> SingleFileHandler;
typedef IAsyncOperationCompletedHandler<IVectorView<StorageFile *> *> MultipleFileHandler;
typedef IAsyncOperationCompletedHandler<StorageFolder *> SingleFolderHandler;
-#endif
QT_BEGIN_NAMESPACE
@@ -152,16 +150,6 @@ private:
QVector<HSTRING> impl;
};
-#ifdef Q_OS_WINPHONE
-class QActivationEvent : public QEvent
-{
-public:
- IInspectable *args() const {
- return reinterpret_cast<IInspectable *>(d);
- }
-};
-#endif
-
template<typename T>
static bool initializePicker(HSTRING runtimeId, T **picker, const QSharedPointer<QFileDialogOptions> &options)
{
@@ -225,23 +213,6 @@ static bool pickFiles(IFileOpenPicker *picker, QWinRTFileDialogHelper *helper, b
Q_ASSERT(picker);
Q_ASSERT(helper);
HRESULT hr;
-#ifdef Q_OS_WINPHONE
- hr = QEventDispatcherWinRT::runOnXamlThread([picker, singleFile]() {
- HRESULT hr;
- ComPtr<IFileOpenPicker2> picker2;
- hr = picker->QueryInterface(IID_PPV_ARGS(picker2.GetAddressOf()));
- RETURN_HR_IF_FAILED("Failed to cast file picker");
- if (singleFile)
- return picker2->PickSingleFileAndContinue();
- else
- return picker2->PickMultipleFilesAndContinue();
- });
- RETURN_FALSE_IF_FAILED("Failed to open file picker");
- QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
- Q_ASSERT(eventDispatcher);
- eventDispatcher->installEventFilter(helper);
- return true;
-#else
hr = QEventDispatcherWinRT::runOnXamlThread([picker, helper, singleFile]() {
HRESULT hr;
if (singleFile) {
@@ -260,7 +231,6 @@ static bool pickFiles(IFileOpenPicker *picker, QWinRTFileDialogHelper *helper, b
return S_OK;
});
return SUCCEEDED(hr);
-#endif
}
static bool pickFolder(IFolderPicker *picker, QWinRTFileDialogHelper *helper)
@@ -268,19 +238,6 @@ static bool pickFolder(IFolderPicker *picker, QWinRTFileDialogHelper *helper)
Q_ASSERT(picker);
Q_ASSERT(helper);
HRESULT hr;
-#ifdef Q_OS_WINPHONE
- hr = QEventDispatcherWinRT::runOnXamlThread([picker]() {
- HRESULT hr;
- ComPtr<IFolderPicker2> picker2;
- hr = picker->QueryInterface(IID_PPV_ARGS(picker2.GetAddressOf()));
- RETURN_HR_IF_FAILED("Failed to cast folder picker");
- return picker2->PickFolderAndContinue();
- });
- RETURN_FALSE_IF_FAILED("Failed to open folder picker");
- QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
- Q_ASSERT(eventDispatcher);
- eventDispatcher->installEventFilter(helper);
-#else
hr = QEventDispatcherWinRT::runOnXamlThread([picker, helper]() {
HRESULT hr;
ComPtr<IAsyncOperation<StorageFolder *>> op;
@@ -290,7 +247,6 @@ static bool pickFolder(IFolderPicker *picker, QWinRTFileDialogHelper *helper)
RETURN_HR_IF_FAILED("Failed to attach folder picker callback");
return S_OK;
});
-#endif
return SUCCEEDED(hr);
}
@@ -299,19 +255,6 @@ static bool pickSaveFile(IFileSavePicker *picker, QWinRTFileDialogHelper *helper
Q_ASSERT(picker);
Q_ASSERT(helper);
HRESULT hr;
-#ifdef Q_OS_WINPHONE
- hr = QEventDispatcherWinRT::runOnXamlThread([picker]() {
- HRESULT hr;
- ComPtr<IFileSavePicker2> picker2;
- hr = picker->QueryInterface(IID_PPV_ARGS(picker2.GetAddressOf()));
- RETURN_HR_IF_FAILED("Failed to cast save file picker");
- return picker2->PickSaveFileAndContinue();
- });
- RETURN_FALSE_IF_FAILED("Failed to open single file picker");
- QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
- Q_ASSERT(eventDispatcher);
- eventDispatcher->installEventFilter(helper);
-#else
hr = QEventDispatcherWinRT::runOnXamlThread([picker, helper]() {
HRESULT hr;
ComPtr<IAsyncOperation<StorageFile *>> op;
@@ -321,7 +264,6 @@ static bool pickSaveFile(IFileSavePicker *picker, QWinRTFileDialogHelper *helper
RETURN_HR_IF_FAILED("Failed to attach save file picker callback");
return S_OK;
});
-#endif
return SUCCEEDED(hr);
}
@@ -488,68 +430,6 @@ void QWinRTFileDialogHelper::hide()
d->shown = false;
}
-#ifdef Q_OS_WINPHONE
-bool QWinRTFileDialogHelper::eventFilter(QObject *, QEvent *e)
-{
- if (e->type() != QEvent::WinEventAct)
- return false;
-
- HRESULT hr;
- QActivationEvent *event = static_cast<QActivationEvent *>(e);
- ComPtr<IInspectable> inspectable = event->args();
- ComPtr<IActivatedEventArgs> arguments;
- hr = inspectable.As(&arguments);
- Q_ASSERT_SUCCEEDED(hr);
-
- ActivationKind activationKind;
- hr = arguments->get_Kind(&activationKind);
- Q_ASSERT_SUCCEEDED(hr);
-
- // Handle only File, Folder and Save file pick continuation here.
- if (activationKind != ActivationKind_PickFileContinuation
- && activationKind != ActivationKind_PickFolderContinuation
- && activationKind != ActivationKind_PickSaveFileContinuation) {
- return false;
- }
-
- QAbstractEventDispatcher *eventDispatcher = QCoreApplication::eventDispatcher();
- Q_ASSERT(eventDispatcher);
- eventDispatcher->removeEventFilter(this);
- e->accept();
-
- if (activationKind == ActivationKind_PickFileContinuation) {
- ComPtr<IFileOpenPickerContinuationEventArgs> fileContinuationArgs;
- hr = arguments.As(&fileContinuationArgs);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IVectorView<StorageFile *>> files;
- hr = fileContinuationArgs->get_Files(&files);
- Q_ASSERT_SUCCEEDED(hr);
- hr = onFilesPicked(files.Get());
- Q_ASSERT_SUCCEEDED(hr);
- } else if (activationKind == ActivationKind_PickFolderContinuation) {
- ComPtr<IFolderPickerContinuationEventArgs> folderContinuationArgs;
- hr = arguments.As(&folderContinuationArgs);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IStorageFolder> folder;
- hr = folderContinuationArgs->get_Folder(&folder);
- Q_ASSERT_SUCCEEDED(hr);
- hr = onFolderPicked(folder.Get());
- Q_ASSERT_SUCCEEDED(hr);
- } else {
- ComPtr<IFileSavePickerContinuationEventArgs> saveFileContinuationArgs;
- hr = arguments.As(&saveFileContinuationArgs);
- Q_ASSERT_SUCCEEDED(hr);
- ComPtr<IStorageFile> file;
- hr = saveFileContinuationArgs->get_File(&file);
- Q_ASSERT_SUCCEEDED(hr);
- hr = onFilePicked(file.Get());
- Q_ASSERT_SUCCEEDED(hr);
- }
-
- return true;
-}
-#endif
-
void QWinRTFileDialogHelper::setDirectory(const QUrl &directory)
{
Q_D(QWinRTFileDialogHelper);
@@ -586,7 +466,6 @@ QString QWinRTFileDialogHelper::selectedNameFilter() const
return d->selectedNameFilter;
}
-#ifndef Q_OS_WINPHONE
HRESULT QWinRTFileDialogHelper::onSingleFilePicked(IAsyncOperation<StorageFile *> *args, AsyncStatus status)
{
Q_D(QWinRTFileDialogHelper);
@@ -643,17 +522,9 @@ HRESULT QWinRTFileDialogHelper::onSingleFolderPicked(IAsyncOperation<StorageFold
Q_ASSERT_SUCCEEDED(hr);
return onFolderPicked(folder.Get());
}
-#endif //Q_OS_WINPHONE
HRESULT QWinRTFileDialogHelper::onFilesPicked(IVectorView<StorageFile *> *files)
{
-#ifdef Q_OS_WINPHONE
- Q_D(QWinRTFileDialogHelper);
- QEventLoopLocker locker(&d->loop);
- d->shown = false;
- d->selectedFiles.clear();
-#endif
-
HRESULT hr;
quint32 size;
hr = files->get_Size(&size);
@@ -676,13 +547,6 @@ HRESULT QWinRTFileDialogHelper::onFilesPicked(IVectorView<StorageFile *> *files)
HRESULT QWinRTFileDialogHelper::onFolderPicked(IStorageFolder *folder)
{
-#ifdef Q_OS_WINPHONE
- Q_D(QWinRTFileDialogHelper);
- QEventLoopLocker locker(&d->loop);
- d->shown = false;
- d->selectedFiles.clear();
-#endif
-
if (!folder) {
emit reject();
return S_OK;
@@ -695,13 +559,6 @@ HRESULT QWinRTFileDialogHelper::onFolderPicked(IStorageFolder *folder)
HRESULT QWinRTFileDialogHelper::onFilePicked(IStorageFile *file)
{
-#ifdef Q_OS_WINPHONE
- Q_D(QWinRTFileDialogHelper);
- QEventLoopLocker locker(&d->loop);
- d->shown = false;
- d->selectedFiles.clear();
-#endif
-
if (!file) {
emit reject();
return S_OK;
diff --git a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
index 413dee7459..99239aad3a 100644
--- a/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
+++ b/src/plugins/platforms/winrt/qwinrtfiledialoghelper.h
@@ -75,9 +75,6 @@ public:
void exec() override;
bool show(Qt::WindowFlags, Qt::WindowModality, QWindow *) override;
void hide() override;
-#ifdef Q_OS_WINPHONE
- bool eventFilter(QObject *o, QEvent *e) override;
-#endif
bool defaultNameFilterDisables() const override { return false; }
void setDirectory(const QUrl &directory) override;
@@ -88,14 +85,12 @@ public:
void selectNameFilter(const QString &selectedNameFilter) override;
QString selectedNameFilter() const override;
-#ifndef Q_OS_WINPHONE
HRESULT onSingleFilePicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFile *> *,
ABI::Windows::Foundation::AsyncStatus);
HRESULT onMultipleFilesPicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile *> *> *,
ABI::Windows::Foundation::AsyncStatus);
HRESULT onSingleFolderPicked(ABI::Windows::Foundation::IAsyncOperation<ABI::Windows::Storage::StorageFolder *> *,
ABI::Windows::Foundation::AsyncStatus);
-#endif
private:
HRESULT onFilesPicked(ABI::Windows::Foundation::Collections::IVectorView<ABI::Windows::Storage::StorageFile *> *files);
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
index 557c13cf63..dab2482ab3 100644
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
@@ -153,7 +153,6 @@ static HRESULT getDestinationFolder(const QString &fileName, const QString &newF
HRESULT hr;
ComPtr<IAsyncOperation<StorageFolder *>> op;
QFileInfo newFileInfo(newFileName);
-#ifndef Q_OS_WINPHONE
QFileInfo fileInfo(fileName);
if (fileInfo.dir() == newFileInfo.dir()) {
ComPtr<IStorageItem2> item;
@@ -161,12 +160,7 @@ static HRESULT getDestinationFolder(const QString &fileName, const QString &newF
Q_ASSERT_SUCCEEDED(hr);
hr = item->GetParentAsync(&op);
- } else
-#else
- Q_UNUSED(fileName);
- Q_UNUSED(file)
-#endif
- {
+ } else {
ComPtr<IStorageFolderStatics> folderFactory;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFolder).Get(),
IID_PPV_ARGS(&folderFactory));
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index ffc3bbf077..7a30c8d98b 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -74,10 +74,8 @@
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
# include <windows.phone.ui.input.h>
-# if _MSC_VER >= 1900
-# include <windows.foundation.metadata.h>
- using namespace ABI::Windows::Foundation::Metadata;
-# endif
+# include <windows.foundation.metadata.h>
+ using namespace ABI::Windows::Foundation::Metadata;
#endif
@@ -153,7 +151,6 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
Q_ASSERT_SUCCEEDED(hr);
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
-#if _MSC_VER >= 1900
d->hasHardwareButtons = false;
ComPtr<IApiInformationStatics> apiInformationStatics;
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation).Get(),
@@ -163,9 +160,6 @@ QWinRTIntegration::QWinRTIntegration() : d_ptr(new QWinRTIntegrationPrivate)
const HStringReference valueRef(L"Windows.Phone.UI.Input.HardwareButtons");
hr = apiInformationStatics->IsTypePresent(valueRef.Get(), &d->hasHardwareButtons);
}
-#else
- d->hasHardwareButtons = true;
-#endif // _MSC_VER >= 1900
if (d->hasHardwareButtons) {
hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Phone_UI_Input_HardwareButtons).Get(),
@@ -226,12 +220,11 @@ QWinRTIntegration::~QWinRTIntegration()
// Do not execute this on Windows Phone as the application is already
// shutting down and trying to unregister suspending/resume handler will
// cause exceptions and assert in debug mode
-#ifndef Q_OS_WINPHONE
for (QHash<CoreApplicationCallbackRemover, EventRegistrationToken>::const_iterator i = d->applicationTokens.begin(); i != d->applicationTokens.end(); ++i) {
hr = (d->application.Get()->*i.key())(i.value());
Q_ASSERT_SUCCEEDED(hr);
}
-#endif
+
destroyScreen(d->mainScreen);
Windows::Foundation::Uninitialize();
}
@@ -318,11 +311,7 @@ QPlatformClipboard *QWinRTIntegration::clipboard() const
#ifndef QT_NO_DRAGANDDROP
QPlatformDrag *QWinRTIntegration::drag() const
{
-#if _MSC_VER >= 1900
return QWinRTDrag::instance();
-#else
- return QPlatformIntegration::drag();
-#endif
}
#endif // QT_NO_DRAGANDDROP
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index 2a4b6c8907..150fc8a25e 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -58,7 +58,7 @@
#include <functional>
#include <wrl.h>
#include <windows.system.h>
-#include <Windows.Applicationmodel.h>
+#include <Windows.ApplicationModel.h>
#include <Windows.ApplicationModel.core.h>
#include <windows.devices.input.h>
#include <windows.ui.h>
@@ -562,7 +562,7 @@ QWinRTScreen::QWinRTScreen()
ComPtr<Xaml::IUIElement> uiElement;
hr = canvas.As(&uiElement);
Q_ASSERT_SUCCEEDED(hr);
-#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP)
+#ifndef QT_NO_DRAGANDDROP
QWinRTDrag::instance()->setUiElement(uiElement);
#endif
hr = window->put_Content(uiElement.Get());
@@ -833,7 +833,7 @@ void QWinRTScreen::addWindow(QWindow *window)
handleExpose();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
-#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP)
+#ifndef QT_NO_DRAGANDDROP
QWinRTDrag::instance()->setDropTarget(window);
#endif
}
@@ -852,7 +852,7 @@ void QWinRTScreen::removeWindow(QWindow *window)
QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason);
handleExpose();
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
-#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP)
+#ifndef QT_NO_DRAGANDDROP
if (wasTopWindow)
QWinRTDrag::instance()->setDropTarget(topWindow());
#endif
@@ -1221,11 +1221,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args)
properties->get_Pressure(&pressure);
boolean isPressed;
-#ifndef Q_OS_WINPHONE
pointerPoint->get_IsInContact(&isPressed);
-#else
- properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone
-#endif
// Devices like the Hololens set a static pressure of 0.5 independent
// of the pressed state. In those cases we need to synthesize the
@@ -1356,16 +1352,10 @@ HRESULT QWinRTScreen::onDpiChanged(IDisplayInformation *, IInspectable *)
Q_D(QWinRTScreen);
HRESULT hr;
-#ifdef Q_OS_WINPHONE
- ComPtr<IDisplayInformation2> displayInformation;
- hr = d->displayInformation.As(&displayInformation);
- RETURN_OK_IF_FAILED("Failed to cast display information.");
- hr = displayInformation->get_RawPixelsPerViewPixel(&d->scaleFactor);
-#else
ResolutionScale resolutionScale;
hr = d->displayInformation->get_ResolutionScale(&resolutionScale);
d->scaleFactor = qreal(resolutionScale) / 100;
-#endif
+
qCDebug(lcQpaWindows) << __FUNCTION__ << "Scale Factor:" << d->scaleFactor;
RETURN_OK_IF_FAILED("Failed to get scale factor");
diff --git a/src/plugins/platforms/winrt/qwinrttheme.cpp b/src/plugins/platforms/winrt/qwinrttheme.cpp
index f84688f045..6b35bde83e 100644
--- a/src/plugins/platforms/winrt/qwinrttheme.cpp
+++ b/src/plugins/platforms/winrt/qwinrttheme.cpp
@@ -84,7 +84,6 @@ static inline QColor fromColor(const Color &color)
return QColor(color.R, color.G, color.B, color.A);
}
-#if _MSC_VER >= 1900
static bool uiColorSettings(const wchar_t *value, UIElementType type, Color *color)
{
static ComPtr<IApiInformationStatics> apiInformationStatics;
@@ -189,103 +188,6 @@ static void nativeColorSettings(QPalette &p)
p.setColor(QPalette::BrightText, fromColor(color));
}
-#else // _MSC_VER >= 1900
-
-static void nativeColorSettings(QPalette &p)
-{
- HRESULT hr;
- Color color;
-
-#ifdef Q_OS_WINPHONE
- hr = uiSettings()->UIElementColor(UIElementType_PopupBackground, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::ToolTipBase, fromColor(color));
- p.setColor(QPalette::AlternateBase, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_NonTextMedium, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Button, fromColor(color));
- hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumHigh, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Midlight, fromColor(color));
- hr = uiSettings()->UIElementColor(UIElementType_NonTextHigh, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Light, fromColor(color));
- hr = uiSettings()->UIElementColor(UIElementType_NonTextMediumLow, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Mid, fromColor(color));
- hr = uiSettings()->UIElementColor(UIElementType_NonTextLow, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Dark, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_TextHigh, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::ButtonText, fromColor(color));
- p.setColor(QPalette::Text, fromColor(color));
- p.setColor(QPalette::WindowText, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_TextMedium, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::ToolTipText, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_AccentColor, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Highlight, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_PageBackground, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Window, fromColor(color));
- p.setColor(QPalette::Base, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_TextContrastWithHigh, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::BrightText, fromColor(color));
-#else
- hr = uiSettings()->UIElementColor(UIElementType_ActiveCaption, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::ToolTipBase, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_Background, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::AlternateBase, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_ButtonFace, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Button, fromColor(color));
- p.setColor(QPalette::Midlight, fromColor(color).lighter(110));
- p.setColor(QPalette::Light, fromColor(color).lighter(150));
- p.setColor(QPalette::Mid, fromColor(color).dark(130));
- p.setColor(QPalette::Dark, fromColor(color).dark(150));
-
- hr = uiSettings()->UIElementColor(UIElementType_ButtonText, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::ButtonText, fromColor(color));
- p.setColor(QPalette::Text, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_CaptionText, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::ToolTipText, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_Highlight, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Highlight, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_HighlightText, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::HighlightedText, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_Window, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::Window, fromColor(color));
- p.setColor(QPalette::Base, fromColor(color));
-
- hr = uiSettings()->UIElementColor(UIElementType_Hotlight, &color);
- Q_ASSERT_SUCCEEDED(hr);
- p.setColor(QPalette::BrightText, fromColor(color));
-#endif
-}
-#endif // _MSC_VER < 1900
-
QWinRTTheme::QWinRTTheme()
: d_ptr(new QWinRTThemePrivate)
{
diff --git a/src/plugins/platforms/winrt/qwinrtwindow.cpp b/src/plugins/platforms/winrt/qwinrtwindow.cpp
index 8f3b86ff3b..c40a1b8c45 100644
--- a/src/plugins/platforms/winrt/qwinrtwindow.cpp
+++ b/src/plugins/platforms/winrt/qwinrtwindow.cpp
@@ -331,7 +331,6 @@ void QWinRTWindow::setWindowState(Qt::WindowState state)
if (d->state == state)
return;
-#if _MSC_VER >= 1900
if (state == Qt::WindowFullScreen) {
HRESULT hr;
boolean success;
@@ -378,7 +377,6 @@ void QWinRTWindow::setWindowState(Qt::WindowState state)
return;
}
}
-#endif // _MSC_VER >= 1900
if (state == Qt::WindowMinimized)
setUIElementVisibility(d->uiElement.Get(), false);
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index be2f5ca7e2..35801fdacc 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -52,7 +52,7 @@ WINRT_SDK_VERSION_STRING = $$(UCRTVersion)
WINRT_SDK_VERSION = $$member($$list($$split(WINRT_SDK_VERSION_STRING, .)), 2)
lessThan(WINRT_SDK_VERSION, 14322): DEFINES += QT_WINRT_LIMITED_DRAGANDDROP
-*-msvc2013|contains(DEFINES, QT_NO_DRAGANDDROP) {
+contains(DEFINES, QT_NO_DRAGANDDROP) {
SOURCES -= qwinrtdrag.cpp
HEADERS -= qwinrtdrag.h
}
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index a293066b93..01b3bca0d2 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -267,11 +267,6 @@ const int QXcbClipboard::clipboard_timeout = 5000;
QXcbClipboard::QXcbClipboard(QXcbConnection *c)
: QXcbObject(c), QPlatformClipboard()
- , m_requestor(XCB_NONE)
- , m_owner(XCB_NONE)
- , m_incr_active(false)
- , m_clipboard_closing(false)
- , m_incr_receive_time(0)
{
Q_ASSERT(QClipboard::Clipboard == 0);
Q_ASSERT(QClipboard::Selection == 1);
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
index a0a4f4e5a1..bfeae13e10 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.h
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -102,14 +102,14 @@ private:
QMimeData *m_clientClipboard[2];
xcb_timestamp_t m_timestamp[2];
- xcb_window_t m_requestor;
- xcb_window_t m_owner;
+ xcb_window_t m_requestor = XCB_NONE;
+ xcb_window_t m_owner = XCB_NONE;
static const int clipboard_timeout;
- bool m_incr_active;
- bool m_clipboard_closing;
- xcb_timestamp_t m_incr_receive_time;
+ bool m_incr_active = false;
+ bool m_clipboard_closing = false;
+ xcb_timestamp_t m_incr_receive_time = 0;
};
#endif // QT_NO_CLIPBOARD
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 5e600c740b..8c5f8cae08 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -131,7 +131,7 @@ typedef struct qt_xcb_ge_event_t {
static inline bool isXIEvent(xcb_generic_event_t *event, int opCode)
{
- qt_xcb_ge_event_t *e = (qt_xcb_ge_event_t *)event;
+ qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event);
return e->extension == opCode;
}
#endif // XCB_USE_XINPUT2
@@ -251,7 +251,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
// Find a fake screen
const auto scrs = virtualDesktop->screens();
for (QPlatformScreen *scr : scrs) {
- QXcbScreen *xcbScreen = (QXcbScreen *)scr;
+ QXcbScreen *xcbScreen = static_cast<QXcbScreen *>(scr);
if (xcbScreen->output() == XCB_NONE) {
screen = xcbScreen;
break;
@@ -377,7 +377,7 @@ void QXcbConnection::destroyScreen(QXcbScreen *screen)
// When primary screen is removed, set the new primary screen
// which belongs to the primary virtual desktop.
if (screen->isPrimary()) {
- QXcbScreen *newPrimary = (QXcbScreen *)virtualDesktop->screens().at(0);
+ QXcbScreen *newPrimary = static_cast<QXcbScreen *>(virtualDesktop->screens().at(0));
newPrimary->setPrimary(true);
const int idx = m_screens.indexOf(newPrimary);
if (idx > 0)
@@ -552,32 +552,10 @@ void QXcbConnection::initializeScreens()
}
QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGrabServer, xcb_visualid_t defaultVisualId, const char *displayName)
- : m_connection(0)
- , m_canGrabServer(canGrabServer)
+ : m_canGrabServer(canGrabServer)
, m_defaultVisualId(defaultVisualId)
- , m_primaryScreenNumber(0)
, m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY"))
, m_nativeInterface(nativeInterface)
-#ifdef XCB_USE_XLIB
- , m_xlib_display(0)
-#endif
- , xfixes_first_event(0)
- , xrandr_first_event(0)
- , xkb_first_event(0)
- , has_xinerama_extension(false)
- , has_shape_extension(false)
- , has_randr_extension(false)
- , has_input_shape(false)
- , has_xkb(false)
- , m_buttons(0)
- , m_focusWindow(0)
- , m_mouseGrabber(0)
- , m_mousePressWindow(0)
- , m_clientLeader(0)
- , m_systemTrayTracker(0)
- , m_glIntegration(Q_NULLPTR)
- , m_xiGrab(false)
- , m_qtSelectionOwner(0)
{
#ifdef XCB_USE_XLIB
Display *dpy = XOpenDisplay(m_displayName.constData());
@@ -618,9 +596,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeAllAtoms();
- m_time = XCB_CURRENT_TIME;
- m_netWmUserTime = XCB_CURRENT_TIME;
-
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR"))
initializeXRandr();
if (!has_randr_extension)
@@ -630,7 +605,6 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
initializeXRender();
#if defined(XCB_USE_XINPUT2)
- m_xi2Enabled = false;
if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2"))
initializeXInput2();
#endif
@@ -712,7 +686,7 @@ QXcbConnection::~QXcbConnection()
delete m_glIntegration;
#ifdef XCB_USE_XLIB
- XCloseDisplay((Display *)m_xlib_display);
+ XCloseDisplay(static_cast<Display *>(m_xlib_display));
#else
xcb_disconnect(xcb_connection());
#endif
@@ -755,7 +729,7 @@ QXcbWindow *QXcbConnection::platformWindowFromId(xcb_window_t id)
#define HANDLE_PLATFORM_WINDOW_EVENT(event_t, windowMember, handler) \
{ \
- event_t *e = (event_t *)event; \
+ event_t *e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->windowMember)) { \
handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
@@ -766,7 +740,7 @@ break;
#define HANDLE_KEYBOARD_EVENT(event_t, handler) \
{ \
- event_t *e = (event_t *)event; \
+ event_t *e = reinterpret_cast<event_t *>(event); \
if (QXcbWindowEventListener *eventListener = windowEventListenerFromId(e->event)) { \
handled = eventListener->handleGenericEvent(event, &result); \
if (!handled) \
@@ -1185,11 +1159,11 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
case XCB_MAPPING_NOTIFY:
- m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
+ m_keyboard->handleMappingNotifyEvent(reinterpret_cast<xcb_mapping_notify_event_t *>(event));
break;
case XCB_SELECTION_REQUEST:
{
- xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
+ xcb_selection_request_event_t *sr = reinterpret_cast<xcb_selection_request_event_t *>(event);
#ifndef QT_NO_DRAGANDDROP
if (sr->selection == atom(QXcbAtom::XdndSelection))
m_drag->handleSelectionRequest(sr);
@@ -1203,19 +1177,19 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
break;
}
case XCB_SELECTION_CLEAR:
- setTime(((xcb_selection_clear_event_t *)event)->time);
+ setTime((reinterpret_cast<xcb_selection_clear_event_t *>(event))->time);
#ifndef QT_NO_CLIPBOARD
- m_clipboard->handleSelectionClearRequest((xcb_selection_clear_event_t *)event);
+ m_clipboard->handleSelectionClearRequest(reinterpret_cast<xcb_selection_clear_event_t *>(event));
#endif
handled = true;
break;
case XCB_SELECTION_NOTIFY:
- setTime(((xcb_selection_notify_event_t *)event)->time);
+ setTime((reinterpret_cast<xcb_selection_notify_event_t *>(event))->time);
handled = false;
break;
case XCB_PROPERTY_NOTIFY:
{
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
if (pn->atom == atom(QXcbAtom::_NET_WORKAREA)) {
QXcbVirtualDesktop *virtualDesktop = virtualDesktopForRootWindow(pn->window);
if (virtualDesktop)
@@ -1240,7 +1214,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
if (!handled) {
if (response_type == xfixes_first_event + XCB_XFIXES_SELECTION_NOTIFY) {
- xcb_xfixes_selection_notify_event_t *notify_event = (xcb_xfixes_selection_notify_event_t *)event;
+ xcb_xfixes_selection_notify_event_t *notify_event = reinterpret_cast<xcb_xfixes_selection_notify_event_t *>(event);
setTime(notify_event->timestamp);
#ifndef QT_NO_CLIPBOARD
m_clipboard->handleXFixesSelectionRequest(notify_event);
@@ -1250,10 +1224,10 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_NOTIFY) {
- updateScreens((xcb_randr_notify_event_t *)event);
+ updateScreens(reinterpret_cast<xcb_randr_notify_event_t *>(event));
handled = true;
} else if (has_randr_extension && response_type == xrandr_first_event + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
- xcb_randr_screen_change_notify_event_t *change_event = (xcb_randr_screen_change_notify_event_t *)event;
+ xcb_randr_screen_change_notify_event_t *change_event = reinterpret_cast<xcb_randr_screen_change_notify_event_t *>(event);
for (QXcbScreen *s : qAsConst(m_screens)) {
if (s->root() == change_event->root )
s->handleScreenChange(change_event);
@@ -1362,7 +1336,7 @@ void QXcbEventReader::run()
void QXcbEventReader::addEvent(xcb_generic_event_t *event)
{
if ((event->response_type & ~0x80) == XCB_CLIENT_MESSAGE
- && ((xcb_client_message_event_t *)event)->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION))
+ && (reinterpret_cast<xcb_client_message_event_t *>(event))->type == m_connection->atom(QXcbAtom::_QT_CLOSE_CONNECTION))
m_connection = 0;
m_events << event;
}
@@ -1428,7 +1402,7 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id)
event.type = atom(a);
event.data.data32[0] = id;
- Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, (const char *)&event));
+ Q_XCB_CALL(xcb_send_event(xcb_connection(), false, eventListener, XCB_EVENT_MASK_NO_EVENT, reinterpret_cast<const char *>(&event)));
Q_XCB_CALL(xcb_destroy_window(m_connection, eventListener));
xcb_flush(xcb_connection());
}
@@ -1448,7 +1422,7 @@ namespace
if ((event->response_type & ~0x80) != type) {
return false;
} else {
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
if ((pn->window == window) && (pn->atom == atom))
return true;
}
@@ -1476,7 +1450,7 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
event = checkEvent(checker);
}
- xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)event;
+ xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
xcb_timestamp_t timestamp = pn->time;
free(event);
@@ -1500,7 +1474,8 @@ xcb_window_t QXcbConnection::getQtSelectionOwner()
{
if (!m_qtSelectionOwner) {
xcb_screen_t *xcbScreen = primaryVirtualDesktop()->screen();
- int x = 0, y = 0, w = 3, h = 3;
+ int16_t x = 0, y = 0;
+ uint16_t w = 3, h = 3;
m_qtSelectionOwner = xcb_generate_id(xcb_connection());
Q_XCB_CALL(xcb_create_window(xcb_connection(),
XCB_COPY_FROM_PARENT, // depth -- same as root
@@ -1689,7 +1664,7 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex,
for (int j = nextIndex; j < eventqueue->size(); ++j) {
xcb_generic_event_t *next = eventqueue->at(j);
if (isValid(next) && next->response_type == XCB_CONFIGURE_NOTIFY
- && ((xcb_configure_notify_event_t *)next)->event == ((xcb_configure_notify_event_t*)event)->event)
+ && reinterpret_cast<xcb_configure_notify_event_t *>(next)->event == reinterpret_cast<xcb_configure_notify_event_t *>(event)->event)
{
return true;
}
@@ -1718,7 +1693,7 @@ void QXcbConnection::processXcbEvents()
(*eventqueue)[i] = 0;
if (!(event->response_type & ~0x80)) {
- handleXcbError((xcb_generic_error_t *)event);
+ handleXcbError(reinterpret_cast<xcb_generic_error_t *>(event));
continue;
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 01a97a187a..ffd0c87a3e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -551,10 +551,9 @@ private:
void destroyScreen(QXcbScreen *screen);
void initializeScreens();
bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const;
-
#ifdef XCB_USE_XINPUT2
- bool m_xi2Enabled;
- int m_xi2Minor;
+ bool m_xi2Enabled = false;
+ int m_xi2Minor = 2;
void initializeXInput2();
void finalizeXInput2();
void xi2SetupDevices();
@@ -568,20 +567,17 @@ private:
#endif // XCB_USE_XINPUT22
#ifndef QT_NO_TABLETEVENT
struct TabletData {
- TabletData() : deviceId(0), pointerType(QTabletEvent::UnknownPointer),
- tool(QTabletEvent::Stylus), buttons(0), serialId(0), inProximity(false) { }
- int deviceId;
- QTabletEvent::PointerType pointerType;
- QTabletEvent::TabletDevice tool;
- Qt::MouseButtons buttons;
- qint64 serialId;
- bool inProximity;
+ int deviceId = 0;
+ QTabletEvent::PointerType pointerType = QTabletEvent::UnknownPointer;
+ QTabletEvent::TabletDevice tool = QTabletEvent::Stylus;
+ Qt::MouseButtons buttons = 0;
+ qint64 serialId = 0;
+ bool inProximity = false;
struct ValuatorClassInfo {
- ValuatorClassInfo() : minVal(0.), maxVal(0.), curVal(0.) { }
- double minVal;
- double maxVal;
- double curVal;
- int number;
+ double minVal = 0;
+ double maxVal = 0;
+ double curVal = 0;
+ int number = -1;
};
QHash<int, ValuatorClassInfo> valuatorInfo;
};
@@ -593,12 +589,13 @@ private:
TabletData *tabletDataForDevice(int id);
#endif // !QT_NO_TABLETEVENT
struct ScrollingDevice {
- ScrollingDevice() : deviceId(0), verticalIndex(0), horizontalIndex(0), orientations(0), legacyOrientations(0) { }
- int deviceId;
- int verticalIndex, horizontalIndex;
- double verticalIncrement, horizontalIncrement;
- Qt::Orientations orientations;
- Qt::Orientations legacyOrientations;
+ int deviceId = 0;
+ int verticalIndex = 0;
+ int horizontalIndex = 0;
+ double verticalIncrement = 0;
+ double horizontalIncrement = 0;
+ Qt::Orientations orientations = 0;
+ Qt::Orientations legacyOrientations = 0;
QPointF lastScrollPosition;
};
void updateScrollingDevice(ScrollingDevice& scrollingDevice, int num_classes, void *classes);
@@ -609,36 +606,36 @@ private:
static void xi2PrepareXIGenericDeviceEvent(xcb_ge_event_t *event);
#endif
- xcb_connection_t *m_connection;
- const xcb_setup_t *m_setup;
- bool m_canGrabServer;
- xcb_visualid_t m_defaultVisualId;
+ xcb_connection_t *m_connection = nullptr;
+ const xcb_setup_t *m_setup = nullptr;
+ const bool m_canGrabServer;
+ const xcb_visualid_t m_defaultVisualId;
QList<QXcbVirtualDesktop *> m_virtualDesktops;
QList<QXcbScreen *> m_screens;
- int m_primaryScreenNumber;
+ int m_primaryScreenNumber = 0;
xcb_atom_t m_allAtoms[QXcbAtom::NAtoms];
- xcb_timestamp_t m_time;
- xcb_timestamp_t m_netWmUserTime;
+ xcb_timestamp_t m_time = XCB_CURRENT_TIME;
+ xcb_timestamp_t m_netWmUserTime = XCB_CURRENT_TIME;
QByteArray m_displayName;
- QXcbKeyboard *m_keyboard;
+ QXcbKeyboard *m_keyboard = nullptr;
#ifndef QT_NO_CLIPBOARD
- QXcbClipboard *m_clipboard;
+ QXcbClipboard *m_clipboard = nullptr;
#endif
#ifndef QT_NO_DRAGANDDROP
- QXcbDrag *m_drag;
+ QXcbDrag *m_drag = nullptr;
#endif
QScopedPointer<QXcbWMSupport> m_wmSupport;
- QXcbNativeInterface *m_nativeInterface;
+ QXcbNativeInterface *m_nativeInterface = nullptr;
#if defined(XCB_USE_XLIB)
- void *m_xlib_display;
+ void *m_xlib_display = nullptr;
#endif
- QXcbEventReader *m_reader;
+ QXcbEventReader *m_reader = nullptr;
#if defined(XCB_USE_XINPUT2)
QHash<int, XInput2TouchDeviceData*> m_touchDevices;
#ifdef XCB_USE_XINPUT22
@@ -671,29 +668,29 @@ private:
QVector<PeekFunc> m_peekFuncs;
- uint32_t xfixes_first_event;
- uint32_t xrandr_first_event;
- uint32_t xkb_first_event;
+ uint32_t xfixes_first_event = 0;
+ uint32_t xrandr_first_event = 0;
+ uint32_t xkb_first_event = 0;
- bool has_xinerama_extension;
- bool has_shape_extension;
- bool has_randr_extension;
+ bool has_xinerama_extension = false;
+ bool has_shape_extension = false;
+ bool has_randr_extension = false;
bool has_input_shape;
- bool has_xkb;
+ bool has_xkb = false;
- Qt::MouseButtons m_buttons;
+ Qt::MouseButtons m_buttons = 0;
- QXcbWindow *m_focusWindow;
- QXcbWindow *m_mouseGrabber;
- QXcbWindow *m_mousePressWindow;
+ QXcbWindow *m_focusWindow = nullptr;
+ QXcbWindow *m_mouseGrabber = nullptr;
+ QXcbWindow *m_mousePressWindow = nullptr;
- xcb_window_t m_clientLeader;
+ xcb_window_t m_clientLeader = 0;
QByteArray m_startupId;
- QXcbSystemTrayTracker *m_systemTrayTracker;
- QXcbGlIntegration *m_glIntegration;
- bool m_xiGrab;
+ QXcbSystemTrayTracker *m_systemTrayTracker = nullptr;
+ QXcbGlIntegration *m_glIntegration = nullptr;
+ bool m_xiGrab = false;
- xcb_window_t m_qtSelectionOwner;
+ xcb_window_t m_qtSelectionOwner = 0;
friend class QXcbEventReader;
};
@@ -704,7 +701,7 @@ Q_DECLARE_TYPEINFO(QXcbConnection::TabletData, Q_MOVABLE_TYPE);
#endif
#endif
-#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
+#define DISPLAY_FROM_XCB(object) (reinterpret_cast<Display *>(object->connection()->xlib_display()))
#define CREATE_VISUALINFO_FROM_DEFAULT_VISUALID(object) ((XVisualInfo *)(object->connection()->createVisualInfoForDefaultVisualId()))
template<typename T>
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index d91cbfe82d..4a30f7b7bc 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -42,6 +42,7 @@
#include "qxcbscreen.h"
#include "qxcbwindow.h"
#include "qtouchdevice.h"
+#include "QtCore/qmetaobject.h"
#include <qpa/qwindowsysteminterface_p.h>
#include <QDebug>
#include <cmath>
@@ -52,14 +53,8 @@
#include <X11/extensions/XI2proto.h>
struct XInput2TouchDeviceData {
- XInput2TouchDeviceData()
- : xiDeviceInfo(0)
- , qtTouchDevice(0)
- , providesTouchOrientation(false)
- {
- }
- XIDeviceInfo *xiDeviceInfo;
- QTouchDevice *qtTouchDevice;
+ XIDeviceInfo *xiDeviceInfo = nullptr;
+ QTouchDevice *qtTouchDevice = nullptr;
QHash<int, QWindowSystemInterface::TouchPoint> touchPoints;
QHash<int, QPointF> pointPressedPosition; // in screen coordinates where each point was pressed
@@ -67,7 +62,7 @@ struct XInput2TouchDeviceData {
QPointF firstPressedPosition; // in screen coordinates where the first point was pressed
QPointF firstPressedNormalPosition; // device coordinates (0 to 1, 0 to 1) where the first point was pressed
QSizeF size; // device size in mm
- bool providesTouchOrientation;
+ bool providesTouchOrientation = false;
};
void QXcbConnection::initializeXInput2()
@@ -80,7 +75,7 @@ void QXcbConnection::initializeXInput2()
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
- m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
+ // try 2.2 first, needed for TouchBegin/Update/End
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
m_xi2Minor = 1; // for smooth scrolling 2.1 is enough
if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
@@ -214,6 +209,8 @@ void QXcbConnection::xi2SetupDevices()
isTablet = true;
tabletData.pointerType = QTabletEvent::Cursor;
dbgType = QLatin1String("cursor");
+ } else if (name.contains("wacom") && name.contains("finger touch")) {
+ isTablet = false;
} else if ((name.contains("pen") || name.contains("stylus")) && isTablet) {
tabletData.pointerType = QTabletEvent::Pen;
dbgType = QLatin1String("pen");
@@ -232,6 +229,9 @@ void QXcbConnection::xi2SetupDevices()
isTablet = true;
tabletData.pointerType = QTabletEvent::Pen;
dbgType = QLatin1String("pen");
+ } else if (name.contains("uc-logic") && isTablet) {
+ tabletData.pointerType = QTabletEvent::Pen;
+ dbgType = QLatin1String("pen");
} else {
isTablet = false;
}
@@ -444,10 +444,10 @@ XInput2TouchDeviceData *QXcbConnection::touchDeviceForId(int id)
dev->size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution);
} else if (vci->label == atom(QXcbAtom::AbsX)) {
caps |= QTouchDevice::Position;
- dev->size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution);
+ dev->size.setWidth((vci->max - vci->min) * 1000.0 / vciResolution);
} else if (vci->label == atom(QXcbAtom::AbsY)) {
caps |= QTouchDevice::Position;
- dev->size.setWidth((vci->max - vci->min) * 1000.0 / vciResolution);
+ dev->size.setHeight((vci->max - vci->min) * 1000.0 / vciResolution);
}
break;
}
@@ -1066,6 +1066,18 @@ static QTabletEvent::TabletDevice toolIdToTabletDevice(quint32 toolId) {
return QTabletEvent::Stylus; // Safe default assumption if nonzero
}
+static const char *toolName(QTabletEvent::TabletDevice tool) {
+ static const QMetaObject *metaObject = qt_getEnumMetaObject(tool);
+ static const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(tool)));
+ return me.valueToKey(tool);
+}
+
+static const char *pointerTypeName(QTabletEvent::PointerType ptype) {
+ static const QMetaObject *metaObject = qt_getEnumMetaObject(ptype);
+ static const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(ptype)));
+ return me.valueToKey(ptype);
+}
+
bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletData)
{
bool handled = true;
@@ -1087,10 +1099,7 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
break;
}
case XI_Motion:
- // Report TabletMove only when the stylus is touching the tablet or any button is pressed.
- // TODO: report proximity (hover) motion (no suitable Qt event exists yet).
- if (tabletData->buttons != Qt::NoButton)
- xi2ReportTabletEvent(xiEvent, tabletData);
+ xi2ReportTabletEvent(xiEvent, tabletData);
break;
case XI_PropertyEvent: {
// This is the wacom driver's way of reporting tool proximity.
@@ -1142,9 +1151,9 @@ bool QXcbConnection::xi2HandleTabletEvent(const void *event, TabletData *tabletD
// TODO maybe have a hash of tabletData->deviceId to device data so we can
// look up the tablet name here, and distinguish multiple tablets
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x TabletDevice %d",
+ qCDebug(lcQpaXInputEvents, "XI2 proximity change on tablet %d (USB %x): last tool: %x id %x current tool: %x id %x %s",
tabletData->deviceId, ptr[_WACSER_USB_ID], ptr[_WACSER_LAST_TOOL_SERIAL], ptr[_WACSER_LAST_TOOL_ID],
- ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], tabletData->tool);
+ ptr[_WACSER_TOOL_SERIAL], ptr[_WACSER_TOOL_ID], toolName(tabletData->tool));
}
XFree(data);
}
@@ -1207,9 +1216,10 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
}
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
- qCDebug(lcQpaXInputEvents, "XI2 event on tablet %d with tool %d type %d seq %d detail %d time %d "
+ qCDebug(lcQpaXInputEvents, "XI2 event on tablet %d with tool %s type %s seq %d detail %d time %d "
"pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf",
- tabletData->deviceId, tabletData->tool, ev->evtype, ev->sequenceNumber, ev->detail, ev->time,
+ tabletData->deviceId, toolName(tabletData->tool), pointerTypeName(tabletData->pointerType),
+ ev->sequenceNumber, ev->detail, ev->time,
fixed1616ToReal(ev->event_x), fixed1616ToReal(ev->event_y),
fixed1616ToReal(ev->root_x), fixed1616ToReal(ev->root_y),
(int)tabletData->buttons, pressure, xTilt, yTilt, rotation);
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index af9ffab8ae..40858b39e0 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -214,6 +214,27 @@ QPlatformWindow *QXcbIntegration::createPlatformWindow(QWindow *window) const
return xcbWindow;
}
+class QXcbForeignWindow : public QXcbWindow
+{
+public:
+ QXcbForeignWindow(QWindow *window, WId nativeHandle)
+ : QXcbWindow(window) { m_window = nativeHandle; }
+ ~QXcbForeignWindow() {}
+ bool isForeignWindow() const override { return true; }
+
+protected:
+ // No-ops
+ void create() override {}
+ void destroy() override {}
+};
+
+QPlatformWindow *QXcbIntegration::createForeignWindow(QWindow *window, WId nativeHandle) const
+{
+ QXcbWindow *xcbWindow = new QXcbForeignWindow(window, nativeHandle);
+ xcbWindow->create();
+ return xcbWindow;
+}
+
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *QXcbIntegration::createPlatformOpenGLContext(QOpenGLContext *context) const
{
@@ -384,9 +405,6 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
case QPlatformIntegration::PasswordMaskCharacter:
// TODO using various xcb, gnome or KDE settings
break; // Not implemented, use defaults
- case QPlatformIntegration::FontSmoothingGamma:
- // Match Qt 4.8 text rendering, and rendering of other X11 toolkits.
- return qreal(1.0);
case QPlatformIntegration::StartDragDistance: {
// The default (in QPlatformTheme::defaultThemeHint) is 10 pixels, but
// on a high-resolution screen it makes sense to increase it.
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index f8034f436f..baa5c9d835 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -61,6 +61,7 @@ public:
~QXcbIntegration();
QPlatformWindow *createPlatformWindow(QWindow *window) const override;
+ QPlatformWindow *createForeignWindow(QWindow *window, WId nativeHandle) const override;
#ifndef QT_NO_OPENGL
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const override;
#endif
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index a5aff7f11f..2e29c208c7 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -1136,12 +1136,6 @@ int QXcbKeyboard::keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modi
QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
: QXcbObject(connection)
- , m_autorepeat_code(0)
- , xkb_context(0)
- , xkb_keymap(0)
- , xkb_state(0)
- , latin_keymap(0)
- , m_hasLatinLayout(false)
{
memset(&xkb_names, 0, sizeof(xkb_names));
#if QT_CONFIG(xkb)
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index dfd2926435..74f9da0353 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -106,14 +106,14 @@ protected:
private:
void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state);
- bool m_config;
- xcb_keycode_t m_autorepeat_code;
+ bool m_config = false;
+ xcb_keycode_t m_autorepeat_code = 0;
- struct xkb_context *xkb_context;
- struct xkb_keymap *xkb_keymap;
- struct xkb_state *xkb_state;
+ struct xkb_context *xkb_context = nullptr;
+ struct xkb_keymap *xkb_keymap = nullptr;
+ struct xkb_state *xkb_state = nullptr;
struct xkb_rule_names xkb_names;
- mutable struct xkb_keymap *latin_keymap;
+ mutable struct xkb_keymap *latin_keymap = nullptr;
struct _mod_masks {
uint alt;
@@ -143,7 +143,7 @@ private:
_mod_masks vmod_masks;
int core_device_id;
#endif
- bool m_hasLatinLayout;
+ bool m_hasLatinLayout = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index b1575cbee4..725288633a 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -90,8 +90,7 @@ static int resourceType(const QByteArray &key)
}
QXcbNativeInterface::QXcbNativeInterface() :
- m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t")),
- m_sysTraySelectionAtom(XCB_ATOM_NONE)
+ m_genericEventFilterType(QByteArrayLiteral("xcb_generic_event_t"))
{
}
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index a830829311..4186d77f4d 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -129,7 +129,7 @@ private:
const QByteArray m_genericEventFilterType;
- xcb_atom_t m_sysTraySelectionAtom;
+ xcb_atom_t m_sysTraySelectionAtom = XCB_ATOM_NONE;
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 0ad9c97521..5e136b5d7e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -59,7 +59,6 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
: QXcbObject(connection)
, m_screen(screen)
, m_number(number)
- , m_xSettings(Q_NULLPTR)
{
const QByteArray cmAtomName = "_NET_WM_CM_S" + QByteArray::number(m_number);
m_net_wm_cm_atom = connection->internAtom(cmAtomName.constData());
@@ -175,20 +174,10 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe
, m_virtualDesktop(virtualDesktop)
, m_output(outputId)
, m_crtc(output ? output->crtc : XCB_NONE)
- , m_mode(XCB_NONE)
- , m_primary(false)
- , m_rotation(XCB_RANDR_ROTATION_ROTATE_0)
, m_outputName(getOutputName(output))
, m_outputSizeMillimeters(output ? QSize(output->mm_width, output->mm_height) : QSize())
, m_virtualSize(virtualDesktop->size())
, m_virtualSizeMillimeters(virtualDesktop->physicalSize())
- , m_orientation(Qt::PrimaryOrientation)
- , m_refreshRate(60)
- , m_forcedDpi(-1)
- , m_pixelDensity(1)
- , m_hintStyle(QFontEngine::HintStyle(-1))
- , m_subpixelType(QFontEngine::SubpixelAntialiasingType(-1))
- , m_antialiasingEnabled(-1)
{
if (connection->hasXRandr()) {
xcb_randr_select_input(xcb_connection(), screen()->root, true);
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index 627397fcaf..4163be2969 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -95,12 +95,12 @@ private:
QRect getWorkArea() const;
xcb_screen_t *m_screen;
- int m_number;
+ const int m_number;
QList<QPlatformScreen *> m_screens;
- QXcbXSettings *m_xSettings;
- xcb_atom_t m_net_wm_cm_atom;
- bool m_compositingActive;
+ QXcbXSettings *m_xSettings = nullptr;
+ xcb_atom_t m_net_wm_cm_atom = 0;
+ bool m_compositingActive = false;
QRect m_workArea;
};
@@ -186,9 +186,9 @@ private:
QXcbVirtualDesktop *m_virtualDesktop;
xcb_randr_output_t m_output;
xcb_randr_crtc_t m_crtc;
- xcb_randr_mode_t m_mode;
- bool m_primary;
- uint8_t m_rotation;
+ xcb_randr_mode_t m_mode = XCB_NONE;
+ bool m_primary = false;
+ uint8_t m_rotation = XCB_RANDR_ROTATION_ROTATE_0;
QString m_outputName;
QSizeF m_outputSizeMillimeters;
@@ -197,18 +197,18 @@ private:
QRect m_availableGeometry;
QSize m_virtualSize;
QSizeF m_virtualSizeMillimeters;
- Qt::ScreenOrientation m_orientation;
+ Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation;
QString m_windowManagerName;
- bool m_syncRequestSupported;
+ bool m_syncRequestSupported = false;
QMap<xcb_visualid_t, xcb_visualtype_t> m_visuals;
QMap<xcb_visualid_t, quint8> m_visualDepths;
QXcbCursor *m_cursor;
- int m_refreshRate;
- int m_forcedDpi;
- int m_pixelDensity;
- QFontEngine::HintStyle m_hintStyle;
- QFontEngine::SubpixelAntialiasingType m_subpixelType;
- int m_antialiasingEnabled;
+ int m_refreshRate = 60;
+ int m_forcedDpi = -1;
+ int m_pixelDensity = 1;
+ QFontEngine::HintStyle m_hintStyle = QFontEngine::HintStyle(-1);
+ QFontEngine::SubpixelAntialiasingType m_subpixelType = QFontEngine::SubpixelAntialiasingType(-1);
+ int m_antialiasingEnabled = -1;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index 5522af86de..fb0a4a3939 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -80,7 +80,6 @@ QXcbSystemTrayTracker::QXcbSystemTrayTracker(QXcbConnection *connection,
, m_selection(selection)
, m_trayAtom(trayAtom)
, m_connection(connection)
- , m_trayWindow(0)
{
}
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
index a6131e6d0e..a95b9374e9 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.h
@@ -77,7 +77,7 @@ private:
const xcb_atom_t m_selection;
const xcb_atom_t m_trayAtom;
QXcbConnection *m_connection;
- xcb_window_t m_trayWindow;
+ xcb_window_t m_trayWindow = 0;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 78d000c774..3f0493669f 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -314,22 +314,6 @@ static const char *wm_window_role_property_id = "_q_xcb_wm_window_role";
QXcbWindow::QXcbWindow(QWindow *window)
: QPlatformWindow(window)
- , m_window(0)
- , m_cmap(0)
- , m_syncCounter(0)
- , m_gravity(XCB_GRAVITY_STATIC)
- , m_mapped(false)
- , m_transparent(false)
- , m_usingSyncProtocol(false)
- , m_deferredActivation(false)
- , m_embedded(false)
- , m_alertState(false)
- , m_netWmUserTimeWindow(XCB_NONE)
- , m_dirtyFrameMargins(false)
- , m_lastWindowStateEvent(-1)
- , m_syncState(NoSyncNeeded)
- , m_pendingSyncRequest(0)
- , m_currentBitmapCursor(XCB_CURSOR_NONE)
{
setConnection(xcbScreen()->connection());
}
@@ -357,11 +341,6 @@ enum {
void QXcbWindow::create()
{
- if (window()->type() == Qt::ForeignWindow) {
- m_window = window()->winId();
- return;
- }
-
destroy();
m_windowState = Qt::WindowNoState;
@@ -413,7 +392,7 @@ void QXcbWindow::create()
xcb_window_t xcb_parent_id = platformScreen->root();
if (parent()) {
xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
- m_embedded = parent()->window()->type() == Qt::ForeignWindow;
+ m_embedded = parent()->isForeignWindow();
QSurfaceFormat parentFormat = parent()->window()->requestedFormat();
if (window()->surfaceType() != QSurface::OpenGLSurface && parentFormat.hasAlpha()) {
@@ -606,9 +585,10 @@ QXcbWindow::~QXcbWindow()
if (m_currentBitmapCursor != XCB_CURSOR_NONE) {
xcb_free_cursor(xcb_connection(), m_currentBitmapCursor);
}
- if (window()->type() != Qt::ForeignWindow)
- destroy();
- else {
+
+ destroy();
+
+ if (isForeignWindow()) {
if (connection()->mouseGrabber() == this)
connection()->setMouseGrabber(Q_NULLPTR);
if (connection()->mousePressWindow() == this)
@@ -1524,7 +1504,7 @@ void QXcbWindow::setParent(const QPlatformWindow *parent)
if (parent) {
const QXcbWindow *qXcbParent = static_cast<const QXcbWindow *>(parent);
xcb_parent_id = qXcbParent->xcb_window();
- m_embedded = qXcbParent->window()->type() == Qt::ForeignWindow;
+ m_embedded = qXcbParent->isForeignWindow();
} else {
xcb_parent_id = xcbScreen()->root();
m_embedded = false;
@@ -2157,12 +2137,9 @@ bool QXcbWindow::isExposed() const
return m_mapped;
}
-bool QXcbWindow::isEmbedded(const QPlatformWindow *parentWindow) const
+bool QXcbWindow::isEmbedded() const
{
- if (!m_embedded)
- return false;
-
- return parentWindow ? (parentWindow == parent()) : true;
+ return m_embedded;
}
QPoint QXcbWindow::mapToGlobal(const QPoint &pos) const
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index d100120d46..b4d947e700 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -87,7 +87,7 @@ public:
void setParent(const QPlatformWindow *window) override;
bool isExposed() const override;
- bool isEmbedded(const QPlatformWindow *parentWindow = 0) const override;
+ bool isEmbedded() const override;
QPoint mapToGlobal(const QPoint &pos) const override;
QPoint mapFromGlobal(const QPoint &pos) const override;
@@ -233,48 +233,48 @@ protected:
void handleLeaveNotifyEvent(int root_x, int root_y,
quint8 mode, quint8 detail, xcb_timestamp_t timestamp);
- xcb_window_t m_window;
- xcb_colormap_t m_cmap;
+ xcb_window_t m_window = 0;
+ xcb_colormap_t m_cmap = 0;
- uint m_depth;
- QImage::Format m_imageFormat;
- bool m_imageRgbSwap;
+ uint m_depth = 0;
+ QImage::Format m_imageFormat = QImage::Format_ARGB32_Premultiplied;
+ bool m_imageRgbSwap = false;
xcb_sync_int64_t m_syncValue;
- xcb_sync_counter_t m_syncCounter;
+ xcb_sync_counter_t m_syncCounter = 0;
- Qt::WindowState m_windowState;
+ Qt::WindowState m_windowState = Qt::WindowNoState;
- xcb_gravity_t m_gravity;
+ xcb_gravity_t m_gravity = XCB_GRAVITY_STATIC;
- bool m_mapped;
- bool m_transparent;
- bool m_usingSyncProtocol;
- bool m_deferredActivation;
- bool m_embedded;
- bool m_alertState;
- xcb_window_t m_netWmUserTimeWindow;
+ bool m_mapped = false;
+ bool m_transparent = false;
+ bool m_usingSyncProtocol = false;
+ bool m_deferredActivation = false;
+ bool m_embedded = false;
+ bool m_alertState = false;
+ xcb_window_t m_netWmUserTimeWindow = XCB_NONE;
QSurfaceFormat m_format;
- mutable bool m_dirtyFrameMargins;
+ mutable bool m_dirtyFrameMargins = false;
mutable QMargins m_frameMargins;
QRegion m_exposeRegion;
QSize m_oldWindowSize;
- xcb_visualid_t m_visualId;
- int m_lastWindowStateEvent;
+ xcb_visualid_t m_visualId = 0;
+ int m_lastWindowStateEvent = -1;
enum SyncState {
NoSyncNeeded,
SyncReceived,
SyncAndConfigureReceived
};
- SyncState m_syncState;
+ SyncState m_syncState = NoSyncNeeded;
- QXcbSyncWindowRequest *m_pendingSyncRequest;
- xcb_cursor_t m_currentBitmapCursor;
+ QXcbSyncWindowRequest *m_pendingSyncRequest = nullptr;
+ xcb_cursor_t m_currentBitmapCursor = XCB_CURSOR_NONE;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
index 52757587b4..38c2d251b4 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3menu.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platformthemes/gtk3/qgtk3menu.h b/src/plugins/platformthemes/gtk3/qgtk3menu.h
index 21e6178ec4..b43f363fa4 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3menu.h
+++ b/src/plugins/platformthemes/gtk3/qgtk3menu.h
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
index 6df631bff3..7e64906476 100644
--- a/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
+++ b/src/plugins/platformthemes/gtk3/qgtk3theme.cpp
@@ -51,11 +51,18 @@ QT_BEGIN_NAMESPACE
const char *QGtk3Theme::name = "gtk3";
-static QString gtkSetting(const gchar *propertyName)
+template <typename T>
+static T gtkSetting(const gchar *propertyName)
{
GtkSettings *settings = gtk_settings_get_default();
- gchararray value;
+ T value;
g_object_get(settings, propertyName, &value, NULL);
+ return value;
+}
+
+static QString gtkSetting(const gchar *propertyName)
+{
+ gchararray value = gtkSetting<gchararray>(propertyName);
QString str = QString::fromUtf8(value);
g_free(value);
return str;
@@ -98,6 +105,18 @@ QGtk3Theme::QGtk3Theme()
QVariant QGtk3Theme::themeHint(QPlatformTheme::ThemeHint hint) const
{
switch (hint) {
+ case QPlatformTheme::CursorFlashTime:
+ return QVariant(gtkSetting<gint>("gtk-cursor-blink-time"));
+ case QPlatformTheme::MouseDoubleClickDistance:
+ return QVariant(gtkSetting<gint>("gtk-double-click-distance"));
+ case QPlatformTheme::MouseDoubleClickInterval:
+ return QVariant(gtkSetting<gint>("gtk-double-click-time"));
+ case QPlatformTheme::MousePressAndHoldInterval:
+ return QVariant(gtkSetting<guint>("gtk-long-press-time"));
+ case QPlatformTheme::PasswordMaskDelay:
+ return QVariant(gtkSetting<guint>("gtk-entry-password-hint-timeout"));
+ case QPlatformTheme::StartDragDistance:
+ return QVariant(gtkSetting<gint>("gtk-dnd-drag-threshold"));
case QPlatformTheme::SystemIconThemeName:
return QVariant(gtkSetting("gtk-icon-theme-name"));
case QPlatformTheme::SystemIconFallbackThemeName:
diff --git a/src/plugins/sqldrivers/psql/qsql_psql.cpp b/src/plugins/sqldrivers/psql/qsql_psql.cpp
index 968b71a27d..e0f9222902 100644
--- a/src/plugins/sqldrivers/psql/qsql_psql.cpp
+++ b/src/plugins/sqldrivers/psql/qsql_psql.cpp
@@ -670,7 +670,7 @@ bool QPSQLResult::exec()
if (params.isEmpty())
stmt = QString::fromLatin1("EXECUTE %1").arg(d->preparedStmtId);
else
- stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId).arg(params);
+ stmt = QString::fromLatin1("EXECUTE %1 (%2)").arg(d->preparedStmtId, params);
d->result = d->drv_d_func()->exec(stmt);
diff --git a/src/plugins/sqldrivers/tds/qsql_tds.cpp b/src/plugins/sqldrivers/tds/qsql_tds.cpp
index 940fd05c74..6ebd09a572 100644
--- a/src/plugins/sqldrivers/tds/qsql_tds.cpp
+++ b/src/plugins/sqldrivers/tds/qsql_tds.cpp
@@ -259,10 +259,9 @@ static int CS_PUBLIC qTdsErrHandler(DBPROCESS* dbproc,
return INT_CANCEL;
}
-
- QString errMsg = QString::fromLatin1("%1 %2\n").arg(QLatin1String(dberrstr)).arg(
- QLatin1String(oserrstr));
- errMsg += p->getErrorMsgs();
+ const QString errMsg = QLatin1String(dberrstr) + QLatin1Char(' ')
+ + QLatin1String(oserrstr) + QLatin1Char('\n')
+ + p->getErrorMsgs();
p->lastError = qMakeError(errMsg, QSqlError::UnknownError, dberr);
p->clearErrorMsgs();