summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/protocol/HPND_LICENSE.txt20
-rw-r--r--src/3rdparty/protocol/MIT_LICENSE.txt18
-rw-r--r--src/3rdparty/protocol/ivi-application.xml35
-rw-r--r--src/3rdparty/protocol/qt_attribution.json70
-rw-r--r--src/3rdparty/protocol/xdg-shell.xml80
-rw-r--r--src/client/client.pro15
-rw-r--r--src/client/global/qwaylandclientextension.cpp39
-rw-r--r--src/client/global/qwaylandclientextension.h3
-rw-r--r--src/client/global/qwaylandclientextension_p.h10
-rw-r--r--src/client/qwaylanddatadevice.cpp3
-rw-r--r--src/client/qwaylanddatadevice_p.h3
-rw-r--r--src/client/qwaylanddisplay.cpp3
-rw-r--r--src/client/qwaylandintegration.cpp75
-rw-r--r--src/client/qwaylandintegration_p.h22
-rw-r--r--src/client/qwaylandnativeinterface.cpp21
-rw-r--r--src/client/qwaylandshm.cpp6
-rw-r--r--src/client/qwaylandwindow.cpp27
-rw-r--r--src/client/qwaylandwindow_p.h4
-rw-r--r--src/client/qwaylandwindowmanagerintegration_p.h4
-rw-r--r--src/client/qwaylandwlshellsurface_p.h4
-rw-r--r--src/client/qwaylandxdgpopup_p.h4
-rw-r--r--src/client/qwaylandxdgshell_p.h2
-rw-r--r--src/client/qwaylandxdgsurface_p.h4
-rw-r--r--src/compositor/compositor.pro4
-rw-r--r--src/compositor/compositor_api/compositor_api.pri19
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.cpp92
-rw-r--r--src/compositor/compositor_api/qwaylandbufferref.h24
-rw-r--r--src/compositor/compositor_api/qwaylandclient.cpp22
-rw-r--r--src/compositor/compositor_api/qwaylandclient.h3
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.cpp164
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor.h33
-rw-r--r--src/compositor/compositor_api/qwaylandcompositor_p.h33
-rw-r--r--src/compositor/compositor_api/qwaylanddestroylistener_p.h2
-rw-r--r--src/compositor/compositor_api/qwaylanddrag.cpp29
-rw-r--r--src/compositor/compositor_api/qwaylanddrag.h15
-rw-r--r--src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp14
-rw-r--r--src/compositor/compositor_api/qwaylandinputmethodcontrol.h2
-rw-r--r--src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h4
-rw-r--r--src/compositor/compositor_api/qwaylandkeyboard.cpp83
-rw-r--r--src/compositor/compositor_api/qwaylandkeyboard.h31
-rw-r--r--src/compositor/compositor_api/qwaylandkeyboard_p.h9
-rw-r--r--src/compositor/compositor_api/qwaylandkeymap.cpp129
-rw-r--r--src/compositor/compositor_api/qwaylandkeymap.h81
-rw-r--r--src/compositor/compositor_api/qwaylandkeymap_p.h72
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.cpp279
-rw-r--r--src/compositor/compositor_api/qwaylandoutput.h28
-rw-r--r--src/compositor/compositor_api/qwaylandoutput_p.h16
-rw-r--r--src/compositor/compositor_api/qwaylandoutputmode.cpp139
-rw-r--r--src/compositor/compositor_api/qwaylandoutputmode.h72
-rw-r--r--src/compositor/compositor_api/qwaylandoutputmode_p.h66
-rw-r--r--src/compositor/compositor_api/qwaylandpointer.cpp38
-rw-r--r--src/compositor/compositor_api/qwaylandpointer.h12
-rw-r--r--src/compositor/compositor_api/qwaylandpointer_p.h6
-rw-r--r--src/compositor/compositor_api/qwaylandquickcompositor.cpp18
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp280
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.h25
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem_p.h16
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.cpp39
-rw-r--r--src/compositor/compositor_api/qwaylandquickoutput.h2
-rw-r--r--src/compositor/compositor_api/qwaylandseat.cpp (renamed from src/compositor/compositor_api/qwaylandinput.cpp)273
-rw-r--r--src/compositor/compositor_api/qwaylandseat.h (renamed from src/compositor/compositor_api/qwaylandinput.h)41
-rw-r--r--src/compositor/compositor_api/qwaylandseat_p.h (renamed from src/compositor/compositor_api/qwaylandinput_p.h)26
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.cpp155
-rw-r--r--src/compositor/compositor_api/qwaylandsurface.h12
-rw-r--r--src/compositor/compositor_api/qwaylandsurface_p.h12
-rw-r--r--src/compositor/compositor_api/qwaylandsurfacegrabber.cpp5
-rw-r--r--src/compositor/compositor_api/qwaylandtouch.cpp149
-rw-r--r--src/compositor/compositor_api/qwaylandtouch.h20
-rw-r--r--src/compositor/compositor_api/qwaylandtouch_p.h29
-rw-r--r--src/compositor/compositor_api/qwaylandview.cpp114
-rw-r--r--src/compositor/compositor_api/qwaylandview.h19
-rw-r--r--src/compositor/compositor_api/qwaylandview_p.h10
-rw-r--r--src/compositor/doc/src/qtwaylandcompositor-overview.qdoc14
-rw-r--r--src/compositor/extensions/extensions.pri32
-rw-r--r--src/compositor/extensions/qwaylandiviapplication.cpp166
-rw-r--r--src/compositor/extensions/qwaylandiviapplication.h71
-rw-r--r--src/compositor/extensions/qwaylandiviapplication_p.h79
-rw-r--r--src/compositor/extensions/qwaylandivisurface.cpp226
-rw-r--r--src/compositor/extensions/qwaylandivisurface.h89
-rw-r--r--src/compositor/extensions/qwaylandivisurface_p.h84
-rw-r--r--src/compositor/extensions/qwaylandivisurfaceintegration.cpp64
-rw-r--r--src/compositor/extensions/qwaylandivisurfaceintegration_p.h77
-rw-r--r--src/compositor/extensions/qwaylandqtwindowmanager.cpp (renamed from src/compositor/extensions/qwaylandwindowmanagerextension.cpp)118
-rw-r--r--src/compositor/extensions/qwaylandqtwindowmanager.h (renamed from src/compositor/extensions/qwaylandwindowmanagerextension.h)21
-rw-r--r--src/compositor/extensions/qwaylandqtwindowmanager_p.h (renamed from src/compositor/extensions/qwaylandwindowmanagerextension_p.h)25
-rw-r--r--src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp4
-rw-r--r--src/compositor/extensions/qwaylandquickshellsurfaceitem.h4
-rw-r--r--src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h4
-rw-r--r--src/compositor/extensions/qwaylandshell.cpp100
-rw-r--r--src/compositor/extensions/qwaylandshell.h107
-rw-r--r--src/compositor/extensions/qwaylandshell_p.h67
-rw-r--r--src/compositor/extensions/qwaylandshellsurface.h7
-rw-r--r--src/compositor/extensions/qwaylandtextinput.cpp2
-rw-r--r--src/compositor/extensions/qwaylandtextinputmanager.cpp10
-rw-r--r--src/compositor/extensions/qwaylandtextinputmanager_p.h2
-rw-r--r--src/compositor/extensions/qwaylandwlshell.cpp155
-rw-r--r--src/compositor/extensions/qwaylandwlshell.h40
-rw-r--r--src/compositor/extensions/qwaylandwlshell_p.h19
-rw-r--r--src/compositor/extensions/qwaylandwlshellintegration.cpp157
-rw-r--r--src/compositor/extensions/qwaylandwlshellintegration_p.h31
-rw-r--r--src/compositor/extensions/qwaylandxdgshell.cpp1114
-rw-r--r--src/compositor/extensions/qwaylandxdgshellintegration.cpp172
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5.cpp1204
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5.h (renamed from src/compositor/extensions/qwaylandxdgshell.h)102
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5_p.h (renamed from src/compositor/extensions/qwaylandxdgshell_p.h)70
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5integration.cpp215
-rw-r--r--src/compositor/extensions/qwaylandxdgshellv5integration_p.h (renamed from src/compositor/extensions/qwaylandxdgshellintegration_p.h)38
-rw-r--r--src/compositor/extensions/qwlqtkey_p.h4
-rw-r--r--src/compositor/extensions/qwlqttouch.cpp4
-rw-r--r--src/compositor/extensions/qwlqttouch_p.h5
-rw-r--r--src/compositor/global/qwaylandcompositorextension.cpp6
-rw-r--r--src/compositor/global/qwaylandcompositorextension.h1
-rw-r--r--src/compositor/global/qwaylandcompositorextension_p.h3
-rw-r--r--src/compositor/global/qwaylandquickextension.h1
-rw-r--r--src/compositor/hardware_integration/hardware_integration.pri6
-rw-r--r--src/compositor/hardware_integration/qwlclientbufferintegration_p.h16
-rw-r--r--src/compositor/wayland_wrapper/qwlbuffermanager.cpp111
-rw-r--r--src/compositor/wayland_wrapper/qwlbuffermanager_p.h77
-rw-r--r--src/compositor/wayland_wrapper/qwlclientbuffer.cpp189
-rw-r--r--src/compositor/wayland_wrapper/qwlclientbuffer_p.h (renamed from src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h)86
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevice.cpp25
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevice_p.h10
-rw-r--r--src/compositor/wayland_wrapper/qwldatadevicemanager.cpp10
-rw-r--r--src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp251
-rw-r--r--src/compositor/wayland_wrapper/wayland_wrapper.pri6
-rw-r--r--src/extensions/qt-windowmanager.xml (renamed from src/extensions/windowmanager.xml)2
-rw-r--r--src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp2
-rw-r--r--src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp2
-rw-r--r--src/hardwareintegration/client/wayland-egl/wayland-egl.pri2
-rw-r--r--src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp2
-rw-r--r--src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp2
-rw-r--r--src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h2
-rw-r--r--src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp4
-rw-r--r--src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri2
-rw-r--r--src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h2
-rw-r--r--src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri2
-rw-r--r--src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp59
-rw-r--r--src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h22
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri1
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp360
-rw-r--r--src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h35
-rw-r--r--src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp50
-rw-r--r--src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h28
-rw-r--r--src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp58
-rw-r--r--src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h29
-rw-r--r--src/imports/compositor/WaylandCursorItem.qml25
-rw-r--r--src/imports/compositor/plugins.qmltypes345
-rw-r--r--src/imports/compositor/qwaylandmousetracker.cpp16
-rw-r--r--src/imports/compositor/qwaylandmousetracker_p.h8
-rw-r--r--src/imports/compositor/qwaylandquickcompositorplugin.cpp34
-rw-r--r--src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro2
-rw-r--r--src/shared/qwaylandsharedmemoryformathelper_p.h (renamed from src/shared/qwaylandshmformathelper_p.h)14
155 files changed, 6374 insertions, 3481 deletions
diff --git a/src/3rdparty/protocol/HPND_LICENSE.txt b/src/3rdparty/protocol/HPND_LICENSE.txt
new file mode 100644
index 000000000..e7a4915da
--- /dev/null
+++ b/src/3rdparty/protocol/HPND_LICENSE.txt
@@ -0,0 +1,20 @@
+Permission to use, copy, modify, distribute, and sell this
+software and its documentation for any purpose is hereby granted
+without fee, provided that the above copyright notice appear in
+all copies and that both that copyright notice and this permission
+notice appear in supporting documentation, and that the name of
+the copyright holders not be used in advertising or publicity
+pertaining to distribution of the software without specific,
+written prior permission. The copyright holders make no
+representations about the suitability of this software for any
+purpose. It is provided "as is" without express or implied
+warranty.
+
+THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/src/3rdparty/protocol/MIT_LICENSE.txt b/src/3rdparty/protocol/MIT_LICENSE.txt
new file mode 100644
index 000000000..edc2e5fb5
--- /dev/null
+++ b/src/3rdparty/protocol/MIT_LICENSE.txt
@@ -0,0 +1,18 @@
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/src/3rdparty/protocol/ivi-application.xml b/src/3rdparty/protocol/ivi-application.xml
index 61ec7d273..8f2422688 100644
--- a/src/3rdparty/protocol/ivi-application.xml
+++ b/src/3rdparty/protocol/ivi-application.xml
@@ -5,23 +5,24 @@
Copyright (C) 2013 DENSO CORPORATION
Copyright (c) 2013 BMW Car IT GmbH
- Permission to use, copy, modify, distribute, and sell this software and
- its documentation for any purpose is hereby granted without fee, provided
- that the above copyright notice appear in all copies and that both that
- copyright notice and this permission notice appear in supporting
- documentation, and that the name of the copyright holders not be used in
- advertising or publicity pertaining to distribution of the software
- without specific, written prior permission. The copyright holders make
- no representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied warranty.
-
- THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="ivi_surface" version="1">
diff --git a/src/3rdparty/protocol/qt_attribution.json b/src/3rdparty/protocol/qt_attribution.json
new file mode 100644
index 000000000..327c408b9
--- /dev/null
+++ b/src/3rdparty/protocol/qt_attribution.json
@@ -0,0 +1,70 @@
+[
+ {
+ "Id": "wayland-protocol",
+ "Name": "Wayland Protocol",
+ "QDocModule": "qtwaylandcompositor",
+ "QtUsage": "Used in the Qt Wayland Compositor, and the Qt Wayland platform plugin.",
+
+ "Description": "Wayland is a protocol for a compositor to talk to its clients.",
+ "Homepage": "https://wayland.freedesktop.org",
+ "Version": "1.6.1",
+ "DownloadLocation": "https://cgit.freedesktop.org/wayland/wayland/tag/?id=1.6.1",
+ "LicenseId": "HPND",
+ "License": "HPND License",
+ "LicenseFile": "HPND_LICENSE.txt",
+ "Copyright": "Copyright © 2008-2011 Kristian Høgsberg
+ Copyright © 2010-2011 Intel Corporation
+ Copyright © 2012-2013 Collabora, Ltd."
+ },
+
+ {
+ "Id": "wayland-ivi-extension-protocol",
+ "Name": "Wayland IVI Extension Protocol",
+ "QDocModule": "qtwaylandcompositor",
+ "QtUsage": "Used in the Qt Wayland Compositor, and the Qt Wayland platform plugin.",
+
+ "Description": "\"Wayland IVI Extension\" is forked from IVI Layer Management to define a common set of APIs by wayland style protocol and provide reference implementation which can be loaded on Weston.",
+ "Homepage": "http://projects.genivi.org/wayland-ivi-extension",
+ "Version": "1.9.1",
+ "DownloadLocation": "http://git.projects.genivi.org/?p=wayland-ivi-extension.git;a=commit;h=44598504503eea5ac7f94c88477a5a78bda01f30",
+ "LicenseId": "MIT",
+ "License": "MIT License",
+ "LicenseFile": "MIT_LICENSE.txt",
+ "Copyright": "Copyright (C) 2013 DENSO CORPORATION
+Copyright (c) 2013 BMW Car IT GmbH"
+ },
+
+ {
+ "Id": "wayland-xdg-shell-protocol",
+ "Name": "Wayland XDG Shell Protocol",
+ "QDocModule": "qtwaylandcompositor",
+ "QtUsage": "Used in the Qt Wayland Compositor, and the Qt Wayland platform plugin.",
+
+ "Description": "The XDG-Shell protocol is an extended way to manage surfaces under Wayland compositors.",
+ "Homepage": "https://wayland.freedesktop.org",
+ "Version": "1.9.0",
+ "DownloadLocation": "https://cgit.freedesktop.org/wayland/weston/tag/?id=1.9.0",
+ "LicenseId": "MIT",
+ "License": "MIT License",
+ "LicenseFile": "MIT_LICENSE.txt",
+ "Copyright": "Copyright © 2008-2013 Kristian Høgsberg
+Copyright © 2013 Rafael Antognolli
+Copyright © 2013 Jasper St. Pierre
+Copyright © 2010-2013 Intel Corporation"
+ },
+
+ {
+ "Id": "wayland-txt-input-unstable",
+ "Name": "Wayland Text Input Protocol",
+ "QDocModule": "qtwaylandcompositor",
+ "QtUsage": "Used in the Qt Wayland Compositor, and the Qt Wayland platform plugin.",
+
+ "Description": "Adds support for text input and input methods to applications.",
+ "Homepage": "https://wayland.freedesktop.org",
+ "LicenseId": "HPND",
+ "License": "HPND License",
+ "LicenseFile": "HPND_LICENSE.txt",
+ "Copyright": "Copyright © 2012, 2013 Intel Corporation
+Copyright © 2015, 2016 Jan Arne Petersen"
+ }
+]
diff --git a/src/3rdparty/protocol/xdg-shell.xml b/src/3rdparty/protocol/xdg-shell.xml
index 44a3a12cb..f98e760d4 100644
--- a/src/3rdparty/protocol/xdg-shell.xml
+++ b/src/3rdparty/protocol/xdg-shell.xml
@@ -7,26 +7,24 @@
Copyright © 2013 Jasper St. Pierre
Copyright © 2010-2013 Intel Corporation
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that copyright notice and this permission
- notice appear in supporting documentation, and that the name of
- the copyright holders not be used in advertising or publicity
- pertaining to distribution of the software without specific,
- written prior permission. The copyright holders make no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied
- warranty.
-
- THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- THIS SOFTWARE.
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ to deal in the Software without restriction, including without limitation
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ and/or sell copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice (including the next
+ paragraph) shall be included in all copies or substantial portions of the
+ Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="xdg_shell" version="1">
@@ -248,10 +246,19 @@
Start an interactive, user-driven move of the surface.
This request must be used in response to some sort of user action
- like a button press, key press, or touch down event.
+ like a button press, key press, or touch down event. The passed
+ serial is used to determine the type of interactive move (touch,
+ pointer, etc).
The server may ignore move requests depending on the state of
- the surface (e.g. fullscreen or maximized).
+ the surface (e.g. fullscreen or maximized), or if the passed serial
+ is no longer valid.
+
+ If triggered, the surface will lose the focus of the device
+ (wl_pointer, wl_touch, etc) used for the move. It is up to the
+ compositor to visually indicate that the move is taking place, such as
+ updating a pointer cursor, during the move. There is no guarantee
+ that the device focus will return when the move is completed.
</description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/>
@@ -260,9 +267,7 @@
<enum name="resize_edge">
<description summary="edge values for resizing">
These values are used to indicate which edge of a surface
- is being dragged in a resize operation. The server may
- use this information to adapt its behavior, e.g. choose
- an appropriate cursor image.
+ is being dragged in a resize operation.
</description>
<entry name="none" value="0"/>
<entry name="top" value="1"/>
@@ -280,10 +285,33 @@
Start a user-driven, interactive resize of the surface.
This request must be used in response to some sort of user action
- like a button press, key press, or touch down event.
+ like a button press, key press, or touch down event. The passed
+ serial is used to determine the type of interactive resize (touch,
+ pointer, etc).
The server may ignore resize requests depending on the state of
the surface (e.g. fullscreen or maximized).
+
+ If triggered, the client will receive configure events with the
+ "resize" state enum value and the expected sizes. See the "resize"
+ enum value for more details about what is required. The client
+ must also acknowledge configure events using "ack_configure". After
+ the resize is completed, the client will receive another "configure"
+ event without the resize state.
+
+ If triggered, the surface also will lose the focus of the device
+ (wl_pointer, wl_touch, etc) used for the resize. It is up to the
+ compositor to visually indicate that the resize is taking place,
+ such as updating a pointer cursor, during the resize. There is no
+ guarantee that the device focus will return when the resize is
+ completed.
+
+ The edges parameter specifies how the surface should be resized,
+ and is one of the values of the resize_edge enum. The compositor
+ may use this information to update the surface position for
+ example when dragging the top left corner. The compositor may also
+ use this information to adapt its behavior, e.g. choose an
+ appropriate cursor image.
</description>
<arg name="seat" type="object" interface="wl_seat" summary="the wl_seat of the user event"/>
<arg name="serial" type="uint" summary="the serial of the user event"/>
diff --git a/src/client/client.pro b/src/client/client.pro
index 8be00c7ac..34955dfbb 100644
--- a/src/client/client.pro
+++ b/src/client/client.pro
@@ -2,15 +2,20 @@ TARGET = QtWaylandClient
MODULE = waylandclient
QT += core-private gui-private
-QT_FOR_PRIVATE += platformsupport-private
+QT_FOR_PRIVATE += service_support-private
+QT_PRIVATE += fontdatabase_support-private eventdispatcher_support-private theme_support-private
# We have a bunch of C code with casts, so we can't have this option
QMAKE_CXXFLAGS_WARN_ON -= -Wcast-qual
+# Prevent gold linker from crashing.
+# This started happening when QtPlatformSupport was modularized.
+use_gold_linker: CONFIG += no_linker_version_script
+
CONFIG -= precompile_header
-CONFIG += link_pkgconfig qpa/genericunixfontdatabase wayland-scanner
+CONFIG += link_pkgconfig wayland-scanner
-!equals(QT_WAYLAND_GL_CONFIG, nogl) {
+contains(QT_CONFIG, opengl) {
DEFINES += QT_WAYLAND_GL_SUPPORT
}
@@ -38,7 +43,7 @@ WAYLANDCLIENTSOURCES += \
../extensions/surface-extension.xml \
../extensions/touch-extension.xml \
../extensions/qtkey-extension.xml \
- ../extensions/windowmanager.xml \
+ ../extensions/qt-windowmanager.xml \
../3rdparty/protocol/text-input-unstable-v2.xml \
../3rdparty/protocol/xdg-shell.xml \
@@ -116,7 +121,7 @@ HEADERS += qwaylandintegration_p.h \
../shared/qwaylandinputmethodeventbuilder_p.h \
../shared/qwaylandmimehelper_p.h \
../shared/qwaylandxkb_p.h \
- ../shared/qwaylandshmformathelper_p.h
+ ../shared/qwaylandsharedmemoryformathelper_p.h
include(hardwareintegration/hardwareintegration.pri)
include(shellintegration/shellintegration.pri)
diff --git a/src/client/global/qwaylandclientextension.cpp b/src/client/global/qwaylandclientextension.cpp
index 04aca8c2e..8e46197f1 100644
--- a/src/client/global/qwaylandclientextension.cpp
+++ b/src/client/global/qwaylandclientextension.cpp
@@ -40,6 +40,8 @@
#include <QtWaylandClient/private/qwaylandintegration_p.h>
#include <QtGui/QGuiApplication>
#include <QtGui/qpa/qplatformnativeinterface.h>
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
@@ -51,35 +53,40 @@ QWaylandClientExtensionPrivate::QWaylandClientExtensionPrivate()
{
// Keep the possibility to use a custom waylandIntegration as a plugin,
// but also add the possibility to run it as a QML component.
- struct ::wl_display *waylandDisplay = NULL;
- if (QGuiApplication::platformNativeInterface()) {
- waylandDisplay = static_cast<struct ::wl_display*>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("wl_display"));
- } else {
+ waylandIntegration = static_cast<QtWaylandClient::QWaylandIntegration *>(QGuiApplicationPrivate::platformIntegration());
+ if (!waylandIntegration)
waylandIntegration = new QtWaylandClient::QWaylandIntegration();
- waylandDisplay = waylandIntegration->display()->wl_display();
- }
- Q_ASSERT(waylandDisplay);
- struct ::wl_registry *registry = wl_display_get_registry(waylandDisplay);
- QtWayland::wl_registry::init(registry);
+ if (!waylandIntegration->nativeInterface()->nativeResourceForIntegration("wl_display"))
+ qWarning() << "This application requires a Wayland platform plugin";
}
-void QWaylandClientExtensionPrivate::registry_global(uint32_t id, const QString &interfaceName, uint32_t ver)
+void QWaylandClientExtensionPrivate::handleRegistryGlobal(void *data, ::wl_registry *registry, uint32_t id,
+ const QString &interface, uint32_t version)
{
- Q_Q(QWaylandClientExtension);
- if (interfaceName == QLatin1String(q->extensionInterface()->name)) {
- struct ::wl_registry *registry = static_cast<struct ::wl_registry *>(QtWayland::wl_registry::object());
- q->bind(registry, id, ver);
- active = true;
- emit q->activeChanged();
+ QWaylandClientExtension *extension = static_cast<QWaylandClientExtension *>(data);
+ if (interface == QLatin1String(extension->extensionInterface()->name) && !extension->d_func()->active) {
+ extension->bind(registry, id, version);
+ extension->d_func()->active = true;
+ emit extension->activeChanged();
}
}
+void QWaylandClientExtension::addRegistryListener()
+{
+ Q_D(QWaylandClientExtension);
+ d->waylandIntegration->display()->addRegistryListener(&QWaylandClientExtensionPrivate::handleRegistryGlobal, this);
+}
+
QWaylandClientExtension::QWaylandClientExtension(const int ver)
: QObject(*new QWaylandClientExtensionPrivate())
{
Q_D(QWaylandClientExtension);
d->version = ver;
+
+ // The registry listener uses virtual functions and we don't want it to be called from
+ // the constructor.
+ QMetaObject::invokeMethod(this, "addRegistryListener", Qt::QueuedConnection);
}
QtWaylandClient::QWaylandIntegration *QWaylandClientExtension::integration() const
diff --git a/src/client/global/qwaylandclientextension.h b/src/client/global/qwaylandclientextension.h
index afb3f868f..d1610c271 100644
--- a/src/client/global/qwaylandclientextension.h
+++ b/src/client/global/qwaylandclientextension.h
@@ -71,6 +71,9 @@ protected:
Q_SIGNALS:
void versionChanged();
void activeChanged();
+
+private Q_SLOTS:
+ void addRegistryListener();
};
template <typename T>
diff --git a/src/client/global/qwaylandclientextension_p.h b/src/client/global/qwaylandclientextension_p.h
index 70cf36c3d..7c88161fa 100644
--- a/src/client/global/qwaylandclientextension_p.h
+++ b/src/client/global/qwaylandclientextension_p.h
@@ -48,25 +48,23 @@
// We mean it.
//
-#include "qwaylandclientextension.h"
#include <QtCore/private/qobject_p.h>
+#include <QtWaylandClient/QWaylandClientExtension>
#include <QtWaylandClient/private/qwaylandintegration_p.h>
-#include <QtWaylandClient/private/qwayland-wayland.h>
QT_BEGIN_NAMESPACE
-class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionPrivate : public QObjectPrivate, public QtWayland::wl_registry
+class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QWaylandClientExtension)
public:
QWaylandClientExtensionPrivate();
+ static void handleRegistryGlobal(void *data, ::wl_registry *registry, uint32_t id,
+ const QString &interface, uint32_t version);
QtWaylandClient::QWaylandIntegration *waylandIntegration;
int version;
bool active;
-
-protected:
- void registry_global(uint32_t id, const QString &interfaceName, uint32_t version) Q_DECL_OVERRIDE;
};
class Q_WAYLAND_CLIENT_EXPORT QWaylandClientExtensionTemplatePrivate : public QWaylandClientExtensionPrivate
diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
index 7deb32609..f1a1ba6f0 100644
--- a/src/client/qwaylanddatadevice.cpp
+++ b/src/client/qwaylanddatadevice.cpp
@@ -185,7 +185,8 @@ void QWaylandDataDevice::data_device_enter(uint32_t serial, wl_surface *surface,
void QWaylandDataDevice::data_device_leave()
{
- QWindowSystemInterface::handleDrag(m_dragWindow, 0, QPoint(), Qt::IgnoreAction);
+ if (m_dragWindow)
+ QWindowSystemInterface::handleDrag(m_dragWindow, 0, QPoint(), Qt::IgnoreAction);
QDrag *drag = static_cast<QWaylandDrag *>(QGuiApplicationPrivate::platformIntegration()->drag())->currentDrag();
if (!drag) {
diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h
index df0f297bc..318636de7 100644
--- a/src/client/qwaylanddatadevice_p.h
+++ b/src/client/qwaylanddatadevice_p.h
@@ -53,6 +53,7 @@
//
#include <QObject>
+#include <QPointer>
#include <QPoint>
#include <QtWaylandClient/private/qwayland-wayland.h>
@@ -108,7 +109,7 @@ private:
QWaylandDisplay *m_display;
QWaylandInputDevice *m_inputDevice;
uint32_t m_enterSerial;
- QWindow *m_dragWindow;
+ QPointer<QWindow> m_dragWindow;
QPoint m_dragPoint;
QScopedPointer<QWaylandDataOffer> m_dragOffer;
QScopedPointer<QWaylandDataOffer> m_selectionOffer;
diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
index b83bd39e2..5f2c4e2ea 100644
--- a/src/client/qwaylanddisplay.cpp
+++ b/src/client/qwaylanddisplay.cpp
@@ -84,7 +84,8 @@ struct wl_surface *QWaylandDisplay::createSurface(void *handle)
QWaylandShellSurface *QWaylandDisplay::createShellSurface(QWaylandWindow *window)
{
- Q_ASSERT(mWaylandIntegration->shellIntegration());
+ if (!mWaylandIntegration->shellIntegration())
+ return 0;
return mWaylandIntegration->shellIntegration()->createShellSurface(window);
}
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index 147e45b0c..32b4b8953 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -50,9 +50,9 @@
#include "qwaylandwindowmanagerintegration_p.h"
#include "qwaylandscreen_p.h"
-#include "QtPlatformSupport/private/qgenericunixfontdatabase_p.h"
-#include <QtPlatformSupport/private/qgenericunixeventdispatcher_p.h>
-#include <QtPlatformSupport/private/qgenericunixthemes_p.h>
+#include <QtFontDatabaseSupport/private/qgenericunixfontdatabase_p.h>
+#include <QtEventDispatcherSupport/private/qgenericunixeventdispatcher_p.h>
+#include <QtThemeSupport/private/qgenericunixthemes_p.h>
#include <QtGui/private/qguiapplication_p.h>
@@ -119,7 +119,6 @@ public:
QWaylandIntegration::QWaylandIntegration()
: mClientBufferIntegration(0)
- , mShellIntegration(Q_NULLPTR)
, mInputDeviceIntegration(Q_NULLPTR)
, mFontDb(new QGenericUnixFontDatabase())
, mNativeInterface(new QWaylandNativeInterface(this))
@@ -131,17 +130,17 @@ QWaylandIntegration::QWaylandIntegration()
, mShellIntegrationInitialized(false)
{
initializeInputDeviceIntegration();
- mDisplay = new QWaylandDisplay(this);
+ mDisplay.reset(new QWaylandDisplay(this));
#ifndef QT_NO_DRAGANDDROP
- mClipboard = new QWaylandClipboard(mDisplay);
- mDrag = new QWaylandDrag(mDisplay);
+ mClipboard.reset(new QWaylandClipboard(mDisplay.data()));
+ mDrag.reset(new QWaylandDrag(mDisplay.data()));
#endif
QString icStr = QPlatformInputContextFactory::requested();
if (!icStr.isNull()) {
mInputContext.reset(QPlatformInputContextFactory::create(icStr));
} else {
//try to use the input context using the wl_text_input interface
- QPlatformInputContext *ctx = new QWaylandInputContext(mDisplay);
+ QPlatformInputContext *ctx = new QWaylandInputContext(mDisplay.data());
mInputContext.reset(ctx);
//use the traditional way for on screen keyboards for now
@@ -154,20 +153,11 @@ QWaylandIntegration::QWaylandIntegration()
QWaylandIntegration::~QWaylandIntegration()
{
-#ifndef QT_NO_DRAGANDDROP
- delete mDrag;
- delete mClipboard;
-#endif
-#ifndef QT_NO_ACCESSIBILITY
- delete mAccessibility;
-#endif
- delete mNativeInterface;
- delete mDisplay;
}
QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
{
- return mNativeInterface;
+ return mNativeInterface.data();
}
bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const
@@ -220,28 +210,28 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
void QWaylandIntegration::initialize()
{
QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
- QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay, SLOT(flushRequests()));
- QObject::connect(dispatcher, SIGNAL(awake()), mDisplay, SLOT(flushRequests()));
+ QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(), SLOT(flushRequests()));
+ QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(), SLOT(flushRequests()));
int fd = wl_display_get_fd(mDisplay->wl_display());
- QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay);
- QObject::connect(sn, SIGNAL(activated(int)), mDisplay, SLOT(flushRequests()));
+ QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay.data());
+ QObject::connect(sn, SIGNAL(activated(int)), mDisplay.data(), SLOT(flushRequests()));
}
QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
{
- return mFontDb;
+ return mFontDb.data();
}
#ifndef QT_NO_DRAGANDDROP
QPlatformClipboard *QWaylandIntegration::clipboard() const
{
- return mClipboard;
+ return mClipboard.data();
}
QPlatformDrag *QWaylandIntegration::drag() const
{
- return mDrag;
+ return mDrag.data();
}
#endif // QT_NO_DRAGANDDROP
@@ -268,7 +258,7 @@ QVariant QWaylandIntegration::styleHint(StyleHint hint) const
#ifndef QT_NO_ACCESSIBILITY
QPlatformAccessibility *QWaylandIntegration::accessibility() const
{
- return mAccessibility;
+ return mAccessibility.data();
}
#endif
@@ -279,7 +269,7 @@ QPlatformServices *QWaylandIntegration::services() const
QWaylandDisplay *QWaylandIntegration::display() const
{
- return mDisplay;
+ return mDisplay.data();
}
QStringList QWaylandIntegration::themeNames() const
@@ -297,7 +287,7 @@ QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration()
if (!mClientBufferIntegrationInitialized)
const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration();
- return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration : 0;
+ return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration.data() : nullptr;
}
QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() const
@@ -305,7 +295,7 @@ QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration()
if (!mServerBufferIntegrationInitialized)
const_cast<QWaylandIntegration *>(this)->initializeServerBufferIntegration();
- return mServerBufferIntegration;
+ return mServerBufferIntegration.data();
}
QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const
@@ -313,7 +303,7 @@ QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const
if (!mShellIntegrationInitialized)
const_cast<QWaylandIntegration *>(this)->initializeShellIntegration();
- return mShellIntegration;
+ return mShellIntegration.data();
}
void QWaylandIntegration::initializeClientBufferIntegration()
@@ -339,10 +329,10 @@ void QWaylandIntegration::initializeClientBufferIntegration()
QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
if (keys.contains(targetKey)) {
- mClientBufferIntegration = QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList());
+ mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
}
if (mClientBufferIntegration)
- mClientBufferIntegration->initialize(mDisplay);
+ mClientBufferIntegration->initialize(mDisplay.data());
else
qWarning("Failed to load client buffer integration: %s\n", qPrintable(targetKey));
}
@@ -369,10 +359,10 @@ void QWaylandIntegration::initializeServerBufferIntegration()
QStringList keys = QWaylandServerBufferIntegrationFactory::keys();
if (keys.contains(targetKey)) {
- mServerBufferIntegration = QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList());
+ mServerBufferIntegration.reset(QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList()));
}
if (mServerBufferIntegration)
- mServerBufferIntegration->initialize(mDisplay);
+ mServerBufferIntegration->initialize(mDisplay.data());
else
qWarning("Failed to load server buffer integration %s\n", qPrintable(targetKey));
}
@@ -388,7 +378,7 @@ void QWaylandIntegration::initializeShellIntegration()
QStringList keys = QWaylandShellIntegrationFactory::keys();
if (keys.contains(targetKey)) {
qDebug("Using the '%s' shell integration", qPrintable(targetKey));
- mShellIntegration = QWaylandShellIntegrationFactory::create(targetKey, QStringList());
+ mShellIntegration.reset(QWaylandShellIntegrationFactory::create(targetKey, QStringList()));
}
} else {
QStringList preferredShells;
@@ -398,17 +388,14 @@ void QWaylandIntegration::initializeShellIntegration()
Q_FOREACH (QString preferredShell, preferredShells) {
if (mDisplay->hasRegistryGlobal(preferredShell)) {
- mShellIntegration = createShellIntegration(preferredShell);
+ mShellIntegration.reset(createShellIntegration(preferredShell));
break;
}
}
}
- Q_ASSERT(mShellIntegration);
-
- if (!mShellIntegration->initialize(mDisplay)) {
- delete mShellIntegration;
- mShellIntegration = Q_NULLPTR;
+ if (!mShellIntegration || !mShellIntegration->initialize(mDisplay.data())) {
+ mShellIntegration.reset();
qWarning("Failed to load shell integration %s", qPrintable(targetKey));
}
}
@@ -432,7 +419,7 @@ void QWaylandIntegration::initializeInputDeviceIntegration()
QStringList keys = QWaylandInputDeviceIntegrationFactory::keys();
if (keys.contains(targetKey)) {
- mInputDeviceIntegration = QWaylandInputDeviceIntegrationFactory::create(targetKey, QStringList());
+ mInputDeviceIntegration.reset(QWaylandInputDeviceIntegrationFactory::create(targetKey, QStringList()));
qDebug("Using the '%s' input device integration", qPrintable(targetKey));
} else {
qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
@@ -442,9 +429,9 @@ void QWaylandIntegration::initializeInputDeviceIntegration()
QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &interfaceName)
{
if (interfaceName == QLatin1Literal("wl_shell")) {
- return new QWaylandWlShellIntegration(mDisplay);
+ return new QWaylandWlShellIntegration(mDisplay.data());
} else if (interfaceName == QLatin1Literal("xdg_shell")) {
- return new QWaylandXdgShellIntegration(mDisplay);
+ return new QWaylandXdgShellIntegration(mDisplay.data());
} else {
return Q_NULLPTR;
}
diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h
index 4f5e651d2..3b91313b5 100644
--- a/src/client/qwaylandintegration_p.h
+++ b/src/client/qwaylandintegration_p.h
@@ -54,6 +54,8 @@
#include <qpa/qplatformintegration.h>
#include <QtWaylandClient/qwaylandclientexport.h>
+#include <QtCore/QScopedPointer>
+
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
@@ -112,10 +114,10 @@ public:
virtual QWaylandShellIntegration *shellIntegration() const;
protected:
- QWaylandClientBufferIntegration *mClientBufferIntegration;
- QWaylandServerBufferIntegration *mServerBufferIntegration;
- QWaylandShellIntegration *mShellIntegration;
- QWaylandInputDeviceIntegration *mInputDeviceIntegration;
+ QScopedPointer<QWaylandClientBufferIntegration> mClientBufferIntegration;
+ QScopedPointer<QWaylandServerBufferIntegration> mServerBufferIntegration;
+ QScopedPointer<QWaylandShellIntegration> mShellIntegration;
+ QScopedPointer<QWaylandInputDeviceIntegration> mInputDeviceIntegration;
private:
void initializeClientBufferIntegration();
@@ -124,16 +126,16 @@ private:
void initializeInputDeviceIntegration();
QWaylandShellIntegration *createShellIntegration(const QString& interfaceName);
- QPlatformFontDatabase *mFontDb;
+ QScopedPointer<QPlatformFontDatabase> mFontDb;
#ifndef QT_NO_DRAGANDDROP
- QPlatformClipboard *mClipboard;
- QPlatformDrag *mDrag;
+ QScopedPointer<QPlatformClipboard> mClipboard;
+ QScopedPointer<QPlatformDrag> mDrag;
#endif
- QWaylandDisplay *mDisplay;
- QPlatformNativeInterface *mNativeInterface;
+ QScopedPointer<QWaylandDisplay> mDisplay;
+ QScopedPointer<QPlatformNativeInterface> mNativeInterface;
QScopedPointer<QPlatformInputContext> mInputContext;
#ifndef QT_NO_ACCESSIBILITY
- QPlatformAccessibility *mAccessibility;
+ QScopedPointer<QPlatformAccessibility> mAccessibility;
#endif
bool mClientBufferIntegrationInitialized;
bool mServerBufferIntegrationInitialized;
diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
index 2c87bb9f6..52c61eec1 100644
--- a/src/client/qwaylandnativeinterface.cpp
+++ b/src/client/qwaylandnativeinterface.cpp
@@ -76,7 +76,7 @@ void *QWaylandNativeInterface::nativeResourceForIntegration(const QByteArray &re
if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())
return m_integration->clientBufferIntegration()->nativeResource(QWaylandClientBufferIntegration::EglDisplay);
- return 0;
+ return nullptr;
}
void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
@@ -88,21 +88,22 @@ void *QWaylandNativeInterface::nativeResourceForWindow(const QByteArray &resourc
if (lowerCaseResource == "compositor")
return const_cast<wl_compositor *>(m_integration->display()->wl_compositor());
if (lowerCaseResource == "surface") {
- return ((QWaylandWindow *) window->handle())->object();
+ QWaylandWindow *w = static_cast<QWaylandWindow*>(window->handle());
+ return w ? w->object() : nullptr;
}
if (lowerCaseResource == "wl_shell_surface") {
- QWaylandWindow *w = (QWaylandWindow *) window->handle();
+ QWaylandWindow *w = static_cast<QWaylandWindow*>(window->handle());
if (!w)
- return NULL;
+ return nullptr;
QWaylandWlShellSurface *s = qobject_cast<QWaylandWlShellSurface *>(w->shellSurface());
if (!s)
- return NULL;
+ return nullptr;
return s->object();
}
if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())
return m_integration->clientBufferIntegration()->nativeResource(QWaylandClientBufferIntegration::EglDisplay);
- return NULL;
+ return nullptr;
}
void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourceString, QScreen *screen)
@@ -112,12 +113,13 @@ void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourc
if (lowerCaseResource == "output")
return ((QWaylandScreen *) screen->handle())->output();
- return NULL;
+ return nullptr;
}
#ifndef QT_NO_OPENGL
void *QWaylandNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
{
+#ifdef QT_WAYLAND_GL_SUPPORT
QByteArray lowerCaseResource = resource.toLower();
if (lowerCaseResource == "eglconfig" && m_integration->clientBufferIntegration())
@@ -128,8 +130,9 @@ void *QWaylandNativeInterface::nativeResourceForContext(const QByteArray &resour
if (lowerCaseResource == "egldisplay" && m_integration->clientBufferIntegration())
return m_integration->clientBufferIntegration()->nativeResourceForContext(QWaylandClientBufferIntegration::EglDisplay, context->handle());
+#endif
- return 0;
+ return nullptr;
}
#endif // QT_NO_OPENGL
@@ -171,7 +174,7 @@ QFunctionPointer QWaylandNativeInterface::platformFunction(const QByteArray &res
} else if (resource == QWaylandWindowFunctions::isSyncIdentifier()) {
return QFunctionPointer(isSync);
}
- return 0;
+ return nullptr;
}
diff --git a/src/client/qwaylandshm.cpp b/src/client/qwaylandshm.cpp
index 790a0e1b9..e94357bb5 100644
--- a/src/client/qwaylandshm.cpp
+++ b/src/client/qwaylandshm.cpp
@@ -39,7 +39,7 @@
#include <QtWaylandClient/private/qwaylandshm_p.h>
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
-#include "qwaylandshmformathelper_p.h"
+#include "qwaylandsharedmemoryformathelper_p.h"
QT_BEGIN_NAMESPACE
@@ -73,12 +73,12 @@ bool QWaylandShm::formatSupported(QImage::Format format) const
wl_shm_format QWaylandShm::formatFrom(QImage::Format format)
{
- return QWaylandShmFormatHelper::fromQImageFormat(format);
+ return QWaylandSharedMemoryFormatHelper::fromQImageFormat(format);
}
QImage::Format QWaylandShm::formatFrom(wl_shm_format format)
{
- return QWaylandShmFormatHelper::fromWaylandShmFormat(format);
+ return QWaylandSharedMemoryFormatHelper::fromWaylandShmFormat(format);
}
}
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 01a0d48bb..6b9dde7c7 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -83,7 +83,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
, mMousePressedInContentArea(Qt::NoButton)
, m_cursor(Qt::ArrowCursor)
, mWaitingForFrameSync(false)
- , mFrameCallback(0)
+ , mFrameCallback(nullptr)
, mRequestResizeSent(false)
, mCanResize(true)
, mResizeDirty(false)
@@ -198,6 +198,7 @@ void QWaylandWindow::initWindow()
setMask(window()->mask());
setWindowStateInternal(window()->windowState());
handleContentOrientationChange(window()->contentOrientation());
+ mFlags = window()->flags();
}
bool QWaylandWindow::shouldCreateShellSurface() const
@@ -456,14 +457,12 @@ void QWaylandWindow::requestResize()
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
{
- if (mFrameCallback) {
- wl_callback_destroy(mFrameCallback);
- mFrameCallback = 0;
- }
+ mFrameCallback = nullptr;
if (buffer) {
- mFrameCallback = frame();
- wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this);
+ auto callback = frame();
+ wl_callback_add_listener(callback, &QWaylandWindow::callbackListener, this);
+ mFrameCallback = callback;
mWaitingForFrameSync = true;
attach(buffer->buffer(), x, y);
@@ -494,11 +493,11 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin
self->mWaitingForFrameSync = false;
wl_callback_destroy(callback);
- self->mFrameCallback = 0;
+ self->mFrameCallback.testAndSetRelaxed(callback, nullptr);
if (self->mUpdateRequested) {
QWindowPrivate *w = QWindowPrivate::get(self->window());
- w->deliverUpdateRequest();
self->mUpdateRequested = false;
+ w->deliverUpdateRequest();
}
}
@@ -583,6 +582,9 @@ void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags)
{
if (mShellSurface)
mShellSurface->setWindowFlags(flags);
+
+ mFlags = flags;
+ createDecoration();
}
bool QWaylandWindow::createDecoration()
@@ -617,9 +619,9 @@ bool QWaylandWindow::createDecoration()
default:
break;
}
- if (window()->flags() & Qt::FramelessWindowHint || isFullscreen())
+ if (mFlags & Qt::FramelessWindowHint || isFullscreen())
decoration = false;
- if (window()->flags() & Qt::BypassWindowManagerHint)
+ if (mFlags & Qt::BypassWindowManagerHint)
decoration = false;
if (mSubSurfaceWindow)
decoration = false;
@@ -667,8 +669,7 @@ bool QWaylandWindow::createDecoration()
QMargins m = frameMargins();
subsurf->set_position(pos.x() + m.left(), pos.y() + m.top());
}
- if (!mChildren.isEmpty())
- window()->requestUpdate();
+ QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
return mWindowDecoration;
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 82898152c..e0c42ace5 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -53,6 +53,7 @@
#include <QtCore/QWaitCondition>
#include <QtCore/QMutex>
+#include <QtCore/QAtomicPointer>
#include <QtGui/QIcon>
#include <QtCore/QVariant>
@@ -220,7 +221,7 @@ protected:
WId mWindowId;
bool mWaitingForFrameSync;
- struct wl_callback *mFrameCallback;
+ QAtomicPointer<struct wl_callback> mFrameCallback;
QWaitCondition mFrameSyncWait;
QMutex mResizeLock;
@@ -237,6 +238,7 @@ protected:
QIcon mWindowIcon;
Qt::WindowState mState;
+ Qt::WindowFlags mFlags;
QRegion mMask;
QWaylandShmBackingStore *mBackingStore;
diff --git a/src/client/qwaylandwindowmanagerintegration_p.h b/src/client/qwaylandwindowmanagerintegration_p.h
index f0c7ced6d..09a79d48d 100644
--- a/src/client/qwaylandwindowmanagerintegration_p.h
+++ b/src/client/qwaylandwindowmanagerintegration_p.h
@@ -55,9 +55,9 @@
#include <QtCore/QScopedPointer>
#include <wayland-client.h>
-#include <QtPlatformSupport/private/qgenericunixservices_p.h>
+#include <QtServiceSupport/private/qgenericunixservices_p.h>
-#include <QtWaylandClient/private/qwayland-windowmanager.h>
+#include <QtWaylandClient/private/qwayland-qt-windowmanager.h>
#include <QtWaylandClient/qwaylandclientexport.h>
QT_BEGIN_NAMESPACE
diff --git a/src/client/qwaylandwlshellsurface_p.h b/src/client/qwaylandwlshellsurface_p.h
index c319cd983..ef732ef85 100644
--- a/src/client/qwaylandwlshellsurface_p.h
+++ b/src/client/qwaylandwlshellsurface_p.h
@@ -55,9 +55,9 @@
#include <wayland-client.h>
-#include <QtWaylandClient/private/qwayland-wayland.h>
#include <QtWaylandClient/qwaylandclientexport.h>
-#include "qwaylandshellsurface_p.h"
+#include <QtWaylandClient/private/qwayland-wayland.h>
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/client/qwaylandxdgpopup_p.h b/src/client/qwaylandxdgpopup_p.h
index 1f211012d..ff5804113 100644
--- a/src/client/qwaylandxdgpopup_p.h
+++ b/src/client/qwaylandxdgpopup_p.h
@@ -47,9 +47,9 @@
#include <wayland-client.h>
-#include <QtWaylandClient/private/qwayland-xdg-shell.h>
#include <QtWaylandClient/qwaylandclientexport.h>
-#include "qwaylandshellsurface_p.h"
+#include <QtWaylandClient/private/qwayland-xdg-shell.h>
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/client/qwaylandxdgshell_p.h b/src/client/qwaylandxdgshell_p.h
index 77b05b462..c04a9ce66 100644
--- a/src/client/qwaylandxdgshell_p.h
+++ b/src/client/qwaylandxdgshell_p.h
@@ -57,7 +57,7 @@
#include <QtWaylandClient/private/qwayland-xdg-shell.h>
#include <QtWaylandClient/qwaylandclientexport.h>
-#include "qwaylandshellsurface_p.h"
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/client/qwaylandxdgsurface_p.h b/src/client/qwaylandxdgsurface_p.h
index 1ce029af8..27decabb4 100644
--- a/src/client/qwaylandxdgsurface_p.h
+++ b/src/client/qwaylandxdgsurface_p.h
@@ -56,9 +56,9 @@
#include <wayland-client.h>
-#include <QtWaylandClient/private/qwayland-xdg-shell.h>
#include <QtWaylandClient/qwaylandclientexport.h>
-#include "qwaylandshellsurface_p.h"
+#include <QtWaylandClient/private/qwayland-xdg-shell.h>
+#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/compositor/compositor.pro b/src/compositor/compositor.pro
index fe58df7ec..251d757e2 100644
--- a/src/compositor/compositor.pro
+++ b/src/compositor/compositor.pro
@@ -5,7 +5,7 @@ QT = core gui-private
qtHaveModule(quick): QT += quick
-contains(QT_CONFIG, opengl):MODULE_DEFINES = QT_COMPOSITOR_WAYLAND_GL
+contains(QT_CONFIG, opengl):MODULE_DEFINES = QT_WAYLAND_COMPOSITOR_GL
CONFIG -= precompile_header
CONFIG += link_pkgconfig
@@ -23,7 +23,7 @@ INCLUDEPATH += ../shared
HEADERS += ../shared/qwaylandmimehelper_p.h \
../shared/qwaylandinputmethodeventbuilder_p.h \
- ../shared/qwaylandshmformathelper_p.h
+ ../shared/qwaylandsharedmemoryformathelper_p.h
SOURCES += ../shared/qwaylandmimehelper.cpp \
../shared/qwaylandinputmethodeventbuilder.cpp
diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri
index 1724ec965..0253cd0ee 100644
--- a/src/compositor/compositor_api/compositor_api.pri
+++ b/src/compositor/compositor_api/compositor_api.pri
@@ -6,15 +6,19 @@ HEADERS += \
compositor_api/qwaylandclient.h \
compositor_api/qwaylandsurface.h \
compositor_api/qwaylandsurface_p.h \
- compositor_api/qwaylandinput.h \
- compositor_api/qwaylandinput_p.h \
+ compositor_api/qwaylandseat.h \
+ compositor_api/qwaylandseat_p.h \
compositor_api/qwaylandkeyboard.h \
compositor_api/qwaylandkeyboard_p.h \
+ compositor_api/qwaylandkeymap.h \
+ compositor_api/qwaylandkeymap_p.h \
compositor_api/qwaylandpointer.h \
compositor_api/qwaylandpointer_p.h \
compositor_api/qwaylandtouch.h \
compositor_api/qwaylandtouch_p.h \
compositor_api/qwaylandoutput.h \
+ compositor_api/qwaylandoutputmode.h \
+ compositor_api/qwaylandoutputmode_p.h \
compositor_api/qwaylanddrag.h \
compositor_api/qwaylandbufferref.h \
compositor_api/qwaylanddestroylistener.h \
@@ -24,17 +28,20 @@ HEADERS += \
compositor_api/qwaylandresource.h \
compositor_api/qwaylandsurfacegrabber.h \
compositor_api/qwaylandinputmethodcontrol.h \
- compositor_api/qwaylandinputmethodcontrol_p.h
+ compositor_api/qwaylandinputmethodcontrol_p.h \
+ compositor_api/qwaylandoutputmode_p.h
SOURCES += \
compositor_api/qwaylandcompositor.cpp \
compositor_api/qwaylandclient.cpp \
compositor_api/qwaylandsurface.cpp \
- compositor_api/qwaylandinput.cpp \
+ compositor_api/qwaylandseat.cpp \
compositor_api/qwaylandkeyboard.cpp \
+ compositor_api/qwaylandkeymap.cpp \
compositor_api/qwaylandpointer.cpp \
compositor_api/qwaylandtouch.cpp \
compositor_api/qwaylandoutput.cpp \
+ compositor_api/qwaylandoutputmode.cpp \
compositor_api/qwaylanddrag.cpp \
compositor_api/qwaylandbufferref.cpp \
compositor_api/qwaylanddestroylistener.cpp \
@@ -45,7 +52,9 @@ SOURCES += \
QT += core-private
-qtHaveModule(quick) {
+qtHaveModule(quick):contains(QT_CONFIG, opengl) {
+ DEFINES += QT_WAYLAND_COMPOSITOR_QUICK
+
SOURCES += \
compositor_api/qwaylandquickcompositor.cpp \
compositor_api/qwaylandquicksurface.cpp \
diff --git a/src/compositor/compositor_api/qwaylandbufferref.cpp b/src/compositor/compositor_api/qwaylandbufferref.cpp
index 624deaff9..6f175de95 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.cpp
+++ b/src/compositor/compositor_api/qwaylandbufferref.cpp
@@ -38,14 +38,14 @@
#include <QAtomicInt>
#include "qwaylandbufferref.h"
-#include "wayland_wrapper/qwlsurfacebuffer_p.h"
+#include "wayland_wrapper/qwlclientbuffer_p.h"
QT_BEGIN_NAMESPACE
class QWaylandBufferRefPrivate
{
public:
- QtWayland::SurfaceBuffer *buffer;
+ QtWayland::ClientBuffer *buffer;
bool nullOrDestroyed() {
return !buffer || buffer->isDestroyed();
@@ -55,7 +55,7 @@ public:
/*!
* \class QWaylandBufferRef
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandBufferRef class holds the reference to a surface buffer
*
* This class can be used to reference a surface buffer. As long as a reference
@@ -74,7 +74,7 @@ QWaylandBufferRef::QWaylandBufferRef()
/*!
* Constructs a reference to \a buffer.
*/
-QWaylandBufferRef::QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer)
+QWaylandBufferRef::QWaylandBufferRef(QtWayland::ClientBuffer *buffer)
: d(new QWaylandBufferRefPrivate)
{
d->buffer = buffer;
@@ -104,17 +104,18 @@ QWaylandBufferRef::~QWaylandBufferRef()
}
/*!
- * Assigns \a ref to this buffer. The previously referenced buffer is
- * dereferenced and the new one gets a new reference.
+ * Assigns \a ref to this buffer and adds a reference to it. The previously referenced buffer is
+ * dereferenced.
*/
QWaylandBufferRef &QWaylandBufferRef::operator=(const QWaylandBufferRef &ref)
{
+ if (ref.d->buffer)
+ ref.d->buffer->ref();
+
if (d->buffer)
d->buffer->deref();
d->buffer = ref.d->buffer;
- if (d->buffer)
- d->buffer->ref();
return *this;
}
@@ -141,7 +142,7 @@ bool QWaylandBufferRef::operator!=(const QWaylandBufferRef &ref)
* Returns true if this QWaylandBufferRef does not reference a buffer.
* Otherwise returns false.
*
- * \sa hasBuffer()
+ * \sa hasBuffer(), hasContent()
*/
bool QWaylandBufferRef::isNull() const
{
@@ -151,12 +152,21 @@ bool QWaylandBufferRef::isNull() const
/*!
* Returns true if this QWaylandBufferRef references a buffer. Otherwise returns false.
*
- * \sa isNull()
+ * \sa isNull(), hasContent()
*/
bool QWaylandBufferRef::hasBuffer() const
{
return d->buffer;
}
+/*!
+ * Returns true if this QWaylandBufferRef references a buffer that has content. Otherwise returns false.
+ *
+ * \sa isNull(), hasBuffer()
+ */
+bool QWaylandBufferRef::hasContent() const
+{
+ return QtWayland::ClientBuffer::hasContent(d->buffer);
+}
/*!
* Returns true if this QWaylandBufferRef references a buffer that
@@ -176,6 +186,14 @@ struct ::wl_resource *QWaylandBufferRef::wl_buffer() const
}
/*!
+ * \internal
+ */
+QtWayland::ClientBuffer *QWaylandBufferRef::buffer() const
+{
+ return d->buffer;
+}
+
+/*!
* Returns the size of the buffer.
* If the buffer referenced is null, an invalid QSize() is returned.
*/
@@ -205,8 +223,8 @@ QWaylandBufferRef::BufferType QWaylandBufferRef::bufferType() const
if (d->nullOrDestroyed())
return BufferType_Null;
- if (isShm())
- return BufferType_Shm;
+ if (isSharedMemory())
+ return BufferType_SharedMemory;
return BufferType_Egl;
}
@@ -222,12 +240,12 @@ QWaylandBufferRef::BufferFormatEgl QWaylandBufferRef::bufferFormatEgl() const
/*!
* Returns true if the buffer is a shared memory buffer. Otherwise returns false.
*/
-bool QWaylandBufferRef::isShm() const
+bool QWaylandBufferRef::isSharedMemory() const
{
if (d->nullOrDestroyed())
return false;
- return d->buffer->isShm();
+ return d->buffer->isSharedMemory();
}
/*!
@@ -241,36 +259,44 @@ QImage QWaylandBufferRef::image() const
return d->buffer->image();
}
-#ifdef QT_COMPOSITOR_WAYLAND_GL
-GLuint QWaylandBufferRef::textureForPlane(int plane) const
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+/*!
+ * Returns an OpenGL texture for the buffer. \a plane is the index for multi-plane formats, such as YUV.
+ *
+ * The returned texture is owned by the buffer. The texture is only valid for as
+ * long as the buffer reference exists. The caller of this function must not delete the texture, and must
+ * keep a reference to the buffer for as long as the texture is being used.
+ *
+ * Returns \c nullptr if there is no valid buffer, or if no texture can be created.
+ */
+QOpenGLTexture *QWaylandBufferRef::toOpenGLTexture(int plane) const
{
if (d->nullOrDestroyed())
- return 0;
+ return nullptr;
- return d->buffer->textureForPlane(plane);
+ return d->buffer->toOpenGlTexture(plane);
}
-#endif
/*!
- * Binds the buffer to the current OpenGL texture. This may
- * perform a copy of the buffer data, depending on the platform
- * and the type of the buffer.
+ * Returns the native handle for this buffer, and marks it as locked so it will not be
+ * released until unlockNativeBuffer() is called.
+ *
+ * Returns 0 if there is no native handle for this buffer, or if the lock was unsuccessful.
*/
-void QWaylandBufferRef::bindToTexture() const
+quintptr QWaylandBufferRef::lockNativeBuffer()
{
- if (d->nullOrDestroyed())
- return;
-
- return d->buffer->bindToTexture();
-
+ return d->buffer->lockNativeBuffer();
}
-void QWaylandBufferRef::updateTexture() const
+/*!
+ * Marks the native buffer as no longer in use. \a handle must correspond to the value returned by
+ * a previous call to lockNativeBuffer().
+ */
+void QWaylandBufferRef::unlockNativeBuffer(quintptr handle)
{
- if (d->nullOrDestroyed() || d->buffer->isShm())
- return;
-
- d->buffer->updateTexture();
+ d->buffer->unlockNativeBuffer(handle);
}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandbufferref.h b/src/compositor/compositor_api/qwaylandbufferref.h
index 50c85b965..06486ef3a 100644
--- a/src/compositor/compositor_api/qwaylandbufferref.h
+++ b/src/compositor/compositor_api/qwaylandbufferref.h
@@ -39,7 +39,7 @@
#include <QImage>
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
#include <QtGui/qopengl.h>
#endif
@@ -50,22 +50,24 @@ struct wl_resource;
QT_BEGIN_NAMESPACE
+class QOpenGLTexture;
+
namespace QtWayland
{
- class SurfaceBuffer;
+ class ClientBuffer;
}
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandBufferRef
{
public:
QWaylandBufferRef();
- explicit QWaylandBufferRef(QtWayland::SurfaceBuffer *buffer);
QWaylandBufferRef(const QWaylandBufferRef &ref);
~QWaylandBufferRef();
QWaylandBufferRef &operator=(const QWaylandBufferRef &ref);
bool isNull() const;
bool hasBuffer() const;
+ bool hasContent() const;
bool isDestroyed() const;
bool operator==(const QWaylandBufferRef &ref);
bool operator!=(const QWaylandBufferRef &ref);
@@ -77,7 +79,7 @@ public:
enum BufferType {
BufferType_Null,
- BufferType_Shm,
+ BufferType_SharedMemory,
BufferType_Egl
};
@@ -94,18 +96,22 @@ public:
BufferType bufferType() const;
BufferFormatEgl bufferFormatEgl() const;
- bool isShm() const;
+ bool isSharedMemory() const;
QImage image() const;
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- GLuint textureForPlane(int plane) const;
+
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+ QOpenGLTexture *toOpenGLTexture(int plane = 0) const;
#endif
- void bindToTexture() const;
- void updateTexture() const;
+ quintptr lockNativeBuffer();
+ void unlockNativeBuffer(quintptr handle);
private:
+ explicit QWaylandBufferRef(QtWayland::ClientBuffer *buffer);
+ QtWayland::ClientBuffer *buffer() const;
class QWaylandBufferRefPrivate *const d;
friend class QWaylandBufferRefPrivate;
+ friend class QWaylandSurfacePrivate;
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp
index fbf8c1275..eb12fa3d8 100644
--- a/src/compositor/compositor_api/qwaylandclient.cpp
+++ b/src/compositor/compositor_api/qwaylandclient.cpp
@@ -87,7 +87,7 @@ public:
/*!
* \qmltype WaylandClient
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief Represents a client connecting to the WaylandCompositor.
*
* This type represents a client connecting to the compositor using the Wayland protocol.
@@ -97,7 +97,7 @@ public:
/*!
* \class QWaylandClient
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandClient class represents a client connecting to the QWaylandCompositor.
*
* This class corresponds to a client connecting to the compositor using the Wayland protocol.
@@ -164,6 +164,24 @@ QWaylandClient *QWaylandClient::fromWlClient(QWaylandCompositor *compositor, wl_
}
/*!
+ * \qmlproperty object QtWaylandCompositor::WaylandClient::compositor
+ *
+ * This property holds the compositor of this WaylandClient.
+ */
+
+/*!
+ * \property QWaylandClient::compositor
+ *
+ * This property holds the compositor of this QWaylandClient.
+ */
+QWaylandCompositor *QWaylandClient::compositor() const
+{
+ Q_D(const QWaylandClient);
+
+ return d->compositor;
+}
+
+/*!
* Returns the Wayland client of this QWaylandClient.
*/
wl_client *QWaylandClient::client() const
diff --git a/src/compositor/compositor_api/qwaylandclient.h b/src/compositor/compositor_api/qwaylandclient.h
index 26e7b95e5..50e7baf72 100644
--- a/src/compositor/compositor_api/qwaylandclient.h
+++ b/src/compositor/compositor_api/qwaylandclient.h
@@ -55,6 +55,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandClient : public QObject
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandClient)
+ Q_PROPERTY(QWaylandCompositor *compositor READ compositor CONSTANT)
Q_PROPERTY(qint64 userId READ userId CONSTANT)
Q_PROPERTY(qint64 groupId READ groupId CONSTANT)
Q_PROPERTY(qint64 processId READ processId CONSTANT)
@@ -63,6 +64,8 @@ public:
static QWaylandClient *fromWlClient(QWaylandCompositor *compositor, wl_client *wlClient);
+ QWaylandCompositor *compositor() const;
+
wl_client *client() const;
qint64 userId() const;
diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp
index 795cb6a59..bcee61d8b 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandcompositor.cpp
@@ -39,7 +39,7 @@
#include "qwaylandcompositor_p.h"
#include <QtWaylandCompositor/qwaylandclient.h>
-#include <QtWaylandCompositor/qwaylandinput.h>
+#include <QtWaylandCompositor/qwaylandseat.h>
#include <QtWaylandCompositor/qwaylandoutput.h>
#include <QtWaylandCompositor/qwaylandview.h>
#include <QtWaylandCompositor/qwaylandclient.h>
@@ -53,17 +53,21 @@
#include "wayland_wrapper/qwldatadevice_p.h"
#include "wayland_wrapper/qwldatadevicemanager_p.h"
+#include "wayland_wrapper/qwlbuffermanager_p.h"
#include "hardware_integration/qwlclientbufferintegration_p.h"
#include "hardware_integration/qwlclientbufferintegrationfactory_p.h"
#include "hardware_integration/qwlserverbufferintegration_p.h"
#include "hardware_integration/qwlserverbufferintegrationfactory_p.h"
+
+#ifdef QT_WAYLAND_COMPOSITOR_GL
#include "hardware_integration/qwlhwintegration_p.h"
+#endif
-#include "extensions/qwaylandwindowmanagerextension.h"
+#include "extensions/qwaylandqtwindowmanager.h"
#include "qwaylandxkb_p.h"
-#include "qwaylandshmformathelper_p.h"
+#include "qwaylandsharedmemoryformathelper_p.h"
#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
@@ -76,8 +80,9 @@
#include <QtGui/qpa/qplatformnativeinterface.h>
#include <QtGui/private/qguiapplication_p.h>
-#ifdef QT_COMPOSITOR_WAYLAND_GL
-# include <QtGui/private/qopengltextureblitter_p.h>
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+# include <QOpenGLTextureBlitter>
+# include <QOpenGLTexture>
# include <QOpenGLContext>
# include <QOpenGLFramebufferObject>
# include <QMatrix4x4>
@@ -97,7 +102,7 @@ public:
{
if (e->type == QWindowSystemInterfacePrivate::Key) {
QWindowSystemInterfacePrivate::KeyEvent *ke = static_cast<QWindowSystemInterfacePrivate::KeyEvent *>(e);
- QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(compositor->defaultInputDevice()->keyboard());
+ QWaylandKeyboardPrivate *keyb = QWaylandKeyboardPrivate::get(compositor->defaultSeat()->keyboard());
uint32_t code = ke->nativeScanCode;
bool isDown = ke->keyType == QEvent::KeyPress;
@@ -122,7 +127,7 @@ public:
QWindowSystemEventHandler::sendEvent(e);
if (!ke->repeat) {
- keyb->updateKeymap();
+ keyb->maybeUpdateKeymap();
keyb->updateModifierState(code, isDown ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED);
}
} else {
@@ -138,12 +143,13 @@ public:
QWaylandCompositorPrivate::QWaylandCompositorPrivate(QWaylandCompositor *compositor)
: display(0)
-#if defined (QT_COMPOSITOR_WAYLAND_GL)
+#if defined (QT_WAYLAND_COMPOSITOR_GL)
, use_hw_integration_extension(true)
, client_buffer_integration(0)
, server_buffer_integration(0)
#endif
, retainSelection(false)
+ , preInitialized(false)
, initialized(false)
{
if (QGuiApplication::platformNativeInterface())
@@ -170,9 +176,10 @@ void QWaylandCompositorPrivate::init()
wl_subcompositor::init(display, 1);
data_device_manager = new QtWayland::DataDeviceManager(q);
+ buffer_manager = new QtWayland::BufferManager(q);
wl_display_init_shm(display);
- QVector<wl_shm_format> formats = QWaylandShmFormatHelper::supportedWaylandFormats();
+ QVector<wl_shm_format> formats = QWaylandSharedMemoryFormatHelper::supportedWaylandFormats();
foreach (wl_shm_format format, formats)
wl_display_add_shm_format(display, format);
@@ -197,7 +204,7 @@ void QWaylandCompositorPrivate::init()
QObject::connect(dispatcher, SIGNAL(aboutToBlock()), q, SLOT(processWaylandEvents()));
initializeHardwareIntegration();
- initializeDefaultInputDevice();
+ initializeSeats();
initialized = true;
@@ -207,6 +214,8 @@ void QWaylandCompositorPrivate::init()
QCoreApplication::sendEvent(object.data(), &polishEvent);
}
}
+
+ emit q->createdChanged();
}
QWaylandCompositorPrivate::~QWaylandCompositorPrivate()
@@ -220,6 +229,19 @@ QWaylandCompositorPrivate::~QWaylandCompositorPrivate()
wl_display_destroy(display);
}
+void QWaylandCompositorPrivate::preInit()
+{
+ Q_Q(QWaylandCompositor);
+
+ if (preInitialized)
+ return;
+
+ if (seats.empty())
+ seats.append(q->createSeat());
+
+ preInitialized = true;
+}
+
void QWaylandCompositorPrivate::destroySurface(QWaylandSurface *surface)
{
Q_Q(QWaylandCompositor);
@@ -287,7 +309,7 @@ void QWaylandCompositorPrivate::compositor_create_surface(wl_compositor::Resourc
{
Q_Q(QWaylandCompositor);
QWaylandClient *client = QWaylandClient::fromWlClient(q, resource->client());
- emit q->createSurface(client, id, resource->version());
+ emit q->surfaceRequested(client, id, resource->version());
#ifndef QT_NO_DEBUG
Q_ASSERT_X(!QWaylandSurfacePrivate::hasUninitializedSurface(), "QWaylandCompositor", QStringLiteral("Found uninitialized QWaylandSurface after emitting QWaylandCompositor::createSurface for id %1. All surfaces has to be initialized immediately after creation. See QWaylandSurface::initialize.").arg(id).toLocal8Bit().constData());
#endif
@@ -332,7 +354,7 @@ QWaylandSurface *QWaylandCompositorPrivate::createDefaultSurface()
void QWaylandCompositorPrivate::initializeHardwareIntegration()
{
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
Q_Q(QWaylandCompositor);
if (use_hw_integration_extension)
hw_integration.reset(new QtWayland::HardwareIntegration(q));
@@ -347,17 +369,15 @@ void QWaylandCompositorPrivate::initializeHardwareIntegration()
#endif
}
-void QWaylandCompositorPrivate::initializeDefaultInputDevice()
+void QWaylandCompositorPrivate::initializeSeats()
{
- Q_Q(QWaylandCompositor);
- QWaylandInputDevice *device = q->createInputDevice();
- inputDevices.append(device);
- q->defaultInputDeviceChanged(device, nullptr);
+ for (QWaylandSeat *seat : qAsConst(seats))
+ seat->initialize();
}
void QWaylandCompositorPrivate::loadClientBufferIntegration()
{
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
Q_Q(QWaylandCompositor);
QStringList keys = QtWayland::ClientBufferIntegrationFactory::keys();
QString targetKey;
@@ -386,7 +406,7 @@ void QWaylandCompositorPrivate::loadClientBufferIntegration()
void QWaylandCompositorPrivate::loadServerBufferIntegration()
{
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
QStringList keys = QtWayland::ServerBufferIntegrationFactory::keys();
QString targetKey;
QByteArray serverBufferIntegration = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION");
@@ -404,16 +424,16 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration()
/*!
\qmltype WaylandCompositor
\inqmlmodule QtWayland.Compositor
- \preliminary
+ \since 5.8
\brief Manages the Wayland display server.
The WaylandCompositor manages the connections to the clients, as well as the different
- \l{WaylandOutput}{outputs} and \l{QWaylandInputDevice}{input devices}.
+ \l{WaylandOutput}{outputs} and \l{QWaylandSeat}{seats}.
Normally, a compositor application will have a single WaylandCompositor
instance, which can have several outputs as children. When a client
requests the compositor to create a surface, the request is handled by
- the onCreateSurface handler.
+ the onSurfaceRequested handler.
Extensions that are supported by the compositor should be instantiated and added to the
extensions property.
@@ -423,11 +443,11 @@ void QWaylandCompositorPrivate::loadServerBufferIntegration()
/*!
\class QWaylandCompositor
\inmodule QtWaylandCompositor
- \preliminary
+ \since 5.8
\brief The QWaylandCompositor class manages the Wayland display server.
The QWaylandCompositor manages the connections to the clients, as well as the different \l{QWaylandOutput}{outputs}
- and \l{QWaylandInputDevice}{input devices}.
+ and \l{QWaylandSeat}{seats}.
Normally, a compositor application will have a single WaylandCompositor
instance, which can have several outputs as children.
@@ -464,11 +484,22 @@ QWaylandCompositor::~QWaylandCompositor()
void QWaylandCompositor::create()
{
Q_D(QWaylandCompositor);
+ d->preInit();
d->init();
}
/*!
- * Returns true if the QWaylandCompositor has been initialized. Otherwise returns false.
+ * \qmlproperty bool QtWaylandCompositor::WaylandCompositor::created
+ *
+ * This property is true if WaylandCompositor has been initialized,
+ * otherwise it's false.
+ */
+
+/*!
+ * \property QWaylandCompositor::created
+ *
+ * This property is true if QWaylandCompositor has been initialized,
+ * otherwise it's false.
*/
bool QWaylandCompositor::isCreated() const
{
@@ -500,11 +531,17 @@ bool QWaylandCompositor::isCreated() const
void QWaylandCompositor::setSocketName(const QByteArray &name)
{
Q_D(QWaylandCompositor);
+
+ if (d->socket_name == name)
+ return;
+
if (d->initialized) {
qWarning("%s: Changing socket name after initializing the compositor is not supported.\n", Q_FUNC_INFO);
return;
}
+
d->socket_name = name;
+ emit socketNameChanged(name);
}
QByteArray QWaylandCompositor::socketName() const
@@ -568,9 +605,9 @@ void QWaylandCompositor::destroyClient(QWaylandClient *client)
if (!client)
return;
- QWaylandWindowManagerExtension *wmExtension = QWaylandWindowManagerExtension::findIn(this);
+ QWaylandQtWindowManager *wmExtension = QWaylandQtWindowManager::findIn(this);
if (wmExtension)
- wmExtension->sendQuitMessage(client->client());
+ wmExtension->sendQuitMessage(client);
wl_client_destroy(client->client());
}
@@ -682,33 +719,33 @@ void QWaylandCompositor::processWaylandEvents()
/*!
* \internal
*/
-QWaylandInputDevice *QWaylandCompositor::createInputDevice()
+QWaylandSeat *QWaylandCompositor::createSeat()
{
- return new QWaylandInputDevice(this);
+ return new QWaylandSeat(this);
}
/*!
* \internal
*/
-QWaylandPointer *QWaylandCompositor::createPointerDevice(QWaylandInputDevice *inputDevice)
+QWaylandPointer *QWaylandCompositor::createPointerDevice(QWaylandSeat *seat)
{
- return new QWaylandPointer(inputDevice);
+ return new QWaylandPointer(seat);
}
/*!
* \internal
*/
-QWaylandKeyboard *QWaylandCompositor::createKeyboardDevice(QWaylandInputDevice *inputDevice)
+QWaylandKeyboard *QWaylandCompositor::createKeyboardDevice(QWaylandSeat *seat)
{
- return new QWaylandKeyboard(inputDevice);
+ return new QWaylandKeyboard(seat);
}
/*!
* \internal
*/
-QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandInputDevice *inputDevice)
+QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandSeat *seat)
{
- return new QWaylandTouch(inputDevice);
+ return new QWaylandTouch(seat);
}
/*!
@@ -725,7 +762,12 @@ QWaylandTouch *QWaylandCompositor::createTouchDevice(QWaylandInputDevice *inputD
void QWaylandCompositor::setRetainedSelectionEnabled(bool enabled)
{
Q_D(QWaylandCompositor);
+
+ if (d->retainSelection == enabled)
+ return;
+
d->retainSelection = enabled;
+ emit retainedSelectionChanged(enabled);
}
bool QWaylandCompositor::retainedSelectionEnabled() const
@@ -751,38 +793,38 @@ void QWaylandCompositor::overrideSelection(const QMimeData *data)
}
/*!
- * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultInputDevice
+ * \qmlproperty object QtWaylandCompositor::WaylandCompositor::defaultSeat
*
- * This property contains the default input device for this
+ * This property contains the default seat for this
* WaylandCompositor.
*/
/*!
- * \property QWaylandCompositor::defaultInputDevice
+ * \property QWaylandCompositor::defaultSeat
*
- * This property contains the default input device for this
+ * This property contains the default seat for this
* QWaylandCompositor.
*/
-QWaylandInputDevice *QWaylandCompositor::defaultInputDevice() const
+QWaylandSeat *QWaylandCompositor::defaultSeat() const
{
Q_D(const QWaylandCompositor);
- if (d->inputDevices.size())
- return d->inputDevices.first();
+ if (d->seats.size())
+ return d->seats.first();
return Q_NULLPTR;
}
/*!
* \internal
*
- * Currently, Qt only supports a single input device, so this exists for
+ * Currently, Qt only supports a single seat, so this exists for
* future proofing the APIs.
*/
-QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent)
+QWaylandSeat *QWaylandCompositor::seatFor(QInputEvent *inputEvent)
{
Q_D(QWaylandCompositor);
- QWaylandInputDevice *dev = NULL;
- for (int i = 0; i < d->inputDevices.size(); i++) {
- QWaylandInputDevice *candidate = d->inputDevices.at(i);
+ QWaylandSeat *dev = NULL;
+ for (int i = 0; i < d->seats.size(); i++) {
+ QWaylandSeat *candidate = d->seats.at(i);
if (candidate->isOwner(inputEvent)) {
dev = candidate;
break;
@@ -810,12 +852,17 @@ QWaylandInputDevice *QWaylandCompositor::inputDeviceFor(QInputEvent *inputEvent)
*/
bool QWaylandCompositor::useHardwareIntegrationExtension() const
{
+#ifdef QT_WAYLAND_COMPOSITOR_GL
Q_D(const QWaylandCompositor);
return d->use_hw_integration_extension;
+#else
+ return false;
+#endif
}
void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use)
{
+#ifdef QT_WAYLAND_COMPOSITOR_GL
Q_D(QWaylandCompositor);
if (use == d->use_hw_integration_extension)
return;
@@ -825,6 +872,10 @@ void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use)
d->use_hw_integration_extension = use;
useHardwareIntegrationExtensionChanged();
+#else
+ if (use)
+ qWarning() << "Hardware integration not supported without OpenGL support";
+#endif
}
/*!
@@ -832,22 +883,22 @@ void QWaylandCompositor::setUseHardwareIntegrationExtension(bool use)
* The default implementation requires a OpenGL context to be bound to the current thread
* to work. If this is not possible, reimplement this function in your compositor subclass
* to implement custom logic.
- * The default implementation only grabs SHM and OpenGL buffers, reimplement this in your
+ * The default implementation only grabs shared memory and OpenGL buffers, reimplement this in your
* compositor subclass to handle more buffer types.
* \note You should not call this manually, but rather use QWaylandSurfaceGrabber (\a grabber).
*/
void QWaylandCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer)
{
- if (buffer.isShm()) {
+ if (buffer.isSharedMemory()) {
emit grabber->success(buffer.image());
} else {
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
if (QOpenGLContext::currentContext()) {
QOpenGLFramebufferObject fbo(buffer.size());
fbo.bind();
QOpenGLTextureBlitter blitter;
blitter.create();
- blitter.bind();
+
glViewport(0, 0, buffer.size().width(), buffer.size().height());
@@ -856,15 +907,10 @@ void QWaylandCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWay
? QOpenGLTextureBlitter::OriginTopLeft
: QOpenGLTextureBlitter::OriginBottomLeft;
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- buffer.bindToTexture();
- blitter.blit(texture, QMatrix4x4(), surfaceOrigin);
-
+ auto texture = buffer.toOpenGLTexture();
+ blitter.bind(texture->target());
+ blitter.blit(texture->textureId(), QMatrix4x4(), surfaceOrigin);
blitter.release();
- glDeleteTextures(1, &texture);
emit grabber->success(fbo.toImage());
} else
diff --git a/src/compositor/compositor_api/qwaylandcompositor.h b/src/compositor/compositor_api/qwaylandcompositor.h
index f97484d86..8b190d1d2 100644
--- a/src/compositor/compositor_api/qwaylandcompositor.h
+++ b/src/compositor/compositor_api/qwaylandcompositor.h
@@ -58,7 +58,7 @@ class QOpenGLContext;
class QWaylandCompositorPrivate;
class QWaylandClient;
class QWaylandSurface;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandGlobalInterface;
class QWaylandView;
class QWaylandPointer;
@@ -73,11 +73,12 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositor : public QWaylandObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandCompositor)
- Q_PROPERTY(QByteArray socketName READ socketName WRITE setSocketName)
- Q_PROPERTY(bool retainedSelection READ retainedSelectionEnabled WRITE setRetainedSelectionEnabled)
+ Q_PROPERTY(QByteArray socketName READ socketName WRITE setSocketName NOTIFY socketNameChanged)
+ Q_PROPERTY(bool created READ isCreated NOTIFY createdChanged)
+ Q_PROPERTY(bool retainedSelection READ retainedSelectionEnabled WRITE setRetainedSelectionEnabled NOTIFY retainedSelectionChanged)
Q_PROPERTY(QWaylandOutput *defaultOutput READ defaultOutput WRITE setDefaultOutput NOTIFY defaultOutputChanged)
Q_PROPERTY(bool useHardwareIntegrationExtension READ useHardwareIntegrationExtension WRITE setUseHardwareIntegrationExtension NOTIFY useHardwareIntegrationExtensionChanged)
- Q_PROPERTY(QWaylandInputDevice *defaultInputDevice READ defaultInputDevice NOTIFY defaultInputDeviceChanged)
+ Q_PROPERTY(QWaylandSeat *defaultSeat READ defaultSeat NOTIFY defaultSeatChanged)
public:
QWaylandCompositor(QObject *parent = nullptr);
@@ -111,11 +112,11 @@ public:
bool retainedSelectionEnabled() const;
void overrideSelection(const QMimeData *data);
- QWaylandInputDevice *defaultInputDevice() const;
+ QWaylandSeat *defaultSeat() const;
QWaylandView *createSurfaceView(QWaylandSurface *surface);
- QWaylandInputDevice *inputDeviceFor(QInputEvent *inputEvent);
+ QWaylandSeat *seatFor(QInputEvent *inputEvent);
bool useHardwareIntegrationExtension() const;
void setUseHardwareIntegrationExtension(bool use);
@@ -126,21 +127,29 @@ public Q_SLOTS:
void processWaylandEvents();
Q_SIGNALS:
- void createSurface(QWaylandClient *client, uint id, int version);
+ void createdChanged();
+ void socketNameChanged(const QByteArray &socketName);
+ void retainedSelectionChanged(bool retainedSelection);
+
+ void surfaceRequested(QWaylandClient *client, uint id, int version);
void surfaceCreated(QWaylandSurface *surface);
void surfaceAboutToBeDestroyed(QWaylandSurface *surface);
void subsurfaceChanged(QWaylandSurface *child, QWaylandSurface *parent);
void defaultOutputChanged();
- void defaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice);
+ void defaultSeatChanged(QWaylandSeat *newDevice, QWaylandSeat *oldDevice);
void useHardwareIntegrationExtensionChanged();
+
+ void outputAdded(QWaylandOutput *output);
+ void outputRemoved(QWaylandOutput *output);
+
protected:
virtual void retainedSelectionReceived(QMimeData *mimeData);
- virtual QWaylandInputDevice *createInputDevice();
- virtual QWaylandPointer *createPointerDevice(QWaylandInputDevice *inputDevice);
- virtual QWaylandKeyboard *createKeyboardDevice(QWaylandInputDevice *inputDevice);
- virtual QWaylandTouch *createTouchDevice(QWaylandInputDevice *inputDevice);
+ virtual QWaylandSeat *createSeat();
+ virtual QWaylandPointer *createPointerDevice(QWaylandSeat *seat);
+ virtual QWaylandKeyboard *createKeyboardDevice(QWaylandSeat *seat);
+ virtual QWaylandTouch *createTouchDevice(QWaylandSeat *seat);
QWaylandCompositor(QWaylandCompositorPrivate &dptr, QObject *parent = nullptr);
};
diff --git a/src/compositor/compositor_api/qwaylandcompositor_p.h b/src/compositor/compositor_api/qwaylandcompositor_p.h
index 8966acb38..5255f3d58 100644
--- a/src/compositor/compositor_api/qwaylandcompositor_p.h
+++ b/src/compositor/compositor_api/qwaylandcompositor_p.h
@@ -64,6 +64,7 @@ namespace QtWayland {
class ClientBufferIntegration;
class ServerBufferIntegration;
class DataDeviceManager;
+ class BufferManager;
}
class QWindowSystemEventHandler;
@@ -77,6 +78,7 @@ public:
QWaylandCompositorPrivate(QWaylandCompositor *compositor);
~QWaylandCompositorPrivate();
+ void preInit();
void init();
void destroySurface(QWaylandSurface *surface);
@@ -88,14 +90,15 @@ public:
inline QtWayland::ServerBufferIntegration *serverBufferIntegration() const;
QtWayland::DataDeviceManager *dataDeviceManager() const { return data_device_manager; }
+ QtWayland::BufferManager *bufferManager() const { return buffer_manager; }
void feedRetainedSelectionData(QMimeData *data);
- QWaylandPointer *callCreatePointerDevice(QWaylandInputDevice *inputDevice)
- { return q_func()->createPointerDevice(inputDevice); }
- QWaylandKeyboard *callCreateKeyboardDevice(QWaylandInputDevice *inputDevice)
- { return q_func()->createKeyboardDevice(inputDevice); }
- QWaylandTouch *callCreateTouchDevice(QWaylandInputDevice *inputDevice)
- { return q_func()->createTouchDevice(inputDevice); }
+ QWaylandPointer *callCreatePointerDevice(QWaylandSeat *seat)
+ { return q_func()->createPointerDevice(seat); }
+ QWaylandKeyboard *callCreateKeyboardDevice(QWaylandSeat *seat)
+ { return q_func()->createKeyboardDevice(seat); }
+ QWaylandTouch *callCreateTouchDevice(QWaylandSeat *seat)
+ { return q_func()->createTouchDevice(seat); }
inline void addClient(QWaylandClient *client);
inline void removeClient(QWaylandClient *client);
@@ -114,7 +117,7 @@ protected:
protected:
void initializeHardwareIntegration();
void initializeExtensions();
- void initializeDefaultInputDevice();
+ void initializeSeats();
void loadClientBufferIntegration();
void loadServerBufferIntegration();
@@ -122,12 +125,13 @@ protected:
QByteArray socket_name;
struct wl_display *display;
- QList<QWaylandInputDevice *> inputDevices;
+ QList<QWaylandSeat *> seats;
QList<QWaylandOutput *> outputs;
QList<QWaylandSurface *> all_surfaces;
QtWayland::DataDeviceManager *data_device_manager;
+ QtWayland::BufferManager *buffer_manager;
QElapsedTimer timer;
@@ -135,7 +139,7 @@ protected:
QList<QWaylandClient *> clients;
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
bool use_hw_integration_extension;
QScopedPointer<QtWayland::HardwareIntegration> hw_integration;
QScopedPointer<QtWayland::ClientBufferIntegration> client_buffer_integration;
@@ -145,6 +149,7 @@ protected:
QScopedPointer<QWindowSystemEventHandler> eventHandler;
bool retainSelection;
+ bool preInitialized;
bool initialized;
QList<QPointer<QObject> > polish_objects;
@@ -154,7 +159,7 @@ protected:
QtWayland::ClientBufferIntegration * QWaylandCompositorPrivate::clientBufferIntegration() const
{
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
return client_buffer_integration.data();
#else
return 0;
@@ -163,7 +168,7 @@ QtWayland::ClientBufferIntegration * QWaylandCompositorPrivate::clientBufferInte
QtWayland::ServerBufferIntegration * QWaylandCompositorPrivate::serverBufferIntegration() const
{
-#ifdef QT_COMPOSITOR_WAYLAND_GL
+#ifdef QT_WAYLAND_COMPOSITOR_GL
return server_buffer_integration.data();
#else
return 0;
@@ -185,16 +190,20 @@ void QWaylandCompositorPrivate::removeClient(QWaylandClient *client)
void QWaylandCompositorPrivate::addOutput(QWaylandOutput *output)
{
Q_ASSERT(output);
+ Q_Q(QWaylandCompositor);
if (outputs.contains(output))
return;
outputs.append(output);
+ emit q->outputAdded(output);
}
void QWaylandCompositorPrivate::removeOutput(QWaylandOutput *output)
{
Q_ASSERT(output);
Q_ASSERT(outputs.count(output) == 1);
- outputs.removeOne(output);
+ Q_Q(QWaylandCompositor);
+ if (outputs.removeOne(output))
+ emit q->outputRemoved(output);
}
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylanddestroylistener_p.h b/src/compositor/compositor_api/qwaylanddestroylistener_p.h
index 63b2d3ce9..03ba73a7f 100644
--- a/src/compositor/compositor_api/qwaylanddestroylistener_p.h
+++ b/src/compositor/compositor_api/qwaylanddestroylistener_p.h
@@ -48,7 +48,7 @@
// We mean it.
//
-#include "qwaylanddestroylistener.h"
+#include <QtWaylandCompositor/QWaylandDestroyListener>
#include <QtCore/private/qobject_p.h>
diff --git a/src/compositor/compositor_api/qwaylanddrag.cpp b/src/compositor/compositor_api/qwaylanddrag.cpp
index cc45c1279..3c3d9ce52 100644
--- a/src/compositor/compositor_api/qwaylanddrag.cpp
+++ b/src/compositor/compositor_api/qwaylanddrag.cpp
@@ -40,33 +40,33 @@
#include "qwldatadevice_p.h"
#include "qwaylandview.h"
-#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/private/qwaylandseat_p.h>
QT_BEGIN_NAMESPACE
class QWaylandDragPrivate : public QObjectPrivate
{
public:
- QWaylandDragPrivate(QWaylandInputDevice *id)
- : inputDevice(id)
+ QWaylandDragPrivate(QWaylandSeat *seat)
+ : seat(seat)
{
}
QtWayland::DataDevice *dataDevice()
{
- return QWaylandInputDevicePrivate::get(inputDevice)->dataDevice();
+ return QWaylandSeatPrivate::get(seat)->dataDevice();
}
const QtWayland::DataDevice *dataDevice() const
{
- return QWaylandInputDevicePrivate::get(inputDevice)->dataDevice();
+ return QWaylandSeatPrivate::get(seat)->dataDevice();
}
- QWaylandInputDevice *inputDevice;
+ QWaylandSeat *seat;
};
-QWaylandDrag::QWaylandDrag(QWaylandInputDevice *inputDevice)
- : QObject(* new QWaylandDragPrivate(inputDevice))
+QWaylandDrag::QWaylandDrag(QWaylandSeat *seat)
+ : QObject(* new QWaylandDragPrivate(seat))
{
}
@@ -81,6 +81,19 @@ QWaylandSurface *QWaylandDrag::icon() const
return dataDevice->dragIcon();
}
+QWaylandSurface *QWaylandDrag::origin() const
+{
+ Q_D(const QWaylandDrag);
+ const QtWayland::DataDevice *dataDevice = d->dataDevice();
+ return dataDevice ? dataDevice->dragOrigin() : nullptr;
+}
+
+QWaylandSeat *QWaylandDrag::seat() const
+{
+ Q_D(const QWaylandDrag);
+ return d->seat;
+}
+
bool QWaylandDrag::visible() const
{
diff --git a/src/compositor/compositor_api/qwaylanddrag.h b/src/compositor/compositor_api/qwaylanddrag.h
index 00a2bee8e..08ad11018 100644
--- a/src/compositor/compositor_api/qwaylanddrag.h
+++ b/src/compositor/compositor_api/qwaylanddrag.h
@@ -46,12 +46,7 @@ QT_BEGIN_NAMESPACE
class QWaylandDragPrivate;
class QWaylandSurface;
-class QWaylandView;
-class QWaylandInputDevice;
-
-namespace QtWayland {
- class DataDevice;
-}
+class QWaylandSeat;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandDrag : public QObject
{
@@ -62,10 +57,11 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandDrag : public QObject
Q_PROPERTY(bool visible READ visible NOTIFY iconChanged)
public:
- explicit QWaylandDrag(QWaylandInputDevice *inputDevice);
+ explicit QWaylandDrag(QWaylandSeat *seat);
QWaylandSurface *icon() const;
- // QPointF position() const;
+ QWaylandSurface *origin() const;
+ QWaylandSeat *seat() const;
bool visible() const;
public Q_SLOTS:
@@ -76,9 +72,6 @@ public Q_SLOTS:
Q_SIGNALS:
void iconChanged();
void dragStarted(); // QWaylandSurface *icon????
-
-private:
- //friend class QtWayland::DataDevice;
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp
index 122c589da..68279bb97 100644
--- a/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp
+++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.cpp
@@ -38,7 +38,7 @@
#include "qwaylandinputmethodcontrol_p.h"
#include "qwaylandcompositor.h"
-#include "qwaylandinput.h"
+#include "qwaylandseat.h"
#include "qwaylandsurface.h"
#include "qwaylandview.h"
#include "qwaylandtextinput.h"
@@ -48,8 +48,8 @@
QWaylandInputMethodControl::QWaylandInputMethodControl(QWaylandSurface *surface)
: QObject(*new QWaylandInputMethodControlPrivate(surface), surface)
{
- connect(d_func()->compositor, &QWaylandCompositor::defaultInputDeviceChanged,
- this, &QWaylandInputMethodControl::defaultInputDeviceChanged);
+ connect(d_func()->compositor, &QWaylandCompositor::defaultSeatChanged,
+ this, &QWaylandInputMethodControl::defaultSeatChanged);
QWaylandTextInput *textInput = d_func()->textInput();
if (textInput) {
connect(textInput, &QWaylandTextInput::surfaceEnabled, this, &QWaylandInputMethodControl::surfaceEnabled);
@@ -135,13 +135,13 @@ void QWaylandInputMethodControl::setSurface(QWaylandSurface *surface)
setEnabled(textInput && textInput->isSurfaceEnabled(d->surface));
}
-void QWaylandInputMethodControl::defaultInputDeviceChanged()
+void QWaylandInputMethodControl::defaultSeatChanged()
{
Q_D(QWaylandInputMethodControl);
disconnect(d->textInput(), 0, this, 0);
- d->inputDevice = d->compositor->defaultInputDevice();
+ d->seat = d->compositor->defaultSeat();
QWaylandTextInput *textInput = d->textInput();
connect(textInput, &QWaylandTextInput::surfaceEnabled, this, &QWaylandInputMethodControl::surfaceEnabled);
@@ -153,7 +153,7 @@ void QWaylandInputMethodControl::defaultInputDeviceChanged()
QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSurface *surface)
: QObjectPrivate()
, compositor(surface->compositor())
- , inputDevice(compositor->defaultInputDevice())
+ , seat(compositor->defaultSeat())
, surface(surface)
, enabled(false)
{
@@ -161,5 +161,5 @@ QWaylandInputMethodControlPrivate::QWaylandInputMethodControlPrivate(QWaylandSur
QWaylandTextInput *QWaylandInputMethodControlPrivate::textInput() const
{
- return QWaylandTextInput::findIn(inputDevice);
+ return QWaylandTextInput::findIn(seat);
}
diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol.h b/src/compositor/compositor_api/qwaylandinputmethodcontrol.h
index f71650294..ab894c9c5 100644
--- a/src/compositor/compositor_api/qwaylandinputmethodcontrol.h
+++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol.h
@@ -74,7 +74,7 @@ Q_SIGNALS:
#endif
private:
- void defaultInputDeviceChanged();
+ void defaultSeatChanged();
void surfaceEnabled(QWaylandSurface *surface);
void surfaceDisabled(QWaylandSurface *surface);
};
diff --git a/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h b/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h
index a687e5299..a4f9ce877 100644
--- a/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h
+++ b/src/compositor/compositor_api/qwaylandinputmethodcontrol_p.h
@@ -56,7 +56,7 @@
QT_BEGIN_NAMESPACE
class QWaylandCompositor;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandSurface;
class QWaylandTextInput;
@@ -70,7 +70,7 @@ public:
QWaylandTextInput *textInput() const;
QWaylandCompositor *compositor;
- QWaylandInputDevice *inputDevice;
+ QWaylandSeat *seat;
QWaylandSurface *surface;
bool enabled;
};
diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp
index 22870654e..5bbec0a45 100644
--- a/src/compositor/compositor_api/qwaylandkeyboard.cpp
+++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp
@@ -37,8 +37,9 @@
#include "qwaylandkeyboard.h"
#include "qwaylandkeyboard_p.h"
+#include <QtWaylandCompositor/QWaylandKeymap>
#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include <QtWaylandCompositor/QWaylandClient>
#include <QtCore/QFile>
@@ -53,7 +54,7 @@
QT_BEGIN_NAMESPACE
-QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandInputDevice *seat)
+QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandSeat *seat)
: QtWaylandServer::wl_keyboard()
, seat(seat)
, focus()
@@ -71,9 +72,6 @@ QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandInputDevice *seat)
, repeatRate(40)
, repeatDelay(400)
{
-#ifndef QT_NO_WAYLAND_XKB
- initXKB();
-#endif
}
QWaylandKeyboardPrivate::~QWaylandKeyboardPrivate()
@@ -232,7 +230,10 @@ void QWaylandKeyboardPrivate::updateModifierState(uint code, uint32_t state)
#endif
}
-void QWaylandKeyboardPrivate::updateKeymap()
+// If there is no key currently pressed, update the keymap right away.
+// Otherwise, delay the update when keys are released
+// see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
+void QWaylandKeyboardPrivate::maybeUpdateKeymap()
{
// There must be no keys pressed when changing the keymap,
// see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
@@ -348,18 +349,19 @@ void QWaylandKeyboardPrivate::createXKBKeymap()
if (!xkb_context)
return;
- struct xkb_rule_names rule_names = { strdup(qPrintable(keymap.rules())),
- strdup(qPrintable(keymap.model())),
- strdup(qPrintable(keymap.layout())),
- strdup(qPrintable(keymap.variant())),
- strdup(qPrintable(keymap.options())) };
- struct xkb_keymap *keymap = xkb_keymap_new_from_names(xkb_context, &rule_names, static_cast<xkb_keymap_compile_flags>(0));
-
- if (keymap) {
- createXKBState(keymap);
- xkb_keymap_unref(keymap);
+ auto keymap = seat->keymap();
+ struct xkb_rule_names rule_names = { strdup(qPrintable(keymap->rules())),
+ strdup(qPrintable(keymap->model())),
+ strdup(qPrintable(keymap->layout())),
+ strdup(qPrintable(keymap->variant())),
+ strdup(qPrintable(keymap->options())) };
+ struct xkb_keymap *xkbKeymap = xkb_keymap_new_from_names(xkb_context, &rule_names, static_cast<xkb_keymap_compile_flags>(0));
+
+ if (xkbKeymap) {
+ createXKBState(xkbKeymap);
+ xkb_keymap_unref(xkbKeymap);
} else {
- qWarning("Failed to load the '%s' XKB keymap.", qPrintable(this->keymap.layout()));
+ qWarning("Failed to load the '%s' XKB keymap.", qPrintable(keymap->layout()));
}
free((char *)rule_names.rules);
@@ -381,27 +383,36 @@ void QWaylandKeyboardPrivate::sendRepeatInfo()
/*!
* \class QWaylandKeyboard
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandKeyboard class represents a keyboard device.
*
- * This class provides access to the keyboard device in a QWaylandInputDevice. It corresponds to
+ * This class provides access to the keyboard device in a QWaylandSeat. It corresponds to
* the Wayland interface wl_keyboard.
*/
/*!
- * Constructs a QWaylandKeyboard for the given \a inputDevice and with the given \a parent.
+ * Constructs a QWaylandKeyboard for the given \a seat and with the given \a parent.
*/
-QWaylandKeyboard::QWaylandKeyboard(QWaylandInputDevice *inputDevice, QObject *parent)
- : QWaylandObject(* new QWaylandKeyboardPrivate(inputDevice), parent)
+QWaylandKeyboard::QWaylandKeyboard(QWaylandSeat *seat, QObject *parent)
+ : QWaylandObject(* new QWaylandKeyboardPrivate(seat), parent)
{
Q_D(QWaylandKeyboard);
connect(&d->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandKeyboard::focusDestroyed);
+ auto keymap = seat->keymap();
+ connect(keymap, &QWaylandKeymap::layoutChanged, this, &QWaylandKeyboard::updateKeymap);
+ connect(keymap, &QWaylandKeymap::variantChanged, this, &QWaylandKeyboard::updateKeymap);
+ connect(keymap, &QWaylandKeymap::optionsChanged, this, &QWaylandKeyboard::updateKeymap);
+ connect(keymap, &QWaylandKeymap::rulesChanged, this, &QWaylandKeyboard::updateKeymap);
+ connect(keymap, &QWaylandKeymap::modelChanged, this, &QWaylandKeyboard::updateKeymap);
+#ifndef QT_NO_WAYLAND_XKB
+ d->initXKB();
+#endif
}
/*!
- * Returns the input device for this QWaylandKeyboard.
+ * Returns the seat for this QWaylandKeyboard.
*/
-QWaylandInputDevice *QWaylandKeyboard::inputDevice() const
+QWaylandSeat *QWaylandKeyboard::seat() const
{
Q_D(const QWaylandKeyboard);
return d->seat;
@@ -429,6 +440,13 @@ void QWaylandKeyboard::focusDestroyed(void *data)
d->focusResource = 0;
}
+void QWaylandKeyboard::updateKeymap()
+{
+ Q_D(QWaylandKeyboard);
+ d->pendingKeymap = true;
+ d->maybeUpdateKeymap();
+}
+
/*!
* Returns the client that currently has keyboard focus.
*/
@@ -538,23 +556,6 @@ void QWaylandKeyboard::setFocus(QWaylandSurface *surface)
}
/*!
- * Sets the keyboard's keymap to \a keymap.
- */
-void QWaylandKeyboard::setKeymap(const QWaylandKeymap &keymap)
-{
- Q_D(QWaylandKeyboard);
- d->keymap = keymap;
- d->pendingKeymap = true;
-
- // If there is no key currently pressed, update right away the keymap
- // Otherwise, delay the update when keys are released
- // see http://lists.freedesktop.org/archives/wayland-devel/2013-October/011395.html
- if (d->keys.isEmpty()) {
- d->updateKeymap();
- }
-}
-
-/*!
* \internal
*/
void QWaylandKeyboard::addClient(QWaylandClient *client, uint32_t id, uint32_t version)
diff --git a/src/compositor/compositor_api/qwaylandkeyboard.h b/src/compositor/compositor_api/qwaylandkeyboard.h
index b5bf6fe5c..685134ff7 100644
--- a/src/compositor/compositor_api/qwaylandkeyboard.h
+++ b/src/compositor/compositor_api/qwaylandkeyboard.h
@@ -47,27 +47,8 @@ QT_BEGIN_NAMESPACE
class QWaylandKeyboard;
class QWaylandKeyboardPrivate;
-class QWaylandInputDevice;
-
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeymap
-{
-public:
- QWaylandKeymap(const QString &layout = QString(), const QString &variant = QString(), const QString &options = QString(),
- const QString &model = QString(), const QString &rules = QString());
-
- inline QString layout() const { return m_layout; }
- inline QString variant() const { return m_variant; }
- inline QString options() const { return m_options; }
- inline QString rules() const { return m_rules; }
- inline QString model() const { return m_model; }
-
-private:
- QString m_layout;
- QString m_variant;
- QString m_options;
- QString m_rules;
- QString m_model;
-};
+class QWaylandSeat;
+class QWaylandKeymap;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeyboard : public QWaylandObject
{
@@ -76,9 +57,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeyboard : public QWaylandObject
Q_PROPERTY(quint32 repeatRate READ repeatRate WRITE setRepeatRate NOTIFY repeatRateChanged)
Q_PROPERTY(quint32 repeatDelay READ repeatDelay WRITE setRepeatDelay NOTIFY repeatDelayChanged)
public:
- QWaylandKeyboard(QWaylandInputDevice *inputDevice, QObject *parent = nullptr);
+ QWaylandKeyboard(QWaylandSeat *seat, QObject *parent = nullptr);
- QWaylandInputDevice *inputDevice() const;
+ QWaylandSeat *seat() const;
QWaylandCompositor *compositor() const;
quint32 repeatRate() const;
@@ -88,7 +69,6 @@ public:
void setRepeatDelay(quint32 delay);
virtual void setFocus(QWaylandSurface *surface);
- virtual void setKeymap(const QWaylandKeymap &keymap);
virtual void sendKeyModifiers(QWaylandClient *client, uint32_t serial);
virtual void sendKeyPressEvent(uint code);
@@ -106,6 +86,9 @@ Q_SIGNALS:
private:
void focusDestroyed(void *data);
+
+private Q_SLOTS:
+ void updateKeymap();
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandkeyboard_p.h b/src/compositor/compositor_api/qwaylandkeyboard_p.h
index ede97d8ba..fc43853cc 100644
--- a/src/compositor/compositor_api/qwaylandkeyboard_p.h
+++ b/src/compositor/compositor_api/qwaylandkeyboard_p.h
@@ -50,7 +50,7 @@
//
#include <QtWaylandCompositor/qwaylandexport.h>
-#include <QtWaylandCompositor/qwaylandinput.h>
+#include <QtWaylandCompositor/qwaylandseat.h>
#include <QtWaylandCompositor/qwaylandkeyboard.h>
#include <QtWaylandCompositor/qwaylanddestroylistener.h>
@@ -74,7 +74,7 @@ public:
static QWaylandKeyboardPrivate *get(QWaylandKeyboard *keyboard);
- QWaylandKeyboardPrivate(QWaylandInputDevice *seat);
+ QWaylandKeyboardPrivate(QWaylandSeat *seat);
~QWaylandKeyboardPrivate();
QWaylandCompositor *compositor() const { return seat->compositor(); }
@@ -91,7 +91,7 @@ public:
void keyEvent(uint code, uint32_t state);
void sendKeyEvent(uint code, uint32_t state);
void updateModifierState(uint code, uint32_t state);
- void updateKeymap();
+ void maybeUpdateKeymap();
void checkFocusResource(Resource *resource);
void sendEnter(QWaylandSurface *surface, Resource *resource);
@@ -111,7 +111,7 @@ private:
void sendRepeatInfo();
- QWaylandInputDevice *seat;
+ QWaylandSeat *seat;
QWaylandSurface *focus;
Resource *focusResource;
@@ -123,7 +123,6 @@ private:
uint32_t modsLocked;
uint32_t group;
- QWaylandKeymap keymap;
bool pendingKeymap;
#ifndef QT_NO_WAYLAND_XKB
size_t keymap_size;
diff --git a/src/compositor/compositor_api/qwaylandkeymap.cpp b/src/compositor/compositor_api/qwaylandkeymap.cpp
new file mode 100644
index 000000000..d11070f26
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandkeymap.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandkeymap.h"
+#include "qwaylandkeymap_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, const QString &options, const QString &model, const QString &rules, QObject *parent)
+ : QObject(*new QWaylandKeymapPrivate(layout, variant, options, model, rules), parent)
+{
+}
+
+QString QWaylandKeymap::layout() const {
+ Q_D(const QWaylandKeymap);
+ return d->m_layout;
+}
+
+void QWaylandKeymap::setLayout(const QString &layout)
+{
+ Q_D(QWaylandKeymap);
+ if (d->m_layout == layout)
+ return;
+ d->m_layout = layout;
+ emit layoutChanged();
+}
+
+QString QWaylandKeymap::variant() const
+{
+ Q_D(const QWaylandKeymap);
+ return d->m_variant;
+}
+
+void QWaylandKeymap::setVariant(const QString &variant)
+{
+ Q_D(QWaylandKeymap);
+ if (d->m_variant == variant)
+ return;
+ d->m_variant = variant;
+ emit variantChanged();
+}
+
+QString QWaylandKeymap::options() const {
+ Q_D(const QWaylandKeymap);
+ return d->m_options;
+}
+
+void QWaylandKeymap::setOptions(const QString &options)
+{
+ Q_D(QWaylandKeymap);
+ if (d->m_options == options)
+ return;
+ d->m_options = options;
+ emit optionsChanged();
+}
+
+QString QWaylandKeymap::rules() const {
+ Q_D(const QWaylandKeymap);
+ return d->m_rules;
+}
+
+void QWaylandKeymap::setRules(const QString &rules)
+{
+ Q_D(QWaylandKeymap);
+ if (d->m_rules == rules)
+ return;
+ d->m_rules = rules;
+ emit rulesChanged();
+}
+
+QString QWaylandKeymap::model() const {
+ Q_D(const QWaylandKeymap);
+ return d->m_model;
+}
+
+void QWaylandKeymap::setModel(const QString &model)
+{
+ Q_D(QWaylandKeymap);
+ if (d->m_model == model)
+ return;
+ d->m_model = model;
+ emit modelChanged();
+}
+
+QWaylandKeymapPrivate::QWaylandKeymapPrivate(const QString &layout, const QString &variant,
+ const QString &options, const QString &model,
+ const QString &rules)
+ : m_layout(layout)
+ , m_variant(variant)
+ , m_options(options)
+ , m_rules(rules)
+ , m_model(model)
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandkeymap.h b/src/compositor/compositor_api/qwaylandkeymap.h
new file mode 100644
index 000000000..c543691df
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandkeymap.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDKEYMAP_H
+#define QWAYLANDKEYMAP_H
+
+#include <QtCore/QObject>
+#include <QtWaylandCompositor/qwaylandexport.h>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandKeymapPrivate;
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeymap : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandKeymap)
+ Q_PROPERTY(QString layout READ layout WRITE setLayout NOTIFY layoutChanged)
+ Q_PROPERTY(QString variant READ variant WRITE setVariant NOTIFY variantChanged)
+ Q_PROPERTY(QString options READ options WRITE setOptions NOTIFY optionsChanged)
+ Q_PROPERTY(QString rules READ rules WRITE setRules NOTIFY rulesChanged)
+ Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged)
+public:
+ QWaylandKeymap(const QString &layout = QString(), const QString &variant = QString(), const QString &options = QString(),
+ const QString &model = QString(), const QString &rules = QString(), QObject *parent = nullptr);
+
+ QString layout() const;
+ void setLayout(const QString &layout);
+ QString variant() const;
+ void setVariant(const QString &variant);
+ QString options() const;
+ void setOptions(const QString &options);
+ QString rules() const;
+ void setRules(const QString &rules);
+ QString model() const;
+ void setModel(const QString &model);
+
+Q_SIGNALS:
+ void layoutChanged();
+ void variantChanged();
+ void optionsChanged();
+ void rulesChanged();
+ void modelChanged();
+};
+
+QT_END_NAMESPACE
+
+#endif //QWAYLANDKEYMAP_H
diff --git a/src/compositor/compositor_api/qwaylandkeymap_p.h b/src/compositor/compositor_api/qwaylandkeymap_p.h
new file mode 100644
index 000000000..2c968ef38
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandkeymap_p.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDKEYMAP_P_H
+#define QWAYLANDKEYMAP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtWaylandCompositor/qwaylandkeymap.h>
+#include <QtCore/private/qobject_p.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandKeymapPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QWaylandKeymap)
+public:
+ QWaylandKeymapPrivate(const QString &layout, const QString &variant, const QString &options,
+ const QString &model, const QString &rules);
+
+ QString m_layout;
+ QString m_variant;
+ QString m_options;
+ QString m_rules;
+ QString m_model;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDKEYMAP_P_H
diff --git a/src/compositor/compositor_api/qwaylandoutput.cpp b/src/compositor/compositor_api/qwaylandoutput.cpp
index a2ebf8b25..0129bd33b 100644
--- a/src/compositor/compositor_api/qwaylandoutput.cpp
+++ b/src/compositor/compositor_api/qwaylandoutput.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2014-2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt.io/licensing/
**
@@ -48,6 +48,7 @@
#include <QtCore/QtMath>
#include <QtGui/QWindow>
#include <QtGui/QExposeEvent>
+#include <QtGui/QScreen>
#include <private/qobject_p.h>
QT_BEGIN_NAMESPACE
@@ -102,16 +103,14 @@ QWaylandOutputPrivate::QWaylandOutputPrivate()
: QtWaylandServer::wl_output()
, compositor(Q_NULLPTR)
, window(Q_NULLPTR)
+ , currentMode(-1)
+ , preferredMode(-1)
, subpixel(QWaylandOutput::SubpixelUnknown)
, transform(QWaylandOutput::TransformNormal)
, scaleFactor(1)
- , sizeFollowsWindow(true)
+ , sizeFollowsWindow(false)
, initialized(false)
{
- mode.size = QSize();
- mode.refreshRate = 60;
-
- qRegisterMetaType<QWaylandOutput::Mode>("WaylandOutput::Mode");
}
QWaylandOutputPrivate::~QWaylandOutputPrivate()
@@ -120,15 +119,10 @@ QWaylandOutputPrivate::~QWaylandOutputPrivate()
void QWaylandOutputPrivate::output_bind_resource(Resource *resource)
{
- send_geometry(resource->handle,
- position.x(), position.y(),
- physicalSize.width(), physicalSize.height(),
- toWlSubpixel(subpixel), manufacturer, model,
- toWlTransform(transform));
+ sendGeometry(resource);
- send_mode(resource->handle, mode_current | mode_preferred,
- mode.size.width(), mode.size.height(),
- mode.refreshRate * 1000);
+ for (const QWaylandOutputMode &mode : modes)
+ sendMode(resource, mode);
if (resource->version() >= 2) {
send_scale(resource->handle, scaleFactor);
@@ -136,19 +130,46 @@ void QWaylandOutputPrivate::output_bind_resource(Resource *resource)
}
}
+void QWaylandOutputPrivate::sendGeometry(const Resource *resource)
+{
+ send_geometry(resource->handle,
+ position.x(), position.y(),
+ physicalSize.width(), physicalSize.height(),
+ toWlSubpixel(subpixel), manufacturer, model,
+ toWlTransform(transform));
+}
+
void QWaylandOutputPrivate::sendGeometryInfo()
{
- Q_FOREACH (Resource *resource, resourceMap().values()) {
- send_geometry(resource->handle,
- position.x(), position.y(),
- physicalSize.width(), physicalSize.height(),
- toWlSubpixel(subpixel), manufacturer, model,
- toWlTransform(transform));
+ for (const Resource *resource : resourceMap().values()) {
+ sendGeometry(resource);
if (resource->version() >= 2)
send_done(resource->handle);
}
}
+void QWaylandOutputPrivate::sendMode(const Resource *resource, const QWaylandOutputMode &mode)
+{
+ quint32 flags = 0;
+ if (currentMode == modes.indexOf(mode))
+ flags |= QtWaylandServer::wl_output::mode_current;
+ if (preferredMode == modes.indexOf(mode))
+ flags |= QtWaylandServer::wl_output::mode_preferred;
+
+ send_mode(resource->handle, flags,
+ mode.size().width(), mode.size().height(),
+ mode.refreshRate());
+}
+
+void QWaylandOutputPrivate::sendModesInfo()
+{
+ for (const Resource *resource : resourceMap().values()) {
+ for (const QWaylandOutputMode &mode : modes)
+ sendMode(resource, mode);
+ if (resource->version() >= 2)
+ send_done(resource->handle);
+ }
+}
void QWaylandOutputPrivate::addView(QWaylandView *view, QWaylandSurface *surface)
{
@@ -189,7 +210,7 @@ QWaylandOutput::QWaylandOutput()
/*!
\qmltype WaylandOutput
\inqmlmodule QtWayland.Compositor
- \preliminary
+ \since 5.8
\brief Provides access to a displayable area managed by the compositor.
The WaylandOutput manages a rectangular area within bounds of the compositor's
@@ -202,7 +223,7 @@ QWaylandOutput::QWaylandOutput()
/*!
\class QWaylandOutput
\inmodule QtWaylandCompositor
- \preliminary
+ \since 5.8
\brief The QWaylandOutput class represents a displayable area managed by the compositor.
The QWaylandOutput manages a rectangular area within bounds of the compositor's
@@ -252,16 +273,23 @@ void QWaylandOutput::initialize()
Q_ASSERT(d->compositor);
Q_ASSERT(d->compositor->isCreated());
- if (d->window)
- d->mode.size = d->window->size();
- else
- d->sizeFollowsWindow = false;
+ // Replace modes with one that follows the window size and refresh rate,
+ // but only if window size is valid
+ if (d->window && d->sizeFollowsWindow) {
+ QWaylandOutputMode mode(d->window->size(),
+ qFloor(d->window->screen()->refreshRate() * 1000));
+ if (mode.isValid()) {
+ d->modes.clear();
+ addMode(mode, true);
+ setCurrentMode(mode);
+ }
+ }
QWaylandCompositorPrivate::get(d->compositor)->addOutput(this);
if (d->window) {
- QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth);
- QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight);
+ QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::handleSetWidth);
+ QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::handleSetHeight);
QObject::connect(d->window, &QObject::destroyed, this, &QWaylandOutput::handleWindowDestroyed);
}
@@ -431,39 +459,75 @@ void QWaylandOutput::setPosition(const QPoint &pt)
}
/*!
- * \property QWaylandOutput::mode
- *
- * This property holds the output's size in pixels and refresh rate in Hz.
+ * Returns the list of modes.
*/
-QWaylandOutput::Mode QWaylandOutput::mode() const
+QList<QWaylandOutputMode> QWaylandOutput::modes() const
{
- return d_func()->mode;
+ Q_D(const QWaylandOutput);
+ return d->modes.toList();
}
-void QWaylandOutput::setMode(const Mode &mode)
+/*!
+ * Adds the mode \a mode to the output and mark it as preferred
+ * if \a preferred is \c true.
+ * Please note there can only be one preferred mode.
+ */
+void QWaylandOutput::addMode(const QWaylandOutputMode &mode, bool preferred)
{
Q_D(QWaylandOutput);
- if (d->mode.size == mode.size && d->mode.refreshRate == mode.refreshRate)
+
+ if (!mode.isValid()) {
+ qWarning("Cannot add an invalid mode");
return;
+ }
- d->mode = mode;
+ d->modes.append(mode);
- Q_FOREACH (QWaylandOutputPrivate::Resource *resource, d->resourceMap().values()) {
- d->send_mode(resource->handle, d->mode_current,
- d->mode.size.width(), d->mode.size.height(),
- d->mode.refreshRate * 1000);
- if (resource->version() >= 2)
- d->send_done(resource->handle);
+ if (preferred)
+ d->preferredMode = d->modes.indexOf(mode);
+
+ emit modeAdded();
+}
+
+/*!
+ * Returns the output's size in pixels and refresh rate in mHz.
+ * If the current mode is not set it will return an invalid mode.
+ *
+ * \sa QWaylandOutput::modes
+ * \sa QWaylandOutputMode
+ */
+QWaylandOutputMode QWaylandOutput::currentMode() const
+{
+ Q_D(const QWaylandOutput);
+
+ if (d->currentMode >= 0 && d->currentMode <= d->modes.size() - 1)
+ return d->modes.at(d->currentMode);
+ return QWaylandOutputMode();
+}
+
+/*!
+ * Sets the current mode.
+ * The mode \a mode must have been previously added.
+ *
+ * \sa QWaylandOutput::modes
+ * \sa QWaylandOutputMode
+ */
+void QWaylandOutput::setCurrentMode(const QWaylandOutputMode &mode)
+{
+ Q_D(QWaylandOutput);
+
+ int index = d->modes.indexOf(mode);
+ if (index < 0) {
+ qWarning("Cannot set an unknown QWaylandOutput mode as current");
+ return;
}
- Q_EMIT modeChanged();
+ d->currentMode = index;
+
+ Q_EMIT currentModeChanged();
Q_EMIT geometryChanged();
- if (d->window) {
- d->window->resize(mode.size);
- d->window->setMinimumSize(mode.size);
- d->window->setMaximumSize(mode.size);
- }
+ d->sendModesInfo();
}
/*!
@@ -477,37 +541,12 @@ void QWaylandOutput::setMode(const Mode &mode)
*
* This property holds the geometry of the QWaylandOutput.
*
- * \sa QWaylandOutput::mode
+ * \sa QWaylandOutput::currentMode
*/
QRect QWaylandOutput::geometry() const
{
Q_D(const QWaylandOutput);
- return QRect(d->position, d->mode.size);
-}
-
-void QWaylandOutput::setGeometry(const QRect &geometry)
-{
- Q_D(QWaylandOutput);
- if (d->position == geometry.topLeft() && d->mode.size == geometry.size())
- return;
-
- d->position = geometry.topLeft();
- d->mode.size = geometry.size();
-
- Q_FOREACH (QWaylandOutputPrivate::Resource *resource, d->resourceMap().values()) {
- d->send_geometry(resource->handle,
- d->position.x(), d->position.y(),
- d->physicalSize.width(), d->physicalSize.height(),
- toWlSubpixel(d->subpixel), d->manufacturer, d->model,
- toWlTransform(d->transform));
- d->send_mode(resource->handle, d->mode_current,
- d->mode.size.width(), d->mode.size.height(),
- d->mode.refreshRate * 1000);
- if (resource->version() >= 2)
- d->send_done(resource->handle);
- }
- Q_EMIT positionChanged();
- Q_EMIT modeChanged();
+ return QRect(d->position, currentMode().size());
}
/*!
@@ -527,13 +566,14 @@ void QWaylandOutput::setGeometry(const QRect &geometry)
* The available geometry is in output coordinates space, starts from 0,0 and it's as big
* as the output by default.
*
- * \sa QWaylandOutput::mode, QWaylandOutput::geometry
+ * \sa QWaylandOutput::currentMode, QWaylandOutput::geometry
*/
QRect QWaylandOutput::availableGeometry() const
{
Q_D(const QWaylandOutput);
+
if (!d->availableGeometry.isValid())
- return QRect(QPoint(0, 0), d->mode.size);
+ return QRect(QPoint(0, 0), currentMode().size());
return d->availableGeometry;
}
@@ -565,7 +605,7 @@ void QWaylandOutput::setAvailableGeometry(const QRect &availableGeometry)
*
* This property holds the physical size of the QWaylandOutput in millimeters.
*
- * \sa QWaylandOutput::geometry, QWaylandOutput::mode
+ * \sa QWaylandOutput::geometry, QWaylandOutput::currentMode
*/
QSize QWaylandOutput::physicalSize() const
{
@@ -755,7 +795,10 @@ void QWaylandOutput::setScaleFactor(int scale)
* This property controls whether the size of the WaylandOutput matches the
* size of its window.
*
- * The default is \c true if this WaylandOutput has a window.
+ * If this property is true, all modes previously added are replaced by a
+ * mode that matches window size and screen refresh rate.
+ *
+ * The default is false.
*/
/*!
@@ -764,7 +807,10 @@ void QWaylandOutput::setScaleFactor(int scale)
* This property controls whether the size of the QWaylandOutput matches the
* size of its window.
*
- * The default is \c true if this QWaylandOutput has a window.
+ * If this property is true, all modes previously added are replaced by a
+ * mode that matches window size and screen refresh rate.
+ *
+ * The default is false.
*/
bool QWaylandOutput::sizeFollowsWindow() const
{
@@ -781,13 +827,6 @@ void QWaylandOutput::setSizeFollowsWindow(bool follow)
}
if (follow != d->sizeFollowsWindow) {
- if (follow) {
- QObject::connect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth);
- QObject::connect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight);
- } else {
- QObject::disconnect(d->window, &QWindow::widthChanged, this, &QWaylandOutput::setWidth);
- QObject::disconnect(d->window, &QWindow::heightChanged, this, &QWaylandOutput::setHeight);
- }
d->sizeFollowsWindow = follow;
Q_EMIT sizeFollowsWindowChanged();
}
@@ -833,7 +872,7 @@ void QWaylandOutput::frameStarted()
Q_D(QWaylandOutput);
for (int i = 0; i < d->surfaceViews.size(); i++) {
QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews[i];
- if (surfacemapper.maybeThrottelingView())
+ if (surfacemapper.maybePrimaryView())
surfacemapper.surface->frameStarted();
}
}
@@ -846,12 +885,12 @@ void QWaylandOutput::sendFrameCallbacks()
Q_D(QWaylandOutput);
for (int i = 0; i < d->surfaceViews.size(); i++) {
const QWaylandSurfaceViewMapper &surfacemapper = d->surfaceViews.at(i);
- if (surfacemapper.surface && surfacemapper.surface->isMapped()) {
+ if (surfacemapper.surface && surfacemapper.surface->hasContent()) {
if (!surfacemapper.has_entered) {
surfaceEnter(surfacemapper.surface);
d->surfaceViews[i].has_entered = true;
}
- if (surfacemapper.maybeThrottelingView())
+ if (surfacemapper.maybePrimaryView())
surfacemapper.surface->sendFrameCallbacks();
}
}
@@ -882,35 +921,63 @@ void QWaylandOutput::surfaceLeave(QWaylandSurface *surface)
}
/*!
- * Sets the width of this QWaylandOutput to \a newWidth.
- *
- * \sa setHeight, QWaylandOutput::geometry
+ * \internal
*/
-void QWaylandOutput::setWidth(int newWidth)
+void QWaylandOutput::handleSetWidth(int newWidth)
{
Q_D(QWaylandOutput);
- if (d->mode.size.width() == newWidth)
+
+ if (!d->window || !d->sizeFollowsWindow)
return;
- QSize s = d->mode.size;
- s.setWidth(newWidth);
- setGeometry(QRect(d->position, s));
+ if (d->currentMode <= d->modes.size() - 1) {
+ if (d->currentMode >= 0) {
+ QWaylandOutputMode mode = d->modes.at(d->currentMode);
+ mode.setWidth(newWidth);
+ d->modes.replace(d->currentMode, mode);
+ d->sendModesInfo();
+ } else {
+ // We didn't add a mode during the initialization because the window
+ // size was invalid, let's add it now
+ QWaylandOutputMode mode(d->window->size(),
+ qFloor(d->window->screen()->refreshRate() * 1000));
+ if (mode.isValid()) {
+ d->modes.clear();
+ addMode(mode, true);
+ setCurrentMode(mode);
+ }
+ }
+ }
}
/*!
- * Sets the height of this QWaylandOutput to \a newHeight.
- *
- * \sa setWidth, QWaylandOutput::geometry
+ * \internal
*/
-void QWaylandOutput::setHeight(int newHeight)
+void QWaylandOutput::handleSetHeight(int newHeight)
{
Q_D(QWaylandOutput);
- if (d->mode.size.height() == newHeight)
+
+ if (!d->window || !d->sizeFollowsWindow)
return;
- QSize s = d->mode.size;
- s.setHeight(newHeight);
- setGeometry(QRect(d->position, s));
+ if (d->currentMode <= d->modes.size() - 1) {
+ if (d->currentMode >= 0) {
+ QWaylandOutputMode mode = d->modes.at(d->currentMode);
+ mode.setHeight(newHeight);
+ d->modes.replace(d->currentMode, mode);
+ d->sendModesInfo();
+ } else {
+ // We didn't add a mode during the initialization because the window
+ // size was invalid, let's add it now
+ QWaylandOutputMode mode(d->window->size(),
+ qFloor(d->window->screen()->refreshRate() * 1000));
+ if (mode.isValid()) {
+ d->modes.clear();
+ addMode(mode, true);
+ setCurrentMode(mode);
+ }
+ }
+ }
}
/*!
diff --git a/src/compositor/compositor_api/qwaylandoutput.h b/src/compositor/compositor_api/qwaylandoutput.h
index e4cbb6109..190231c12 100644
--- a/src/compositor/compositor_api/qwaylandoutput.h
+++ b/src/compositor/compositor_api/qwaylandoutput.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2014-2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Contact: http://www.qt.io/licensing/
**
@@ -39,6 +39,7 @@
#define QWAYLANDOUTPUT_H
#include <QtWaylandCompositor/qwaylandcompositorextension.h>
+#include <QtWaylandCompositor/QWaylandOutputMode>
#include <QtCore/QObject>
#include <QObject>
@@ -66,7 +67,6 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandOutput : public QWaylandObject
Q_PROPERTY(QString manufacturer READ manufacturer WRITE setManufacturer NOTIFY manufacturerChanged)
Q_PROPERTY(QString model READ model WRITE setModel NOTIFY modelChanged)
Q_PROPERTY(QPoint position READ position WRITE setPosition NOTIFY positionChanged)
- Q_PROPERTY(QWaylandOutput::Mode mode READ mode WRITE setMode NOTIFY modeChanged)
Q_PROPERTY(QRect geometry READ geometry NOTIFY geometryChanged)
Q_PROPERTY(QRect availableGeometry READ availableGeometry WRITE setAvailableGeometry NOTIFY availableGeometryChanged)
Q_PROPERTY(QSize physicalSize READ physicalSize WRITE setPhysicalSize NOTIFY physicalSizeChanged)
@@ -99,12 +99,6 @@ public:
};
Q_ENUM(Transform)
- struct Mode
- {
- QSize size;
- qreal refreshRate;
- };
-
QWaylandOutput();
QWaylandOutput(QWaylandCompositor *compositor, QWindow *window);
~QWaylandOutput();
@@ -127,13 +121,14 @@ public:
QPoint position() const;
void setPosition(const QPoint &pt);
- Mode mode() const;
- void setMode(const Mode &mode);
+ QList<QWaylandOutputMode> modes() const;
+
+ void addMode(const QWaylandOutputMode &mode, bool preferred = false);
+
+ QWaylandOutputMode currentMode() const;
+ void setCurrentMode(const QWaylandOutputMode &mode);
QRect geometry() const;
- void setGeometry(const QRect &geometry);
- void setWidth(int newWidth);
- void setHeight(int newHeight);
QRect availableGeometry() const;
void setAvailableGeometry(const QRect &availableGeometry);
@@ -169,7 +164,8 @@ Q_SIGNALS:
void windowChanged();
void positionChanged();
void geometryChanged();
- void modeChanged();
+ void modeAdded();
+ void currentModeChanged();
void availableGeometryChanged();
void physicalSizeChanged();
void scaleFactorChanged();
@@ -182,6 +178,8 @@ Q_SIGNALS:
void windowDestroyed();
private Q_SLOTS:
+ void handleSetWidth(int newWidth);
+ void handleSetHeight(int newHeight);
void handleWindowDestroyed();
protected:
@@ -192,6 +190,4 @@ protected:
QT_END_NAMESPACE
-Q_DECLARE_METATYPE(QWaylandOutput::Mode)
-
#endif // QWAYLANDOUTPUT_H
diff --git a/src/compositor/compositor_api/qwaylandoutput_p.h b/src/compositor/compositor_api/qwaylandoutput_p.h
index 9b6ba9076..638575db9 100644
--- a/src/compositor/compositor_api/qwaylandoutput_p.h
+++ b/src/compositor/compositor_api/qwaylandoutput_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2014-2015 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Copyright (C) 2014-2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Copyright (C) 2013 Klarälvdalens Datakonsult AB (KDAB).
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
@@ -78,10 +78,10 @@ struct QWaylandSurfaceViewMapper
, has_entered(false)
{}
- QWaylandView *maybeThrottelingView() const
+ QWaylandView *maybePrimaryView() const
{
for (int i = 0; i < views.size(); i++) {
- if (surface && surface->throttlingView() == views.at(i))
+ if (surface && surface->primaryView() == views.at(i))
return views.at(i);
}
return Q_NULLPTR;
@@ -102,19 +102,25 @@ public:
void addView(QWaylandView *view, QWaylandSurface *surface);
void removeView(QWaylandView *view, QWaylandSurface *surface);
+
+ void sendGeometry(const Resource *resource);
void sendGeometryInfo();
+ void sendMode(const Resource *resource, const QWaylandOutputMode &mode);
+ void sendModesInfo();
+
protected:
void output_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
-
private:
QWaylandCompositor *compositor;
QWindow *window;
QString manufacturer;
QString model;
QPoint position;
- QWaylandOutput::Mode mode;
+ QVector<QWaylandOutputMode> modes;
+ int currentMode;
+ int preferredMode;
QRect availableGeometry;
QVector<QWaylandSurfaceViewMapper> surfaceViews;
QSize physicalSize;
diff --git a/src/compositor/compositor_api/qwaylandoutputmode.cpp b/src/compositor/compositor_api/qwaylandoutputmode.cpp
new file mode 100644
index 000000000..463b984ad
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutputmode.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandoutputmode.h"
+#include "qwaylandoutputmode_p.h"
+
+/*!
+ \class QWaylandOutputMode
+ \inmodule QtWaylandCompositor
+ \since 5.8
+ \brief The QWaylandOutputMode class holds the resolution and refresh rate of an output.
+
+ QWaylandOutputMode holds the resolution and refresh rate of an output.
+ Resolution is expressed in pixels and refresh rate is measured in mHz.
+
+ \sa QWaylandOutput
+*/
+
+QWaylandOutputMode::QWaylandOutputMode()
+ : d(new QWaylandOutputModePrivate)
+{
+}
+
+QWaylandOutputMode::QWaylandOutputMode(const QSize &size, int refreshRate)
+ : d(new QWaylandOutputModePrivate)
+{
+ d->size = size;
+ d->refreshRate = refreshRate;
+}
+
+QWaylandOutputMode::QWaylandOutputMode(const QWaylandOutputMode &other)
+ : d(new QWaylandOutputModePrivate)
+{
+ d->size = other.size();
+ d->refreshRate = other.refreshRate();
+}
+
+QWaylandOutputMode::~QWaylandOutputMode()
+{
+ delete d;
+}
+
+QWaylandOutputMode &QWaylandOutputMode::operator=(const QWaylandOutputMode &other)
+{
+ d->size = other.size();
+ d->refreshRate = other.refreshRate();
+ return *this;
+}
+
+/*!
+ Returns \c true if this mode is equal to \a other,
+ otherwise returns \c false.
+*/
+bool QWaylandOutputMode::operator==(const QWaylandOutputMode &other) const
+{
+ return size() == other.size() && refreshRate() == refreshRate();
+}
+
+/*!
+ Returns \c true if this mode is not equal to \a other,
+ otherwise returns \c false.
+*/
+bool QWaylandOutputMode::operator!=(const QWaylandOutputMode &other) const
+{
+ return size() != other.size() || refreshRate() != refreshRate();
+}
+
+/*!
+ Returns whether this mode contains a valid resolution and refresh rate.
+*/
+bool QWaylandOutputMode::isValid() const
+{
+ return !d->size.isEmpty() && d->refreshRate > 0;
+}
+
+/*!
+ Returns the resolution in pixels.
+*/
+QSize QWaylandOutputMode::size() const
+{
+ return d->size;
+}
+
+/*!
+ Returns the refresh rate in mHz.
+*/
+int QWaylandOutputMode::refreshRate() const
+{
+ return d->refreshRate;
+}
+
+/*!
+ * \internal
+ */
+void QWaylandOutputMode::setWidth(int width)
+{
+ d->size.setWidth(width);
+}
+
+/*!
+ * \internal
+ */
+void QWaylandOutputMode::setHeight(int height)
+{
+ d->size.setHeight(height);
+}
diff --git a/src/compositor/compositor_api/qwaylandoutputmode.h b/src/compositor/compositor_api/qwaylandoutputmode.h
new file mode 100644
index 000000000..4ef57f2ee
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutputmode.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDOUTPUTMODE_H
+#define QWAYLANDOUTPUTMODE_H
+
+#include <QtWaylandCompositor/qwaylandexport.h>
+#include <QtCore/QSize>
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandOutputMode
+{
+public:
+ explicit QWaylandOutputMode();
+ QWaylandOutputMode(const QSize &size, int refreshRate);
+ QWaylandOutputMode(const QWaylandOutputMode &other);
+ ~QWaylandOutputMode();
+
+ QWaylandOutputMode &operator=(const QWaylandOutputMode &other);
+ bool operator==(const QWaylandOutputMode &other) const;
+ bool operator!=(const QWaylandOutputMode &other) const;
+
+ bool isValid() const;
+
+ QSize size() const;
+ int refreshRate() const;
+
+private:
+ class QWaylandOutputModePrivate *const d;
+ friend class QWaylandOutput;
+
+ void setWidth(int width);
+ void setHeight(int height);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDOUTPUTMODE_H
diff --git a/src/compositor/compositor_api/qwaylandoutputmode_p.h b/src/compositor/compositor_api/qwaylandoutputmode_p.h
new file mode 100644
index 000000000..e9a0eaa37
--- /dev/null
+++ b/src/compositor/compositor_api/qwaylandoutputmode_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDOUTPUTMODE_P_H
+#define QWAYLANDOUTPUTMODE_P_H
+
+#include <QtWaylandCompositor/QWaylandOutput>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandOutputModePrivate
+{
+public:
+ QWaylandOutputModePrivate() {}
+
+ QSize size;
+ int refreshRate = 60000;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDOUTPUTMODE_P_H
diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp
index 5e9778637..2ff56a1e6 100644
--- a/src/compositor/compositor_api/qwaylandpointer.cpp
+++ b/src/compositor/compositor_api/qwaylandpointer.cpp
@@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE
QWaylandSurfaceRole QWaylandPointerPrivate::s_role("wl_pointer");
-QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat)
+QWaylandPointerPrivate::QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandSeat *seat)
: QObjectPrivate()
, wl_pointer()
, seat(seat)
@@ -94,27 +94,27 @@ void QWaylandPointerPrivate::pointer_set_cursor(wl_pointer::Resource *resource,
/*!
* \class QWaylandPointer
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandPointer class represents a pointer device.
*
- * This class provides access to the pointer device in a QWaylandInputDevice. It corresponds to
+ * This class provides access to the pointer device in a QWaylandSeat. It corresponds to
* the Wayland interface wl_pointer.
*/
/*!
- * Constructs a QWaylandPointer for the given \a inputDevice and with the given \a parent.
+ * Constructs a QWaylandPointer for the given \a seat and with the given \a parent.
*/
-QWaylandPointer::QWaylandPointer(QWaylandInputDevice *inputDevice, QObject *parent)
- : QWaylandObject(* new QWaylandPointerPrivate(this, inputDevice), parent)
+QWaylandPointer::QWaylandPointer(QWaylandSeat *seat, QObject *parent)
+ : QWaylandObject(* new QWaylandPointerPrivate(this, seat), parent)
{
connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandPointer::focusDestroyed);
- connect(inputDevice, &QWaylandInputDevice::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged);
+ connect(seat, &QWaylandSeat::mouseFocusChanged, this, &QWaylandPointer::pointerFocusChanged);
}
/*!
* Returns the input device for this QWaylandPointer.
*/
-QWaylandInputDevice *QWaylandPointer::inputDevice() const
+QWaylandSeat *QWaylandPointer::seat() const
{
Q_D(const QWaylandPointer);
return d->seat;
@@ -151,34 +151,45 @@ void QWaylandPointer::setOutput(QWaylandOutput *output)
/*!
* Sends a mouse press event for \a button to the view currently holding mouse focus.
+ *
+ * Returns the serial number of the press event.
*/
-void QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
+uint QWaylandPointer::sendMousePressEvent(Qt::MouseButton button)
{
Q_D(QWaylandPointer);
uint32_t time = d->compositor()->currentTimeMsecs();
d->buttonCount++;
+ uint serial = 0;
+
if (d->focusResource)
- sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_PRESSED);
+ serial = sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_PRESSED);
if (d->buttonCount == 1) {
emit buttonPressedChanged();
}
+
+ return serial;
}
/*!
* Sends a mouse release event for \a button to the view currently holding mouse focus.
+ *
+ * Returns the serial number of the release event.
*/
-void QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button)
+uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button)
{
Q_D(QWaylandPointer);
uint32_t time = d->compositor()->currentTimeMsecs();
d->buttonCount--;
+ uint serial = 0;
if (d->focusResource)
- sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_RELEASED);
+ serial = sendButton(d->focusResource, time, button, WL_POINTER_BUTTON_STATE_RELEASED);
if (d->buttonCount == 0)
emit buttonPressedChanged();
+
+ return serial;
}
/*!
@@ -308,11 +319,12 @@ struct wl_resource *QWaylandPointer::focusResource() const
/*!
* \internal
*/
-void QWaylandPointer::sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state)
+uint QWaylandPointer::sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state)
{
Q_D(QWaylandPointer);
uint32_t serial = d->compositor()->nextSerial();
d->send_button(resource, serial, time, toWaylandButton(button), state);
+ return serial;
}
/*!
diff --git a/src/compositor/compositor_api/qwaylandpointer.h b/src/compositor/compositor_api/qwaylandpointer.h
index 9d7d06807..87bf31c97 100644
--- a/src/compositor/compositor_api/qwaylandpointer.h
+++ b/src/compositor/compositor_api/qwaylandpointer.h
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
class QWaylandPointer;
class QWaylandPointerPrivate;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandView;
class QWaylandOutput;
class QWaylandClient;
@@ -56,16 +56,16 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandPointer : public QWaylandObject
Q_DECLARE_PRIVATE(QWaylandPointer)
Q_PROPERTY(bool isButtonPressed READ isButtonPressed NOTIFY buttonPressedChanged)
public:
- QWaylandPointer(QWaylandInputDevice *inputDevice, QObject *parent = nullptr);
+ QWaylandPointer(QWaylandSeat *seat, QObject *parent = nullptr);
- QWaylandInputDevice *inputDevice() const;
+ QWaylandSeat *seat() const;
QWaylandCompositor *compositor() const;
QWaylandOutput *output() const;
void setOutput(QWaylandOutput *output);
- virtual void sendMousePressEvent(Qt::MouseButton button);
- virtual void sendMouseReleaseEvent(Qt::MouseButton button);
+ virtual uint sendMousePressEvent(Qt::MouseButton button);
+ virtual uint sendMouseReleaseEvent(Qt::MouseButton button);
virtual void sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos);
virtual void sendMouseWheelEvent(Qt::Orientation orientation, int delta);
@@ -80,7 +80,7 @@ public:
wl_resource *focusResource() const;
static uint32_t toWaylandButton(Qt::MouseButton button);
- void sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state);
+ uint sendButton(struct wl_resource *resource, uint32_t time, Qt::MouseButton button, uint32_t state);
Q_SIGNALS:
void outputChanged();
void buttonPressedChanged();
diff --git a/src/compositor/compositor_api/qwaylandpointer_p.h b/src/compositor/compositor_api/qwaylandpointer_p.h
index 5ac030029..54ac72d11 100644
--- a/src/compositor/compositor_api/qwaylandpointer_p.h
+++ b/src/compositor/compositor_api/qwaylandpointer_p.h
@@ -61,7 +61,7 @@
#include <QtWaylandCompositor/private/qwayland-server-wayland.h>
#include <QtWaylandCompositor/QWaylandView>
#include <QtWaylandCompositor/QWaylandSurface>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include <stdint.h>
@@ -74,7 +74,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandPointerPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QWaylandPointer)
public:
- QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandInputDevice *seat);
+ QWaylandPointerPrivate(QWaylandPointer *pointer, QWaylandSeat *seat);
QWaylandCompositor *compositor() const { return seat->compositor(); }
@@ -86,7 +86,7 @@ protected:
private:
void focusDestroyed(void *data);
- QWaylandInputDevice *seat;
+ QWaylandSeat *seat;
QWaylandOutput *output;
QPointF localPosition;
diff --git a/src/compositor/compositor_api/qwaylandquickcompositor.cpp b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
index 64e6fec70..b69e20791 100644
--- a/src/compositor/compositor_api/qwaylandquickcompositor.cpp
+++ b/src/compositor/compositor_api/qwaylandquickcompositor.cpp
@@ -37,7 +37,8 @@
#include <QtQml/QQmlEngine>
#include <QQuickWindow>
-#include <QtGui/private/qopengltextureblitter_p.h>
+#include <QOpenGLTextureBlitter>
+#include <QOpenGLTexture>
#include <QOpenGLFramebufferObject>
#include <QMatrix4x4>
#include <QRunnable>
@@ -101,6 +102,7 @@ void QWaylandQuickCompositor::create()
void QWaylandQuickCompositor::classBegin()
{
+ QWaylandCompositorPrivate::get(this)->preInit();
}
void QWaylandQuickCompositor::componentComplete()
@@ -114,7 +116,7 @@ void QWaylandQuickCompositor::componentComplete()
*/
void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const QWaylandBufferRef &buffer)
{
- if (buffer.isShm()) {
+ if (buffer.isSharedMemory()) {
QWaylandCompositor::grabSurface(grabber, buffer);
return;
}
@@ -139,7 +141,6 @@ void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const
fbo.bind();
QOpenGLTextureBlitter blitter;
blitter.create();
- blitter.bind();
glViewport(0, 0, buffer.size().width(), buffer.size().height());
@@ -148,15 +149,10 @@ void QWaylandQuickCompositor::grabSurface(QWaylandSurfaceGrabber *grabber, const
? QOpenGLTextureBlitter::OriginTopLeft
: QOpenGLTextureBlitter::OriginBottomLeft;
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- buffer.bindToTexture();
- blitter.blit(texture, QMatrix4x4(), surfaceOrigin);
-
+ auto texture = buffer.toOpenGLTexture();
+ blitter.bind(texture->target());
+ blitter.blit(texture->textureId(), QMatrix4x4(), surfaceOrigin);
blitter.release();
- glDeleteTextures(1, &texture);
emit grabber->success(fbo.toImage());
}
diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
index 5e90c06c7..e6cfce343 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
+++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
@@ -39,14 +39,18 @@
#include "qwaylandquicksurface.h"
#include "qwaylandinputmethodcontrol.h"
#include "qwaylandtextinput.h"
+#include "qwaylandquickoutput.h"
#include <QtWaylandCompositor/qwaylandcompositor.h>
-#include <QtWaylandCompositor/qwaylandinput.h>
+#include <QtWaylandCompositor/qwaylandseat.h>
#include <QtWaylandCompositor/qwaylandbufferref.h>
+#include <QtWaylandCompositor/QWaylandDrag>
#include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h>
#include <QtGui/QKeyEvent>
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QOpenGLTexture>
#include <QtQuick/QSGSimpleTextureNode>
#include <QtQuick/QQuickWindow>
@@ -185,52 +189,40 @@ QWaylandBufferMaterial::QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEg
QWaylandBufferMaterial::~QWaylandBufferMaterial()
{
- QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
-
- for (GLuint texture : m_textures)
- gl->glDeleteTextures(1, &texture);
}
-void QWaylandBufferMaterial::setTextureForPlane(int plane, uint texture)
+void QWaylandBufferMaterial::setTextureForPlane(int plane, QOpenGLTexture *texture)
{
if (plane < 0 || plane >= bufferTypes[m_format].planeCount) {
qWarning("plane index is out of range");
return;
}
- QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
- const GLenum target = bufferTypes[m_format].textureTarget;
-
- gl->glBindTexture(target, texture);
- setTextureParameters(target);
+ texture->bind();
+ setTextureParameters(texture->target());
ensureTextures(plane - 1);
- if (m_textures.size() <= plane) {
+ if (m_textures.size() <= plane)
m_textures << texture;
- } else {
- std::swap(m_textures[plane], texture);
- gl->glDeleteTextures(1, &texture);
- }
+ else
+ m_textures[plane] = texture;
}
void QWaylandBufferMaterial::bind()
{
- QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
- const GLenum target = bufferTypes[m_format].textureTarget;
-
ensureTextures(bufferTypes[m_format].planeCount);
switch (m_textures.size()) {
case 3:
- gl->glActiveTexture(GL_TEXTURE2);
- gl->glBindTexture(target, m_textures[2]);
+ if (m_textures[2])
+ m_textures[2]->bind(GL_TEXTURE2);
case 2:
- gl->glActiveTexture(GL_TEXTURE1);
- gl->glBindTexture(target, m_textures[1]);
+ if (m_textures[1])
+ m_textures[1]->bind(GL_TEXTURE1);
case 1:
- gl->glActiveTexture(GL_TEXTURE0);
- gl->glBindTexture(target, m_textures[0]);
+ if (m_textures[0])
+ m_textures[0]->bind(GL_TEXTURE0);
}
}
@@ -257,15 +249,8 @@ void QWaylandBufferMaterial::setTextureParameters(GLenum target)
//TODO move this into a separate centralized texture management class
void QWaylandBufferMaterial::ensureTextures(int count)
{
- QOpenGLFunctions *gl = QOpenGLContext::currentContext()->functions();
- const GLenum target = bufferTypes[m_format].textureTarget;
- GLuint texture;
-
for (int plane = m_textures.size(); plane < count; plane++) {
- gl->glGenTextures(1, &texture);
- gl->glBindTexture(target, texture);
- setTextureParameters(target);
- m_textures << texture;
+ m_textures << nullptr;
}
}
@@ -293,7 +278,7 @@ public:
delete m_sgTex;
m_sgTex = 0;
if (m_ref.hasBuffer()) {
- if (buffer.isShm()) {
+ if (buffer.isSharedMemory()) {
m_sgTex = surfaceItem->window()->createTextureFromImage(buffer.image());
if (m_sgTex) {
m_sgTex->bind();
@@ -305,11 +290,8 @@ public:
opt |= QQuickWindow::TextureHasAlphaChannel;
}
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(GL_TEXTURE_2D, texture);
- buffer.bindToTexture();
- m_sgTex = surfaceItem->window()->createTextureFromId(texture , QSize(surfaceItem->width(), surfaceItem->height()), opt);
+ auto texture = buffer.toOpenGLTexture();
+ m_sgTex = surfaceItem->window()->createTextureFromId(texture->textureId() , QSize(surfaceItem->width(), surfaceItem->height()), opt);
}
}
emit textureChanged();
@@ -332,7 +314,7 @@ private:
/*!
* \qmltype WaylandQuickItem
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief Provides a Qt Quick item that represents a WaylandView.
*
* Qt Quick-based Wayland compositors can use this type to display a client's
@@ -343,7 +325,7 @@ private:
/*!
* \class QWaylandQuickItem
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandQuickItem class provides a Qt Quick item representing a QWaylandView.
*
* When writing a QWaylandCompositor in Qt Quick, this class can be used to display a
@@ -492,13 +474,13 @@ void QWaylandQuickItem::mousePressEvent(QMouseEvent *event)
return;
}
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
+ QWaylandSeat *seat = compositor()->seatFor(event);
if (d->focusOnClick)
- takeFocus(inputDevice);
+ takeFocus(seat);
- inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos());
- inputDevice->sendMousePressEvent(event->button());
+ seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos());
+ seat->sendMousePressEvent(event->button());
}
/*!
@@ -508,8 +490,20 @@ void QWaylandQuickItem::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendMouseMoveEvent(d->view.data(), event->localPos() / d->scaleFactor(), event->windowPos());
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ if (d->isDragging) {
+ QWaylandQuickOutput *currentOutput = qobject_cast<QWaylandQuickOutput *>(view()->output());
+ //TODO: also check if dragging onto other outputs
+ QWaylandQuickItem *targetItem = qobject_cast<QWaylandQuickItem *>(currentOutput->pickClickableItem(mapToScene(event->localPos())));
+ QWaylandSurface *targetSurface = targetItem ? targetItem->surface() : nullptr;
+ if (targetSurface) {
+ QPointF position = mapToItem(targetItem, event->localPos());
+ QPointF surfacePosition = targetItem->mapToSurface(position);
+ seat->drag()->dragMove(targetSurface, surfacePosition);
+ }
+ } else {
+ seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos());
+ }
} else {
emit mouseMove(event->windowPos());
event->ignore();
@@ -523,8 +517,13 @@ void QWaylandQuickItem::mouseReleaseEvent(QMouseEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendMouseReleaseEvent(event->button());
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ if (d->isDragging) {
+ d->isDragging = false;
+ seat->drag()->drop();
+ } else {
+ seat->sendMouseReleaseEvent(event->button());
+ }
} else {
emit mouseRelease();
event->ignore();
@@ -542,8 +541,8 @@ void QWaylandQuickItem::hoverEnterEvent(QHoverEvent *event)
return;
}
if (d->shouldSendInputEvents()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos()));
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ seat->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos()));
} else {
event->ignore();
}
@@ -562,8 +561,8 @@ void QWaylandQuickItem::hoverMoveEvent(QHoverEvent *event)
}
}
if (d->shouldSendInputEvents()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendMouseMoveEvent(d->view.data(), event->pos() / d->scaleFactor(), mapToScene(event->pos()));
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->pos()), mapToScene(event->pos()));
} else {
event->ignore();
}
@@ -576,8 +575,8 @@ void QWaylandQuickItem::hoverLeaveEvent(QHoverEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->setMouseFocus(Q_NULLPTR);
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ seat->setMouseFocus(Q_NULLPTR);
} else {
event->ignore();
}
@@ -595,8 +594,8 @@ void QWaylandQuickItem::wheelEvent(QWheelEvent *event)
return;
}
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendMouseWheelEvent(event->orientation(), event->delta());
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ seat->sendMouseWheelEvent(event->orientation(), event->delta());
} else {
event->ignore();
}
@@ -609,8 +608,8 @@ void QWaylandQuickItem::keyPressEvent(QKeyEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendFullKeyEvent(event);
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ seat->sendFullKeyEvent(event);
} else {
event->ignore();
}
@@ -623,8 +622,8 @@ void QWaylandQuickItem::keyReleaseEvent(QKeyEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents() && hasFocus()) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
- inputDevice->sendFullKeyEvent(event);
+ QWaylandSeat *seat = compositor()->seatFor(event);
+ seat->sendFullKeyEvent(event);
} else {
event->ignore();
}
@@ -637,19 +636,7 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event)
{
Q_D(QWaylandQuickItem);
if (d->shouldSendInputEvents() && d->touchEventsEnabled) {
- QWaylandInputDevice *inputDevice = compositor()->inputDeviceFor(event);
-
- if (event->type() == QEvent::TouchBegin) {
- QQuickItem *grabber = window()->mouseGrabberItem();
- if (grabber != this)
- grabMouse();
- }
-
- if (event->type() == QEvent::TouchEnd) {
- QQuickItem *grabber = window()->mouseGrabberItem();
- if (grabber == this)
- ungrabMouse();
- }
+ QWaylandSeat *seat = compositor()->seatFor(event);
QPoint pointPos;
const QList<QTouchEvent::TouchPoint> &points = event->touchPoints();
@@ -662,26 +649,18 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event)
}
event->accept();
- if (inputDevice->mouseFocus() != d->view.data()) {
- inputDevice->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos));
+ if (seat->mouseFocus() != d->view.data()) {
+ seat->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos));
}
- inputDevice->sendFullTouchEvent(event);
+ seat->sendFullTouchEvent(surface(), event);
+
+ if (event->type() == QEvent::TouchBegin && d->focusOnClick)
+ takeFocus(seat);
} else {
event->ignore();
}
}
-/*!
- * \internal
- */
-void QWaylandQuickItem::mouseUngrabEvent()
-{
- if (surface()) {
- QTouchEvent e(QEvent::TouchCancel);
- touchEvent(&e);
- }
-}
-
#ifndef QT_NO_IM
/*!
* \internal
@@ -763,31 +742,107 @@ void QWaylandQuickItem::setSubsurfaceHandler(QObject *handler)
}
/*!
+ * \property QWaylandQuickItem::output
+ *
+ * This property holds the output on which this item is displayed.
+ */
+QWaylandOutput *QWaylandQuickItem::output() const
+{
+ Q_D(const QWaylandQuickItem);
+ return d->view->output();
+}
+
+void QWaylandQuickItem::setOutput(QWaylandOutput *output)
+{
+ Q_D(QWaylandQuickItem);
+ d->view->setOutput(output);
+}
+
+/*!
+ * \property QWaylandQuickItem::bufferLocked
+ *
+ * This property holds whether the item's buffer is currently locked. As long as
+ * the buffer is locked, it will not be released and returned to the client.
+ *
+ * The default is false.
+ */
+bool QWaylandQuickItem::isBufferLocked() const
+{
+ Q_D(const QWaylandQuickItem);
+ return d->view->isBufferLocked();
+}
+
+void QWaylandQuickItem::setBufferLocked(bool locked)
+{
+ Q_D(QWaylandQuickItem);
+ d->view->setBufferLocked(locked);
+}
+
+/*!
+ * \property bool QWaylandQuickItem::allowDiscardFrontBuffer
+ *
+ * By default, the item locks the current buffer until a new buffer is available
+ * and updatePaintNode() is called. Set this property to true to allow Qt to release the buffer
+ * immediately when the throttling view is no longer using it. This is useful for items that have
+ * slow update intervals.
+ */
+bool QWaylandQuickItem::allowDiscardFrontBuffer() const
+{
+ Q_D(const QWaylandQuickItem);
+ return d->view->allowDiscardFrontBuffer();
+}
+
+void QWaylandQuickItem::setAllowDiscardFrontBuffer(bool discard)
+{
+ Q_D(QWaylandQuickItem);
+ d->view->setAllowDiscardFrontBuffer(discard);
+}
+
+/*!
+ * \qmlmethod QtWaylandCompositor::WaylandQuickItem::setPrimary
+ *
+ * Makes this WaylandQuickItem the primary view for the surface.
+ */
+
+/*!
+ * Makes this QWaylandQuickItem's view the primary view for the surface.
+ *
+ * \sa QWaylandSurface::primaryView
+ */
+void QWaylandQuickItem::setPrimary()
+{
+ Q_D(QWaylandQuickItem);
+ d->view->setPrimary();
+}
+
+/*!
* \internal
*/
void QWaylandQuickItem::handleSurfaceChanged()
{
Q_D(QWaylandQuickItem);
if (d->oldSurface) {
- disconnect(d->oldSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged);
+ disconnect(d->oldSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged);
disconnect(d->oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged);
disconnect(d->oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize);
disconnect(d->oldSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize);
disconnect(d->oldSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer);
disconnect(d->oldSurface, &QWaylandSurface::redraw, this, &QQuickItem::update);
disconnect(d->oldSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded);
+ disconnect(d->oldSurface, &QWaylandSurface::dragStarted, this, &QWaylandQuickItem::handleDragStarted);
#ifndef QT_NO_IM
disconnect(d->oldSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod);
#endif
}
if (QWaylandSurface *newSurface = d->view->surface()) {
- connect(newSurface, &QWaylandSurface::mappedChanged, this, &QWaylandQuickItem::surfaceMappedChanged);
+ connect(newSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged);
connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged);
connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize);
connect(newSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize);
connect(newSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer);
connect(newSurface, &QWaylandSurface::redraw, this, &QQuickItem::update);
connect(newSurface, &QWaylandSurface::childAdded, this, &QWaylandQuickItem::handleSubsurfaceAdded);
+ connect(newSurface, &QWaylandSurface::dragStarted, this, &QWaylandQuickItem::handleDragStarted);
#ifndef QT_NO_IM
connect(newSurface->inputMethodControl(), &QWaylandInputMethodControl::updateInputMethod, this, &QWaylandQuickItem::updateInputMethod);
#endif
@@ -814,16 +869,16 @@ void QWaylandQuickItem::handleSurfaceChanged()
* Calling this function causes the item to take the focus of the
* input \a device.
*/
-void QWaylandQuickItem::takeFocus(QWaylandInputDevice *device)
+void QWaylandQuickItem::takeFocus(QWaylandSeat *device)
{
forceActiveFocus();
if (!surface())
return;
- QWaylandInputDevice *target = device;
+ QWaylandSeat *target = device;
if (!target) {
- target = compositor()->defaultInputDevice();
+ target = compositor()->defaultSeat();
}
target->setKeyboardFocus(surface());
QWaylandTextInput *textInput = QWaylandTextInput::findIn(target);
@@ -869,7 +924,7 @@ void QWaylandQuickItem::updateSize()
* \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::focusOnClick
*
* This property specifies whether the WaylandQuickItem should take focus when
- * it is clicked.
+ * it is clicked or touched.
*
* The default is \c true.
*/
@@ -878,7 +933,7 @@ void QWaylandQuickItem::updateSize()
* \property QWaylandQuickItem::focusOnClick
*
* This property specifies whether the QWaylandQuickItem should take focus when
- * it is clicked.
+ * it is clicked or touched.
*
* The default is \c true.
*/
@@ -904,13 +959,23 @@ void QWaylandQuickItem::setFocusOnClick(bool focus)
*/
bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition)
{
- Q_D(QWaylandQuickItem);
if (QWaylandSurface *s = surface())
- return s->inputRegionContains(localPosition.toPoint() / d->scaleFactor());
+ return s->inputRegionContains(mapToSurface(localPosition).toPoint());
return false;
}
/*!
+ * Maps the given \a point in this item's coordinate system to the equivalent
+ * point within the Wayland surface's coordinate system, and returns the mapped
+ * coordinate.
+ */
+QPointF QWaylandQuickItem::mapToSurface(const QPointF &point) const
+{
+ Q_D(const QWaylandQuickItem);
+ return point / d->scaleFactor();
+}
+
+/*!
* \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::sizeFollowsSurface
*
* This property specifies whether the size of the item should always match
@@ -1049,9 +1114,9 @@ void QWaylandQuickItem::updateInputMethod(Qt::InputMethodQueries queries)
QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
Q_D(QWaylandQuickItem);
- const bool mapped = surface() && surface()->isMapped() && d->view->currentBuffer().hasBuffer();
+ const bool hasContent = surface() && surface()->hasContent() && d->view->currentBuffer().hasContent();
- if (!mapped || !d->paintEnabled) {
+ if (!hasContent || !d->paintEnabled) {
delete oldNode;
return 0;
}
@@ -1061,7 +1126,8 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
const QRectF rect = invertY ? QRectF(0, height(), width(), -height())
: QRectF(0, 0, width(), height());
- if (ref.isShm() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) {
+ if (ref.isSharedMemory() || bufferTypes[ref.bufferFormatEgl()].canProvideTexture) {
+ // This case could covered by the more general path below, but this is more efficient (especially when using ShaderEffect items).
QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>(oldNode);
if (!node) {
@@ -1104,13 +1170,11 @@ QSGNode *QWaylandQuickItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
if (d->newTexture) {
d->newTexture = false;
for (int plane = 0; plane < bufferTypes[ref.bufferFormatEgl()].planeCount; plane++)
- if (uint texture = ref.textureForPlane(plane))
+ if (auto texture = ref.toOpenGLTexture(plane))
material->setTextureForPlane(plane, texture);
material->bind();
- ref.bindToTexture();
}
- ref.updateTexture();
QSGGeometry::updateTexturedRectGeometry(geometry, rect, QRectF(0, 0, 1, 1));
node->setGeometry(geometry);
@@ -1144,6 +1208,8 @@ void QWaylandQuickItem::setInputEventsEnabled(bool enabled)
{
Q_D(QWaylandQuickItem);
if (d->inputEventsEnabled != enabled) {
+ if (enabled)
+ setEnabled(true);
d->setInputEventsEnabled(enabled);
emit inputEventsEnabledChanged();
}
@@ -1178,5 +1244,13 @@ void QWaylandQuickItem::handleSubsurfacePosition(const QPoint &pos)
QQuickItem::setPosition(pos * d->scaleFactor());
}
+void QWaylandQuickItem::handleDragStarted(QWaylandDrag *drag)
+{
+ Q_D(QWaylandQuickItem);
+ Q_ASSERT(drag->origin() == surface());
+ drag->seat()->setMouseFocus(nullptr);
+ d->isDragging = true;
+}
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h
index 07b6a40a4..821826d69 100644
--- a/src/compositor/compositor_api/qwaylandquickitem.h
+++ b/src/compositor/compositor_api/qwaylandquickitem.h
@@ -51,14 +51,13 @@ Q_DECLARE_METATYPE(QWaylandQuickSurface*)
QT_BEGIN_NAMESPACE
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandQuickItemPrivate;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickItem : public QQuickItem
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandQuickItem)
- Q_PROPERTY(QWaylandView *view READ view CONSTANT)
Q_PROPERTY(QWaylandCompositor *compositor READ compositor)
Q_PROPERTY(QWaylandSurface *surface READ surface WRITE setSurface NOTIFY surfaceChanged)
Q_PROPERTY(bool paintEnabled READ paintEnabled WRITE setPaintEnabled)
@@ -68,6 +67,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickItem : public QQuickItem
Q_PROPERTY(bool focusOnClick READ focusOnClick WRITE setFocusOnClick NOTIFY focusOnClickChanged)
Q_PROPERTY(bool sizeFollowsSurface READ sizeFollowsSurface WRITE setSizeFollowsSurface NOTIFY sizeFollowsSurfaceChanged)
Q_PROPERTY(QObject *subsurfaceHandler READ subsurfaceHandler WRITE setSubsurfaceHandler NOTIFY subsurfaceHandlerChanged)
+ Q_PROPERTY(QWaylandOutput *output READ output WRITE setOutput NOTIFY outputChanged)
+ Q_PROPERTY(bool bufferLocked READ isBufferLocked WRITE setBufferLocked NOTIFY bufferLockedChanged)
+ Q_PROPERTY(bool allowDiscardFrontBuffer READ allowDiscardFrontBuffer WRITE setAllowDiscardFrontBuffer NOTIFY allowDiscardFrontBufferChanged)
public:
QWaylandQuickItem(QQuickItem *parent = nullptr);
~QWaylandQuickItem();
@@ -95,6 +97,7 @@ public:
void setFocusOnClick(bool focus);
bool inputRegionContains(const QPointF &localPosition);
+ Q_INVOKABLE QPointF mapToSurface(const QPointF &point) const;
bool sizeFollowsSurface() const;
void setSizeFollowsSurface(bool sizeFollowsSurface);
@@ -107,6 +110,17 @@ public:
QObject *subsurfaceHandler() const;
void setSubsurfaceHandler(QObject*);
+ QWaylandOutput *output() const;
+ void setOutput(QWaylandOutput *output);
+
+ bool isBufferLocked() const;
+ void setBufferLocked(bool locked);
+
+ bool allowDiscardFrontBuffer() const;
+ void setAllowDiscardFrontBuffer(bool discard);
+
+ Q_INVOKABLE void setPrimary();
+
protected:
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
@@ -120,7 +134,6 @@ protected:
void keyReleaseEvent(QKeyEvent *event) Q_DECL_OVERRIDE;
void touchEvent(QTouchEvent *event) Q_DECL_OVERRIDE;
- void mouseUngrabEvent() Q_DECL_OVERRIDE;
#ifndef QT_NO_IM
void inputMethodEvent(QInputMethodEvent *event) Q_DECL_OVERRIDE;
@@ -128,7 +141,7 @@ protected:
virtual void surfaceChangedEvent(QWaylandSurface *newSurface, QWaylandSurface *oldSurface);
public Q_SLOTS:
- virtual void takeFocus(QWaylandInputDevice *device = nullptr);
+ virtual void takeFocus(QWaylandSeat *device = nullptr);
void setPaintEnabled(bool paintEnabled);
void raise();
void lower();
@@ -143,6 +156,7 @@ private Q_SLOTS:
void beforeSync();
void handleSubsurfaceAdded(QWaylandSurface *childSurface);
void handleSubsurfacePosition(const QPoint &pos);
+ void handleDragStarted(QWaylandDrag *drag);
#ifndef QT_NO_IM
void updateInputMethod(Qt::InputMethodQueries queries);
#endif
@@ -158,6 +172,9 @@ Q_SIGNALS:
void mouseRelease();
void sizeFollowsSurfaceChanged();
void subsurfaceHandlerChanged();
+ void outputChanged();
+ void bufferLockedChanged();
+ void allowDiscardFrontBufferChanged();
protected:
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) Q_DECL_OVERRIDE;
diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h
index b529ba959..5eba99572 100644
--- a/src/compositor/compositor_api/qwaylandquickitem_p.h
+++ b/src/compositor/compositor_api/qwaylandquickitem_p.h
@@ -52,14 +52,14 @@
#include <QtQuick/QSGMaterialShader>
#include <QtQuick/QSGMaterial>
-#include "qwaylandquickitem.h"
-
+#include <QtWaylandCompositor/QWaylandQuickItem>
#include <QtWaylandCompositor/QWaylandOutput>
QT_BEGIN_NAMESPACE
class QWaylandSurfaceTextureProvider;
class QMutex;
+class QOpenGLTexture;
class QWaylandBufferMaterialShader : public QSGMaterialShader
{
@@ -85,7 +85,7 @@ public:
QWaylandBufferMaterial(QWaylandBufferRef::BufferFormatEgl format);
~QWaylandBufferMaterial();
- void setTextureForPlane(int plane, uint texture);
+ void setTextureForPlane(int plane, QOpenGLTexture *texture);
void bind();
@@ -97,7 +97,7 @@ private:
void ensureTextures(int count);
const QWaylandBufferRef::BufferFormatEgl m_format;
- QVarLengthArray<GLuint, 3> m_textures;
+ QVarLengthArray<QOpenGLTexture*, 3> m_textures;
};
class QWaylandQuickItemPrivate : public QQuickItemPrivate
@@ -110,8 +110,9 @@ public:
, oldSurface(Q_NULLPTR)
, provider(Q_NULLPTR)
, paintEnabled(true)
- , touchEventsEnabled(false)
+ , touchEventsEnabled(true)
, inputEventsEnabled(true)
+ , isDragging(false)
, newTexture(false)
, focusOnClick(true)
, sizeFollowsSurface(true)
@@ -138,9 +139,11 @@ public:
QObject::connect(view.data(), &QWaylandView::surfaceChanged, q, &QWaylandQuickItem::surfaceChanged);
QObject::connect(view.data(), &QWaylandView::surfaceChanged, q, &QWaylandQuickItem::handleSurfaceChanged);
QObject::connect(view.data(), &QWaylandView::surfaceDestroyed, q, &QWaylandQuickItem::surfaceDestroyed);
+ QObject::connect(view.data(), &QWaylandView::outputChanged, q, &QWaylandQuickItem::outputChanged);
+ QObject::connect(view.data(), &QWaylandView::bufferLockedChanged, q, &QWaylandQuickItem::bufferLockedChanged);
+ QObject::connect(view.data(), &QWaylandView::allowDiscardFrontBufferChanged, q, &QWaylandQuickItem::allowDiscardFrontBuffer);
}
-
void setInputEventsEnabled(bool enable)
{
Q_Q(QWaylandQuickItem);
@@ -164,6 +167,7 @@ public:
bool paintEnabled;
bool touchEventsEnabled;
bool inputEventsEnabled;
+ bool isDragging;
bool newTexture;
bool focusOnClick;
bool sizeFollowsSurface;
diff --git a/src/compositor/compositor_api/qwaylandquickoutput.cpp b/src/compositor/compositor_api/qwaylandquickoutput.cpp
index 8abf6cbb1..0e25362fc 100644
--- a/src/compositor/compositor_api/qwaylandquickoutput.cpp
+++ b/src/compositor/compositor_api/qwaylandquickoutput.cpp
@@ -37,6 +37,7 @@
#include "qwaylandquickoutput.h"
#include "qwaylandquickcompositor.h"
+#include "qwaylandquickitem_p.h"
QT_BEGIN_NAMESPACE
@@ -102,6 +103,44 @@ void QWaylandQuickOutput::setAutomaticFrameCallback(bool automatic)
automaticFrameCallbackChanged();
}
+static QQuickItem* clickableItemAtPosition(QQuickItem *rootItem, const QPointF &position)
+{
+ if (!rootItem->isEnabled() || !rootItem->isVisible())
+ return nullptr;
+
+ QList<QQuickItem *> paintOrderItems = QQuickItemPrivate::get(rootItem)->paintOrderChildItems();
+ auto negativeZStart = paintOrderItems.crend();
+ for (auto it = paintOrderItems.crbegin(); it != paintOrderItems.crend(); ++it) {
+ if ((*it)->z() < 0) {
+ negativeZStart = it;
+ break;
+ }
+ QQuickItem *item = clickableItemAtPosition(*it, rootItem->mapToItem(*it, position));
+ if (item)
+ return item;
+ }
+
+ if (rootItem->contains(position) && rootItem->acceptedMouseButtons() != Qt::NoButton)
+ return rootItem;
+
+ for (auto it = negativeZStart; it != paintOrderItems.crend(); ++it) {
+ QQuickItem *item = clickableItemAtPosition(*it, rootItem->mapToItem(*it, position));
+ if (item)
+ return item;
+ }
+
+ return nullptr;
+}
+
+QQuickItem *QWaylandQuickOutput::pickClickableItem(const QPointF &position)
+{
+ QQuickWindow *quickWindow = qobject_cast<QQuickWindow *>(window());
+ if (!quickWindow)
+ return nullptr;
+
+ return clickableItemAtPosition(quickWindow->contentItem(), position);
+}
+
/*!
* \internal
*/
diff --git a/src/compositor/compositor_api/qwaylandquickoutput.h b/src/compositor/compositor_api/qwaylandquickoutput.h
index 83091e4c7..2cef03282 100644
--- a/src/compositor/compositor_api/qwaylandquickoutput.h
+++ b/src/compositor/compositor_api/qwaylandquickoutput.h
@@ -59,6 +59,8 @@ public:
bool automaticFrameCallback() const;
void setAutomaticFrameCallback(bool automatic);
+ QQuickItem *pickClickableItem(const QPointF &position);
+
public Q_SLOTS:
void updateStarted();
diff --git a/src/compositor/compositor_api/qwaylandinput.cpp b/src/compositor/compositor_api/qwaylandseat.cpp
index 6f0f8c758..f6a5276d4 100644
--- a/src/compositor/compositor_api/qwaylandinput.cpp
+++ b/src/compositor/compositor_api/qwaylandseat.cpp
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#include "qwaylandinput.h"
-#include "qwaylandinput_p.h"
+#include "qwaylandseat.h"
+#include "qwaylandseat_p.h"
#include "qwaylandcompositor.h"
#include "qwaylandinputmethodcontrol.h"
@@ -43,8 +43,8 @@
#include <QtWaylandCompositor/QWaylandDrag>
#include <QtWaylandCompositor/QWaylandTouch>
#include <QtWaylandCompositor/QWaylandPointer>
-#include <QtWaylandCompositor/QWaylandWlShellSurface>
-#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/QWaylandKeymap>
+#include <QtWaylandCompositor/private/qwaylandseat_p.h>
#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
#include <QtWaylandCompositor/private/qwldatadevice_p.h>
@@ -53,37 +53,39 @@
QT_BEGIN_NAMESPACE
-QWaylandInputDevicePrivate::QWaylandInputDevicePrivate(QWaylandInputDevice *inputdevice, QWaylandCompositor *compositor)
+QWaylandSeatPrivate::QWaylandSeatPrivate(QWaylandSeat *seat)
: QObjectPrivate()
- , QtWaylandServer::wl_seat(compositor->display(), 4)
- , compositor(compositor)
+ , QtWaylandServer::wl_seat()
+ , isInitialized(false)
+ , compositor(nullptr)
, mouseFocus(Q_NULLPTR)
, keyboardFocus(nullptr)
, capabilities()
, data_device()
- , drag_handle(new QWaylandDrag(inputdevice))
+ , drag_handle(new QWaylandDrag(seat))
+ , keymap(new QWaylandKeymap())
{
}
-QWaylandInputDevicePrivate::~QWaylandInputDevicePrivate()
+QWaylandSeatPrivate::~QWaylandSeatPrivate()
{
}
-void QWaylandInputDevicePrivate::setCapabilities(QWaylandInputDevice::CapabilityFlags caps)
+void QWaylandSeatPrivate::setCapabilities(QWaylandSeat::CapabilityFlags caps)
{
- Q_Q(QWaylandInputDevice);
+ Q_Q(QWaylandSeat);
if (capabilities != caps) {
- QWaylandInputDevice::CapabilityFlags changed = caps ^ capabilities;
+ QWaylandSeat::CapabilityFlags changed = caps ^ capabilities;
- if (changed & QWaylandInputDevice::Pointer) {
+ if (changed & QWaylandSeat::Pointer) {
pointer.reset(pointer.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreatePointerDevice(q) : 0);
}
- if (changed & QWaylandInputDevice::Keyboard) {
+ if (changed & QWaylandSeat::Keyboard) {
keyboard.reset(keyboard.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateKeyboardDevice(q) : 0);
}
- if (changed & QWaylandInputDevice::Touch) {
+ if (changed & QWaylandSeat::Touch) {
touch.reset(touch.isNull() ? QWaylandCompositorPrivate::get(compositor)->callCreateTouchDevice(q) : 0);
}
@@ -93,112 +95,127 @@ void QWaylandInputDevicePrivate::setCapabilities(QWaylandInputDevice::Capability
wl_seat::send_capabilities(resources.at(i)->handle, (uint32_t)capabilities);
}
- if ((changed & caps & QWaylandInputDevice::Keyboard) && keyboardFocus != nullptr)
+ if ((changed & caps & QWaylandSeat::Keyboard) && keyboardFocus != nullptr)
keyboard->setFocus(keyboardFocus);
}
}
-void QWaylandInputDevicePrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id)
+void QWaylandSeatPrivate::clientRequestedDataDevice(QtWayland::DataDeviceManager *, struct wl_client *client, uint32_t id)
{
- Q_Q(QWaylandInputDevice);
+ Q_Q(QWaylandSeat);
if (!data_device)
data_device.reset(new QtWayland::DataDevice(q));
data_device->add(client, id, 1);
}
-void QWaylandInputDevicePrivate::seat_destroy_resource(wl_seat::Resource *)
+void QWaylandSeatPrivate::seat_destroy_resource(wl_seat::Resource *)
{
// cleanupDataDeviceForClient(resource->client(), true);
}
-void QWaylandInputDevicePrivate::seat_bind_resource(wl_seat::Resource *resource)
+void QWaylandSeatPrivate::seat_bind_resource(wl_seat::Resource *resource)
{
// The order of capabilities matches the order defined in the wayland protocol
wl_seat::send_capabilities(resource->handle, (uint32_t)capabilities);
}
-void QWaylandInputDevicePrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
+void QWaylandSeatPrivate::seat_get_pointer(wl_seat::Resource *resource, uint32_t id)
{
if (!pointer.isNull()) {
pointer->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
}
}
-void QWaylandInputDevicePrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
+void QWaylandSeatPrivate::seat_get_keyboard(wl_seat::Resource *resource, uint32_t id)
{
if (!keyboard.isNull()) {
keyboard->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
}
}
-void QWaylandInputDevicePrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
+void QWaylandSeatPrivate::seat_get_touch(wl_seat::Resource *resource, uint32_t id)
{
if (!touch.isNull()) {
touch->addClient(QWaylandClient::fromWlClient(compositor, resource->client()), id, resource->version());
}
}
-QWaylandKeymap::QWaylandKeymap(const QString &layout, const QString &variant, const QString &options, const QString &model, const QString &rules)
- : m_layout(layout)
- , m_variant(variant)
- , m_options(options)
- , m_rules(rules)
- , m_model(model)
-{
-}
-
-
/*!
- * \class QWaylandInputDevice
+ * \class QWaylandSeat
* \inmodule QtWaylandCompositor
- * \preliminary
- * \brief The QWaylandInputDevice class provides access to keyboard, mouse, and touch input.
+ * \since 5.8
+ * \brief The QWaylandSeat class provides access to keyboard, mouse, and touch input.
*
- * The QWaylandInputDevice provides access to different types of user input and maintains
+ * The QWaylandSeat provides access to different types of user input and maintains
* a keyboard focus and a mouse pointer. It corresponds to the wl_seat interface in the Wayland protocol.
*/
/*!
- * \enum QWaylandInputDevice::CapabilityFlag
+ * \enum QWaylandSeat::CapabilityFlag
*
- * This enum type describes the capabilities of a QWaylandInputDevice.
+ * This enum type describes the capabilities of a QWaylandSeat.
*
- * \value Pointer The QWaylandInputDevice supports pointer input.
- * \value Keyboard The QWaylandInputDevice supports keyboard input.
- * \value Touch The QWaylandInputDevice supports touch input.
+ * \value Pointer The QWaylandSeat supports pointer input.
+ * \value Keyboard The QWaylandSeat supports keyboard input.
+ * \value Touch The QWaylandSeat supports touch input.
*/
/*!
- * Constructs a QWaylandInputDevice for the given \a compositor and with the given \a capabilityFlags.
+ * Constructs a QWaylandSeat for the given \a compositor and with the given \a capabilityFlags.
*/
-QWaylandInputDevice::QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags)
- : QWaylandObject(*new QWaylandInputDevicePrivate(this,compositor))
+QWaylandSeat::QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags)
+ : QWaylandObject(*new QWaylandSeatPrivate(this))
{
- d_func()->setCapabilities(capabilityFlags);
+ Q_D(QWaylandSeat);
+ d->compositor = compositor;
+ d->capabilities = capabilityFlags;
+ if (compositor->isCreated())
+ initialize();
}
/*!
- * Destroys the QWaylandInputDevice
+ * Destroys the QWaylandSeat
*/
-QWaylandInputDevice::~QWaylandInputDevice()
+QWaylandSeat::~QWaylandSeat()
{
}
+void QWaylandSeat::initialize()
+{
+ Q_D(QWaylandSeat);
+ d->init(d->compositor->display(), 4);
+
+ if (d->capabilities & QWaylandSeat::Pointer)
+ d->pointer.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreatePointerDevice(this));
+ if (d->capabilities & QWaylandSeat::Touch)
+ d->touch.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateTouchDevice(this));
+ if (d->capabilities & QWaylandSeat::Keyboard)
+ d->keyboard.reset(QWaylandCompositorPrivate::get(d->compositor)->callCreateKeyboardDevice(this));
+
+ d->isInitialized = true;
+}
+
+bool QWaylandSeat::isInitialized() const
+{
+ Q_D(const QWaylandSeat);
+ return d->isInitialized;
+}
+
/*!
- * Sends a mouse press event for \a button to the QWaylandInputDevice's pointer device.
+ * Sends a mouse press event for \a button to the QWaylandSeat's pointer device.
*/
-void QWaylandInputDevice::sendMousePressEvent(Qt::MouseButton button)
+void QWaylandSeat::sendMousePressEvent(Qt::MouseButton button)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
d->pointer->sendMousePressEvent(button);
}
/*!
- * Sends a mouse release event for \a button to the QWaylandInputDevice's pointer device.
+ * Sends a mouse release event for \a button to the QWaylandSeat's pointer device.
*/
-void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button)
+void QWaylandSeat::sendMouseReleaseEvent(Qt::MouseButton button)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
d->pointer->sendMouseReleaseEvent(button);
}
@@ -206,97 +223,94 @@ void QWaylandInputDevice::sendMouseReleaseEvent(Qt::MouseButton button)
* Sets the mouse focus to \a view and sends a mouse move event to the pointer device with the
* local position \a localPos and output space position \a outputSpacePos.
**/
-void QWaylandInputDevice::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos)
+void QWaylandSeat::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
d->pointer->sendMouseMoveEvent(view, localPos, outputSpacePos);
}
/*!
- * Sends a mouse wheel event to the QWaylandInputDevice's pointer device with the given \a orientation and \a delta.
+ * Sends a mouse wheel event to the QWaylandSeat's pointer device with the given \a orientation and \a delta.
*/
-void QWaylandInputDevice::sendMouseWheelEvent(Qt::Orientation orientation, int delta)
+void QWaylandSeat::sendMouseWheelEvent(Qt::Orientation orientation, int delta)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
d->pointer->sendMouseWheelEvent(orientation, delta);
}
/*!
* Sends a key press event with the key \a code to the keyboard device.
*/
-void QWaylandInputDevice::sendKeyPressEvent(uint code)
+void QWaylandSeat::sendKeyPressEvent(uint code)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
d->keyboard->sendKeyPressEvent(code);
}
/*!
* Sends a key release event with the key \a code to the keyboard device.
*/
-void QWaylandInputDevice::sendKeyReleaseEvent(uint code)
+void QWaylandSeat::sendKeyReleaseEvent(uint code)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
d->keyboard->sendKeyReleaseEvent(code);
}
/*!
- * Sends a touch point event with the given \a id and \a state to the touch device. The position
- * of the touch point is given by \a point.
+ * Sends a touch point event to the \a surface on a touch device with the given
+ * \a id, \a point and \a state.
+ *
+ * Returns the serial for the touch up or touch down event.
*/
-void QWaylandInputDevice::sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state)
+uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &point, Qt::TouchPointState state)
{
- Q_D(QWaylandInputDevice);
- if (d->touch.isNull()) {
- return;
- }
- d->touch->sendTouchPointEvent(id, point,state);
+ Q_D(QWaylandSeat);
+
+ if (d->touch.isNull())
+ return 0;
+
+ return d->touch->sendTouchPointEvent(surface, id, point,state);
}
/*!
- * Sends a frame event to the touch device.
+ * Sends a frame event to the touch device of a \a client.
*/
-void QWaylandInputDevice::sendTouchFrameEvent()
+void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
{
- Q_D(QWaylandInputDevice);
- if (!d->touch.isNull()) {
- d->touch->sendFrameEvent();
- }
+ Q_D(QWaylandSeat);
+ if (!d->touch.isNull())
+ d->touch->sendFrameEvent(client);
}
/*!
- * Sends a cancel event to the touch device.
+ * Sends a cancel event to the touch device of a \a client.
*/
-void QWaylandInputDevice::sendTouchCancelEvent()
+void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
{
- Q_D(QWaylandInputDevice);
- if (!d->touch.isNull()) {
- d->touch->sendCancelEvent();
- }
+ Q_D(QWaylandSeat);
+ if (!d->touch.isNull())
+ d->touch->sendCancelEvent(client);
}
/*!
- * Sends the \a event to the touch device.
+ * Sends the \a event to the specified \a surface on the touch device.
*/
-void QWaylandInputDevice::sendFullTouchEvent(QTouchEvent *event)
+void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
{
- Q_D(QWaylandInputDevice);
- if (!mouseFocus()) {
- qWarning("Cannot send touch event, no pointer focus, fix the compositor");
- return;
- }
+ Q_D(QWaylandSeat);
if (!d->touch)
return;
- d->touch->sendFullTouchEvent(event);
+ d->touch->sendFullTouchEvent(surface, event);
}
/*!
* Sends the \a event to the keyboard device.
*/
-void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event)
+void QWaylandSeat::sendFullKeyEvent(QKeyEvent *event)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
if (!keyboardFocus()) {
qWarning("Cannot send key event, no keyboard focus, fix the compositor");
@@ -327,18 +341,18 @@ void QWaylandInputDevice::sendFullKeyEvent(QKeyEvent *event)
/*!
* Returns the keyboard for this input device.
*/
-QWaylandKeyboard *QWaylandInputDevice::keyboard() const
+QWaylandKeyboard *QWaylandSeat::keyboard() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->keyboard.data();
}
/*!
* Returns the current focused surface for keyboard input.
*/
-QWaylandSurface *QWaylandInputDevice::keyboardFocus() const
+QWaylandSurface *QWaylandSeat::keyboardFocus() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
if (d->keyboard.isNull() || !d->keyboard->focus())
return Q_NULLPTR;
@@ -348,9 +362,9 @@ QWaylandSurface *QWaylandInputDevice::keyboardFocus() const
/*!
* Sets the current keyboard focus to \a surface.
*/
-bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface)
+bool QWaylandSeat::setKeyboardFocus(QWaylandSurface *surface)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
if (surface && surface->isDestroyed())
return false;
@@ -358,10 +372,6 @@ bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface)
if (surface == oldSurface)
return true;
- QWaylandWlShellSurface *wlShellsurface = QWaylandWlShellSurface::findIn(surface);
- if (wlShellsurface && wlShellsurface->focusPolicy() == QWaylandWlShellSurface::NoKeyboardFocus)
- return false;
-
d->keyboardFocus = surface;
if (!d->keyboard.isNull())
d->keyboard->setFocus(surface);
@@ -371,48 +381,45 @@ bool QWaylandInputDevice::setKeyboardFocus(QWaylandSurface *surface)
return true;
}
-/*!
- * Sets the key map of this QWaylandInputDevice to \a keymap.
- */
-void QWaylandInputDevice::setKeymap(const QWaylandKeymap &keymap)
+QWaylandKeymap *QWaylandSeat::keymap()
{
- if (keyboard())
- keyboard()->setKeymap(keymap);
+ Q_D(const QWaylandSeat);
+ return d->keymap.data();
}
/*!
- * Returns the pointer device for this QWaylandInputDevice.
+ * Returns the pointer device for this QWaylandSeat.
*/
-QWaylandPointer *QWaylandInputDevice::pointer() const
+QWaylandPointer *QWaylandSeat::pointer() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->pointer.data();
}
/*!
- * Returns the touch device for this QWaylandInputDevice.
+ * Returns the touch device for this QWaylandSeat.
*/
-QWaylandTouch *QWaylandInputDevice::touch() const
+QWaylandTouch *QWaylandSeat::touch() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->touch.data();
}
/*!
* Returns the view that currently has mouse focus.
*/
-QWaylandView *QWaylandInputDevice::mouseFocus() const
+QWaylandView *QWaylandSeat::mouseFocus() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->mouseFocus;
}
/*!
* Sets the current mouse focus to \a view.
*/
-void QWaylandInputDevice::setMouseFocus(QWaylandView *view)
+void QWaylandSeat::setMouseFocus(QWaylandView *view)
{
- Q_D(QWaylandInputDevice);
+ Q_D(QWaylandSeat);
if (view == d->mouseFocus)
return;
@@ -422,52 +429,52 @@ void QWaylandInputDevice::setMouseFocus(QWaylandView *view)
}
/*!
- * Returns the compositor for this QWaylandInputDevice.
+ * Returns the compositor for this QWaylandSeat.
*/
-QWaylandCompositor *QWaylandInputDevice::compositor() const
+QWaylandCompositor *QWaylandSeat::compositor() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->compositor;
}
/*!
- * Returns the drag object for this QWaylandInputDevice.
+ * Returns the drag object for this QWaylandSeat.
*/
-QWaylandDrag *QWaylandInputDevice::drag() const
+QWaylandDrag *QWaylandSeat::drag() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->drag_handle.data();
}
/*!
- * Returns the capability flags for this QWaylandInputDevice.
+ * Returns the capability flags for this QWaylandSeat.
*/
-QWaylandInputDevice::CapabilityFlags QWaylandInputDevice::capabilities() const
+QWaylandSeat::CapabilityFlags QWaylandSeat::capabilities() const
{
- Q_D(const QWaylandInputDevice);
+ Q_D(const QWaylandSeat);
return d->capabilities;
}
/*!
* \internal
*/
-bool QWaylandInputDevice::isOwner(QInputEvent *inputEvent) const
+bool QWaylandSeat::isOwner(QInputEvent *inputEvent) const
{
Q_UNUSED(inputEvent);
return true;
}
/*!
- * Returns the QWaylandInputDevice corresponding to the \a resource. The \a resource is expected
+ * Returns the QWaylandSeat corresponding to the \a resource. The \a resource is expected
* to have the type wl_seat.
*/
-QWaylandInputDevice *QWaylandInputDevice::fromSeatResource(struct ::wl_resource *resource)
+QWaylandSeat *QWaylandSeat::fromSeatResource(struct ::wl_resource *resource)
{
- return static_cast<QWaylandInputDevicePrivate *>(QWaylandInputDevicePrivate::Resource::fromResource(resource)->seat_object)->q_func();
+ return static_cast<QWaylandSeatPrivate *>(QWaylandSeatPrivate::Resource::fromResource(resource)->seat_object)->q_func();
}
/*!
- * \fn void QWaylandInputDevice::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
+ * \fn void QWaylandSeat::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
*
* This signal is emitted when the mouse focus has changed from \a oldFocus to \a newFocus.
*/
diff --git a/src/compositor/compositor_api/qwaylandinput.h b/src/compositor/compositor_api/qwaylandseat.h
index d1cb922b7..3e90342c7 100644
--- a/src/compositor/compositor_api/qwaylandinput.h
+++ b/src/compositor/compositor_api/qwaylandseat.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QWAYLANDINPUT_H
-#define QWAYLANDINPUT_H
+#ifndef QWAYLANDSEAT_H
+#define QWAYLANDSEAT_H
#include <QtCore/qnamespace.h>
#include <QtCore/QPoint>
@@ -53,20 +53,19 @@ class QKeyEvent;
class QTouchEvent;
class QWaylandView;
class QInputEvent;
-class QWaylandInputDevicePrivate;
+class QWaylandSeatPrivate;
class QWaylandDrag;
class QWaylandKeyboard;
class QWaylandPointer;
class QWaylandTouch;
-namespace QtWayland {
-class InputDevice;
-}
-
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputDevice : public QWaylandObject
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSeat : public QWaylandObject
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QWaylandInputDevice)
+ Q_DECLARE_PRIVATE(QWaylandSeat)
+
+ Q_PROPERTY(QWaylandDrag *drag READ drag CONSTANT)
+ Q_PROPERTY(QWaylandKeymap *keymap READ keymap CONSTANT)
public:
enum CapabilityFlag {
// The order should match the enum WL_SEAT_CAPABILITY_*
@@ -79,8 +78,10 @@ public:
Q_DECLARE_FLAGS(CapabilityFlags, CapabilityFlag)
Q_ENUM(CapabilityFlags)
- QWaylandInputDevice(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags = DefaultCapabilities);
- virtual ~QWaylandInputDevice();
+ QWaylandSeat(QWaylandCompositor *compositor, CapabilityFlags capabilityFlags = DefaultCapabilities);
+ virtual ~QWaylandSeat();
+ virtual void initialize();
+ bool isInitialized() const;
void sendMousePressEvent(Qt::MouseButton button);
void sendMouseReleaseEvent(Qt::MouseButton button);
@@ -93,11 +94,11 @@ public:
void sendFullKeyEvent(QKeyEvent *event);
void sendFullKeyEvent(QWaylandSurface *surface, QKeyEvent *event);
- void sendTouchPointEvent(int id, const QPointF &point, Qt::TouchPointState state);
- void sendTouchFrameEvent();
- void sendTouchCancelEvent();
+ uint sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &point, Qt::TouchPointState state);
+ void sendTouchFrameEvent(QWaylandClient *client);
+ void sendTouchCancelEvent(QWaylandClient *client);
- void sendFullTouchEvent(QTouchEvent *event);
+ void sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event);
QWaylandPointer *pointer() const;
//Normally set by the mouse device,
@@ -108,7 +109,7 @@ public:
QWaylandKeyboard *keyboard() const;
QWaylandSurface *keyboardFocus() const;
bool setKeyboardFocus(QWaylandSurface *surface);
- void setKeymap(const QWaylandKeymap &keymap);
+ QWaylandKeymap *keymap();
QWaylandTouch *touch() const;
@@ -116,11 +117,11 @@ public:
QWaylandDrag *drag() const;
- QWaylandInputDevice::CapabilityFlags capabilities() const;
+ QWaylandSeat::CapabilityFlags capabilities() const;
virtual bool isOwner(QInputEvent *inputEvent) const;
- static QWaylandInputDevice *fromSeatResource(struct ::wl_resource *resource);
+ static QWaylandSeat *fromSeatResource(struct ::wl_resource *resource);
Q_SIGNALS:
void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus);
@@ -128,8 +129,8 @@ Q_SIGNALS:
void cursorSurfaceRequest(QWaylandSurface *surface, int hotspotX, int hotspotY);
};
-Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandInputDevice::CapabilityFlags)
+Q_DECLARE_OPERATORS_FOR_FLAGS(QWaylandSeat::CapabilityFlags)
QT_END_NAMESPACE
-#endif // QWAYLANDINPUT_H
+#endif // QWAYLANDSEAT_H
diff --git a/src/compositor/compositor_api/qwaylandinput_p.h b/src/compositor/compositor_api/qwaylandseat_p.h
index 5e57c43cc..eb86aec37 100644
--- a/src/compositor/compositor_api/qwaylandinput_p.h
+++ b/src/compositor/compositor_api/qwaylandseat_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef QWAYLANDINPUT_P_H
-#define QWAYLANDINPUT_P_H
+#ifndef QWAYLANDSEAT_P_H
+#define QWAYLANDSEAT_P_H
//
// W A R N I N G
@@ -51,7 +51,7 @@
#include <stdint.h>
#include <QtWaylandCompositor/qwaylandexport.h>
-#include <QtWaylandCompositor/qwaylandinput.h>
+#include <QtWaylandCompositor/qwaylandseat.h>
#include <QtCore/QList>
#include <QtCore/QPoint>
@@ -68,7 +68,7 @@ QT_BEGIN_NAMESPACE
class QKeyEvent;
class QTouchEvent;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandDrag;
class QWaylandView;
@@ -85,18 +85,18 @@ class InputMethod;
}
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandInputDevicePrivate : public QObjectPrivate, public QtWaylandServer::wl_seat
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSeatPrivate : public QObjectPrivate, public QtWaylandServer::wl_seat
{
public:
- Q_DECLARE_PUBLIC(QWaylandInputDevice)
+ Q_DECLARE_PUBLIC(QWaylandSeat)
- QWaylandInputDevicePrivate(QWaylandInputDevice *device, QWaylandCompositor *compositor);
- ~QWaylandInputDevicePrivate();
+ QWaylandSeatPrivate(QWaylandSeat *seat);
+ ~QWaylandSeatPrivate();
void clientRequestedDataDevice(QtWayland::DataDeviceManager *dndSelection, struct wl_client *client, uint32_t id);
- void setCapabilities(QWaylandInputDevice::CapabilityFlags caps);
+ void setCapabilities(QWaylandSeat::CapabilityFlags caps);
- static QWaylandInputDevicePrivate *get(QWaylandInputDevice *device) { return device->d_func(); }
+ static QWaylandSeatPrivate *get(QWaylandSeat *device) { return device->d_func(); }
QtWayland::DataDevice *dataDevice() const { return data_device.data(); }
@@ -113,19 +113,21 @@ protected:
void seat_destroy_resource(wl_seat::Resource *resource) Q_DECL_OVERRIDE;
private:
+ bool isInitialized;
QWaylandCompositor *compositor;
QWaylandView *mouseFocus;
QWaylandSurface *keyboardFocus;
- QWaylandInputDevice::CapabilityFlags capabilities;
+ QWaylandSeat::CapabilityFlags capabilities;
QScopedPointer<QWaylandPointer> pointer;
QScopedPointer<QWaylandKeyboard> keyboard;
QScopedPointer<QWaylandTouch> touch;
QScopedPointer<QtWayland::DataDevice> data_device;
QScopedPointer<QWaylandDrag> drag_handle;
+ QScopedPointer<QWaylandKeymap> keymap;
};
QT_END_NAMESPACE
-#endif // QWAYLANDINPUT_P_H
+#endif // QWAYLANDSEAT_P_H
diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
index edb34e0bd..f79fd57ef 100644
--- a/src/compositor/compositor_api/qwaylandsurface.cpp
+++ b/src/compositor/compositor_api/qwaylandsurface.cpp
@@ -40,6 +40,7 @@
#include "wayland_wrapper/qwldatadevice_p.h"
#include "wayland_wrapper/qwldatadevicemanager_p.h"
+#include "wayland_wrapper/qwlbuffermanager_p.h"
#include "wayland_wrapper/qwlregion_p.h"
#include "extensions/qwlextendedsurface_p.h"
@@ -52,7 +53,7 @@
#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
#include <QtWaylandCompositor/private/qwaylandview_p.h>
-#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/private/qwaylandseat_p.h>
#include <QtCore/private/qobject_p.h>
@@ -123,19 +124,18 @@ QWaylandSurfacePrivate::QWaylandSurfacePrivate()
, compositor(Q_NULLPTR)
, refCount(1)
, client(Q_NULLPTR)
- , buffer(0)
, role(0)
, inputRegion(infiniteRegion())
, bufferScale(1)
, isCursorSurface(false)
, destroyed(false)
- , mapped(false)
+ , hasContent(false)
, isInitialized(false)
, contentOrientation(Qt::PrimaryOrientation)
, inputMethodControl(Q_NULLPTR)
, subsurface(0)
{
- pending.buffer = 0;
+ pending.buffer = QWaylandBufferRef();
pending.newlyAttached = false;
pending.inputRegion = infiniteRegion();
pending.bufferScale = 1;
@@ -153,9 +153,6 @@ QWaylandSurfacePrivate::~QWaylandSurfacePrivate()
bufferRef = QWaylandBufferRef();
- for (int i = 0; i < bufferPool.size(); i++)
- bufferPool[i]->setDestroyIfUnused(true);
-
foreach (QtWayland::FrameCallback *c, pendingFrameCallbacks)
c->destroy();
foreach (QtWayland::FrameCallback *c, frameCallbacks)
@@ -193,9 +190,9 @@ void QWaylandSurfacePrivate::notifyViewsAboutDestruction()
foreach (QWaylandView *view, views) {
QWaylandViewPrivate::get(view)->markSurfaceAsDestroyed(q);
}
- if (mapped) {
- mapped = false;
- emit q->mappedChanged();
+ if (hasContent) {
+ hasContent = false;
+ emit q->hasContentChanged();
}
}
@@ -237,9 +234,7 @@ void QWaylandSurfacePrivate::surface_destroy(Resource *resource)
void QWaylandSurfacePrivate::surface_attach(Resource *, struct wl_resource *buffer, int x, int y)
{
- if (pending.buffer)
- pending.buffer->disown();
- pending.buffer = createSurfaceBuffer(buffer);
+ pending.buffer = QWaylandBufferRef(getBuffer(buffer));
pending.offset = QPoint(x, y);
pending.newlyAttached = true;
}
@@ -274,19 +269,37 @@ void QWaylandSurfacePrivate::surface_commit(Resource *)
{
Q_Q(QWaylandSurface);
- if (pending.buffer || pending.newlyAttached) {
- setBackBuffer(pending.buffer, pending.damage);
+ if (pending.buffer.hasBuffer() || pending.newlyAttached)
+ bufferRef = pending.buffer;
+
+ auto buffer = bufferRef.buffer();
+ if (buffer)
+ buffer->setCommitted(pending.damage);
+
+ setSize(bufferRef.size());
+ damage = pending.damage.intersected(QRect(QPoint(), size));
+
+ for (int i = 0; i < views.size(); i++) {
+ views.at(i)->bufferCommitted(bufferRef, damage);
}
- pending.buffer = 0;
- pending.offset = QPoint();
- pending.newlyAttached = false;
- pending.damage = QRegion();
+ emit q->damaged(damage);
+
+ bool oldHasContent = hasContent;
+ hasContent = bufferRef.hasContent();
+ if (oldHasContent != hasContent)
+ emit q->hasContentChanged();
+
+ if (!pending.offset.isNull())
+ emit q->offsetForNextFrame(pending.offset);
setBufferScale(pending.bufferScale);
- if (buffer)
- buffer->setCommitted();
+
+ pending.buffer = QWaylandBufferRef();
+ pending.offset = QPoint();
+ pending.newlyAttached = false;
+ pending.damage = QRegion();
frameCallbacks << pendingFrameCallbacks;
pendingFrameCallbacks.clear();
@@ -326,58 +339,16 @@ void QWaylandSurfacePrivate::surface_set_buffer_scale(QtWaylandServer::wl_surfac
pending.bufferScale = scale;
}
-void QWaylandSurfacePrivate::setBackBuffer(QtWayland::SurfaceBuffer *b, const QRegion &d)
+QtWayland::ClientBuffer *QWaylandSurfacePrivate::getBuffer(struct ::wl_resource *buffer)
{
- Q_Q(QWaylandSurface);
- buffer = b;
-
- bufferRef = QWaylandBufferRef(buffer);
-
- setSize(bufferRef.size());
- damage = d.intersected(QRect(QPoint(), size));
-
- for (int i = 0; i < views.size(); i++) {
- views.at(i)->attach(bufferRef, damage);
- }
-
- emit q->damaged(damage);
-
- bool oldMapped = mapped;
- mapped = QtWayland::SurfaceBuffer::hasContent(buffer);
- if (oldMapped != mapped)
- emit q->mappedChanged();
-
- if (!pending.offset.isNull())
- emit q->offsetForNextFrame(pending.offset);
-}
-
-QtWayland::SurfaceBuffer *QWaylandSurfacePrivate::createSurfaceBuffer(struct ::wl_resource *buffer)
-{
- Q_Q(QWaylandSurface);
- QtWayland::SurfaceBuffer *newBuffer = 0;
- for (int i = 0; i < bufferPool.size(); i++) {
- if (!bufferPool[i]->isRegisteredWithBuffer()) {
- newBuffer = bufferPool[i];
- newBuffer->initialize(buffer);
- break;
- }
- }
-
- if (!newBuffer) {
- newBuffer = new QtWayland::SurfaceBuffer(q);
- newBuffer->initialize(buffer);
- bufferPool.append(newBuffer);
- if (bufferPool.size() > 3)
- qWarning() << "Increased buffer pool size to" << bufferPool.size() << "for surface" << q;
- }
-
- return newBuffer;
+ QtWayland::BufferManager *bufMan = QWaylandCompositorPrivate::get(compositor)->bufferManager();
+ return bufMan->getBuffer(buffer);
}
/*!
* \qmltype WaylandSurface
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief Represents a rectangular area on an output device.
*
* This type encapsulates a rectangular area of pixels that is displayed on an output device. It
@@ -387,7 +358,7 @@ QtWayland::SurfaceBuffer *QWaylandSurfacePrivate::createSurfaceBuffer(struct ::w
/*!
* \class QWaylandSurface
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandSurface class represents a rectangular area on an output device.
*
* This class encapsulates a rectangular area of pixels that is displayed on an output device. It
@@ -484,20 +455,20 @@ QWaylandClient *QWaylandSurface::client() const
}
/*!
- * \qmlproperty bool QtWaylandCompositor::WaylandSurface::isMapped
+ * \qmlproperty bool QtWaylandCompositor::WaylandSurface::hasContent
*
* This property holds whether the WaylandSurface has content.
*/
/*!
- * \property QWaylandSurface::isMapped
+ * \property QWaylandSurface::hasContent
*
* This property holds whether the QWaylandSurface has content.
*/
-bool QWaylandSurface::isMapped() const
+bool QWaylandSurface::hasContent() const
{
Q_D(const QWaylandSurface);
- return d->mapped;
+ return d->hasContent;
}
/*!
@@ -590,7 +561,7 @@ Qt::ScreenOrientation QWaylandSurface::contentOrientation() const
QWaylandSurface::Origin QWaylandSurface::origin() const
{
Q_D(const QWaylandSurface);
- return d->buffer ? d->buffer->origin() : QWaylandSurface::OriginTopLeft;
+ return d->bufferRef.origin();
}
/*!
@@ -708,9 +679,9 @@ QWaylandInputMethodControl *QWaylandSurface::inputMethodControl() const
void QWaylandSurface::updateSelection()
{
Q_D(QWaylandSurface);
- QWaylandInputDevice *inputDevice = d->compositor->defaultInputDevice();
- if (inputDevice) {
- const QtWayland::DataDevice *dataDevice = QWaylandInputDevicePrivate::get(inputDevice)->dataDevice();
+ QWaylandSeat *seat = d->compositor->defaultSeat();
+ if (seat) {
+ const QtWayland::DataDevice *dataDevice = QWaylandSeatPrivate::get(seat)->dataDevice();
if (dataDevice) {
QWaylandCompositorPrivate::get(d->compositor)->dataDeviceManager()->offerRetainedSelection(
dataDevice->resourceMap().value(d->resource()->client())->handle);
@@ -719,11 +690,11 @@ void QWaylandSurface::updateSelection()
}
/*!
- * Returns this QWaylandSurface's throttling view.
+ * Returns this QWaylandSurface's primary view.
*
- * \sa QWaylandView::advance()
+ * \sa QWaylandView::advance(), QWaylandSurface::setPrimaryView()
*/
-QWaylandView *QWaylandSurface::throttlingView() const
+QWaylandView *QWaylandSurface::primaryView() const
{
Q_D(const QWaylandSurface);
if (d->views.isEmpty())
@@ -732,15 +703,20 @@ QWaylandView *QWaylandSurface::throttlingView() const
}
/*!
- * Sets this QWaylandSurface's throttling view to \a view, in case there are
- * multiple views of this surface. The throttling view is the view that
+ * Sets this QWaylandSurface's primary view to \a view, in case there are
+ * multiple views of this surface. The primary view is the view that
* governs the client's refresh rate. It takes care of discarding buffer
* references when QWaylandView::advance() is called. See the documentation
* for QWaylandView::advance() for more details.
*
+ * In shell surface integrations, such as QWaylandWlShellIntegration and
+ * QWaylandXdgShellV5Integration, maximize and fullscreen requests from the
+ * client will only have an effect if the integration has the primary view
+ * of the surface.
+ *
* \sa QWaylandView::advance()
*/
-void QWaylandSurface::setThrottlingView(QWaylandView *view)
+void QWaylandSurface::setPrimaryView(QWaylandView *view)
{
Q_D(QWaylandSurface);
@@ -835,8 +811,7 @@ void QWaylandSurfacePrivate::refView(QWaylandView *view)
views.append(view);
ref();
- QWaylandBufferRef ref(buffer);
- view->attach(ref, QRect(QPoint(0,0), ref.size()));
+ view->bufferCommitted(bufferRef, QRect(QPoint(0,0), bufferRef.size()));
}
void QWaylandSurfacePrivate::derefView(QWaylandView *view)
@@ -894,4 +869,16 @@ void QWaylandSurfacePrivate::Subsurface::subsurface_set_desync(wl_subsurface::Re
qDebug() << Q_FUNC_INFO;
}
+/*!
+ * \qmlsignal void QtWaylandCompositor::WaylandSurface::dragStarted(object drag)
+ *
+ * This signal is emitted when a \a drag has started from this surface.
+ */
+
+/*!
+ * \fn void QWaylandSurface::dragStarted(QWaylandDrag *drag)
+ *
+ * This signal is emitted when a \a drag has started from this surface.
+ */
+
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h
index 816b5c987..40753ad47 100644
--- a/src/compositor/compositor_api/qwaylandsurface.h
+++ b/src/compositor/compositor_api/qwaylandsurface.h
@@ -60,6 +60,7 @@ class QWaylandBufferRef;
class QWaylandView;
class QWaylandSurfaceOp;
class QWaylandInputMethodControl;
+class QWaylandDrag;
class QWaylandSurfaceRole
{
@@ -81,7 +82,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject
Q_PROPERTY(int bufferScale READ bufferScale NOTIFY bufferScaleChanged)
Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged)
Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged)
- Q_PROPERTY(bool isMapped READ isMapped NOTIFY mappedChanged)
+ Q_PROPERTY(bool hasContent READ hasContent NOTIFY hasContentChanged)
Q_PROPERTY(bool cursorSurface READ isCursorSurface WRITE markAsCursorSurface)
public:
@@ -104,7 +105,7 @@ public:
bool setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode);
QWaylandSurfaceRole *role() const;
- bool isMapped() const;
+ bool hasContent() const;
QSize size() const;
int bufferScale() const;
@@ -123,8 +124,8 @@ public:
Q_INVOKABLE void frameStarted();
Q_INVOKABLE void sendFrameCallbacks();
- QWaylandView *throttlingView() const;
- void setThrottlingView(QWaylandView *view);
+ QWaylandView *primaryView() const;
+ void setPrimaryView(QWaylandView *view);
QList<QWaylandView *> views() const;
@@ -143,7 +144,7 @@ protected:
QWaylandSurface(QWaylandSurfacePrivate &dptr);
Q_SIGNALS:
- void mappedChanged();
+ void hasContentChanged();
void damaged(const QRegion &rect);
void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent);
void childAdded(QWaylandSurface *child);
@@ -156,6 +157,7 @@ Q_SIGNALS:
void subsurfacePositionChanged(const QPoint &position);
void subsurfacePlaceAbove(QWaylandSurface *sibling);
void subsurfacePlaceBelow(QWaylandSurface *sibling);
+ void dragStarted(QWaylandDrag *drag);
void configure(bool hasBuffer);
void redraw();
diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h
index e37179cc6..94ec287bd 100644
--- a/src/compositor/compositor_api/qwaylandsurface_p.h
+++ b/src/compositor/compositor_api/qwaylandsurface_p.h
@@ -52,7 +52,7 @@
#include <QtWaylandCompositor/qwaylandexport.h>
#include <private/qobject_p.h>
-#include <private/qwlsurfacebuffer_p.h>
+#include <private/qwlclientbuffer_p.h>
#include <QtWaylandCompositor/qwaylandsurface.h>
#include <QtWaylandCompositor/qwaylandbufferref.h>
@@ -134,8 +134,7 @@ protected:
void surface_set_buffer_transform(Resource *resource, int32_t transform) Q_DECL_OVERRIDE;
void surface_set_buffer_scale(Resource *resource, int32_t bufferScale) Q_DECL_OVERRIDE;
- void setBackBuffer(QtWayland::SurfaceBuffer *buffer, const QRegion &damage);
- QtWayland::SurfaceBuffer *createSurfaceBuffer(struct ::wl_resource *buffer);
+ QtWayland::ClientBuffer *getBuffer(struct ::wl_resource *buffer);
public: //member variables
QWaylandCompositor *compositor;
@@ -143,12 +142,11 @@ public: //member variables
QWaylandClient *client;
QList<QWaylandView *> views;
QRegion damage;
- QtWayland::SurfaceBuffer *buffer;
QWaylandBufferRef bufferRef;
QWaylandSurfaceRole *role;
struct {
- QtWayland::SurfaceBuffer *buffer;
+ QWaylandBufferRef buffer;
QRegion damage;
QPoint offset;
bool newlyAttached;
@@ -165,13 +163,11 @@ public: //member variables
QRegion inputRegion;
QRegion opaqueRegion;
- QVector<QtWayland::SurfaceBuffer *> bufferPool;
-
QSize size;
int bufferScale;
bool isCursorSurface;
bool destroyed;
- bool mapped;
+ bool hasContent;
bool isInitialized;
Qt::ScreenOrientation contentOrientation;
QWindow::Visibility visibility;
diff --git a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp
index d415642c4..58a8b7be6 100644
--- a/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp
+++ b/src/compositor/compositor_api/qwaylandsurfacegrabber.cpp
@@ -46,12 +46,13 @@ QT_BEGIN_NAMESPACE
/*!
\class QWaylandSurfaceGrabber
\inmodule QtWaylandCompositor
- \preliminary
+ \since 5.8
\brief The QWaylandSurfaceGrabber class allows to read the content of a QWaylandSurface
Sometimes it is needed to get the contents of a surface, for example to provide a screenshot
to the user. The QWaylandSurfaceGrabber class provides a simple method to do so, without
- having to care what type of buffer backs the surface, be it SHM, OpenGL or something else.
+ having to care what type of buffer backs the surface, be it shared memory, OpenGL or something
+ else.
*/
/*!
diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp
index a9b44527e..92a8f5cf3 100644
--- a/src/compositor/compositor_api/qwaylandtouch.cpp
+++ b/src/compositor/compositor_api/qwaylandtouch.cpp
@@ -38,7 +38,7 @@
#include "qwaylandtouch_p.h"
#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include <QtWaylandCompositor/QWaylandView>
#include <QtWaylandCompositor/QWaylandClient>
@@ -46,60 +46,49 @@
QT_BEGIN_NAMESPACE
-QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDevice *seat)
+QWaylandTouchPrivate::QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandSeat *seat)
: wl_touch()
, seat(seat)
- , focusResource()
{
Q_UNUSED(touch);
}
-void QWaylandTouchPrivate::resetFocusState()
-{
- focusDestroyListener.reset();
- focusResource = 0;
-}
-
-void QWaylandTouchPrivate::touch_bind_resource(Resource *resource)
-{
- focusResource = resource;
-}
-
-void QWaylandTouchPrivate::touch_destroy_resource(Resource *resource)
-{
- if (focusResource == resource) {
- resetFocusState();
- }
-}
-
void QWaylandTouchPrivate::touch_release(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
-void QWaylandTouchPrivate::sendDown(uint32_t time, int touch_id, const QPointF &position)
+uint QWaylandTouchPrivate::sendDown(QWaylandSurface *surface, uint32_t time, int touch_id, const QPointF &position)
{
Q_Q(QWaylandTouch);
- if (!focusResource || !q->mouseFocus())
- return;
+ auto focusResource = resourceMap().value(surface->client()->client());
+ if (!focusResource)
+ return 0;
uint32_t serial = q->compositor()->nextSerial();
- wl_touch_send_down(focusResource->handle, serial, time, q->mouseFocus()->surfaceResource(), touch_id,
+ wl_touch_send_down(focusResource->handle, serial, time, surface->resource(), touch_id,
wl_fixed_from_double(position.x()), wl_fixed_from_double(position.y()));
+ return serial;
}
-void QWaylandTouchPrivate::sendUp(uint32_t time, int touch_id)
+uint QWaylandTouchPrivate::sendUp(QWaylandClient *client, uint32_t time, int touch_id)
{
+ auto focusResource = resourceMap().value(client->client());
+
if (!focusResource)
- return;
+ return 0;
uint32_t serial = compositor()->nextSerial();
wl_touch_send_up(focusResource->handle, serial, time, touch_id);
+ return serial;
}
-void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF &position)
+
+void QWaylandTouchPrivate::sendMotion(QWaylandClient *client, uint32_t time, int touch_id, const QPointF &position)
{
+ auto focusResource = resourceMap().value(client->client());
+
if (!focusResource)
return;
@@ -110,26 +99,25 @@ void QWaylandTouchPrivate::sendMotion(uint32_t time, int touch_id, const QPointF
/*!
* \class QWaylandTouch
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandTouch class provides access to a touch device.
*
- * This class provides access to the touch device in a QWaylandInputDevice. It corresponds to
+ * This class provides access to the touch device in a QWaylandSeat. It corresponds to
* the Wayland interface wl_touch.
*/
/*!
- * Constructs a QWaylandTouch for the \a inputDevice and with the given \a parent.
+ * Constructs a QWaylandTouch for the \a seat and with the given \a parent.
*/
-QWaylandTouch::QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent)
- : QWaylandObject(*new QWaylandTouchPrivate(this, inputDevice), parent)
+QWaylandTouch::QWaylandTouch(QWaylandSeat *seat, QObject *parent)
+ : QWaylandObject(*new QWaylandTouchPrivate(this, seat), parent)
{
- connect(&d_func()->focusDestroyListener, &QWaylandDestroyListener::fired, this, &QWaylandTouch::focusDestroyed);
}
/*!
* Returns the input device for this QWaylandTouch.
*/
-QWaylandInputDevice *QWaylandTouch::inputDevice() const
+QWaylandSeat *QWaylandTouch::seat() const
{
Q_D(const QWaylandTouch);
return d->seat;
@@ -145,71 +133,73 @@ QWaylandCompositor *QWaylandTouch::compositor() const
}
/*!
- * Sends a touch point event for the touch device with the given \a id,
+ * Sends a touch point event to the touch device of \a surface with the given \a id,
* \a position, and \a state.
*
- *
- * \sa mouseFocus()
+ * Returns the serial of the down or up event if sent, otherwise 0.
*/
-void QWaylandTouch::sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state)
+uint QWaylandTouch::sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &position, Qt::TouchPointState state)
{
Q_D(QWaylandTouch);
uint32_t time = compositor()->currentTimeMsecs();
+ uint serial = 0;
switch (state) {
case Qt::TouchPointPressed:
- d->sendDown(time, id, position);
+ serial = d->sendDown(surface, time, id, position);
break;
case Qt::TouchPointMoved:
- d->sendMotion(time, id, position);
+ d->sendMotion(surface->client(), time, id, position);
break;
case Qt::TouchPointReleased:
- d->sendUp(time, id);
+ serial = d->sendUp(surface->client(), time, id);
break;
case Qt::TouchPointStationary:
// stationary points are not sent through wayland, the client must cache them
break;
- default:
- break;
}
+
+ return serial;
}
/*!
- * Sends a touch frame event for the touch device. This indicates the end of a
+ * Sends a touch frame event to the touch device of a \a client. This indicates the end of a
* contact point list.
*/
-void QWaylandTouch::sendFrameEvent()
+void QWaylandTouch::sendFrameEvent(QWaylandClient *client)
{
Q_D(QWaylandTouch);
- if (d->focusResource)
- d->send_frame(d->focusResource->handle);
+ auto focusResource = d->resourceMap().value(client->client());
+ if (focusResource)
+ d->send_frame(focusResource->handle);
}
/*!
- * Sends a touch cancel event for the touch device.
+ * Sends a touch cancel event to the touch device of a \a client.
*/
-void QWaylandTouch::sendCancelEvent()
+void QWaylandTouch::sendCancelEvent(QWaylandClient *client)
{
Q_D(QWaylandTouch);
- if (d->focusResource)
- d->send_cancel(d->focusResource->handle);
+ auto focusResource = d->resourceMap().value(client->client());
+ if (focusResource)
+ d->send_cancel(focusResource->handle);
}
/*!
- * Sends all the touch points in \a event for this touch device, followed
- * by a touch frame event.
+ * Sends all touch points in \a event to the specified \a surface,
+ * followed by a touch frame event.
*
* \sa sendTouchPointEvent(), sendFrameEvent()
*/
-void QWaylandTouch::sendFullTouchEvent(QTouchEvent *event)
+void QWaylandTouch::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
{
Q_D(QWaylandTouch);
if (event->type() == QEvent::TouchCancel) {
- sendCancelEvent();
+ sendCancelEvent(surface->client());
return;
}
QtWayland::TouchExtensionGlobal *ext = QtWayland::TouchExtensionGlobal::findIn(d->compositor());
- if (ext && ext->postTouchEvent(event, d->seat->mouseFocus()))
+ if (ext && ext->postTouchEvent(event, surface))
return;
const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
@@ -220,9 +210,9 @@ void QWaylandTouch::sendFullTouchEvent(QTouchEvent *event)
for (int i = 0; i < pointCount; ++i) {
const QTouchEvent::TouchPoint &tp(points.at(i));
// Convert the local pos in the compositor window to surface-relative.
- sendTouchPointEvent(tp.id(), tp.pos(), tp.state());
+ sendTouchPointEvent(surface, tp.id(), tp.pos(), tp.state());
}
- sendFrameEvent();
+ sendFrameEvent(surface->client());
}
/*!
@@ -234,45 +224,4 @@ void QWaylandTouch::addClient(QWaylandClient *client, uint32_t id, uint32_t vers
d->add(client->client(), id, qMin<uint32_t>(QtWaylandServer::wl_touch::interfaceVersion(), version));
}
-/*!
- * Returns the Wayland resource for this QWaylandTouch.
- */
-struct wl_resource *QWaylandTouch::focusResource() const
-{
- Q_D(const QWaylandTouch);
- if (!d->focusResource)
- return Q_NULLPTR;
- return d->focusResource->handle;
-}
-
-/*!
- * Returns the view currently holding mouse focus in the input device.
- */
-QWaylandView *QWaylandTouch::mouseFocus() const
-{
- Q_D(const QWaylandTouch);
- return d->seat->mouseFocus();
-}
-
-/*!
- * \internal
- */
-void QWaylandTouch::focusDestroyed(void *data)
-{
- Q_UNUSED(data)
- Q_D(QWaylandTouch);
- d->resetFocusState();
-}
-
-/*!
- * \internal
- */
-void QWaylandTouch::mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus)
-{
- Q_UNUSED(newFocus);
- Q_UNUSED(oldFocus);
- Q_D(QWaylandTouch);
- d->resetFocusState();
-}
-
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandtouch.h b/src/compositor/compositor_api/qwaylandtouch.h
index b6c40ea96..05ee5ad40 100644
--- a/src/compositor/compositor_api/qwaylandtouch.h
+++ b/src/compositor/compositor_api/qwaylandtouch.h
@@ -48,34 +48,30 @@ QT_BEGIN_NAMESPACE
class QWaylandTouch;
class QWaylandTouchPrivate;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandView;
class QWaylandClient;
+class QWaylandSurface;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouch : public QWaylandObject
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandTouch)
public:
- QWaylandTouch(QWaylandInputDevice *inputDevice, QObject *parent = nullptr);
+ QWaylandTouch(QWaylandSeat *seat, QObject *parent = nullptr);
- QWaylandInputDevice *inputDevice() const;
+ QWaylandSeat *seat() const;
QWaylandCompositor *compositor() const;
- virtual void sendTouchPointEvent(int id, const QPointF &position, Qt::TouchPointState state);
- virtual void sendFrameEvent();
- virtual void sendCancelEvent();
-
- virtual void sendFullTouchEvent(QTouchEvent *event);
+ virtual uint sendTouchPointEvent(QWaylandSurface *surface, int id, const QPointF &position, Qt::TouchPointState state);
+ virtual void sendFrameEvent(QWaylandClient *client);
+ virtual void sendCancelEvent(QWaylandClient *client);
+ virtual void sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event);
virtual void addClient(QWaylandClient *client, uint32_t id, uint32_t version);
- wl_resource *focusResource() const;
-
- QWaylandView *mouseFocus() const;
private:
void focusDestroyed(void *data);
- void mouseFocusChanged(QWaylandView *newFocus, QWaylandView *oldFocus);
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandtouch_p.h b/src/compositor/compositor_api/qwaylandtouch_p.h
index ea334eea1..75529134b 100644
--- a/src/compositor/compositor_api/qwaylandtouch_p.h
+++ b/src/compositor/compositor_api/qwaylandtouch_p.h
@@ -52,7 +52,7 @@
#include <QtWaylandCompositor/qwaylandexport.h>
#include <QtWaylandCompositor/QWaylandDestroyListener>
#include <QtWaylandCompositor/QWaylandTouch>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include <QtWaylandCompositor/QWaylandView>
#include <QtWaylandCompositor/QWaylandCompositor>
@@ -67,35 +67,18 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandTouchPrivate : public QObjectPrivate,
{
Q_DECLARE_PUBLIC(QWaylandTouch)
public:
- explicit QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandInputDevice *seat);
+ explicit QWaylandTouchPrivate(QWaylandTouch *touch, QWaylandSeat *seat);
QWaylandCompositor *compositor() const { return seat->compositor(); }
- void sendDown(uint32_t time, int touch_id, const QPointF &position);
- void sendMotion(uint32_t time, int touch_id, const QPointF &position);
- void sendUp(uint32_t time, int touch_id);
+ uint sendDown(QWaylandSurface *surface, uint32_t time, int touch_id, const QPointF &position);
+ void sendMotion(QWaylandClient *client, uint32_t time, int touch_id, const QPointF &position);
+ uint sendUp(QWaylandClient *client, uint32_t time, int touch_id);
- void setFocusResource()
- {
- if (focusResource)
- return;
-
- QWaylandView *mouseFocus = seat->mouseFocus();
- if (!mouseFocus || !mouseFocus->surface())
- return;
-
- focusResource = resourceMap().value(mouseFocus->surface()->waylandClient());
- }
private:
- void resetFocusState();
- void touch_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
- void touch_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
void touch_release(Resource *resource) Q_DECL_OVERRIDE;
- QWaylandInputDevice *seat;
-
- Resource *focusResource;
- QWaylandDestroyListener focusDestroyListener;
+ QWaylandSeat *seat;
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp
index 12b67bf5d..2302fe604 100644
--- a/src/compositor/compositor_api/qwaylandview.cpp
+++ b/src/compositor/compositor_api/qwaylandview.cpp
@@ -37,7 +37,7 @@
#include "qwaylandview.h"
#include "qwaylandview_p.h"
#include "qwaylandsurface.h"
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/private/qwaylandsurface_p.h>
@@ -59,7 +59,7 @@ void QWaylandViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface)
/*!
* \qmltype WaylandView
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief Represents a view of a surface on an output.
*
* The WaylandView corresponds to the presentation of a surface on a specific
@@ -70,7 +70,7 @@ void QWaylandViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface)
/*!
* \class QWaylandView
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandView class represents a view of a surface on an output.
*
* The QWaylandView corresponds to the presentation of a surface on a specific
@@ -96,7 +96,7 @@ QWaylandView::~QWaylandView()
if (d->surface) {
if (d->output)
QWaylandOutputPrivate::get(d->output)->removeView(this, d->surface);
- QWaylandInputDevice *i = d->surface->compositor()->defaultInputDevice();
+ QWaylandSeat *i = d->surface->compositor()->defaultSeat();
if (i->mouseFocus() == this)
i->setMouseFocus(Q_NULLPTR);
@@ -145,12 +145,13 @@ void QWaylandView::setSurface(QWaylandSurface *newSurface)
d->surface = newSurface;
- if (!d->bufferLock) {
+ if (!d->bufferLocked) {
d->currentBuffer = QWaylandBufferRef();
d->currentDamage = QRegion();
}
d->nextBuffer = QWaylandBufferRef();
+ d->nextBufferCommitted = false;
d->nextDamage = QRegion();
if (d->surface) {
@@ -198,51 +199,49 @@ void QWaylandView::setOutput(QWaylandOutput *newOutput)
}
/*!
- * Attaches a new buffer \a ref and a \a damage region to this QWaylandView. These
- * will become current on a subsequent call to the advance() method.
+ * This function is called when a new \a buffer is committed to this view's surface.
+ * \a damage contains the region that is different from the current buffer, i.e. the
+ * region that needs to be updated.
+ * The new \a buffer will become current on the next call to advance().
+ *
+ * Subclasses that reimplement this function \e must call the base implementation.
*/
-void QWaylandView::attach(const QWaylandBufferRef &ref, const QRegion &damage)
+void QWaylandView::bufferCommitted(const QWaylandBufferRef &buffer, const QRegion &damage)
{
Q_D(QWaylandView);
QMutexLocker locker(&d->bufferMutex);
- d->nextBuffer = ref;
+ d->nextBuffer = buffer;
d->nextDamage = damage;
+ d->nextBufferCommitted = true;
}
/*!
- * Sets the next buffer and damage region to current and returns \c true. If the buffer
- * is locked or if no new buffer has been attached since the last call to
- * advance(), the function returns \c false and does nothing.
- *
- * If this view is set as the surface's throttling view, discardCurrentBuffer()
- * is called on all views of the same surface for which the
- * \l{QWaylandView::discardFrontBuffers}{discardFrontBuffers}
- * property is set to true and the current buffer is the same as the
- * throttling view's current buffer.
+ * Updates the current buffer and damage region to the latest version committed by the client.
+ * Returns true if new content was committed since the previous call to advance().
+ * Otherwise returns false.
*
- * To enable clients to reuse existing buffers, enable the primary view to ensure
- * that views running on a lower frequency will release their front buffer
- * references. This design approach should avoid the situation where the lower
- * frequency views throttle the frame rate of the client application.
+ * \sa currentBuffer(), currentDamage()
*/
bool QWaylandView::advance()
{
Q_D(QWaylandView);
- if (d->currentBuffer == d->nextBuffer && !d->forceAdvanceSucceed)
+
+ if (!d->nextBufferCommitted && !d->forceAdvanceSucceed)
return false;
- if (d->bufferLock)
+ if (d->bufferLocked)
return false;
- if (d->surface && d->surface->throttlingView() == this) {
+ if (d->surface && d->surface->primaryView() == this) {
Q_FOREACH (QWaylandView *view, d->surface->views()) {
- if (view != this && view->discardFrontBuffers() && view->d_func()->currentBuffer == d->currentBuffer)
+ if (view != this && view->allowDiscardFrontBuffer() && view->d_func()->currentBuffer == d->currentBuffer)
view->discardCurrentBuffer();
}
}
QMutexLocker locker(&d->bufferMutex);
d->forceAdvanceSucceed = false;
+ d->nextBufferCommitted = false;
d->currentBuffer = d->nextBuffer;
d->currentDamage = d->nextDamage;
return true;
@@ -280,7 +279,7 @@ QRegion QWaylandView::currentDamage()
}
/*!
- * \qmlproperty bool QtWaylandCompositor::WaylandView::bufferLock
+ * \qmlproperty bool QtWaylandCompositor::WaylandView::bufferLocked
*
* This property holds whether the view's buffer is currently locked. When
* the buffer is locked, advance() will not advance to the next buffer and
@@ -290,7 +289,7 @@ QRegion QWaylandView::currentDamage()
*/
/*!
- * \property QWaylandView::bufferLock
+ * \property QWaylandView::bufferLocked
*
* This property holds whether the view's buffer is currently locked. When
* the buffer is locked, advance() will not advance to the next buffer
@@ -301,42 +300,71 @@ QRegion QWaylandView::currentDamage()
bool QWaylandView::isBufferLocked() const
{
Q_D(const QWaylandView);
- return d->bufferLock;
+ return d->bufferLocked;
}
-void QWaylandView::setBufferLock(bool locked)
+void QWaylandView::setBufferLocked(bool locked)
{
Q_D(QWaylandView);
- if (d->bufferLock == locked)
+ if (d->bufferLocked == locked)
return;
- d->bufferLock = locked;
- emit bufferLockChanged();
+ d->bufferLocked = locked;
+ emit bufferLockedChanged();
}
/*!
- * \qmlproperty bool QtWaylandCompositor::WaylandView::discardFrontBuffers
+ * \qmlproperty bool QtWaylandCompositor::WaylandView::allowDiscardFrontBuffer
*
* By default, the view locks the current buffer until advance() is called. Set this property
- * to true to allow Qt to release the buffer when the throttling view is no longer using it.
+ * to true to allow Qt to release the buffer when the primary view is no longer using it.
+ *
+ * This can be used to avoid the situation where a secondary view that updates on a lower
+ * frequency will throttle the frame rate of the client application.
*/
+
/*!
- * \property QWaylandView::discardFrontBuffers
+ * \property QWaylandView::allowDiscardFrontBuffer
*
* By default, the view locks the current buffer until advance() is called. Set this property
- * to \c true to allow Qt to release the buffer when the throttling view is no longer using it.
+ * to \c true to allow Qt to release the buffer when the primary view is no longer using it.
+ *
+ * This can be used to avoid the situation where a secondary view that updates on a lower
+ * frequency will throttle the frame rate of the client application.
*/
-bool QWaylandView::discardFrontBuffers() const
+bool QWaylandView::allowDiscardFrontBuffer() const
{
Q_D(const QWaylandView);
- return d->discardFrontBuffers;
+ return d->allowDiscardFrontBuffer;
}
-void QWaylandView::setDiscardFrontBuffers(bool discard)
+void QWaylandView::setAllowDiscardFrontBuffer(bool discard)
{
Q_D(QWaylandView);
- if (d->discardFrontBuffers == discard)
+ if (d->allowDiscardFrontBuffer == discard)
return;
- d->discardFrontBuffers = discard;
- emit discardFrontBuffersChanged();
+ d->allowDiscardFrontBuffer = discard;
+ emit allowDiscardFrontBufferChanged();
+}
+
+/*!
+ * Makes this QWaylandView the primary view for the surface.
+ *
+ * \sa QWaylandSurface::primaryView
+ */
+void QWaylandView::setPrimary()
+{
+ Q_D(QWaylandView);
+ d->surface->setPrimaryView(this);
+}
+
+/*!
+ * Returns true if this QWaylandView is the primary view for the QWaylandSurface
+ *
+ * \sa QWaylandSurface::primaryView
+ */
+bool QWaylandView::isPrimary() const
+{
+ Q_D(const QWaylandView);
+ return d->surface->primaryView() == this;
}
/*!
diff --git a/src/compositor/compositor_api/qwaylandview.h b/src/compositor/compositor_api/qwaylandview.h
index f89d8ca78..987340034 100644
--- a/src/compositor/compositor_api/qwaylandview.h
+++ b/src/compositor/compositor_api/qwaylandview.h
@@ -56,8 +56,8 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandView : public QObject
Q_PROPERTY(QObject *renderObject READ renderObject CONSTANT)
Q_PROPERTY(QWaylandSurface *surface READ surface WRITE setSurface NOTIFY surfaceChanged)
Q_PROPERTY(QWaylandOutput *output READ output WRITE setOutput NOTIFY outputChanged)
- Q_PROPERTY(bool bufferLock READ isBufferLocked WRITE setBufferLock NOTIFY bufferLockChanged)
- Q_PROPERTY(bool discardFrontBuffers READ discardFrontBuffers WRITE setDiscardFrontBuffers NOTIFY discardFrontBuffersChanged)
+ Q_PROPERTY(bool bufferLocked READ isBufferLocked WRITE setBufferLocked NOTIFY bufferLockedChanged)
+ Q_PROPERTY(bool allowDiscardFrontBuffer READ allowDiscardFrontBuffer WRITE setAllowDiscardFrontBuffer NOTIFY allowDiscardFrontBufferChanged)
public:
QWaylandView(QObject *renderObject = nullptr, QObject *parent = nullptr);
virtual ~QWaylandView();
@@ -70,17 +70,20 @@ public:
QWaylandOutput *output() const;
void setOutput(QWaylandOutput *output);
- virtual void attach(const QWaylandBufferRef &ref, const QRegion &damage);
+ virtual void bufferCommitted(const QWaylandBufferRef &buffer, const QRegion &damage);
virtual bool advance();
virtual void discardCurrentBuffer();
virtual QWaylandBufferRef currentBuffer();
virtual QRegion currentDamage();
bool isBufferLocked() const;
- void setBufferLock(bool locked);
+ void setBufferLocked(bool locked);
- bool discardFrontBuffers() const;
- void setDiscardFrontBuffers(bool discard);
+ bool allowDiscardFrontBuffer() const;
+ void setAllowDiscardFrontBuffer(bool discard);
+
+ void setPrimary();
+ bool isPrimary() const;
struct wl_resource *surfaceResource() const;
@@ -88,8 +91,8 @@ Q_SIGNALS:
void surfaceChanged();
void surfaceDestroyed();
void outputChanged();
- void bufferLockChanged();
- void discardFrontBuffersChanged();
+ void bufferLockedChanged();
+ void allowDiscardFrontBufferChanged();
};
QT_END_NAMESPACE
diff --git a/src/compositor/compositor_api/qwaylandview_p.h b/src/compositor/compositor_api/qwaylandview_p.h
index 8c4cea085..8c55eca36 100644
--- a/src/compositor/compositor_api/qwaylandview_p.h
+++ b/src/compositor/compositor_api/qwaylandview_p.h
@@ -69,10 +69,11 @@ public:
: renderObject(Q_NULLPTR)
, surface(Q_NULLPTR)
, output(Q_NULLPTR)
- , bufferLock(false)
+ , nextBufferCommitted(false)
+ , bufferLocked(false)
, broadcastRequestedPositionChanged(false)
, forceAdvanceSucceed(false)
- , discardFrontBuffers(false)
+ , allowDiscardFrontBuffer(false)
{ }
void markSurfaceAsDestroyed(QWaylandSurface *surface);
@@ -86,10 +87,11 @@ public:
QRegion currentDamage;
QWaylandBufferRef nextBuffer;
QRegion nextDamage;
- bool bufferLock;
+ bool nextBufferCommitted;
+ bool bufferLocked;
bool broadcastRequestedPositionChanged;
bool forceAdvanceSucceed;
- bool discardFrontBuffers;
+ bool allowDiscardFrontBuffer;
};
QT_END_NAMESPACE
diff --git a/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc b/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc
index d2f0f6f40..05ab4fb03 100644
--- a/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc
+++ b/src/compositor/doc/src/qtwaylandcompositor-overview.qdoc
@@ -62,6 +62,20 @@
Take a look at the \l{Qt Wayland Compositor Examples} for a demonstration on
how the APIs can be used to write custom display servers.
+ \section1 Licenses and Attributions
+
+ Qt Wayland Compositor and the Qt Wayland integration plugin
+ are available under commercial licenses from \l{The Qt Company}.
+ In addition, they are available under the
+ \l{GNU Lesser General Public License, version 3}, or
+ the \l{GNU General Public License, version 2}.
+ See \l{Qt Licensing} for further details.
+
+ Qt Wayland Compositor and the Qt Wayland integration plugin
+ use protocol definitions under following permissive licenses:
+
+ \generatelist{groupsbymodule attributions-qtwaylandcompositor}
+
\section1 API Reference
The Qt Wayland Compositor API can be used from C++ or QML.
diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri
index 4894eb3c4..9c5b37eac 100644
--- a/src/compositor/extensions/extensions.pri
+++ b/src/compositor/extensions/extensions.pri
@@ -5,47 +5,59 @@ WAYLANDSERVERSOURCES += \
../extensions/surface-extension.xml \
../extensions/touch-extension.xml \
../extensions/qtkey-extension.xml \
- ../extensions/windowmanager.xml \
+ ../extensions/qt-windowmanager.xml \
../3rdparty/protocol/text-input-unstable-v2.xml \
../3rdparty/protocol/xdg-shell.xml \
+ ../3rdparty/protocol/ivi-application.xml \
HEADERS += \
extensions/qwlextendedsurface_p.h \
extensions/qwlqttouch_p.h \
extensions/qwlqtkey_p.h \
+ extensions/qwaylandshell.h \
+ extensions/qwaylandshell_p.h \
extensions/qwaylandwlshell.h \
extensions/qwaylandwlshell_p.h \
extensions/qwaylandtextinput.h \
extensions/qwaylandtextinput_p.h \
extensions/qwaylandtextinputmanager.h \
extensions/qwaylandtextinputmanager_p.h \
- extensions/qwaylandwindowmanagerextension.h \
- extensions/qwaylandwindowmanagerextension_p.h \
- extensions/qwaylandxdgshell.h \
- extensions/qwaylandxdgshell_p.h \
+ extensions/qwaylandqtwindowmanager.h \
+ extensions/qwaylandqtwindowmanager_p.h \
+ extensions/qwaylandxdgshellv5.h \
+ extensions/qwaylandxdgshellv5_p.h \
extensions/qwaylandshellsurface.h \
+ extensions/qwaylandiviapplication.h \
+ extensions/qwaylandiviapplication_p.h \
+ extensions/qwaylandivisurface.h \
+ extensions/qwaylandivisurface_p.h \
SOURCES += \
extensions/qwlextendedsurface.cpp \
extensions/qwlqttouch.cpp \
extensions/qwlqtkey.cpp \
+ extensions/qwaylandshell.cpp \
extensions/qwaylandwlshell.cpp \
extensions/qwaylandtextinput.cpp \
extensions/qwaylandtextinputmanager.cpp \
- extensions/qwaylandwindowmanagerextension.cpp \
- extensions/qwaylandxdgshell.cpp \
+ extensions/qwaylandqtwindowmanager.cpp \
+ extensions/qwaylandxdgshellv5.cpp \
+ extensions/qwaylandiviapplication.cpp \
+ extensions/qwaylandivisurface.cpp \
-qtHaveModule(quick) {
+qtHaveModule(quick):contains(QT_CONFIG, opengl) {
HEADERS += \
extensions/qwaylandquickshellsurfaceitem.h \
extensions/qwaylandquickshellsurfaceitem_p.h \
+ extensions/qwaylandivisurfaceintegration_p.h \
extensions/qwaylandwlshellintegration_p.h \
- extensions/qwaylandxdgshellintegration_p.h \
+ extensions/qwaylandxdgshellv5integration_p.h \
SOURCES += \
extensions/qwaylandquickshellsurfaceitem.cpp \
+ extensions/qwaylandivisurfaceintegration.cpp \
extensions/qwaylandwlshellintegration.cpp \
- extensions/qwaylandxdgshellintegration.cpp \
+ extensions/qwaylandxdgshellv5integration.cpp \
}
diff --git a/src/compositor/extensions/qwaylandiviapplication.cpp b/src/compositor/extensions/qwaylandiviapplication.cpp
new file mode 100644
index 000000000..30784e4ec
--- /dev/null
+++ b/src/compositor/extensions/qwaylandiviapplication.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandiviapplication.h"
+#include "qwaylandiviapplication_p.h"
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandIviSurface>
+#include <QtWaylandCompositor/QWaylandResource>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ * Constructs a QWaylandIviApplication object.
+ */
+QWaylandIviApplication::QWaylandIviApplication()
+ : QWaylandCompositorExtensionTemplate<QWaylandIviApplication>(*new QWaylandIviApplicationPrivate())
+{
+}
+
+/*!
+ * Constructs a QWaylandIviApplication object for the provided \a compositor.
+ */
+QWaylandIviApplication::QWaylandIviApplication(QWaylandCompositor *compositor)
+ : QWaylandCompositorExtensionTemplate<QWaylandIviApplication>(compositor, *new QWaylandIviApplicationPrivate())
+{
+}
+
+/*!
+ * Initializes the shell extension.
+ */
+void QWaylandIviApplication::initialize()
+{
+ Q_D(QWaylandIviApplication);
+ QWaylandCompositorExtensionTemplate::initialize();
+
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ if (!compositor) {
+ qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandIviApplication";
+ return;
+ }
+
+ d->init(compositor->display(), 1);
+}
+
+/*!
+ * Returns the Wayland interface for the QWaylandIviApplication.
+ */
+const struct wl_interface *QWaylandIviApplication::interface()
+{
+ return QWaylandIviApplicationPrivate::interface();
+}
+
+QByteArray QWaylandIviApplication::interfaceName()
+{
+ return QWaylandIviApplicationPrivate::interfaceName();
+}
+
+/*!
+ * \qmlsignal void QtWaylandCompositor::IviApplication::iviSurfaceRequested(object surface, int iviId, object resource)
+ *
+ * This signal is emitted when the client has requested an \c ivi_surface to be associated
+ * with \a surface, which is identified by \a id. The handler for this signal is
+ * expected to create the ivi surface and initialize it within the scope of the
+ * signal emission. If no ivi surface is created, a default one will be created instead.
+ */
+
+/*!
+ * \fn void QWaylandWlShell::iviSurfaceRequested(QWaylandSurface *surface, uint iviId, const QWaylandResource &resource)
+ *
+ * This signal is emitted when the client has requested an \c ivi_surface to be associated
+ * with \a surface, which is identified by \a id. The handler for this signal is
+ * expected to create the ivi surface and initialize it within the scope of the
+ * signal emission. If no ivi surface is created, a default one will be created instead.
+ */
+
+/*!
+ * \qmlsignal void QtWaylandCompositor::IviApplication::iviSurfaceCreated(object *iviSurface)
+ *
+ * This signal is emitted when an IviSurface has been created. The supplied \a iviSurface is
+ * most commonly used to instantiate a ShellSurfaceItem.
+ */
+
+/*!
+ * \fn void QtWaylandCompositor::IviApplication::iviSurfaceCreated(QWaylandIviSurface *iviSurface)
+ *
+ * This signal is emitted when an IviSurface has been created.
+ */
+
+QWaylandIviApplicationPrivate::QWaylandIviApplicationPrivate()
+ : QWaylandCompositorExtensionPrivate()
+ , ivi_application()
+{
+}
+
+void QWaylandIviApplicationPrivate::unregisterIviSurface(QWaylandIviSurface *iviSurface)
+{
+ m_iviSurfaces.remove(iviSurface->iviId());
+}
+
+void QWaylandIviApplicationPrivate::ivi_application_surface_create(QtWaylandServer::ivi_application::Resource *resource,
+ uint32_t ivi_id, wl_resource *surfaceResource, uint32_t id)
+{
+ Q_Q(QWaylandIviApplication);
+ QWaylandSurface *surface = QWaylandSurface::fromResource(surfaceResource);
+
+ if (m_iviSurfaces.contains(ivi_id)) {
+ wl_resource_post_error(resource->handle, IVI_APPLICATION_ERROR_IVI_ID,
+ "Given ivi_id, %d, is already assigned to wl_surface@%d", ivi_id,
+ wl_resource_get_id(m_iviSurfaces[ivi_id]->surface()->resource()));
+ return;
+ }
+
+ if (!surface->setRole(QWaylandIviSurface::role(), resource->handle, IVI_APPLICATION_ERROR_ROLE))
+ return;
+
+ QWaylandResource iviSurfaceResource(wl_resource_create(resource->client(), &ivi_surface_interface,
+ wl_resource_get_version(resource->handle), id));
+
+ emit q->iviSurfaceRequested(surface, ivi_id, iviSurfaceResource);
+
+ QWaylandIviSurface *iviSurface = QWaylandIviSurface::fromResource(iviSurfaceResource.resource());
+
+ if (!iviSurface)
+ iviSurface = new QWaylandIviSurface(q, surface, ivi_id, iviSurfaceResource);
+
+ m_iviSurfaces.insert(ivi_id, iviSurface);
+
+ emit q->iviSurfaceCreated(iviSurface);
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandiviapplication.h b/src/compositor/extensions/qwaylandiviapplication.h
new file mode 100644
index 000000000..a3e057a86
--- /dev/null
+++ b/src/compositor/extensions/qwaylandiviapplication.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIVIAPPLICATION_H
+#define QWAYLANDIVIAPPLICATION_H
+
+#include <QtWaylandCompositor/QWaylandCompositorExtension>
+#include <QtCore/QSize>
+
+class QWaylandIviSurface;
+class QWaylandSurface;
+class QWaylandResource;
+class QWaylandIviApplicationPrivate;
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandIviApplication : public QWaylandCompositorExtensionTemplate<QWaylandIviApplication>
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandIviApplication)
+
+public:
+ QWaylandIviApplication();
+ QWaylandIviApplication(QWaylandCompositor *compositor);
+
+ void initialize() Q_DECL_OVERRIDE;
+
+ static const struct wl_interface *interface();
+ static QByteArray interfaceName();
+
+Q_SIGNALS:
+ void iviSurfaceRequested(QWaylandSurface *surface, uint iviId, const QWaylandResource &resource);
+ void iviSurfaceCreated(QWaylandIviSurface *iviSurface);
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIVIAPPLICATION_H
diff --git a/src/compositor/extensions/qwaylandiviapplication_p.h b/src/compositor/extensions/qwaylandiviapplication_p.h
new file mode 100644
index 000000000..ea211a84a
--- /dev/null
+++ b/src/compositor/extensions/qwaylandiviapplication_p.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIVIAPPLICATION_P_H
+#define QWAYLANDIVIAPPLICATION_P_H
+
+#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
+#include <QtWaylandCompositor/private/qwayland-server-ivi-application.h>
+
+#include <QtWaylandCompositor/QWaylandIviApplication>
+
+#include <QHash>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandIviApplicationPrivate
+ : public QWaylandCompositorExtensionPrivate
+ , public QtWaylandServer::ivi_application
+{
+ Q_DECLARE_PUBLIC(QWaylandIviApplication)
+
+public:
+ QWaylandIviApplicationPrivate();
+ static QWaylandIviApplicationPrivate *get(QWaylandIviApplication *iviApplication) { return iviApplication->d_func(); }
+ void unregisterIviSurface(QWaylandIviSurface *iviSurface);
+
+ QHash<uint, QWaylandIviSurface*> m_iviSurfaces;
+
+protected:
+ void ivi_application_surface_create(Resource *resource, uint32_t ivi_id, wl_resource *surface, uint32_t id) Q_DECL_OVERRIDE;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIVIAPPLICATION_P_H
diff --git a/src/compositor/extensions/qwaylandivisurface.cpp b/src/compositor/extensions/qwaylandivisurface.cpp
new file mode 100644
index 000000000..06e12a5ab
--- /dev/null
+++ b/src/compositor/extensions/qwaylandivisurface.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandivisurface.h"
+#include "qwaylandivisurface_p.h"
+#include "qwaylandiviapplication_p.h"
+#include "qwaylandivisurfaceintegration_p.h"
+
+#include <QtWaylandCompositor/QWaylandResource>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandSurfaceRole QWaylandIviSurfacePrivate::s_role("ivi_surface");
+
+/*!
+ * \class QWaylandIviSurface
+ * \inmodule QtWaylandCompositor
+ * \since 5.8
+ * \brief The QWaylandIviSurface class provides a simple way to identify and resize a surface.
+ *
+ * This class is part of the QWaylandIviApplication extension and provides a way to
+ * extend the functionality of an existing QWaylandSurface with features a way to
+ * resize and identify it.
+ *
+ * It corresponds to the Wayland interface ivi_surface.
+ */
+
+/*!
+ * Constructs a QWaylandIviSurface.
+ */
+QWaylandIviSurface::QWaylandIviSurface()
+ : QWaylandShellSurfaceTemplate<QWaylandIviSurface>(*new QWaylandIviSurfacePrivate())
+{
+}
+
+/*!
+ * Constructs a QWaylandIviSurface for \a surface and initializes it with the
+ * given \a application, \a surface, \a iviId, and \a resource.
+ */
+QWaylandIviSurface::QWaylandIviSurface(QWaylandIviApplication *application, QWaylandSurface *surface, uint iviId, const QWaylandResource &resource)
+ : QWaylandShellSurfaceTemplate<QWaylandIviSurface>(*new QWaylandIviSurfacePrivate())
+{
+ initialize(application, surface, iviId, resource);
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::IviSurface::initialize(object iviApplication, object surface, int iviId, object resource)
+ *
+ * Initializes the IviSurface, associating it with the given \a iviApplication, \a surface,
+ * \a client, \a iviId, and \a resource.
+ */
+
+/*!
+ * Initializes the QWaylandIviSurface, associating it with the given \a iviApplication, \a surface,
+ * \a iviId, and \a resource.
+ */
+void QWaylandIviSurface::initialize(QWaylandIviApplication *iviApplication, QWaylandSurface *surface, uint iviId, const QWaylandResource &resource)
+{
+ Q_D(QWaylandIviSurface);
+
+ d->m_iviApplication = iviApplication;
+ d->m_surface = surface;
+ d->m_iviId = iviId;
+
+ d->init(resource.resource());
+ setExtensionContainer(surface);
+
+ emit surfaceChanged();
+ emit iviIdChanged();
+
+ QWaylandCompositorExtension::initialize();
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::IviSurface::surface
+ *
+ * This property holds the surface associated with this IviSurface.
+ */
+
+/*!
+ * \property QWaylandIviSurface::surface
+ *
+ * This property holds the surface associated with this QWaylandIviSurface.
+ */
+QWaylandSurface *QWaylandIviSurface::surface() const
+{
+ Q_D(const QWaylandIviSurface);
+ return d->m_surface;
+}
+
+/*!
+ * \qmlproperty int QtWaylandCompositor::IviSurface::iviId
+ * \readonly
+ *
+ * This property holds the ivi id id of this IviSurface.
+ */
+
+/*!
+ * \property QWaylandIviSurface::iviId
+ *
+ * This property holds the ivi id of this QWaylandIviSurface.
+ */
+uint QWaylandIviSurface::iviId() const
+{
+ Q_D(const QWaylandIviSurface);
+ return d->m_iviId;
+}
+
+/*!
+ * Returns the Wayland interface for the QWaylandIviSurface.
+ */
+const struct wl_interface *QWaylandIviSurface::interface()
+{
+ return QWaylandIviSurfacePrivate::interface();
+}
+
+QByteArray QWaylandIviSurface::interfaceName()
+{
+ return QWaylandIviSurfacePrivate::interfaceName();
+}
+
+/*!
+ * Returns the surface role for the QWaylandIviSurface.
+ */
+QWaylandSurfaceRole *QWaylandIviSurface::role()
+{
+ return &QWaylandIviSurfacePrivate::s_role;
+}
+
+/*!
+ * Returns the QWaylandIviSurface corresponding to the \a resource.
+ */
+QWaylandIviSurface *QWaylandIviSurface::fromResource(wl_resource *resource)
+{
+ auto iviSurfaceResource = QWaylandIviSurfacePrivate::Resource::fromResource(resource);
+ if (!iviSurfaceResource)
+ return nullptr;
+ return static_cast<QWaylandIviSurfacePrivate *>(iviSurfaceResource->ivi_surface_object)->q_func();
+}
+
+/*!
+ * \qmlmethod int QtWaylandCompositor::IviSurface::sendConfigure(size size)
+ *
+ * Sends a configure event to the client, telling it to resize the surface to the given \a size.
+ */
+
+/*!
+ * Sends a configure event to the client, telling it to resize the surface to the given \a size.
+ */
+void QWaylandIviSurface::sendConfigure(const QSize &size)
+{
+ Q_D(QWaylandIviSurface);
+ d->send_configure(size.width(), size.height());
+}
+
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
+QWaylandQuickShellIntegration *QWaylandIviSurface::createIntegration(QWaylandQuickShellSurfaceItem *item)
+{
+ return new QtWayland::IviSurfaceIntegration(item);
+}
+#endif
+
+/*!
+ * \internal
+ */
+void QWaylandIviSurface::initialize()
+{
+ QWaylandShellSurfaceTemplate::initialize();
+}
+
+QWaylandIviSurfacePrivate::QWaylandIviSurfacePrivate()
+ : QWaylandCompositorExtensionPrivate()
+ , ivi_surface()
+ , m_iviApplication(nullptr)
+ , m_surface(nullptr)
+ , m_iviId(UINT_MAX)
+{
+}
+
+void QWaylandIviSurfacePrivate::ivi_surface_destroy_resource(QtWaylandServer::ivi_surface::Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandIviSurface);
+ QWaylandIviApplicationPrivate::get(m_iviApplication)->unregisterIviSurface(q);
+ delete q;
+}
+
+void QWaylandIviSurfacePrivate::ivi_surface_destroy(QtWaylandServer::ivi_surface::Resource *resource)
+{
+ wl_resource_destroy(resource->handle);
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandivisurface.h b/src/compositor/extensions/qwaylandivisurface.h
new file mode 100644
index 000000000..37c37c0f3
--- /dev/null
+++ b/src/compositor/extensions/qwaylandivisurface.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIVISURFACE_H
+#define QWAYLANDIVISURFACE_H
+
+#include <QtWaylandCompositor/QWaylandShellSurface>
+
+class QWaylandIviSurfacePrivate;
+class QWaylandSurface;
+class QWaylandIviApplication;
+class QWaylandSurfaceRole;
+class QWaylandResource;
+class wl_resource;
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandIviSurface : public QWaylandShellSurfaceTemplate<QWaylandIviSurface>
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandIviSurface)
+ Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged)
+ Q_PROPERTY(uint iviId READ iviId NOTIFY iviIdChanged)
+
+public:
+ QWaylandIviSurface();
+ QWaylandIviSurface(QWaylandIviApplication *application, QWaylandSurface *surface, uint iviId, const QWaylandResource &resource);
+
+ Q_INVOKABLE void initialize(QWaylandIviApplication *iviApplication, QWaylandSurface *surface,
+ uint iviId, const QWaylandResource &resource);
+
+ QWaylandSurface *surface() const;
+ uint iviId() const;
+
+ static const struct wl_interface *interface();
+ static QByteArray interfaceName();
+ static QWaylandSurfaceRole *role();
+ static QWaylandIviSurface *fromResource(::wl_resource *resource);
+
+ Q_INVOKABLE void sendConfigure(const QSize &size);
+
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
+ QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE;
+#endif
+
+Q_SIGNALS:
+ void surfaceChanged();
+ void iviIdChanged();
+
+private:
+ void initialize();
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIVISURFACE_H
diff --git a/src/compositor/extensions/qwaylandivisurface_p.h b/src/compositor/extensions/qwaylandivisurface_p.h
new file mode 100644
index 000000000..db237721d
--- /dev/null
+++ b/src/compositor/extensions/qwaylandivisurface_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIVISURFACE_P_H
+#define QWAYLANDIVISURFACE_P_H
+
+#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
+#include <QtWaylandCompositor/private/qwayland-server-ivi-application.h>
+
+#include <QtWaylandCompositor/QWaylandIviSurface>
+
+#include <QtWaylandCompositor/QWaylandSurfaceRole>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandIviSurfacePrivate
+ : public QWaylandCompositorExtensionPrivate
+ , public QtWaylandServer::ivi_surface
+{
+ Q_DECLARE_PUBLIC(QWaylandIviSurface)
+
+public:
+ QWaylandIviSurfacePrivate();
+ static QWaylandIviSurfacePrivate *get(QWaylandIviSurface *iviSurface) { return iviSurface->d_func(); }
+
+protected:
+ void ivi_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
+ void ivi_surface_destroy(Resource *resource) Q_DECL_OVERRIDE;
+
+private:
+ QWaylandIviApplication *m_iviApplication;
+ QWaylandSurface *m_surface;
+ uint m_iviId;
+
+ static QWaylandSurfaceRole s_role;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIVISURFACE_P_H
diff --git a/src/compositor/extensions/qwaylandivisurfaceintegration.cpp b/src/compositor/extensions/qwaylandivisurfaceintegration.cpp
new file mode 100644
index 000000000..3a3d9c1c9
--- /dev/null
+++ b/src/compositor/extensions/qwaylandivisurfaceintegration.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandivisurfaceintegration_p.h"
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandIviSurface>
+#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
+#include <QtWaylandCompositor/QWaylandSeat>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+IviSurfaceIntegration::IviSurfaceIntegration(QWaylandQuickShellSurfaceItem *item)
+ : QWaylandQuickShellIntegration(item)
+ , m_item(item)
+ , m_shellSurface(qobject_cast<QWaylandIviSurface *>(item->shellSurface()))
+{
+ m_item->setSurface(m_shellSurface->surface());
+ connect(m_shellSurface, &QWaylandIviSurface::destroyed, this, &IviSurfaceIntegration::handleIviSurfaceDestroyed);
+}
+
+void IviSurfaceIntegration::handleIviSurfaceDestroyed()
+{
+ m_shellSurface = nullptr;
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandivisurfaceintegration_p.h b/src/compositor/extensions/qwaylandivisurfaceintegration_p.h
new file mode 100644
index 000000000..534caf642
--- /dev/null
+++ b/src/compositor/extensions/qwaylandivisurfaceintegration_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDIVISURFACEINTEGRATION_H
+#define QWAYLANDIVISURFACEINTEGRATION_H
+
+#include <QtWaylandCompositor/private/qwaylandquickshellsurfaceitem_p.h>
+
+#include <QtWaylandCompositor/QWaylandIviSurface>
+
+QT_BEGIN_NAMESPACE
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+namespace QtWayland {
+
+class IviSurfaceIntegration : public QWaylandQuickShellIntegration
+{
+ Q_OBJECT
+public:
+ IviSurfaceIntegration(QWaylandQuickShellSurfaceItem *item);
+
+private Q_SLOTS:
+ void handleIviSurfaceDestroyed();
+
+private:
+ QWaylandQuickShellSurfaceItem *m_item;
+ QWaylandIviSurface *m_shellSurface;
+};
+
+}
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDIVISURFACEINTEGRATION_H
diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp b/src/compositor/extensions/qwaylandqtwindowmanager.cpp
index 1e7ed2892..f82a8e46f 100644
--- a/src/compositor/extensions/qwaylandwindowmanagerextension.cpp
+++ b/src/compositor/extensions/qwaylandqtwindowmanager.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
@@ -34,115 +35,116 @@
**
****************************************************************************/
-#include "qwaylandwindowmanagerextension.h"
-#include "qwaylandwindowmanagerextension_p.h"
+#include <QtCore/QObject>
+#include <QtCore/QUrl>
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandClient>
-#include <QtCore/QUrl>
+#include "qwaylandqtwindowmanager.h"
+#include "qwaylandqtwindowmanager_p.h"
QT_BEGIN_NAMESPACE
-QWaylandWindowManagerExtension::QWaylandWindowManagerExtension()
- : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(*new QWaylandWindowManagerExtensionPrivate)
+QWaylandQtWindowManagerPrivate::QWaylandQtWindowManagerPrivate()
+ : QWaylandCompositorExtensionPrivate()
+ , qt_windowmanager()
+ , showIsFullScreen(false)
{
}
-QWaylandWindowManagerExtension::QWaylandWindowManagerExtension(QWaylandCompositor *compositor)
- : QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>(compositor, *new QWaylandWindowManagerExtensionPrivate)
+void QWaylandQtWindowManagerPrivate::windowmanager_bind_resource(Resource *resource)
{
+ send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen));
}
-QWaylandWindowManagerExtensionPrivate::QWaylandWindowManagerExtensionPrivate()
- : QWaylandCompositorExtensionPrivate()
- , QtWaylandServer::qt_windowmanager()
- , showIsFullScreen(false)
+void QWaylandQtWindowManagerPrivate::windowmanager_destroy_resource(Resource *resource)
+{
+ urls.remove(resource);
+}
+
+void QWaylandQtWindowManagerPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl)
+{
+ Q_Q(QWaylandQtWindowManager);
+
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer());
+ if (!compositor) {
+ qWarning() << "Failed to find QWaylandCompositor from QWaylandQtWindowManager::windowmanager_open_url()";
+ return;
+ }
+
+ QString url = urls.value(resource, QString());
+
+ url.append(newUrl);
+
+ if (remaining)
+ urls.insert(resource, url);
+ else {
+ urls.remove(resource);
+ q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url));
+ }
+}
+
+QWaylandQtWindowManager::QWaylandQtWindowManager()
+ : QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>(*new QWaylandQtWindowManagerPrivate())
{
}
-bool QWaylandWindowManagerExtension::showIsFullScreen() const
+QWaylandQtWindowManager::QWaylandQtWindowManager(QWaylandCompositor *compositor)
+ : QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>(compositor, *new QWaylandQtWindowManagerPrivate())
{
- Q_D(const QWaylandWindowManagerExtension);
+}
+
+bool QWaylandQtWindowManager::showIsFullScreen() const
+{
+ Q_D(const QWaylandQtWindowManager);
return d->showIsFullScreen;
}
-void QWaylandWindowManagerExtension::setShowIsFullScreen(bool value)
+void QWaylandQtWindowManager::setShowIsFullScreen(bool value)
{
- Q_D(QWaylandWindowManagerExtension);
+ Q_D(QWaylandQtWindowManager);
if (d->showIsFullScreen == value)
return;
d->showIsFullScreen = value;
- Q_FOREACH (QWaylandWindowManagerExtensionPrivate::Resource *resource, d->resourceMap().values()) {
+ Q_FOREACH (QWaylandQtWindowManagerPrivate::Resource *resource, d->resourceMap().values()) {
d->send_hints(resource->handle, static_cast<int32_t>(d->showIsFullScreen));
}
Q_EMIT showIsFullScreenChanged();
}
-void QWaylandWindowManagerExtension::sendQuitMessage(wl_client *client)
+void QWaylandQtWindowManager::sendQuitMessage(QWaylandClient *client)
{
- Q_D(QWaylandWindowManagerExtension);
- QWaylandWindowManagerExtensionPrivate::Resource *resource = d->resourceMap().value(client);
+ Q_D(QWaylandQtWindowManager);
+ QWaylandQtWindowManagerPrivate::Resource *resource = d->resourceMap().value(client->client());
if (resource)
d->send_quit(resource->handle);
}
-void QWaylandWindowManagerExtension::initialize()
+void QWaylandQtWindowManager::initialize()
{
- Q_D(QWaylandWindowManagerExtension);
+ Q_D(QWaylandQtWindowManager);
QWaylandCompositorExtensionTemplate::initialize();
QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
if (!compositor) {
- qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWindowManagerExtension";
+ qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandQtWindowManager";
return;
}
d->init(compositor->display(), 1);
}
-void QWaylandWindowManagerExtensionPrivate::windowmanager_bind_resource(Resource *resource)
-{
- send_hints(resource->handle, static_cast<int32_t>(showIsFullScreen));
-}
-
-void QWaylandWindowManagerExtensionPrivate::windowmanager_destroy_resource(Resource *resource)
-{
- urls.remove(resource);
-}
-
-void QWaylandWindowManagerExtensionPrivate::windowmanager_open_url(Resource *resource, uint32_t remaining, const QString &newUrl)
-{
- Q_Q(QWaylandWindowManagerExtension);
-
- QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer());
- if (!compositor) {
- qWarning() << "Failed to find QWaylandCompositor from QWaylandWindowManagerExtension::windowmanager_open_url()";
- return;
- }
-
- QString url = urls.value(resource, QString());
-
- url.append(newUrl);
-
- if (remaining)
- urls.insert(resource, url);
- else {
- urls.remove(resource);
- q->openUrl(QWaylandClient::fromWlClient(compositor, resource->client()), QUrl(url));
- }
-}
-
-const struct wl_interface *QWaylandWindowManagerExtension::interface()
+const struct wl_interface *QWaylandQtWindowManager::interface()
{
- return QWaylandWindowManagerExtensionPrivate::interface();
+ return QWaylandQtWindowManagerPrivate::interface();
}
-QByteArray QWaylandWindowManagerExtension::interfaceName()
+QByteArray QWaylandQtWindowManager::interfaceName()
{
- return QWaylandWindowManagerExtensionPrivate::interfaceName();
+ return QWaylandQtWindowManagerPrivate::interfaceName();
}
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension.h b/src/compositor/extensions/qwaylandqtwindowmanager.h
index 184bcc3c5..4d3951025 100644
--- a/src/compositor/extensions/qwaylandwindowmanagerextension.h
+++ b/src/compositor/extensions/qwaylandqtwindowmanager.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
@@ -34,8 +35,8 @@
**
****************************************************************************/
-#ifndef WAYLANDWINDOWMANAGERINTEGRATION_H
-#define WAYLANDWINDOWMANAGERINTEGRATION_H
+#ifndef QWAYLANDQTWINDOWMANAGER_H
+#define QWAYLANDQTWINDOWMANAGER_H
#include <QtWaylandCompositor/QWaylandCompositorExtension>
#include <QtWaylandCompositor/QWaylandClient>
@@ -44,23 +45,21 @@
QT_BEGIN_NAMESPACE
-class QWaylandCompositor;
+class QWaylandQtWindowManagerPrivate;
-class QWaylandWindowManagerExtensionPrivate;
-
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtension : public QWaylandCompositorExtensionTemplate<QWaylandWindowManagerExtension>
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQtWindowManager : public QWaylandCompositorExtensionTemplate<QWaylandQtWindowManager>
{
Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandQtWindowManager)
Q_PROPERTY(bool showIsFullScreen READ showIsFullScreen WRITE setShowIsFullScreen NOTIFY showIsFullScreenChanged)
- Q_DECLARE_PRIVATE(QWaylandWindowManagerExtension)
public:
- QWaylandWindowManagerExtension();
- explicit QWaylandWindowManagerExtension(QWaylandCompositor *compositor);
+ QWaylandQtWindowManager();
+ explicit QWaylandQtWindowManager(QWaylandCompositor *compositor);
bool showIsFullScreen() const;
void setShowIsFullScreen(bool value);
- void sendQuitMessage(wl_client *client);
+ void sendQuitMessage(QWaylandClient *client);
void initialize() Q_DECL_OVERRIDE;
@@ -74,4 +73,4 @@ Q_SIGNALS:
QT_END_NAMESPACE
-#endif // WAYLANDWINDOWMANAGERINTEGRATION_H
+#endif // QWAYLANDQTWINDOWMANAGER_H
diff --git a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h b/src/compositor/extensions/qwaylandqtwindowmanager_p.h
index 9573855d5..a6df2138f 100644
--- a/src/compositor/extensions/qwaylandwindowmanagerextension_p.h
+++ b/src/compositor/extensions/qwaylandqtwindowmanager_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
@@ -34,8 +35,14 @@
**
****************************************************************************/
-#ifndef QWAYLANDWINDOWMANAGEREXTENSION_P_H
-#define QWAYLANDWINDOWMANAGEREXTENSION_P_H
+#ifndef QWAYLANDQTWINDOWMANAGER_P_H
+#define QWAYLANDQTWINDOWMANAGER_P_H
+
+#include <QtCore/QMap>
+
+#include <QtWaylandCompositor/QWaylandQtWindowManager>
+#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
+#include <QtWaylandCompositor/private/qwayland-server-qt-windowmanager.h>
//
// W A R N I N G
@@ -48,21 +55,15 @@
// We mean it.
//
-#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
-
-#include <QtWaylandCompositor/private/qwayland-server-windowmanager.h>
-
-#include <QMap>
-
QT_BEGIN_NAMESPACE
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWindowManagerExtensionPrivate
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQtWindowManagerPrivate
: public QWaylandCompositorExtensionPrivate
, public QtWaylandServer::qt_windowmanager
{
- Q_DECLARE_PUBLIC(QWaylandWindowManagerExtension)
+ Q_DECLARE_PUBLIC(QWaylandQtWindowManager)
public:
- QWaylandWindowManagerExtensionPrivate();
+ QWaylandQtWindowManagerPrivate();
protected:
void windowmanager_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
@@ -76,4 +77,4 @@ private:
QT_END_NAMESPACE
-#endif /*QWAYLANDWINDOWMANAGEREXTENSION_P_H*/
+#endif // QWAYLANDQTWINDOWMANAGER_P_H
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
index 9cb65fbef..f6a88e434 100644
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
@@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE
/*!
* \qmltype ShellSurfaceItem
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief A Qt Quick item type representing a WlShellSurface.
*
* This type is used to render \c wl_shell or \c xdg_shell surfaces as part of a Qt Quick
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE
/*!
* \class QWaylandQuickShellSurfaceItem
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandQuickShellSurfaceItem class provides a Qt Quick item that represents a QWaylandShellSurface.
*
* This class is used to render \c wl_shell or \c xdg_shell surfaces as part of a Qt Quick
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h
index e233c99e5..f72b970c2 100644
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h
@@ -51,8 +51,6 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellSurfaceItem : public QWaylan
Q_DECLARE_PRIVATE(QWaylandQuickShellSurfaceItem)
Q_PROPERTY(QWaylandShellSurface *shellSurface READ shellSurface WRITE setShellSurface NOTIFY shellSurfaceChanged)
Q_PROPERTY(QQuickItem *moveItem READ moveItem WRITE setMoveItem NOTIFY moveItemChanged)
-
- QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent);
public:
QWaylandQuickShellSurfaceItem(QQuickItem *parent = nullptr);
@@ -67,6 +65,8 @@ Q_SIGNALS:
void moveItemChanged();
protected:
+ QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent);
+
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
};
diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h
index c39a1cd08..3cd9bf228 100644
--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h
+++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem_p.h
@@ -40,6 +40,8 @@
#include <QtWaylandCompositor/private/qwaylandquickitem_p.h>
#include <QtCore/QBasicTimer>
+#include <functional>
+
QT_BEGIN_NAMESPACE
//
@@ -83,7 +85,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellEventFilter : public QObject
{
Q_OBJECT
public:
- typedef void (*CallbackFunction)(void);
+ typedef std::function<void()> CallbackFunction;
static void startFilter(QWaylandClient *client, CallbackFunction closePopupCallback);
static void cancelFilter();
diff --git a/src/compositor/extensions/qwaylandshell.cpp b/src/compositor/extensions/qwaylandshell.cpp
new file mode 100644
index 000000000..7811a1c2a
--- /dev/null
+++ b/src/compositor/extensions/qwaylandshell.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandshell.h"
+#include "qwaylandshell_p.h"
+
+QT_BEGIN_NAMESPACE
+
+QWaylandShellPrivate::QWaylandShellPrivate()
+ : focusPolicy(QWaylandShell::AutomaticFocus)
+{
+}
+
+QWaylandShell::QWaylandShell()
+ : QWaylandCompositorExtension()
+{
+}
+
+QWaylandShell::QWaylandShell(QWaylandObject *waylandObject)
+ : QWaylandCompositorExtension(waylandObject, *new QWaylandShellPrivate())
+{
+}
+
+/*!
+ * \qmlproperty enum QtWaylandCompositor::Shell::focusPolicy
+ *
+ * This property holds the focus policy of the Shell.
+ */
+
+/*!
+ * \enum QWaylandShell::FocusPolicy
+ *
+ * This enum type is used to specify the focus policy for shell surfaces.
+ *
+ * \value AutomaticFocus Shell surfaces will automatically get keyboard focus when they are created.
+ * \value ManualFocus The compositor will decide whether shell surfaces should get keyboard focus or not.
+ */
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::Shell::focusPolicy
+ *
+ * This property holds the focus policy of the Shell.
+ */
+
+/*!
+ * \property QWaylandShell::focusPolicy
+ *
+ * This property holds the focus policy of the QWaylandShell.
+ */
+QWaylandShell::FocusPolicy QWaylandShell::focusPolicy() const
+{
+ Q_D(const QWaylandShell);
+ return d->focusPolicy;
+}
+
+void QWaylandShell::setFocusPolicy(QWaylandShell::FocusPolicy focusPolicy)
+{
+ Q_D(QWaylandShell);
+
+ if (d->focusPolicy == focusPolicy)
+ return;
+
+ d->focusPolicy = focusPolicy;
+ emit focusPolicyChanged();
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandshell.h b/src/compositor/extensions/qwaylandshell.h
new file mode 100644
index 000000000..997573c95
--- /dev/null
+++ b/src/compositor/extensions/qwaylandshell.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDSHELL_H
+#define QWAYLANDSHELL_H
+
+#include <QtWaylandCompositor/QWaylandCompositorExtension>
+
+QT_BEGIN_NAMESPACE
+
+class QWaylandShellPrivate;
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShell : public QWaylandCompositorExtension
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QWaylandShell)
+ Q_PROPERTY(FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy NOTIFY focusPolicyChanged)
+public:
+ enum FocusPolicy {
+ AutomaticFocus,
+ ManualFocus
+ };
+ Q_ENUM(FocusPolicy)
+
+ QWaylandShell();
+ QWaylandShell(QWaylandObject *waylandObject);
+
+ FocusPolicy focusPolicy() const;
+ void setFocusPolicy(FocusPolicy focusPolicy);
+
+Q_SIGNALS:
+ void focusPolicyChanged();
+
+protected:
+ QWaylandShell(QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(dd) {}
+ QWaylandShell(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(container, dd) {}
+};
+
+template <typename T>
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellTemplate : public QWaylandShell
+{
+public:
+ QWaylandShellTemplate()
+ : QWaylandShell()
+ { }
+
+ QWaylandShellTemplate(QWaylandObject *container)
+ : QWaylandShell(container)
+ { }
+
+ const struct wl_interface *extensionInterface() const Q_DECL_OVERRIDE
+ {
+ return T::interface();
+ }
+
+ static T *findIn(QWaylandObject *container)
+ {
+ if (!container) return nullptr;
+ return qobject_cast<T *>(container->extension(T::interfaceName()));
+ }
+
+protected:
+ QWaylandShellTemplate(QWaylandCompositorExtensionPrivate &dd)
+ : QWaylandShell(dd)
+ { }
+
+ QWaylandShellTemplate(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd)
+ : QWaylandShell(container,dd)
+ { }
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDSHELL_H
diff --git a/src/compositor/extensions/qwaylandshell_p.h b/src/compositor/extensions/qwaylandshell_p.h
new file mode 100644
index 000000000..7f849c76d
--- /dev/null
+++ b/src/compositor/extensions/qwaylandshell_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWAYLANDSHELL_P_H
+#define QWAYLANDSHELL_P_H
+
+#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
+#include <QtWaylandCompositor/QWaylandShell>
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
+
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellPrivate : public QWaylandCompositorExtensionPrivate
+{
+ Q_DECLARE_PUBLIC(QWaylandShell)
+public:
+ QWaylandShellPrivate();
+
+ QWaylandShell::FocusPolicy focusPolicy;
+};
+
+QT_END_NAMESPACE
+
+#endif // QWAYLANDSHELL_P_H
diff --git a/src/compositor/extensions/qwaylandshellsurface.h b/src/compositor/extensions/qwaylandshellsurface.h
index 1e9fcb5ab..e8c75327c 100644
--- a/src/compositor/extensions/qwaylandshellsurface.h
+++ b/src/compositor/extensions/qwaylandshellsurface.h
@@ -49,13 +49,20 @@ class QWaylandShellSurfaceTemplatePrivate;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellSurface : public QWaylandCompositorExtension
{
Q_OBJECT
+ Q_PROPERTY(Qt::WindowType windowType READ windowType NOTIFY windowTypeChanged)
public:
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
virtual QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) = 0;
+#endif
QWaylandShellSurface(QWaylandObject *waylandObject) : QWaylandCompositorExtension(waylandObject) {}
+ virtual Qt::WindowType windowType() const { return Qt::WindowType::Window; }
protected:
QWaylandShellSurface(QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(dd){}
QWaylandShellSurface(QWaylandObject *container, QWaylandCompositorExtensionPrivate &dd) : QWaylandCompositorExtension(container, dd) {}
+
+Q_SIGNALS:
+ void windowTypeChanged();
};
template <typename T>
diff --git a/src/compositor/extensions/qwaylandtextinput.cpp b/src/compositor/extensions/qwaylandtextinput.cpp
index 973308f2f..14dafaab0 100644
--- a/src/compositor/extensions/qwaylandtextinput.cpp
+++ b/src/compositor/extensions/qwaylandtextinput.cpp
@@ -38,7 +38,7 @@
#include "qwaylandtextinput_p.h"
#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/private/qwaylandseat_p.h>
#include "qwaylandsurface.h"
#include "qwaylandview.h"
diff --git a/src/compositor/extensions/qwaylandtextinputmanager.cpp b/src/compositor/extensions/qwaylandtextinputmanager.cpp
index 9dd7ace8f..7be00b6dd 100644
--- a/src/compositor/extensions/qwaylandtextinputmanager.cpp
+++ b/src/compositor/extensions/qwaylandtextinputmanager.cpp
@@ -38,7 +38,7 @@
#include "qwaylandtextinputmanager_p.h"
#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include "qwaylandtextinput.h"
@@ -50,14 +50,14 @@ QWaylandTextInputManagerPrivate::QWaylandTextInputManagerPrivate()
{
}
-void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat)
+void QWaylandTextInputManagerPrivate::zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seatResource)
{
Q_Q(QWaylandTextInputManager);
QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(q->extensionContainer());
- QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat);
- QWaylandTextInput *textInput = QWaylandTextInput::findIn(inputDevice);
+ QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource);
+ QWaylandTextInput *textInput = QWaylandTextInput::findIn(seat);
if (!textInput) {
- textInput = new QWaylandTextInput(inputDevice, compositor);
+ textInput = new QWaylandTextInput(seat, compositor);
}
textInput->add(resource->client(), id, wl_resource_get_version(resource->handle));
}
diff --git a/src/compositor/extensions/qwaylandtextinputmanager_p.h b/src/compositor/extensions/qwaylandtextinputmanager_p.h
index 4af717096..955a5cc8a 100644
--- a/src/compositor/extensions/qwaylandtextinputmanager_p.h
+++ b/src/compositor/extensions/qwaylandtextinputmanager_p.h
@@ -61,7 +61,7 @@ public:
QWaylandTextInputManagerPrivate();
protected:
- void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seat) Q_DECL_OVERRIDE;
+ void zwp_text_input_manager_v2_get_text_input(Resource *resource, uint32_t id, struct ::wl_resource *seatResource) Q_DECL_OVERRIDE;
};
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp
index c79ddac7c..3145c6646 100644
--- a/src/compositor/extensions/qwaylandwlshell.cpp
+++ b/src/compositor/extensions/qwaylandwlshell.cpp
@@ -38,7 +38,9 @@
#include "qwaylandwlshell.h"
#include "qwaylandwlshell_p.h"
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
#include "qwaylandwlshellintegration_p.h"
+#endif
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandView>
@@ -77,16 +79,23 @@ void QWaylandWlShellPrivate::shell_get_shell_surface(Resource *resource, uint32_
if (!surface->setRole(QWaylandWlShellSurface::role(), displayRes, WL_DISPLAY_ERROR_INVALID_OBJECT))
return;
- emit q->createShellSurface(surface, shellSurfaceResource);
+ emit q->wlShellSurfaceRequested(surface, shellSurfaceResource);
QWaylandWlShellSurface *shellSurface = QWaylandWlShellSurface::fromResource(shellSurfaceResource.resource());
if (!shellSurface) {
- // A QWaylandShellSurface was not created in response to the createShellSurface signal
- // we create one as fallback here instead.
+ // A QWaylandWlShellSurface was not created in response to the wlShellSurfaceRequested
+ // signal, so we create one as fallback here instead.
shellSurface = new QWaylandWlShellSurface(q, surface, shellSurfaceResource);
}
- emit q->shellSurfaceCreated(shellSurface);
+ m_shellSurfaces.append(shellSurface);
+ emit q->wlShellSurfaceCreated(shellSurface);
+}
+
+void QWaylandWlShellPrivate::unregisterShellSurface(QWaylandWlShellSurface *shellSurface)
+{
+ if (!m_shellSurfaces.removeOne(shellSurface))
+ qWarning("Unexpected state. Can't find registered shell surface.");
}
QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate()
@@ -94,7 +103,7 @@ QWaylandWlShellSurfacePrivate::QWaylandWlShellSurfacePrivate()
, wl_shell_surface()
, m_shell(Q_NULLPTR)
, m_surface(Q_NULLPTR)
- , m_focusPolicy(QWaylandWlShellSurface::DefaultFocus)
+ , m_windowType(Qt::WindowType::Window)
{
}
@@ -108,6 +117,16 @@ void QWaylandWlShellSurfacePrivate::ping(uint32_t serial)
send_ping(serial);
}
+void QWaylandWlShellSurfacePrivate::setWindowType(Qt::WindowType windowType)
+{
+ if (m_windowType == windowType)
+ return;
+ m_windowType = windowType;
+
+ Q_Q(QWaylandWlShellSurface);
+ emit q->windowTypeChanged();
+}
+
void QWaylandWlShellSurfacePrivate::shell_surface_destroy_resource(Resource *)
{
Q_Q(QWaylandWlShellSurface);
@@ -123,7 +142,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_move(Resource *resource,
Q_UNUSED(serial);
Q_Q(QWaylandWlShellSurface);
- QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super);
+ QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(input_device_super);
emit q->startMove(input_device);
}
@@ -136,7 +155,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_resize(Resource *resource,
Q_UNUSED(serial);
Q_Q(QWaylandWlShellSurface);
- QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(input_device_super);
+ QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(input_device_super);
emit q->startResize(input_device, QWaylandWlShellSurface::ResizeEdge(edges));
}
@@ -144,7 +163,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_toplevel(Resource *resourc
{
Q_UNUSED(resource);
Q_Q(QWaylandWlShellSurface);
- setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
+ setWindowType(Qt::WindowType::Window);
emit q->setDefaultToplevel();
}
@@ -158,11 +177,8 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_transient(Resource *resour
Q_UNUSED(resource);
Q_Q(QWaylandWlShellSurface);
QWaylandSurface *parent_surface = QWaylandSurface::fromResource(parent_surface_resource);
- QWaylandWlShellSurface::FocusPolicy focusPolicy =
- flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE ? QWaylandWlShellSurface::NoKeyboardFocus
- : QWaylandWlShellSurface::DefaultFocus;
- setFocusPolicy(focusPolicy);
- emit q->setTransient(parent_surface, QPoint(x,y), focusPolicy);
+ setWindowType(Qt::WindowType::SubWindow);
+ emit q->setTransient(parent_surface, QPoint(x,y), flags & WL_SHELL_SURFACE_TRANSIENT_INACTIVE);
}
void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resource,
@@ -174,10 +190,10 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_fullscreen(Resource *resou
Q_UNUSED(method);
Q_UNUSED(framerate);
Q_Q(QWaylandWlShellSurface);
- setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
QWaylandOutput *output = output_resource
? QWaylandOutput::fromResource(output_resource)
: Q_NULLPTR;
+ setWindowType(Qt::WindowType::Window);
emit q->setFullScreen(QWaylandWlShellSurface::FullScreenMethod(method), framerate, output);
}
@@ -187,9 +203,9 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_popup(Resource *resource,
Q_UNUSED(serial);
Q_UNUSED(flags);
Q_Q(QWaylandWlShellSurface);
- setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
- QWaylandInputDevice *input = QWaylandInputDevice::fromSeatResource(input_device);
+ QWaylandSeat *input = QWaylandSeat::fromSeatResource(input_device);
QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent);
+ setWindowType(Qt::WindowType::Popup);
emit q->setPopup(input, parentSurface, QPoint(x,y));
}
@@ -199,10 +215,10 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_maximized(Resource *resour
{
Q_UNUSED(resource);
Q_Q(QWaylandWlShellSurface);
- setFocusPolicy(QWaylandWlShellSurface::DefaultFocus);
QWaylandOutput *output = output_resource
? QWaylandOutput::fromResource(output_resource)
: Q_NULLPTR;
+ setWindowType(Qt::WindowType::Window);
emit q->setMaximized(output);
}
@@ -242,7 +258,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource,
/*!
* \qmltype WlShell
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief Provides an extension for desktop-style user interfaces.
*
* The WlShell extension provides a way to assiociate a ShellSurface
@@ -268,7 +284,7 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource,
/*!
* \class QWaylandWlShell
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandWlShell class is an extension for desktop-style user interfaces.
*
* The QWaylandWlShell extension provides a way to assiociate a QWaylandWlShellSurface with
@@ -282,14 +298,14 @@ void QWaylandWlShellSurfacePrivate::shell_surface_set_class(Resource *resource,
* Constructs a QWaylandWlShell object.
*/
QWaylandWlShell::QWaylandWlShell()
- : QWaylandCompositorExtensionTemplate<QWaylandWlShell>(*new QWaylandWlShellPrivate())
+ : QWaylandShellTemplate<QWaylandWlShell>(*new QWaylandWlShellPrivate())
{ }
/*!
* Constructs a QWaylandWlShell object for the provided \a compositor.
*/
QWaylandWlShell::QWaylandWlShell(QWaylandCompositor *compositor)
- : QWaylandCompositorExtensionTemplate<QWaylandWlShell>(compositor, *new QWaylandWlShellPrivate())
+ : QWaylandShellTemplate<QWaylandWlShell>(compositor, *new QWaylandWlShellPrivate())
{ }
@@ -299,8 +315,8 @@ QWaylandWlShell::QWaylandWlShell(QWaylandCompositor *compositor)
void QWaylandWlShell::initialize()
{
Q_D(QWaylandWlShell);
- QWaylandCompositorExtensionTemplate::initialize();
- QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ QWaylandShellTemplate::initialize();
+ QWaylandCompositor *compositor = qobject_cast<QWaylandCompositor *>(extensionContainer());
if (!compositor) {
qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandWlShell";
return;
@@ -308,6 +324,54 @@ void QWaylandWlShell::initialize()
d->init(compositor->display(), 1);
}
+QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfaces() const
+{
+ Q_D(const QWaylandWlShell);
+ return d->m_shellSurfaces;
+}
+
+QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfacesForClient(QWaylandClient *client) const
+{
+ Q_D(const QWaylandWlShell);
+ QList<QWaylandWlShellSurface *> surfsForClient;
+ Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) {
+ if (shellSurface->surface()->client() == client)
+ surfsForClient.append(shellSurface);
+ }
+ return surfsForClient;
+}
+
+QList<QWaylandWlShellSurface *> QWaylandWlShell::mappedPopups() const
+{
+ Q_D(const QWaylandWlShell);
+ QList<QWaylandWlShellSurface *> popupSurfaces;
+ Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) {
+ if (shellSurface->windowType() == Qt::WindowType::Popup
+ && shellSurface->surface()->hasContent()) {
+ popupSurfaces.append(shellSurface);
+ }
+ }
+ return popupSurfaces;
+}
+
+QWaylandClient *QWaylandWlShell::popupClient() const
+{
+ Q_D(const QWaylandWlShell);
+ Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) {
+ if (shellSurface->windowType() == Qt::WindowType::Popup
+ && shellSurface->surface()->hasContent()) {
+ return shellSurface->surface()->client();
+ }
+ }
+ return nullptr;
+}
+
+void QWaylandWlShell::closeAllPopups()
+{
+ Q_FOREACH (QWaylandWlShellSurface* shellSurface, mappedPopups())
+ shellSurface->sendPopupDone();
+}
+
/*!
* Returns the Wayland interface for the QWaylandWlShell.
*/
@@ -317,7 +381,7 @@ const struct wl_interface *QWaylandWlShell::interface()
}
/*!
- * \qmlsignal void QtWaylandCompositor::WlShell::createShellSurface(object surface, object client, int id)
+ * \qmlsignal void QtWaylandCompositor::WlShell::wlShellSurfaceRequested(object surface, object client, int id)
*
* This signal is emitted when the \a client has requested a \c wl_shell_surface to be associated
* with \a surface, which is identified by \a id. The handler for this signal is
@@ -326,7 +390,7 @@ const struct wl_interface *QWaylandWlShell::interface()
*/
/*!
- * \fn void QWaylandWlShell::createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource)
+ * \fn void QWaylandWlShell::wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource)
*
* Constructs a QWaylandSurface, assigns it to \a surface and initializes it with the given \a resource.
*/
@@ -342,7 +406,7 @@ QByteArray QWaylandWlShell::interfaceName()
/*!
* \qmltype WlShellSurface
* \inqmlmodule QtWayland.Compositor
- * \preliminary
+ * \since 5.8
* \brief Provides a \c wl_shell_surface that offers desktop-style compositor-specific features to a surface.
*
* This type is part of the \l{WlShell} extension and provides a way to extend
@@ -355,7 +419,7 @@ QByteArray QWaylandWlShell::interfaceName()
/*!
* \class QWaylandWlShellSurface
* \inmodule QtWaylandCompositor
- * \preliminary
+ * \since 5.8
* \brief The QWaylandWlShellSurface class provides desktop-style compositor-specific features to a surface.
*
* This class is part of the QWaylandWlShell extension and provides a way to extend
@@ -382,6 +446,12 @@ QWaylandWlShellSurface::QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandS
initialize(shell, surface, res);
}
+QWaylandWlShellSurface::~QWaylandWlShellSurface()
+{
+ Q_D(QWaylandWlShellSurface);
+ QWaylandWlShellPrivate::get(d->m_shell)->unregisterShellSurface(this);
+}
+
/*!
* \qmlmethod void QtWaylandCompositor::WlShellSurface::initialize(object shell, object surface, object client, int id)
*
@@ -399,6 +469,7 @@ void QWaylandWlShellSurface::initialize(QWaylandWlShell *shell, QWaylandSurface
d->init(resource.resource());
setExtensionContainer(surface);
emit surfaceChanged();
+ emit shellChanged();
QWaylandCompositorExtension::initialize();
}
@@ -493,10 +564,12 @@ void QWaylandWlShellSurface::sendPopupDone()
d->send_popup_done();
}
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
QWaylandQuickShellIntegration *QWaylandWlShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item)
{
return new QtWayland::WlShellIntegration(item);
}
+#endif
/*!
* \qmlproperty object QtWaylandCompositor::WlShellSurface::surface
@@ -516,29 +589,37 @@ QWaylandSurface *QWaylandWlShellSurface::surface() const
}
/*!
- * \enum QWaylandWlShellSurface::FocusPolicy
+ * \qmlproperty object QtWaylandCompositor::WlShellSurface::shell
*
- * This enum type is used to specify the focus policy of a shell surface.
+ * This property holds the shell associated with this WlShellSurface.
+ */
+
+/*!
+ * \property QWaylandWlShellSurface::shell
*
- * \value DefaultFocus The default focus policy should be used.
- * \value NoKeyboardFocus The shell surface should not get keyboard focus.
+ * This property holds the shell associated with this QWaylandWlShellSurface.
*/
+QWaylandWlShell *QWaylandWlShellSurface::shell() const
+{
+ Q_D(const QWaylandWlShellSurface);
+ return d->m_shell;
+}
/*!
- * \qmlproperty enum QtWaylandCompositor::WlShellSurface::focusPolicy
+ * \qmlproperty enum QtWaylandCompositor::WlShellSurface::windowType
*
- * This property holds the focus policy of the WlShellSurface.
+ * This property holds the window type of the WlShellSurface.
*/
/*!
- * \property QWaylandWlShellSurface::focusPolicy
+ * \property QWaylandWlShellSurface::windowType
*
- * This property holds the focus policy of the QWaylandWlShellSurface.
+ * This property holds the window type of the QWaylandWlShellSurface.
*/
-QWaylandWlShellSurface::FocusPolicy QWaylandWlShellSurface::focusPolicy() const
+Qt::WindowType QWaylandWlShellSurface::windowType() const
{
Q_D(const QWaylandWlShellSurface);
- return d->m_focusPolicy;
+ return d->m_windowType;
}
/*!
diff --git a/src/compositor/extensions/qwaylandwlshell.h b/src/compositor/extensions/qwaylandwlshell.h
index 5bddd4f7b..7fe07e7a9 100644
--- a/src/compositor/extensions/qwaylandwlshell.h
+++ b/src/compositor/extensions/qwaylandwlshell.h
@@ -39,6 +39,7 @@
#include <QtWaylandCompositor/QWaylandCompositorExtension>
#include <QtWaylandCompositor/QWaylandResource>
+#include <QtWaylandCompositor/QWaylandShell>
#include <QtWaylandCompositor/QWaylandShellSurface>
#include <QtCore/QSize>
@@ -49,12 +50,12 @@ class QWaylandWlShellPrivate;
class QWaylandWlShellSurfacePrivate;
class QWaylandSurface;
class QWaylandClient;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandOutput;
class QWaylandSurfaceRole;
class QWaylandWlShellSurface;
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShell : public QWaylandCompositorExtensionTemplate<QWaylandWlShell>
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShell : public QWaylandShellTemplate<QWaylandWlShell>
{
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandWlShell)
@@ -63,13 +64,20 @@ public:
QWaylandWlShell(QWaylandCompositor *compositor);
void initialize() Q_DECL_OVERRIDE;
+ QList<QWaylandWlShellSurface *> shellSurfaces() const;
+ QList<QWaylandWlShellSurface *> shellSurfacesForClient(QWaylandClient* client) const;
+ QList<QWaylandWlShellSurface *> mappedPopups() const;
+ QWaylandClient *popupClient() const;
static const struct wl_interface *interface();
static QByteArray interfaceName();
+public Q_SLOTS:
+ void closeAllPopups();
+
Q_SIGNALS:
- void createShellSurface(QWaylandSurface *surface, const QWaylandResource &resource);
- void shellSurfaceCreated(QWaylandWlShellSurface *shellSurface);
+ void wlShellSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource);
+ void wlShellSurfaceCreated(QWaylandWlShellSurface *shellSurface);
};
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellSurfaceTemplate<QWaylandWlShellSurface>
@@ -77,9 +85,9 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurface : public QWaylandShellS
Q_OBJECT
Q_DECLARE_PRIVATE(QWaylandWlShellSurface)
Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged)
+ Q_PROPERTY(QWaylandWlShell *shell READ shell NOTIFY shellChanged)
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(QString className READ className NOTIFY classNameChanged)
- Q_PROPERTY(FocusPolicy focusPolicy READ focusPolicy NOTIFY focusPolicyChanged)
public:
enum FullScreenMethod {
@@ -103,14 +111,9 @@ public:
};
Q_ENUM(ResizeEdge);
- enum FocusPolicy{
- DefaultFocus,
- NoKeyboardFocus
- };
- Q_ENUM(FocusPolicy)
-
QWaylandWlShellSurface();
QWaylandWlShellSurface(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource);
+ virtual ~QWaylandWlShellSurface();
Q_INVOKABLE void initialize(QWaylandWlShell *shell, QWaylandSurface *surface, const QWaylandResource &resource);
@@ -118,8 +121,9 @@ public:
QString className() const;
QWaylandSurface *surface() const;
+ QWaylandWlShell *shell() const;
- FocusPolicy focusPolicy() const;
+ Qt::WindowType windowType() const override;
static const struct wl_interface *interface();
static QByteArray interfaceName();
@@ -131,24 +135,26 @@ public:
Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges);
Q_INVOKABLE void sendPopupDone();
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE;
+#endif
public Q_SLOTS:
void ping();
Q_SIGNALS:
void surfaceChanged();
+ void shellChanged();
void titleChanged();
void classNameChanged();
- void focusPolicyChanged();
void pong();
- void startMove(QWaylandInputDevice *inputDevice);
- void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges);
+ void startMove(QWaylandSeat *seat);
+ void startResize(QWaylandSeat *seat, ResizeEdge edges);
void setDefaultToplevel();
- void setTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, FocusPolicy focusPolicy);
+ void setTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, bool inactive);
void setFullScreen(FullScreenMethod method, uint framerate, QWaylandOutput *output);
- void setPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parentSurface, const QPoint &relativeToParent);
+ void setPopup(QWaylandSeat *seat, QWaylandSurface *parentSurface, const QPoint &relativeToParent);
void setMaximized(QWaylandOutput *output);
private:
diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h
index 39ed645c1..5e8903090 100644
--- a/src/compositor/extensions/qwaylandwlshell_p.h
+++ b/src/compositor/extensions/qwaylandwlshell_p.h
@@ -41,7 +41,7 @@
#include <QtWaylandCompositor/qwaylandsurface.h>
#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
#include <QtWaylandCompositor/QWaylandWlShellSurface>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
#include <wayland-server.h>
#include <QHash>
@@ -70,10 +70,15 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellPrivate
Q_DECLARE_PUBLIC(QWaylandWlShell)
public:
QWaylandWlShellPrivate();
+
+ void unregisterShellSurface(QWaylandWlShellSurface *shellSurface);
+
static QWaylandWlShellPrivate *get(QWaylandWlShell *shell) { return shell->d_func(); }
protected:
void shell_get_shell_surface(Resource *resource, uint32_t id, struct ::wl_resource *surface) Q_DECL_OVERRIDE;
+
+ QList<QWaylandWlShellSurface *> m_shellSurfaces;
};
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandWlShellSurfacePrivate
@@ -89,14 +94,8 @@ public:
void ping(uint32_t serial);
- void setFocusPolicy(QWaylandWlShellSurface::FocusPolicy focusPolicy)
- {
- if (focusPolicy == m_focusPolicy)
- return;
- Q_Q(QWaylandWlShellSurface);
- m_focusPolicy = focusPolicy;
- emit q->focusPolicyChanged();
- }
+ void setWindowType(Qt::WindowType windowType);
+
private:
QWaylandWlShell *m_shell;
QWaylandSurface *m_surface;
@@ -105,7 +104,7 @@ private:
QString m_title;
QString m_className;
- QWaylandWlShellSurface::FocusPolicy m_focusPolicy;
+ Qt::WindowType m_windowType;
void shell_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp
index a1ef5f32a..30e4704af 100644
--- a/src/compositor/extensions/qwaylandwlshellintegration.cpp
+++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp
@@ -39,7 +39,7 @@
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandWlShellSurface>
#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
QT_BEGIN_NAMESPACE
@@ -51,37 +51,123 @@ WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item)
, m_shellSurface(qobject_cast<QWaylandWlShellSurface *>(item->shellSurface()))
, grabberState(GrabberState::Default)
, isPopup(false)
+ , currentState(State::Windowed)
+ , nextState(State::Windowed)
{
m_item->setSurface(m_shellSurface->surface());
connect(m_shellSurface, &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove);
connect(m_shellSurface, &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize);
+ connect(m_shellSurface->surface(), &QWaylandSurface::redraw, this, &WlShellIntegration::handleRedraw);
connect(m_shellSurface->surface(), &QWaylandSurface::offsetForNextFrame, this, &WlShellIntegration::adjustOffsetForNextFrame);
+ connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, this, &WlShellIntegration::handleSurfaceHasContentChanged);
+ connect(m_shellSurface, &QWaylandWlShellSurface::setDefaultToplevel, this, &WlShellIntegration::handleSetDefaultTopLevel);
+ connect(m_shellSurface, &QWaylandWlShellSurface::setTransient, this, &WlShellIntegration::handleSetTransient);
+ connect(m_shellSurface, &QWaylandWlShellSurface::setMaximized, this, &WlShellIntegration::handleSetMaximized);
+ connect(m_shellSurface, &QWaylandWlShellSurface::setFullScreen, this, &WlShellIntegration::handleSetFullScreen);
connect(m_shellSurface, &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup);
connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed);
}
-void WlShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice)
+void WlShellIntegration::handleStartMove(QWaylandSeat *seat)
{
grabberState = GrabberState::Move;
- moveState.inputDevice = inputDevice;
+ moveState.seat = seat;
moveState.initialized = false;
}
-void WlShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges)
+void WlShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandWlShellSurface::ResizeEdge edges)
{
grabberState = GrabberState::Resize;
- resizeState.inputDevice = inputDevice;
+ resizeState.seat = seat;
resizeState.resizeEdges = edges;
float scaleFactor = m_item->view()->output()->scaleFactor();
resizeState.initialSize = m_shellSurface->surface()->size() / scaleFactor;
resizeState.initialized = false;
}
-void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent)
+void WlShellIntegration::handleSetDefaultTopLevel()
{
- Q_UNUSED(inputDevice);
+ // Take focus if the policy allows
+ if (m_shellSurface->shell()->focusPolicy() == QWaylandShell::AutomaticFocus)
+ m_item->takeFocus();
+
+ // In order to restore the window state, the client calls setDefaultToplevel()
+ // so we need to unset the flags here but we save the previous state and move
+ // to the initial position when redrawing
+ nextState = State::Windowed;
+}
+
+void WlShellIntegration::handleSetTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, bool inactive)
+{
+ Q_UNUSED(parentSurface)
+ Q_UNUSED(relativeToParent)
+
+ // Take focus if the policy allows and it's not inactive
+ if (m_shellSurface->shell()->focusPolicy() == QWaylandShell::AutomaticFocus && !inactive)
+ m_item->takeFocus();
+}
+
+void WlShellIntegration::handleSetMaximized(QWaylandOutput *output)
+{
+ if (!m_item->view()->isPrimary())
+ return;
+
+ if (currentState == State::Maximized)
+ return;
+
+ QWaylandOutput *designatedOutput = output ? output : m_item->view()->output();
+ if (!designatedOutput)
+ return;
+
+ if (currentState == State::Windowed)
+ normalPosition = m_item->moveItem()->position();
+
+ nextState = State::Maximized;
+ finalPosition = designatedOutput->position() + designatedOutput->availableGeometry().topLeft();
+
+ m_shellSurface->sendConfigure(designatedOutput->availableGeometry().size(), QWaylandWlShellSurface::NoneEdge);
+}
+
+void WlShellIntegration::handleSetFullScreen(QWaylandWlShellSurface::FullScreenMethod method, uint framerate, QWaylandOutput *output)
+{
+ Q_UNUSED(method);
+ Q_UNUSED(framerate);
+
+ if (!m_item->view()->isPrimary())
+ return;
+
+ if (currentState == State::FullScreen)
+ return;
+
+ QWaylandOutput *designatedOutput = output ? output : m_item->view()->output();
+ if (!designatedOutput)
+ return;
+
+ if (currentState == State::Windowed)
+ normalPosition = m_item->moveItem()->position();
+
+ nextState = State::FullScreen;
+ finalPosition = designatedOutput->position();
+
+ m_shellSurface->sendConfigure(designatedOutput->geometry().size(), QWaylandWlShellSurface::NoneEdge);
+}
+
+void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const QPoint &relativeToParent)
+{
+ Q_UNUSED(seat);
+
+ // Find the parent item on the same output
+ QWaylandQuickShellSurfaceItem *parentItem = nullptr;
+ Q_FOREACH (QWaylandView *view, parent->views()) {
+ if (view->output() == m_item->view()->output()) {
+ QWaylandQuickShellSurfaceItem *item = qobject_cast<QWaylandQuickShellSurfaceItem*>(view->renderObject());
+ if (item) {
+ parentItem = item;
+ break;
+ }
+ }
+ }
- QWaylandQuickShellSurfaceItem* parentItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(parent->views().first()->renderObject());
if (parentItem) {
// Clear all the transforms for this ShellSurfaceItem. They are not
// applicable when the item becomes a child to a surface that has its
@@ -96,33 +182,29 @@ void WlShellIntegration::handleSetPopup(QWaylandInputDevice *inputDevice, QWayla
}
isPopup = true;
- QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), &closePopups);
+ QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), [&]() {
+ m_shellSurface->shell()->closeAllPopups();
+ });
- if (!popupShellSurfaces.contains(m_shellSurface)) {
- popupShellSurfaces.append(m_shellSurface);
- QObject::connect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged,
- this, &WlShellIntegration::handleSurfaceUnmapped);
- }
+ QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged,
+ this, &WlShellIntegration::handleSurfaceHasContentChanged);
}
void WlShellIntegration::handlePopupClosed()
{
handlePopupRemoved();
if (m_shellSurface)
- QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::mappedChanged,
- this, &WlShellIntegration::handleSurfaceUnmapped);
+ QObject::disconnect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged,
+ this, &WlShellIntegration::handleSurfaceHasContentChanged);
}
void WlShellIntegration::handlePopupRemoved()
{
- if (m_shellSurface)
- popupShellSurfaces.removeOne(m_shellSurface);
- if (popupShellSurfaces.isEmpty())
+ if (m_shellSurface->shell()->mappedPopups().isEmpty())
QWaylandQuickShellEventFilter::cancelFilter();
isPopup = false;
}
-
void WlShellIntegration::handleShellSurfaceDestroyed()
{
if (isPopup)
@@ -130,15 +212,28 @@ void WlShellIntegration::handleShellSurfaceDestroyed()
m_shellSurface = nullptr;
}
-void WlShellIntegration::handleSurfaceUnmapped()
+void WlShellIntegration::handleSurfaceHasContentChanged()
{
- if (!m_shellSurface || !m_shellSurface->surface()->size().isEmpty())
+ if (m_shellSurface && m_shellSurface->surface()->size().isEmpty()
+ && m_shellSurface->windowType() == Qt::WindowType::Popup) {
+ handlePopupClosed();
+ }
+}
+
+void WlShellIntegration::handleRedraw()
+{
+ if (currentState == nextState)
return;
- handlePopupClosed();
+
+ m_item->moveItem()->setPosition(nextState == State::Windowed ? normalPosition : finalPosition);
+ currentState = nextState;
}
void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset)
{
+ if (!m_item->view()->isPrimary())
+ return;
+
float scaleFactor = m_item->view()->output()->scaleFactor();
QQuickItem *moveItem = m_item->moveItem();
moveItem->setPosition(moveItem->position() + offset * scaleFactor);
@@ -147,7 +242,7 @@ void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset)
bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event)
{
if (grabberState == GrabberState::Resize) {
- Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event));
+ Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event));
if (!resizeState.initialized) {
resizeState.initialMousePos = event->windowPos();
resizeState.initialized = true;
@@ -158,7 +253,7 @@ bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event)
QSize newSize = m_shellSurface->sizeForResize(resizeState.initialSize, delta, resizeState.resizeEdges);
m_shellSurface->sendConfigure(newSize, resizeState.resizeEdges);
} else if (grabberState == GrabberState::Move) {
- Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event));
+ Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event));
QQuickItem *moveItem = m_item->moveItem();
if (!moveState.initialized) {
moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos());
@@ -183,18 +278,6 @@ bool WlShellIntegration::mouseReleaseEvent(QMouseEvent *event)
return false;
}
-QVector<QWaylandWlShellSurface*> WlShellIntegration::popupShellSurfaces;
-
-void WlShellIntegration::closePopups()
-{
- if (!popupShellSurfaces.isEmpty()) {
- Q_FOREACH (QWaylandWlShellSurface* shellSurface, popupShellSurfaces) {
- shellSurface->sendPopupDone();
- }
- popupShellSurfaces.clear();
- }
-}
-
}
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h
index 3f063af39..bbdfbd733 100644
--- a/src/compositor/extensions/qwaylandwlshellintegration_p.h
+++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h
@@ -65,11 +65,16 @@ public:
bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private Q_SLOTS:
- void handleStartMove(QWaylandInputDevice *inputDevice);
- void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandWlShellSurface::ResizeEdge edges);
- void handleSetPopup(QWaylandInputDevice *inputDevice, QWaylandSurface *parent, const QPoint &relativeToParent);
+ void handleStartMove(QWaylandSeat *seat);
+ void handleStartResize(QWaylandSeat *seat, QWaylandWlShellSurface::ResizeEdge edges);
+ void handleSetDefaultTopLevel();
+ void handleSetTransient(QWaylandSurface *parentSurface, const QPoint &relativeToParent, bool inactive);
+ void handleSetMaximized(QWaylandOutput *output);
+ void handleSetFullScreen(QWaylandWlShellSurface::FullScreenMethod method, uint framerate, QWaylandOutput *output);
+ void handleSetPopup(QWaylandSeat *seat, QWaylandSurface *parent, const QPoint &relativeToParent);
void handleShellSurfaceDestroyed();
- void handleSurfaceUnmapped();
+ void handleSurfaceHasContentChanged();
+ void handleRedraw();
void adjustOffsetForNextFrame(const QPointF &offset);
private:
@@ -82,26 +87,34 @@ private:
void handlePopupClosed();
void handlePopupRemoved();
- static void closePopups();
-
QWaylandQuickShellSurfaceItem *m_item;
QWaylandWlShellSurface *m_shellSurface;
GrabberState grabberState;
struct {
- QWaylandInputDevice *inputDevice;
+ QWaylandSeat *seat;
QPointF initialOffset;
bool initialized;
} moveState;
struct {
- QWaylandInputDevice *inputDevice;
+ QWaylandSeat *seat;
QWaylandWlShellSurface::ResizeEdge resizeEdges;
QSizeF initialSize;
QPointF initialMousePos;
bool initialized;
} resizeState;
- static QVector<QWaylandWlShellSurface*> popupShellSurfaces;
bool isPopup;
+
+ enum class State {
+ Windowed,
+ Maximized,
+ FullScreen
+ };
+
+ State currentState;
+ State nextState;
+ QPointF normalPosition;
+ QPointF finalPosition;
};
}
diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp
deleted file mode 100644
index dbfcfd625..000000000
--- a/src/compositor/extensions/qwaylandxdgshell.cpp
+++ /dev/null
@@ -1,1114 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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.
-**
-** 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.LGPLv3 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.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 later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwaylandxdgshell.h"
-#include "qwaylandxdgshell_p.h"
-#include "qwaylandxdgshellintegration_p.h"
-
-#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/QWaylandSurface>
-#include <QtWaylandCompositor/QWaylandSurfaceRole>
-#include <QtWaylandCompositor/QWaylandResource>
-#include <QtWaylandCompositor/QWaylandInputDevice>
-
-#include <QtCore/QObject>
-
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-QWaylandSurfaceRole QWaylandXdgSurfacePrivate::s_role("xdg_surface");
-QWaylandSurfaceRole QWaylandXdgPopupPrivate::s_role("xdg_popup");
-
-QWaylandXdgShellPrivate::QWaylandXdgShellPrivate()
- : QWaylandCompositorExtensionPrivate()
- , xdg_shell()
-{
-}
-
-void QWaylandXdgShellPrivate::ping(Resource *resource, uint32_t serial)
-{
- m_pings.insert(serial);
- send_ping(resource->handle, serial);
-}
-
-void QWaylandXdgShellPrivate::registerSurface(QWaylandXdgSurface *xdgSurface)
-{
- m_xdgSurfaces.insert(xdgSurface->surface()->client()->client(), xdgSurface);
-}
-
-void QWaylandXdgShellPrivate::unregisterXdgSurface(QWaylandXdgSurface *xdgSurface)
-{
- auto xdgSurfacePrivate = QWaylandXdgSurfacePrivate::get(xdgSurface);
- if (!m_xdgSurfaces.remove(xdgSurfacePrivate->resource()->client(), xdgSurface))
- qWarning("%s Unexpected state. Can't find registered xdg surface\n", Q_FUNC_INFO);
-}
-
-void QWaylandXdgShellPrivate::registerXdgPopup(QWaylandXdgPopup *xdgPopup)
-{
- m_xdgPopups.insert(xdgPopup->surface()->client()->client(), xdgPopup);
-}
-
-void QWaylandXdgShellPrivate::unregisterXdgPopup(QWaylandXdgPopup *xdgPopup)
-{
- auto xdgPopupPrivate = QWaylandXdgPopupPrivate::get(xdgPopup);
- if (!m_xdgPopups.remove(xdgPopupPrivate->resource()->client(), xdgPopup))
- qWarning("%s Unexpected state. Can't find registered xdg popup\n", Q_FUNC_INFO);
-}
-
-bool QWaylandXdgShellPrivate::isValidPopupParent(QWaylandSurface *parentSurface) const
-{
- QWaylandXdgPopup *topmostPopup = topmostPopupForClient(parentSurface->client()->client());
- if (topmostPopup && topmostPopup->surface() != parentSurface) {
- return false;
- }
-
- QWaylandSurfaceRole *parentRole = parentSurface->role();
- if (parentRole != QWaylandXdgSurface::role() && parentRole != QWaylandXdgPopup::role()) {
- return false;
- }
-
- return true;
-}
-
-QWaylandXdgPopup *QWaylandXdgShellPrivate::topmostPopupForClient(wl_client *client) const
-{
- QList<QWaylandXdgPopup *> clientPopups = m_xdgPopups.values(client);
- return clientPopups.empty() ? nullptr : clientPopups.last();
-}
-
-QWaylandXdgSurface *QWaylandXdgShellPrivate::xdgSurfaceFromSurface(QWaylandSurface *surface)
-{
- Q_FOREACH (QWaylandXdgSurface *xdgSurface, m_xdgSurfaces) {
- if (surface == xdgSurface->surface())
- return xdgSurface;
- }
- return nullptr;
-}
-
-void QWaylandXdgShellPrivate::xdg_shell_destroy(Resource *resource)
-{
- if (!m_xdgSurfaces.values(resource->client()).empty())
- wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_DEFUNCT_SURFACES,
- "xdg_shell was destroyed before children");
-
- wl_resource_destroy(resource->handle);
-}
-
-void QWaylandXdgShellPrivate::xdg_shell_get_xdg_surface(Resource *resource, uint32_t id,
- wl_resource *surface_res)
-{
- Q_Q(QWaylandXdgShell);
- QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res);
-
- if (xdgSurfaceFromSurface(surface)) {
- wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_ROLE,
- "An active xdg_surface already exists for wl_surface@%d",
- wl_resource_get_id(surface->resource()));
- return;
- }
-
- if (!surface->setRole(QWaylandXdgSurface::role(), resource->handle, XDG_SHELL_ERROR_ROLE))
- return;
-
- QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface,
- wl_resource_get_version(resource->handle), id));
-
- emit q->createXdgSurface(surface, xdgSurfaceResource);
-
- QWaylandXdgSurface *xdgSurface = QWaylandXdgSurface::fromResource(xdgSurfaceResource.resource());
- if (!xdgSurface) {
- // A QWaylandXdgSurface was not created in response to the createXdgSurface signal, so we
- // create one as fallback here instead.
- xdgSurface = new QWaylandXdgSurface(q, surface, xdgSurfaceResource);
- }
-
- registerSurface(xdgSurface);
- emit q->xdgSurfaceCreated(xdgSurface);
-}
-
-void QWaylandXdgShellPrivate::xdg_shell_use_unstable_version(Resource *resource, int32_t version)
-{
- if (xdg_shell::version_current != version) {
- wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
- "incompatible version, server is %d, but client wants %d",
- xdg_shell::version_current, version);
- }
-}
-
-void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id,
- wl_resource *surface_res, wl_resource *parent,
- wl_resource *seat, uint32_t serial,
- int32_t x, int32_t y)
-{
- Q_UNUSED(serial);
- Q_Q(QWaylandXdgShell);
- QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res);
- QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent);
-
- if (!isValidPopupParent(parentSurface)) {
- wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_INVALID_POPUP_PARENT,
- "the client specified an invalid popup parent surface");
- return;
- }
-
- if (!surface->setRole(QWaylandXdgPopup::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) {
- return;
- }
-
- QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface,
- wl_resource_get_version(resource->handle), id));
- QWaylandInputDevice *inputDevice = QWaylandInputDevice::fromSeatResource(seat);
- QPoint position(x, y);
- emit q->createXdgPopup(surface, parentSurface, inputDevice, position, xdgPopupResource);
-
- QWaylandXdgPopup *xdgPopup = QWaylandXdgPopup::fromResource(xdgPopupResource.resource());
- if (!xdgPopup) {
- // A QWaylandXdgPopup was not created in response to the createXdgPopup signal, so we
- // create one as fallback here instead.
- xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, xdgPopupResource);
- }
-
- registerXdgPopup(xdgPopup);
- emit q->xdgPopupCreated(xdgPopup);
-}
-
-void QWaylandXdgShellPrivate::xdg_shell_pong(Resource *resource, uint32_t serial)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgShell);
- if (m_pings.remove(serial))
- emit q->pong(serial);
- else
- qWarning("Received an unexpected pong!");
-}
-
-QWaylandXdgSurfacePrivate::QWaylandXdgSurfacePrivate()
- : QWaylandCompositorExtensionPrivate()
- , xdg_surface()
- , m_surface(nullptr)
- , m_parentSurface(nullptr)
- , m_unsetWindowGeometry(true)
- , m_lastAckedConfigure({{}, QSize(0, 0), 0})
-{
-}
-
-void QWaylandXdgSurfacePrivate::handleFocusLost()
-{
- Q_Q(QWaylandXdgSurface);
- QWaylandXdgSurfacePrivate::ConfigureEvent current = lastSentConfigure();
- current.states.removeOne(QWaylandXdgSurface::State::ActivatedState);
- q->sendConfigure(current.size, current.states);
-}
-
-void QWaylandXdgSurfacePrivate::handleFocusReceived()
-{
- Q_Q(QWaylandXdgSurface);
-
- QWaylandXdgSurfacePrivate::ConfigureEvent current = lastSentConfigure();
- if (!current.states.contains(QWaylandXdgSurface::State::ActivatedState)) {
- current.states.push_back(QWaylandXdgSurface::State::ActivatedState);
- }
-
- q->sendConfigure(current.size, current.states);
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_destroy_resource(Resource *resource)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
- QWaylandXdgShellPrivate::get(m_xdgShell)->unregisterXdgSurface(q);
- delete q;
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_destroy(Resource *resource)
-{
- wl_resource_destroy(resource->handle);
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_move(Resource *resource, wl_resource *seat, uint32_t serial)
-{
- Q_UNUSED(resource);
- Q_UNUSED(serial);
-
- Q_Q(QWaylandXdgSurface);
- QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat);
- emit q->startMove(input_device);
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_resize(Resource *resource, wl_resource *seat,
- uint32_t serial, uint32_t edges)
-{
- Q_UNUSED(resource);
- Q_UNUSED(serial);
-
- Q_Q(QWaylandXdgSurface);
- QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat);
- emit q->startResize(input_device, QWaylandXdgSurface::ResizeEdge(edges));
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_maximized(Resource *resource)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
- emit q->setMaximized();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_unset_maximized(Resource *resource)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
- emit q->unsetMaximized();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_fullscreen(Resource *resource, wl_resource *output_res)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
- QWaylandOutput *output = output_res ? QWaylandOutput::fromResource(output_res) : nullptr;
- emit q->setFullscreen(output);
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_unset_fullscreen(Resource *resource)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
- emit q->unsetFullscreen();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_minimized(Resource *resource)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
- emit q->setMinimized();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_parent(Resource *resource, wl_resource *parent)
-{
- Q_UNUSED(resource);
- QWaylandXdgSurface *parentSurface = nullptr;
- if (parent) {
- parentSurface = static_cast<QWaylandXdgSurfacePrivate *>(
- QWaylandXdgSurfacePrivate::Resource::fromResource(parent)->xdg_surface_object)->q_func();
- }
-
- if (m_parentSurface == parentSurface)
- return;
-
- Q_Q(QWaylandXdgSurface);
- m_parentSurface = parentSurface;
- emit q->parentSurfaceChanged();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const QString &app_id)
-{
- Q_UNUSED(resource);
- if (app_id == m_appId)
- return;
- Q_Q(QWaylandXdgSurface);
- m_appId = app_id;
- emit q->appIdChanged();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seat,
- uint32_t serial, int32_t x, int32_t y)
-{
- Q_UNUSED(resource);
- Q_UNUSED(serial);
- QPoint position(x, y);
- auto inputDevice = QWaylandInputDevice::fromSeatResource(seat);
- Q_Q(QWaylandXdgSurface);
- emit q->showWindowMenu(inputDevice, position);
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_ack_configure(Resource *resource, uint32_t serial)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgSurface);
-
- ConfigureEvent config;
- Q_FOREVER {
- if (m_pendingConfigures.empty()) {
- qWarning("Received an unexpected ack_configure!");
- return;
- }
-
- config = m_pendingConfigures.takeFirst();
-
- if (config.serial == serial)
- break;
- }
-
- QVector<uint> changedStates;
- std::set_symmetric_difference(
- m_lastAckedConfigure.states.begin(), m_lastAckedConfigure.states.end(),
- config.states.begin(), config.states.end(),
- std::back_inserter(changedStates));
-
- m_lastAckedConfigure = config;
-
- if (!changedStates.empty()) {
- Q_FOREACH (uint state, changedStates) {
- switch (state) {
- case QWaylandXdgSurface::State::MaximizedState:
- emit q->maximizedChanged();
- break;
- case QWaylandXdgSurface::State::FullscreenState:
- emit q->fullscreenChanged();
- break;
- case QWaylandXdgSurface::State::ResizingState:
- emit q->resizingChanged();
- break;
- case QWaylandXdgSurface::State::ActivatedState:
- emit q->activatedChanged();
- break;
- }
- }
- emit q->statesChanged();
- }
-
- emit q->ackConfigure(serial);
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_title(Resource *resource, const QString &title)
-{
- Q_UNUSED(resource);
- if (title == m_title)
- return;
- Q_Q(QWaylandXdgSurface);
- m_title = title;
- emit q->titleChanged();
-}
-
-void QWaylandXdgSurfacePrivate::xdg_surface_set_window_geometry(Resource *resource,
- int32_t x, int32_t y,
- int32_t width, int32_t height)
-{
- Q_UNUSED(resource);
-
- if (width <= 0 || height <= 0) {
- qWarning() << "Invalid (non-positive) dimensions received in set_window_geometry";
- return;
- }
-
- m_unsetWindowGeometry = false;
-
- QRect geometry(x, y, width, height);
-
- Q_Q(QWaylandXdgSurface);
- if ((q->maximized() || q->fullscreen()) && m_lastAckedConfigure.size != geometry.size())
- qWarning() << "Client window geometry did not obey last acked configure";
-
- if (geometry == m_windowGeometry)
- return;
-
- m_windowGeometry = geometry;
- emit q->windowGeometryChanged();
-}
-
-QWaylandXdgPopupPrivate::QWaylandXdgPopupPrivate()
- : QWaylandCompositorExtensionPrivate()
- , xdg_popup()
- , m_surface(nullptr)
- , m_parentSurface(nullptr)
- , m_xdgShell(nullptr)
-{
-}
-
-void QWaylandXdgPopupPrivate::xdg_popup_destroy_resource(Resource *resource)
-{
- Q_UNUSED(resource);
- Q_Q(QWaylandXdgPopup);
- QWaylandXdgShellPrivate::get(m_xdgShell)->unregisterXdgPopup(q);
- delete q;
-}
-
-void QWaylandXdgPopupPrivate::xdg_popup_destroy(Resource *resource)
-{
- //TODO: post error if not topmost popup
- wl_resource_destroy(resource->handle);
-}
-
-
-/*!
- * \qmltype XdgShell
- * \inqmlmodule QtWayland.Compositor
- * \preliminary
- * \brief Provides an extension for desktop-style user interfaces.
- *
- * The XdgShell extension provides desktop functionality such as minimize,
- * maximize, and resize using the \c xdg-shell protocol. It creates an XdgSurface
- * for each Wayland surface.
- *
- * The following snippet demonstrates how to use the extension:
- * \quotefromfile minimal-qml/main.qml
- * \skipto import
- * \printuntil /^\}$/
- *
- */
-
-/*!
- * \class QWaylandXdgShell
- * \inmodule QtWaylandCompositor
- * \preliminary
- * \brief Provides an extension for desktop-style user interfaces.
- *
- * The QWaylandXdgShell extension provides desktop functionality such as minimize,
- * maximize, and resize using the \c xdg-shell protocol. It creates an QWaylandXdgSurface
- * for each Wayland surface.
- *
- */
-
-/*!
- * Constructs a QWaylandXdgShell object.
- */
-QWaylandXdgShell::QWaylandXdgShell()
- : QWaylandCompositorExtensionTemplate<QWaylandXdgShell>(*new QWaylandXdgShellPrivate())
-{ }
-
-/*!
- * Constructs a QWaylandXdgShell object for the provided \a compositor.
- */
-QWaylandXdgShell::QWaylandXdgShell(QWaylandCompositor *compositor)
- : QWaylandCompositorExtensionTemplate<QWaylandXdgShell>(compositor, *new QWaylandXdgShellPrivate())
-{ }
-
-/*!
- * Initializes the shell extension.
- */
-void QWaylandXdgShell::initialize()
-{
- Q_D(QWaylandXdgShell);
- QWaylandCompositorExtensionTemplate::initialize();
- QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
- if (!compositor) {
- qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgShell";
- return;
- }
- d->init(compositor->display(), 1);
-
- handleDefaultInputDeviceChanged(compositor->defaultInputDevice(), nullptr);
-
- connect(compositor, &QWaylandCompositor::defaultInputDeviceChanged,
- this, &QWaylandXdgShell::handleDefaultInputDeviceChanged);
-}
-
-/*!
- * Returns the Wayland interface for the QWaylandXdgShell.
- */
-const struct wl_interface *QWaylandXdgShell::interface()
-{
- return QWaylandXdgShellPrivate::interface();
-}
-
-QByteArray QWaylandXdgShell::interfaceName()
-{
- return QWaylandXdgShellPrivate::interfaceName();
-}
-
-/*!
- * \qmlmethod void QtWaylandCompositor::XdgShell::ping(object client)
- *
- * Sends a ping event to the \a client. If the client replies to the event the
- * \l pong signal will be emitted.
- */
-
-/*!
- * Sends a ping event to the client. If the client replies to the event the
- * \a pong signal will be emitted.
- */
-uint QWaylandXdgShell::ping(QWaylandClient *client)
-{
- Q_D(QWaylandXdgShell);
-
- QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
- Q_ASSERT(compositor);
-
- uint32_t serial = compositor->nextSerial();
-
- QWaylandXdgShellPrivate::Resource *clientResource = d->resourceMap().value(client->client(), nullptr);
- Q_ASSERT(clientResource);
-
- d->ping(clientResource, serial);
- return serial;
-}
-
-void QWaylandXdgShell::closeAllPopups()
-{
- Q_D(QWaylandXdgShell);
- Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) {
- QList<QWaylandXdgPopup *> popups = d->m_xdgPopups.values(client);
- std::reverse(popups.begin(), popups.end());
- Q_FOREACH (QWaylandXdgPopup *currentTopmostPopup, popups) {
- currentTopmostPopup->sendPopupDone();
- }
- }
-}
-
-void QWaylandXdgShell::handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice)
-{
- if (oldDevice != nullptr) {
- disconnect(oldDevice, &QWaylandInputDevice::keyboardFocusChanged,
- this, &QWaylandXdgShell::handleFocusChanged);
- }
-
- if (newDevice != nullptr) {
- connect(newDevice, &QWaylandInputDevice::keyboardFocusChanged,
- this, &QWaylandXdgShell::handleFocusChanged);
- }
-}
-
-void QWaylandXdgShell::handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface)
-{
- Q_D(QWaylandXdgShell);
-
- QWaylandXdgSurface *newXdgSurface = d->xdgSurfaceFromSurface(newSurface);
- QWaylandXdgSurface *oldXdgSurface = d->xdgSurfaceFromSurface(oldSurface);
-
- if (newXdgSurface)
- QWaylandXdgSurfacePrivate::get(newXdgSurface)->handleFocusReceived();
-
- if (oldXdgSurface)
- QWaylandXdgSurfacePrivate::get(oldXdgSurface)->handleFocusLost();
-}
-/*!
- * \qmltype XdgSurface
- * \inqmlmodule QtWayland.Compositor
- * \preliminary
- * \brief Provides an XDG surface that offers desktop functionality.
- *
- * XdgSurface is part of the XdgShell extension and provides desktop
- * functionality such as minimize, maximize, and resize using the
- * \c xdg-shell protocol.
- *
- */
-
-/*!
- * \class QWaylandXdgSurface
- * \inmodule QtWaylandCompositor
- * \preliminary
- * \brief The QWaylandXdgSurface class provides desktop functionality.
- *
- * The QWaylandXdgSurface class is part of the QWaylandXdgShell extension and
- * provides a way to extend the functionality of an existing QWaylandSurface with
- * features specific to desktop-style compositors, such as resizing and moving the
- * surface.
- *
- * It corresponds to the Wayland interface \c xdg_surface.
- */
-
-/*!
- * Constructs a QWaylandXdgSurface.
- */
-QWaylandXdgSurface::QWaylandXdgSurface()
- : QWaylandShellSurfaceTemplate<QWaylandXdgSurface>(*new QWaylandXdgSurfacePrivate)
-{
-}
-
-/*!
- * Constructs a QWaylandXdgSurface for \a surface and initializes it with the
- * given \a xdgShell, \a surface, and resource \a res.
- */
-QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, const QWaylandResource &res)
- : QWaylandShellSurfaceTemplate<QWaylandXdgSurface>(*new QWaylandXdgSurfacePrivate)
-{
- initialize(xdgShell, surface, res);
-}
-
-/*!
- * \qmlmethod void QtWaylandCompositor::XdgSurface::initialize(object surface, object client, int id)
- *
- * Initializes the XdgSurface and associates it with the given \a surface,
- * \a client, and \a id.
- */
-
-/*!
- * Initializes the QWaylandXdgSurface and associates it with the given \a xdgShell, \a surface,
- * and \a resource.
- */
-void QWaylandXdgSurface::initialize(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, const QWaylandResource &resource)
-{
- Q_D(QWaylandXdgSurface);
- d->m_xdgShell = xdgShell;
- d->m_surface = surface;
- d->init(resource.resource());
- setExtensionContainer(surface);
- d->m_windowGeometry = QRect(QPoint(0,0), surface->size());
- connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged);
- emit surfaceChanged();
- emit windowGeometryChanged();
- QWaylandCompositorExtension::initialize();
-}
-
-/*!
- * \internal
- */
-void QWaylandXdgSurface::initialize()
-{
- QWaylandCompositorExtension::initialize();
-}
-
-QList<int> QWaylandXdgSurface::statesAsInts() const
-{
- QList<int> list;
- Q_FOREACH (uint state, states()) {
- list << static_cast<int>(state);
- }
- return list;
-}
-
-void QWaylandXdgSurface::handleSurfaceSizeChanged()
-{
- Q_D(QWaylandXdgSurface);
- if (d->m_unsetWindowGeometry && d->m_windowGeometry.size() != surface()->size()) {
- // TODO: The unset window geometry should include subsurfaces as well, so this solution
- // won't work too well on those kinds of clients.
- d->m_windowGeometry.setSize(surface()->size());
- emit windowGeometryChanged();
- }
-}
-
-/*!
- * \qmlproperty object QtWaylandCompositor::XdgSurface::surface
- *
- * This property holds the surface associated with this XdgSurface.
- */
-
-/*!
- * \property QWaylandXdgSurface::surface
- *
- * This property holds the surface associated with this QWaylandXdgSurface.
- */
-QWaylandSurface *QWaylandXdgSurface::surface() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_surface;
-}
-
-/*!
- * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface
- *
- * This property holds the parent of this XdgSurface.
- */
-
-/*!
- * \property QWaylandXdgSurface::parentSurface
- *
- * This property holds the parent of this XdgSurface.
- */
-QWaylandXdgSurface *QWaylandXdgSurface::parentSurface() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_parentSurface;
-}
-
-/*!
- * \qmlproperty string QtWaylandCompositor::XdgSurface::title
- *
- * This property holds the title of the XdgSurface.
- */
-
-/*!
- * \property QWaylandXdgSurface::title
- *
- * This property holds the title of the QWaylandXdgSurface.
- */
-QString QWaylandXdgSurface::title() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_title;
-}
-
-/*!
- * \property QWaylandXdgSurface::appId
- *
- * This property holds the app id of the QWaylandXdgSurface.
- */
-QString QWaylandXdgSurface::appId() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_appId;
-}
-
-/*!
- * \property QWaylandXdgSurface::windowGeometry
- *
- * This property holds the window geometry of the QWaylandXdgSurface. The window
- * geometry describes the window's visible bounds from the user's perspective.
- * The geometry includes title bars and borders if drawn by the client, but
- * excludes drop shadows. It is meant to be used for aligning and tiling
- * windows.
- */
-QRect QWaylandXdgSurface::windowGeometry() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_windowGeometry;
-}
-
-/*!
- * \property QWaylandXdgSurface::states
- *
- * This property holds the last states the client acknowledged for this QWaylandXdgSurface.
- */
-QVector<uint> QWaylandXdgSurface::states() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_lastAckedConfigure.states;
-}
-
-bool QWaylandXdgSurface::maximized() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::MaximizedState);
-}
-
-bool QWaylandXdgSurface::fullscreen() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::FullscreenState);
-}
-
-bool QWaylandXdgSurface::resizing() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::ResizingState);
-}
-
-bool QWaylandXdgSurface::activated() const
-{
- Q_D(const QWaylandXdgSurface);
- return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::ActivatedState);
-}
-
-/*!
- * Returns the Wayland interface for the QWaylandXdgSurface.
- */
-const wl_interface *QWaylandXdgSurface::interface()
-{
- return QWaylandXdgSurfacePrivate::interface();
-}
-
-QByteArray QWaylandXdgSurface::interfaceName()
-{
- return QWaylandXdgSurfacePrivate::interfaceName();
-}
-
-/*!
- * Returns the surface role for the QWaylandXdgSurface.
- */
-QWaylandSurfaceRole *QWaylandXdgSurface::role()
-{
- return &QWaylandXdgSurfacePrivate::s_role;
-}
-
-/*!
- * Returns the QWaylandXdgSurface corresponding to the \a resource.
- */
-QWaylandXdgSurface *QWaylandXdgSurface::fromResource(wl_resource *resource)
-{
- auto xsResource = QWaylandXdgSurfacePrivate::Resource::fromResource(resource);
- if (!xsResource)
- return nullptr;
- return static_cast<QWaylandXdgSurfacePrivate *>(xsResource->xdg_surface_object)->q_func();
-}
-
-QSize QWaylandXdgSurface::sizeForResize(const QSizeF &size, const QPointF &delta,
- QWaylandXdgSurface::ResizeEdge edge)
-{
- qreal width = size.width();
- qreal height = size.height();
- if (edge & LeftEdge)
- width -= delta.x();
- else if (edge & RightEdge)
- width += delta.x();
-
- if (edge & TopEdge)
- height -= delta.y();
- else if (edge & BottomEdge)
- height += delta.y();
-
- return QSizeF(width, height).toSize();
-}
-
-/*!
- * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, List<uint>)
- *
- * Sends a configure event to the client. Known states are enumerated in XdgSurface::State
- */
-
-/*!
- * Sends a configure event to the client. Known states are enumerated in QWaylandXdgSurface::State
- */
-uint QWaylandXdgSurface::sendConfigure(const QSize &size, const QVector<uint> &states)
-{
- Q_D(QWaylandXdgSurface);
- auto statesBytes = QByteArray::fromRawData((char *)states.data(), states.size() * sizeof(State));
- QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
- Q_ASSERT(compositor);
- uint32_t serial = compositor->nextSerial();
- d->m_pendingConfigures.append(QWaylandXdgSurfacePrivate::ConfigureEvent{states, size, serial});
- d->send_configure(size.width(), size.height(), statesBytes, serial);
- return serial;
-}
-
-uint QWaylandXdgSurface::sendConfigure(const QSize &size, const QVector<QWaylandXdgSurface::State> &states)
-{
- QVector<uint> asUints;
- Q_FOREACH (QWaylandXdgSurface::State state, states) {
- asUints << state;
- }
- return sendConfigure(size, asUints);
-}
-
-/*!
- * \qmlmethod void QtWaylandCompositor::XdgSurface::sendClose()
- *
- * Sends a close event to the client.
- */
-
-/*!
- * Sends a close event to the client.
- */
-void QWaylandXdgSurface::sendClose()
-{
- Q_D(QWaylandXdgSurface);
- d->send_close();
-}
-
-uint QWaylandXdgSurface::requestMaximized(const QSize &size)
-{
- Q_D(QWaylandXdgSurface);
- QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure();
-
- if (!conf.states.contains(QWaylandXdgSurface::State::MaximizedState))
- conf.states.append(QWaylandXdgSurface::State::MaximizedState);
- conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState);
- conf.states.removeOne(QWaylandXdgSurface::State::ResizingState);
-
- return sendConfigure(size, conf.states);
-}
-
-uint QWaylandXdgSurface::requestUnMaximized(const QSize &size)
-{
- Q_D(QWaylandXdgSurface);
- QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure();
-
- conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState);
- conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState);
- conf.states.removeOne(QWaylandXdgSurface::State::ResizingState);
-
- return sendConfigure(size, conf.states);
-}
-
-uint QWaylandXdgSurface::requestFullscreen(const QSize &size)
-{
- Q_D(QWaylandXdgSurface);
- QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure();
-
- if (!conf.states.contains(QWaylandXdgSurface::State::FullscreenState))
- conf.states.append(QWaylandXdgSurface::State::FullscreenState);
- conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState);
- conf.states.removeOne(QWaylandXdgSurface::State::ResizingState);
-
- return sendConfigure(size, conf.states);
-}
-
-uint QWaylandXdgSurface::requestResizing(const QSize &maxSize)
-{
- Q_D(QWaylandXdgSurface);
- QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure();
-
- if (!conf.states.contains(QWaylandXdgSurface::State::ResizingState))
- conf.states.append(QWaylandXdgSurface::State::ResizingState);
- conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState);
- conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState);
-
- return sendConfigure(maxSize, conf.states);
-}
-
-QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQuickShellSurfaceItem *item)
-{
- return new QtWayland::XdgShellIntegration(item);
-}
-
-/*!
- * \qmltype XdgPopup
- * \inqmlmodule QtWayland.Compositor
- * \preliminary
- * \brief Provides menus for an xdg surface
- *
- * XdgPopup is part of the XdgShell extension and provides desktop-style
- * menus for an XdgSurface.
- *
- * It corresponds to the Wayland interface \c xdg_popup.
- */
-
-/*!
- * \class QWaylandXdgPopup
- * \inmodule QtWaylandCompositor
- * \preliminary
- * \brief The QWaylandXdgPopup class provides menus for an xdg surface
- *
- * The QWaylandXdbPopup class is part of the QWaylandXdgShell extension and
- * provides a way to extend the functionality of an existing QWaylandSurface
- * with features specific to desktop-style menus for an xdg surface.
- *
- * It corresponds to the Wayland interface \c xdg_popup.
- */
-
-/*!
- * Constructs a QWaylandXdgPopup.
- */
-QWaylandXdgPopup::QWaylandXdgPopup()
- : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate)
-{
-}
-
-/*!
- * Constructs a QWaylandXdgPopup for \a surface and initializes it with the
- * given \a parentSurface and \a resource.
- */
-QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface,
- QWaylandSurface *parentSurface, const QWaylandResource &resource)
- : QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>(*new QWaylandXdgPopupPrivate)
-{
- initialize(xdgShell, surface, parentSurface, resource);
-}
-
-/*!
- * \qmlmethod void QtWaylandCompositor::XdgPopup::initialize(object surface, object parentSurface, object resource)
- *
- * Initializes the xdg popup and associates it with the given \a shell, \a surface,
- * \a parentSurface, and \a resource.
- */
-
-/*!
- * Initializes the QWaylandXdgPopup and associates it with the given \a shell \a surface,
- * \a parentSurface, and \a resource.
- */
-void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface,
- QWaylandSurface *parentSurface, const QWaylandResource &resource)
-{
- Q_D(QWaylandXdgPopup);
- d->m_surface = surface;
- d->m_parentSurface = parentSurface;
- d->m_xdgShell = shell;
- d->init(resource.resource());
- setExtensionContainer(surface);
- emit surfaceChanged();
- emit parentSurfaceChanged();
- QWaylandCompositorExtension::initialize();
-}
-
-/*!
- * \qmlproperty object QtWaylandCompositor::XdgPopup::surface
- *
- * This property holds the surface associated with this XdgPopup.
- */
-
-/*!
- * \property QWaylandXdgPopup::surface
- *
- * This property holds the surface associated with this QWaylandXdgPopup.
- */
-QWaylandSurface *QWaylandXdgPopup::surface() const
-{
- Q_D(const QWaylandXdgPopup);
- return d->m_surface;
-}
-
-/*!
- * \qmlproperty object QtWaylandCompositor::XdgPopup::parentSurface
- *
- * This property holds the surface associated with the parent of this XdgPopup.
- */
-
-/*!
- * \property QWaylandXdgPopup::parentSurface
- *
- * This property holds the surface associated with the parent of this
- * QWaylandXdgPopup.
- */
-QWaylandSurface *QWaylandXdgPopup::parentSurface() const
-{
- Q_D(const QWaylandXdgPopup);
- return d->m_parentSurface;
-}
-
-/*!
- * \internal
- */
-void QWaylandXdgPopup::initialize()
-{
- QWaylandCompositorExtensionTemplate::initialize();
-}
-
-/*!
- * Returns the Wayland interface for the QWaylandXdgPopup.
- */
-const wl_interface *QWaylandXdgPopup::interface()
-{
- return QWaylandXdgPopupPrivate::interface();
-}
-
-QByteArray QWaylandXdgPopup::interfaceName()
-{
- return QWaylandXdgPopupPrivate::interfaceName();
-}
-
-/*!
- * Returns the surface role for the QWaylandXdgPopup.
- */
-QWaylandSurfaceRole *QWaylandXdgPopup::role()
-{
- return &QWaylandXdgPopupPrivate::s_role;
-}
-
-QWaylandXdgPopup *QWaylandXdgPopup::fromResource(wl_resource *resource)
-{
- auto popupResource = QWaylandXdgPopupPrivate::Resource::fromResource(resource);
- if (!popupResource)
- return nullptr;
- return static_cast<QWaylandXdgPopupPrivate *>(popupResource->xdg_popup_object)->q_func();
-}
-
-void QWaylandXdgPopup::sendPopupDone()
-{
- Q_D(QWaylandXdgPopup);
- d->send_popup_done();
-}
-
-QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp
deleted file mode 100644
index ab10011e6..000000000
--- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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.
-**
-** 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.LGPLv3 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.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 later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwaylandxdgshellintegration_p.h"
-
-#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
-#include <QtWaylandCompositor/QWaylandCompositor>
-#include <QtWaylandCompositor/QWaylandInputDevice>
-#include <QMouseEvent>
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWayland {
-
-XdgShellIntegration::XdgShellIntegration(QWaylandQuickShellSurfaceItem *item)
- : QWaylandQuickShellIntegration(item)
- , m_item(item)
- , m_xdgSurface(qobject_cast<QWaylandXdgSurface *>(item->shellSurface()))
- , grabberState(GrabberState::Default)
-{
- m_item->setSurface(m_xdgSurface->surface());
- connect(m_xdgSurface, &QWaylandXdgSurface::startMove, this, &XdgShellIntegration::handleStartMove);
- connect(m_xdgSurface, &QWaylandXdgSurface::startResize, this, &XdgShellIntegration::handleStartResize);
- connect(m_xdgSurface, &QWaylandXdgSurface::setMaximized, this, &XdgShellIntegration::handleSetMaximized);
- connect(m_xdgSurface, &QWaylandXdgSurface::unsetMaximized, this, &XdgShellIntegration::handleUnsetMaximized);
- connect(m_xdgSurface, &QWaylandXdgSurface::maximizedChanged, this, &XdgShellIntegration::handleMaximizedChanged);
- connect(m_xdgSurface, &QWaylandXdgSurface::activatedChanged, this, &XdgShellIntegration::handleActivatedChanged);
- connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellIntegration::handleSurfaceSizeChanged);
-}
-
-bool XdgShellIntegration::mouseMoveEvent(QMouseEvent *event)
-{
- if (grabberState == GrabberState::Resize) {
- Q_ASSERT(resizeState.inputDevice == m_item->compositor()->inputDeviceFor(event));
- if (!resizeState.initialized) {
- resizeState.initialMousePos = event->windowPos();
- resizeState.initialized = true;
- return true;
- }
- float scaleFactor = m_item->view()->output()->scaleFactor();
- QPointF delta = (event->windowPos() - resizeState.initialMousePos) / scaleFactor;
- QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges);
- m_xdgSurface->requestResizing(newSize);
- } else if (grabberState == GrabberState::Move) {
- Q_ASSERT(moveState.inputDevice == m_item->compositor()->inputDeviceFor(event));
- QQuickItem *moveItem = m_item->moveItem();
- if (!moveState.initialized) {
- moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos());
- moveState.initialized = true;
- return true;
- }
- if (!moveItem->parentItem())
- return true;
- QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->windowPos());
- moveItem->setPosition(parentPos - moveState.initialOffset);
- }
- return false;
-}
-
-bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event)
-{
- Q_UNUSED(event);
-
- if (grabberState == GrabberState::Resize) {
- m_xdgSurface->requestUnMaximized();
- grabberState = GrabberState::Default;
- return true;
- } else if (grabberState == GrabberState::Move) {
- grabberState = GrabberState::Default;
- return true;
- }
- return false;
-}
-
-void XdgShellIntegration::handleStartMove(QWaylandInputDevice *inputDevice)
-{
- grabberState = GrabberState::Move;
- moveState.inputDevice = inputDevice;
- moveState.initialized = false;
-}
-
-void XdgShellIntegration::handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges)
-{
- grabberState = GrabberState::Resize;
- resizeState.inputDevice = inputDevice;
- resizeState.resizeEdges = edges;
- resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size();
- resizeState.initialPosition = m_item->position();
- resizeState.initialSurfaceSize = m_item->surface()->size();
- resizeState.initialized = false;
-}
-
-void XdgShellIntegration::handleSetMaximized()
-{
- maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size();
- maximizeState.initialPosition = m_item->position();
-
- QWaylandOutput *output = m_item->compositor()->outputs().first();
- m_xdgSurface->requestMaximized(output->geometry().size() / output->scaleFactor());
-}
-
-void XdgShellIntegration::handleUnsetMaximized()
-{
- m_xdgSurface->requestUnMaximized(maximizeState.initialWindowSize);
-}
-
-void XdgShellIntegration::handleMaximizedChanged()
-{
- if (m_xdgSurface->maximized()) {
- QWaylandOutput *output = m_item->compositor()->outputs().first();
- m_item->setPosition(output->geometry().topLeft());
- } else {
- m_item->setPosition(maximizeState.initialPosition);
- }
-}
-
-void XdgShellIntegration::handleActivatedChanged()
-{
- if (m_xdgSurface->activated())
- m_item->raise();
-}
-
-void XdgShellIntegration::handleSurfaceSizeChanged()
-{
- if (grabberState == GrabberState::Resize) {
- qreal x = resizeState.initialPosition.x();
- qreal y = resizeState.initialPosition.y();
- if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::TopEdge)
- y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height();
-
- if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::LeftEdge)
- x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width();
- m_item->setPosition(QPointF(x, y));
- }
-}
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp
new file mode 100644
index 000000000..fd23865cf
--- /dev/null
+++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp
@@ -0,0 +1,1204 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxdgshellv5.h"
+#include "qwaylandxdgshellv5_p.h"
+
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
+#include "qwaylandxdgshellv5integration_p.h"
+#endif
+
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandSurface>
+#include <QtWaylandCompositor/QWaylandSurfaceRole>
+#include <QtWaylandCompositor/QWaylandResource>
+#include <QtWaylandCompositor/QWaylandSeat>
+
+#include <QtCore/QObject>
+
+#include <algorithm>
+
+QT_BEGIN_NAMESPACE
+
+QWaylandSurfaceRole QWaylandXdgSurfaceV5Private::s_role("xdg_surface");
+QWaylandSurfaceRole QWaylandXdgPopupV5Private::s_role("xdg_popup");
+
+QWaylandXdgShellV5Private::QWaylandXdgShellV5Private()
+ : QWaylandCompositorExtensionPrivate()
+ , xdg_shell()
+{
+}
+
+void QWaylandXdgShellV5Private::ping(Resource *resource, uint32_t serial)
+{
+ m_pings.insert(serial);
+ send_ping(resource->handle, serial);
+}
+
+void QWaylandXdgShellV5Private::registerSurface(QWaylandXdgSurfaceV5 *xdgSurface)
+{
+ m_xdgSurfaces.insert(xdgSurface->surface()->client()->client(), xdgSurface);
+}
+
+void QWaylandXdgShellV5Private::unregisterXdgSurface(QWaylandXdgSurfaceV5 *xdgSurface)
+{
+ auto xdgSurfacePrivate = QWaylandXdgSurfaceV5Private::get(xdgSurface);
+ if (!m_xdgSurfaces.remove(xdgSurfacePrivate->resource()->client(), xdgSurface))
+ qWarning("%s Unexpected state. Can't find registered xdg surface\n", Q_FUNC_INFO);
+}
+
+void QWaylandXdgShellV5Private::registerXdgPopup(QWaylandXdgPopupV5 *xdgPopup)
+{
+ m_xdgPopups.insert(xdgPopup->surface()->client()->client(), xdgPopup);
+}
+
+void QWaylandXdgShellV5Private::unregisterXdgPopup(QWaylandXdgPopupV5 *xdgPopup)
+{
+ auto xdgPopupPrivate = QWaylandXdgPopupV5Private::get(xdgPopup);
+ if (!m_xdgPopups.remove(xdgPopupPrivate->resource()->client(), xdgPopup))
+ qWarning("%s Unexpected state. Can't find registered xdg popup\n", Q_FUNC_INFO);
+}
+
+bool QWaylandXdgShellV5Private::isValidPopupParent(QWaylandSurface *parentSurface) const
+{
+ QWaylandXdgPopupV5 *topmostPopup = topmostPopupForClient(parentSurface->client()->client());
+ if (topmostPopup && topmostPopup->surface() != parentSurface) {
+ return false;
+ }
+
+ QWaylandSurfaceRole *parentRole = parentSurface->role();
+ if (parentRole != QWaylandXdgSurfaceV5::role() && parentRole != QWaylandXdgPopupV5::role()) {
+ return false;
+ }
+
+ return true;
+}
+
+QWaylandXdgPopupV5 *QWaylandXdgShellV5Private::topmostPopupForClient(wl_client *client) const
+{
+ QList<QWaylandXdgPopupV5 *> clientPopups = m_xdgPopups.values(client);
+ return clientPopups.empty() ? nullptr : clientPopups.last();
+}
+
+QWaylandXdgSurfaceV5 *QWaylandXdgShellV5Private::xdgSurfaceFromSurface(QWaylandSurface *surface)
+{
+ Q_FOREACH (QWaylandXdgSurfaceV5 *xdgSurface, m_xdgSurfaces) {
+ if (surface == xdgSurface->surface())
+ return xdgSurface;
+ }
+ return nullptr;
+}
+
+void QWaylandXdgShellV5Private::xdg_shell_destroy(Resource *resource)
+{
+ if (!m_xdgSurfaces.values(resource->client()).empty())
+ wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_DEFUNCT_SURFACES,
+ "xdg_shell was destroyed before children");
+
+ wl_resource_destroy(resource->handle);
+}
+
+void QWaylandXdgShellV5Private::xdg_shell_get_xdg_surface(Resource *resource, uint32_t id,
+ wl_resource *surface_res)
+{
+ Q_Q(QWaylandXdgShellV5);
+ QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res);
+
+ if (xdgSurfaceFromSurface(surface)) {
+ wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_ROLE,
+ "An active xdg_surface already exists for wl_surface@%d",
+ wl_resource_get_id(surface->resource()));
+ return;
+ }
+
+ if (!surface->setRole(QWaylandXdgSurfaceV5::role(), resource->handle, XDG_SHELL_ERROR_ROLE))
+ return;
+
+ QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface,
+ wl_resource_get_version(resource->handle), id));
+
+ emit q->xdgSurfaceRequested(surface, xdgSurfaceResource);
+
+ QWaylandXdgSurfaceV5 *xdgSurface = QWaylandXdgSurfaceV5::fromResource(xdgSurfaceResource.resource());
+ if (!xdgSurface) {
+ // A QWaylandXdgSurfaceV5 was not created in response to the xdgSurfaceRequested signal, so we
+ // create one as fallback here instead.
+ xdgSurface = new QWaylandXdgSurfaceV5(q, surface, xdgSurfaceResource);
+ }
+
+ registerSurface(xdgSurface);
+ emit q->xdgSurfaceCreated(xdgSurface);
+}
+
+void QWaylandXdgShellV5Private::xdg_shell_use_unstable_version(Resource *resource, int32_t version)
+{
+ if (xdg_shell::version_current != version) {
+ wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "incompatible version, server is %d, but client wants %d",
+ xdg_shell::version_current, version);
+ }
+}
+
+void QWaylandXdgShellV5Private::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id,
+ wl_resource *surface_res, wl_resource *parent,
+ wl_resource *seatResource, uint32_t serial,
+ int32_t x, int32_t y)
+{
+ Q_UNUSED(serial);
+ Q_Q(QWaylandXdgShellV5);
+ QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res);
+ QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent);
+
+ if (!isValidPopupParent(parentSurface)) {
+ wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_INVALID_POPUP_PARENT,
+ "the client specified an invalid popup parent surface");
+ return;
+ }
+
+ if (!surface->setRole(QWaylandXdgPopupV5::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) {
+ return;
+ }
+
+ QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface,
+ wl_resource_get_version(resource->handle), id));
+ QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource);
+ QPoint position(x, y);
+ emit q->xdgPopupRequested(surface, parentSurface, seat, position, xdgPopupResource);
+
+ QWaylandXdgPopupV5 *xdgPopup = QWaylandXdgPopupV5::fromResource(xdgPopupResource.resource());
+ if (!xdgPopup) {
+ // A QWaylandXdgPopupV5 was not created in response to the xdgPopupRequested signal, so we
+ // create one as fallback here instead.
+ xdgPopup = new QWaylandXdgPopupV5(q, surface, parentSurface, position, xdgPopupResource);
+ }
+
+ registerXdgPopup(xdgPopup);
+ emit q->xdgPopupCreated(xdgPopup);
+}
+
+void QWaylandXdgShellV5Private::xdg_shell_pong(Resource *resource, uint32_t serial)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgShellV5);
+ if (m_pings.remove(serial))
+ emit q->pong(serial);
+ else
+ qWarning("Received an unexpected pong!");
+}
+
+QWaylandXdgSurfaceV5Private::QWaylandXdgSurfaceV5Private()
+ : QWaylandCompositorExtensionPrivate()
+ , xdg_surface()
+ , m_surface(nullptr)
+ , m_parentSurface(nullptr)
+ , m_windowType(UnknownWindowType)
+ , m_unsetWindowGeometry(true)
+ , m_lastAckedConfigure({{}, QSize(0, 0), 0})
+{
+}
+
+void QWaylandXdgSurfaceV5Private::handleFocusLost()
+{
+ Q_Q(QWaylandXdgSurfaceV5);
+ QWaylandXdgSurfaceV5Private::ConfigureEvent current = lastSentConfigure();
+ current.states.removeOne(QWaylandXdgSurfaceV5::State::ActivatedState);
+ q->sendConfigure(current.size, current.states);
+}
+
+void QWaylandXdgSurfaceV5Private::handleFocusReceived()
+{
+ Q_Q(QWaylandXdgSurfaceV5);
+
+ QWaylandXdgSurfaceV5Private::ConfigureEvent current = lastSentConfigure();
+ if (!current.states.contains(QWaylandXdgSurfaceV5::State::ActivatedState)) {
+ current.states.push_back(QWaylandXdgSurfaceV5::State::ActivatedState);
+ }
+
+ q->sendConfigure(current.size, current.states);
+}
+
+QRect QWaylandXdgSurfaceV5Private::calculateFallbackWindowGeometry() const
+{
+ // TODO: The unset window geometry should include subsurfaces as well, so this solution
+ // won't work too well on those kinds of clients.
+ return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale());
+}
+
+void QWaylandXdgSurfaceV5Private::updateFallbackWindowGeometry()
+{
+ Q_Q(QWaylandXdgSurfaceV5);
+ if (!m_unsetWindowGeometry)
+ return;
+
+ const QRect unsetGeometry = calculateFallbackWindowGeometry();
+ if (unsetGeometry == m_windowGeometry)
+ return;
+
+ m_windowGeometry = unsetGeometry;
+ emit q->windowGeometryChanged();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_destroy_resource(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ QWaylandXdgShellV5Private::get(m_xdgShell)->unregisterXdgSurface(q);
+ delete q;
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_destroy(Resource *resource)
+{
+ wl_resource_destroy(resource->handle);
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_move(Resource *resource, wl_resource *seat, uint32_t serial)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+
+ Q_Q(QWaylandXdgSurfaceV5);
+ QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat);
+ emit q->startMove(input_device);
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_resize(Resource *resource, wl_resource *seat,
+ uint32_t serial, uint32_t edges)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+
+ Q_Q(QWaylandXdgSurfaceV5);
+ QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat);
+ emit q->startResize(input_device, QWaylandXdgSurfaceV5::ResizeEdge(edges));
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_maximized(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ emit q->setMaximized();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_unset_maximized(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ emit q->unsetMaximized();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_fullscreen(Resource *resource, wl_resource *output_res)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ QWaylandOutput *output = output_res ? QWaylandOutput::fromResource(output_res) : nullptr;
+ emit q->setFullscreen(output);
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_unset_fullscreen(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ emit q->unsetFullscreen();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_minimized(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ emit q->setMinimized();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_parent(Resource *resource, wl_resource *parent)
+{
+ Q_UNUSED(resource);
+ QWaylandXdgSurfaceV5 *parentSurface = nullptr;
+ if (parent) {
+ parentSurface = static_cast<QWaylandXdgSurfaceV5Private *>(
+ QWaylandXdgSurfaceV5Private::Resource::fromResource(parent)->xdg_surface_object)->q_func();
+ }
+
+ Q_Q(QWaylandXdgSurfaceV5);
+
+ if (m_parentSurface != parentSurface) {
+ m_parentSurface = parentSurface;
+ emit q->parentSurfaceChanged();
+ }
+
+ if (m_parentSurface && m_windowType != TransientWindowType) {
+ // There's a parent now, which means the surface is transient
+ m_windowType = TransientWindowType;
+ emit q->setTransient();
+ } else if (!m_parentSurface && m_windowType != TopLevelWindowType) {
+ // When the surface has no parent it is toplevel
+ m_windowType = TopLevelWindowType;
+ emit q->setTopLevel();
+ }
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_app_id(Resource *resource, const QString &app_id)
+{
+ Q_UNUSED(resource);
+ if (app_id == m_appId)
+ return;
+ Q_Q(QWaylandXdgSurfaceV5);
+ m_appId = app_id;
+ emit q->appIdChanged();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_show_window_menu(Resource *resource, wl_resource *seatResource,
+ uint32_t serial, int32_t x, int32_t y)
+{
+ Q_UNUSED(resource);
+ Q_UNUSED(serial);
+ QPoint position(x, y);
+ auto seat = QWaylandSeat::fromSeatResource(seatResource);
+ Q_Q(QWaylandXdgSurfaceV5);
+ emit q->showWindowMenu(seat, position);
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_ack_configure(Resource *resource, uint32_t serial)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgSurfaceV5);
+
+ ConfigureEvent config;
+ Q_FOREVER {
+ if (m_pendingConfigures.empty()) {
+ qWarning("Received an unexpected ack_configure!");
+ return;
+ }
+
+ config = m_pendingConfigures.takeFirst();
+
+ if (config.serial == serial)
+ break;
+ }
+
+ QVector<uint> changedStates;
+ std::set_symmetric_difference(
+ m_lastAckedConfigure.states.begin(), m_lastAckedConfigure.states.end(),
+ config.states.begin(), config.states.end(),
+ std::back_inserter(changedStates));
+
+ m_lastAckedConfigure = config;
+
+ if (!changedStates.empty()) {
+ Q_FOREACH (uint state, changedStates) {
+ switch (state) {
+ case QWaylandXdgSurfaceV5::State::MaximizedState:
+ emit q->maximizedChanged();
+ break;
+ case QWaylandXdgSurfaceV5::State::FullscreenState:
+ emit q->fullscreenChanged();
+ break;
+ case QWaylandXdgSurfaceV5::State::ResizingState:
+ emit q->resizingChanged();
+ break;
+ case QWaylandXdgSurfaceV5::State::ActivatedState:
+ emit q->activatedChanged();
+ break;
+ }
+ }
+ emit q->statesChanged();
+ }
+
+ emit q->ackConfigure(serial);
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_title(Resource *resource, const QString &title)
+{
+ Q_UNUSED(resource);
+ if (title == m_title)
+ return;
+ Q_Q(QWaylandXdgSurfaceV5);
+ m_title = title;
+ emit q->titleChanged();
+}
+
+void QWaylandXdgSurfaceV5Private::xdg_surface_set_window_geometry(Resource *resource,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
+{
+ Q_UNUSED(resource);
+
+ if (width <= 0 || height <= 0) {
+ qWarning() << "Invalid (non-positive) dimensions received in set_window_geometry";
+ return;
+ }
+
+ m_unsetWindowGeometry = false;
+
+ QRect geometry(x, y, width, height);
+
+ Q_Q(QWaylandXdgSurfaceV5);
+ if ((q->maximized() || q->fullscreen()) && m_lastAckedConfigure.size != geometry.size())
+ qWarning() << "Client window geometry did not obey last acked configure";
+
+ if (geometry == m_windowGeometry)
+ return;
+
+ m_windowGeometry = geometry;
+ emit q->windowGeometryChanged();
+}
+
+QWaylandXdgPopupV5Private::QWaylandXdgPopupV5Private()
+ : QWaylandCompositorExtensionPrivate()
+ , xdg_popup()
+ , m_surface(nullptr)
+ , m_parentSurface(nullptr)
+ , m_xdgShell(nullptr)
+{
+}
+
+void QWaylandXdgPopupV5Private::xdg_popup_destroy_resource(Resource *resource)
+{
+ Q_UNUSED(resource);
+ Q_Q(QWaylandXdgPopupV5);
+ QWaylandXdgShellV5Private::get(m_xdgShell)->unregisterXdgPopup(q);
+ delete q;
+}
+
+void QWaylandXdgPopupV5Private::xdg_popup_destroy(Resource *resource)
+{
+ //TODO: post error if not topmost popup
+ wl_resource_destroy(resource->handle);
+}
+
+/*!
+ * Constructs a QWaylandXdgShellV5 object.
+ */
+QWaylandXdgShellV5::QWaylandXdgShellV5()
+ : QWaylandShellTemplate<QWaylandXdgShellV5>(*new QWaylandXdgShellV5Private())
+{ }
+
+/*!
+ * Constructs a QWaylandXdgShellV5 object for the provided \a compositor.
+ */
+QWaylandXdgShellV5::QWaylandXdgShellV5(QWaylandCompositor *compositor)
+ : QWaylandShellTemplate<QWaylandXdgShellV5>(compositor, *new QWaylandXdgShellV5Private())
+{ }
+
+/*!
+ * Initializes the shell extension.
+ */
+void QWaylandXdgShellV5::initialize()
+{
+ Q_D(QWaylandXdgShellV5);
+ QWaylandShellTemplate::initialize();
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ if (!compositor) {
+ qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgShellV5";
+ return;
+ }
+ d->init(compositor->display(), 1);
+
+ handleSeatChanged(compositor->defaultSeat(), nullptr);
+
+ connect(compositor, &QWaylandCompositor::defaultSeatChanged,
+ this, &QWaylandXdgShellV5::handleSeatChanged);
+}
+
+QWaylandClient *QWaylandXdgShellV5::popupClient() const
+{
+ Q_D(const QWaylandXdgShellV5);
+ Q_FOREACH (QWaylandXdgPopupV5 *popup, d->m_xdgPopups) {
+ if (popup->surface()->hasContent())
+ return popup->surface()->client();
+ }
+ return nullptr;
+}
+
+/*!
+ * Returns the Wayland interface for the QWaylandXdgShellV5.
+ */
+const struct wl_interface *QWaylandXdgShellV5::interface()
+{
+ return QWaylandXdgShellV5Private::interface();
+}
+
+QByteArray QWaylandXdgShellV5::interfaceName()
+{
+ return QWaylandXdgShellV5Private::interfaceName();
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::XdgSurface::ping()
+ *
+ * Sends a ping event to the client. If the client replies to the event the
+ * \a pong signal will be emitted.
+ */
+
+/*!
+ * Sends a ping event to the client. If the client replies to the event the
+ * \a pong signal will be emitted.
+ */
+uint QWaylandXdgShellV5::ping(QWaylandClient *client)
+{
+ Q_D(QWaylandXdgShellV5);
+
+ QWaylandCompositor *compositor = static_cast<QWaylandCompositor *>(extensionContainer());
+ Q_ASSERT(compositor);
+
+ uint32_t serial = compositor->nextSerial();
+
+ QWaylandXdgShellV5Private::Resource *clientResource = d->resourceMap().value(client->client(), nullptr);
+ Q_ASSERT(clientResource);
+
+ d->ping(clientResource, serial);
+ return serial;
+}
+
+void QWaylandXdgShellV5::closeAllPopups()
+{
+ Q_D(QWaylandXdgShellV5);
+ Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) {
+ QList<QWaylandXdgPopupV5 *> popups = d->m_xdgPopups.values(client);
+ std::reverse(popups.begin(), popups.end());
+ Q_FOREACH (QWaylandXdgPopupV5 *currentTopmostPopup, popups) {
+ currentTopmostPopup->sendPopupDone();
+ }
+ }
+}
+
+void QWaylandXdgShellV5::handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat)
+{
+ if (oldSeat != nullptr) {
+ disconnect(oldSeat, &QWaylandSeat::keyboardFocusChanged,
+ this, &QWaylandXdgShellV5::handleFocusChanged);
+ }
+
+ if (newSeat != nullptr) {
+ connect(newSeat, &QWaylandSeat::keyboardFocusChanged,
+ this, &QWaylandXdgShellV5::handleFocusChanged);
+ }
+}
+
+void QWaylandXdgShellV5::handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface)
+{
+ Q_D(QWaylandXdgShellV5);
+
+ QWaylandXdgSurfaceV5 *newXdgSurface = d->xdgSurfaceFromSurface(newSurface);
+ QWaylandXdgSurfaceV5 *oldXdgSurface = d->xdgSurfaceFromSurface(oldSurface);
+
+ if (newXdgSurface)
+ QWaylandXdgSurfaceV5Private::get(newXdgSurface)->handleFocusReceived();
+
+ if (oldXdgSurface)
+ QWaylandXdgSurfaceV5Private::get(oldXdgSurface)->handleFocusLost();
+}
+
+/*!
+ * \class QWaylandXdgSurfaceV5
+ * \inmodule QtWaylandCompositor
+ * \since 5.8
+ * \brief The QWaylandXdgSurfaceV5 class provides desktop-style compositor-specific features to an xdg surface.
+ *
+ * This class is part of the QWaylandXdgShellV5 extension and provides a way to
+ * extend the functionality of an existing QWaylandSurface with features
+ * specific to desktop-style compositors, such as resizing and moving the
+ * surface.
+ *
+ * It corresponds to the Wayland interface xdg_surface.
+ */
+
+/*!
+ * \qmlsignal QtWaylandCompositor::XdgSurface::setTopLevel()
+ *
+ * This signal is emitted when the parent surface is unset, effectively
+ * making the window top level.
+ */
+
+/*!
+ * \qmlsignal QtWaylandCompositor::XdgSurface::setTransient()
+ *
+ * This signal is emitted when the parent surface is set, effectively
+ * making the window transient.
+ */
+
+/*!
+ * Constructs a QWaylandXdgSurfaceV5.
+ */
+QWaylandXdgSurfaceV5::QWaylandXdgSurfaceV5()
+ : QWaylandShellSurfaceTemplate<QWaylandXdgSurfaceV5>(*new QWaylandXdgSurfaceV5Private)
+{
+}
+
+/*!
+ * Constructs a QWaylandXdgSurfaceV5 for \a surface and initializes it with the
+ * given \a xdgShell, \a surface, and resource \a res.
+ */
+QWaylandXdgSurfaceV5::QWaylandXdgSurfaceV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, const QWaylandResource &res)
+ : QWaylandShellSurfaceTemplate<QWaylandXdgSurfaceV5>(*new QWaylandXdgSurfaceV5Private)
+{
+ initialize(xdgShell, surface, res);
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::XdgSurface::initialize(object surface, object client, int id)
+ *
+ * Initializes the XdgSurface, associating it with the given \a surface,
+ * \a client, and \a id.
+ */
+
+/*!
+ * Initializes the QWaylandXdgSurfaceV5, associating it with the given \a xdgShell, \a surface
+ * and \a resource.
+ */
+void QWaylandXdgSurfaceV5::initialize(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, const QWaylandResource &resource)
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ d->m_xdgShell = xdgShell;
+ d->m_surface = surface;
+ d->init(resource.resource());
+ setExtensionContainer(surface);
+ d->m_windowGeometry = d->calculateFallbackWindowGeometry();
+ connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurfaceV5::handleSurfaceSizeChanged);
+ connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurfaceV5::handleBufferScaleChanged);
+ emit shellChanged();
+ emit surfaceChanged();
+ emit windowGeometryChanged();
+ QWaylandCompositorExtension::initialize();
+}
+
+/*!
+ * \internal
+ */
+void QWaylandXdgSurfaceV5::initialize()
+{
+ QWaylandCompositorExtension::initialize();
+}
+
+QList<int> QWaylandXdgSurfaceV5::statesAsInts() const
+{
+ QList<int> list;
+ Q_FOREACH (uint state, states()) {
+ list << static_cast<int>(state);
+ }
+ return list;
+}
+
+void QWaylandXdgSurfaceV5::handleSurfaceSizeChanged()
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ d->updateFallbackWindowGeometry();
+}
+
+void QWaylandXdgSurfaceV5::handleBufferScaleChanged()
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ d->updateFallbackWindowGeometry();
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgSurface::shell
+ *
+ * This property holds the shell associated with this XdgSurface.
+ */
+
+/*!
+ * \property QWaylandXdgSurfaceV5::shell
+ *
+ * This property holds the shell associated with this QWaylandXdgSurfaceV5.
+ */
+QWaylandXdgShellV5 *QWaylandXdgSurfaceV5::shell() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_xdgShell;
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgSurface::surface
+ *
+ * This property holds the surface associated with this XdgSurface.
+ */
+
+/*!
+ * \property QWaylandXdgSurfaceV5::surface
+ *
+ * This property holds the surface associated with this QWaylandXdgSurfaceV5.
+ */
+QWaylandSurface *QWaylandXdgSurfaceV5::surface() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_surface;
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface
+ *
+ * This property holds the XdgSurface parent of this XdgSurface.
+ * When a parent surface is set, the parentSurfaceChanged() signal
+ * is guaranteed to be emitted before setTopLevel() and setTransient().
+ *
+ * \sa QtWaylandCompositor::XdgSurface::setTopLevel()
+ * \sa QtWaylandCompositor::XdgSurface::setTransient()
+ */
+
+/*!
+ * \property QWaylandXdgSurfaceV5::parentSurface
+ *
+ * This property holds the XdgSurface parent of this XdgSurface.
+ * When a parent surface is set, the parentSurfaceChanged() signal
+ * is guaranteed to be emitted before setTopLevel() and setTransient().
+ *
+ * \sa QWaylandXdgSurfaceV5::setTopLevel()
+ * \sa QWaylandXdgSurfaceV5::setTransient()
+ */
+QWaylandXdgSurfaceV5 *QWaylandXdgSurfaceV5::parentSurface() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_parentSurface;
+}
+
+/*!
+ * \qmlproperty string QtWaylandCompositor::XdgSurface::title
+ *
+ * This property holds the title of the XdgSurface.
+ */
+
+/*!
+ * \property QWaylandXdgSurfaceV5::title
+ *
+ * This property holds the title of the QWaylandXdgSurfaceV5.
+ */
+QString QWaylandXdgSurfaceV5::title() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_title;
+}
+
+/*!
+ * \property QWaylandXdgSurfaceV5::appId
+ *
+ * This property holds the app id of the QWaylandXdgSurfaceV5.
+ */
+QString QWaylandXdgSurfaceV5::appId() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_appId;
+}
+
+/*!
+ * \property QWaylandXdgSurfaceV5::windowGeometry
+ *
+ * This property holds the window geometry of the QWaylandXdgSurfaceV5. The window
+ * geometry describes the window's visible bounds from the user's perspective.
+ * The geometry includes title bars and borders if drawn by the client, but
+ * excludes drop shadows. It is meant to be used for aligning and tiling
+ * windows.
+ */
+QRect QWaylandXdgSurfaceV5::windowGeometry() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_windowGeometry;
+}
+
+/*!
+ * \property QWaylandXdgSurfaceV5::states
+ *
+ * This property holds the last states the client acknowledged for this QWaylandXdgSurfaceV5.
+ */
+QVector<uint> QWaylandXdgSurfaceV5::states() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_lastAckedConfigure.states;
+}
+
+bool QWaylandXdgSurfaceV5::maximized() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::MaximizedState);
+}
+
+bool QWaylandXdgSurfaceV5::fullscreen() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::FullscreenState);
+}
+
+bool QWaylandXdgSurfaceV5::resizing() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::ResizingState);
+}
+
+bool QWaylandXdgSurfaceV5::activated() const
+{
+ Q_D(const QWaylandXdgSurfaceV5);
+ return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::ActivatedState);
+}
+
+/*!
+ * Returns the Wayland interface for the QWaylandXdgSurfaceV5.
+ */
+const wl_interface *QWaylandXdgSurfaceV5::interface()
+{
+ return QWaylandXdgSurfaceV5Private::interface();
+}
+
+QByteArray QWaylandXdgSurfaceV5::interfaceName()
+{
+ return QWaylandXdgSurfaceV5Private::interfaceName();
+}
+
+/*!
+ * Returns the surface role for the QWaylandXdgSurfaceV5.
+ */
+QWaylandSurfaceRole *QWaylandXdgSurfaceV5::role()
+{
+ return &QWaylandXdgSurfaceV5Private::s_role;
+}
+
+/*!
+ * Returns the QWaylandXdgSurfaceV5 corresponding to the \a resource.
+ */
+QWaylandXdgSurfaceV5 *QWaylandXdgSurfaceV5::fromResource(wl_resource *resource)
+{
+ auto xsResource = QWaylandXdgSurfaceV5Private::Resource::fromResource(resource);
+ if (!xsResource)
+ return nullptr;
+ return static_cast<QWaylandXdgSurfaceV5Private *>(xsResource->xdg_surface_object)->q_func();
+}
+
+QSize QWaylandXdgSurfaceV5::sizeForResize(const QSizeF &size, const QPointF &delta,
+ QWaylandXdgSurfaceV5::ResizeEdge edge)
+{
+ qreal width = size.width();
+ qreal height = size.height();
+ if (edge & LeftEdge)
+ width -= delta.x();
+ else if (edge & RightEdge)
+ width += delta.x();
+
+ if (edge & TopEdge)
+ height -= delta.y();
+ else if (edge & BottomEdge)
+ height += delta.y();
+
+ return QSizeF(width, height).toSize();
+}
+
+/*!
+ * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, list<uint> states)
+ *
+ * Sends a configure event to the client. \a size contains the pixel size of the surface.
+ * Known \a states are enumerated in XdgSurface::State.
+ */
+
+/*!
+ * Sends a configure event to the client. Parameter \a size contains the pixel size
+ * of the surface. Known \a states are enumerated in QWaylandXdgSurfaceV5::State.
+ */
+uint QWaylandXdgSurfaceV5::sendConfigure(const QSize &size, const QVector<uint> &states)
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ auto statesBytes = QByteArray::fromRawData((char *)states.data(), states.size() * sizeof(State));
+ QWaylandSurface *surface = qobject_cast<QWaylandSurface *>(extensionContainer());
+ Q_ASSERT(surface);
+ QWaylandCompositor *compositor = surface->compositor();
+ Q_ASSERT(compositor);
+ uint32_t serial = compositor->nextSerial();
+ d->m_pendingConfigures.append(QWaylandXdgSurfaceV5Private::ConfigureEvent{states, size, serial});
+ d->send_configure(size.width(), size.height(), statesBytes, serial);
+ return serial;
+}
+
+uint QWaylandXdgSurfaceV5::sendConfigure(const QSize &size, const QVector<QWaylandXdgSurfaceV5::State> &states)
+{
+ QVector<uint> asUints;
+ Q_FOREACH (QWaylandXdgSurfaceV5::State state, states) {
+ asUints << state;
+ }
+ return sendConfigure(size, asUints);
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::XdgSurface::sendClose()
+ *
+ * Sends a close event to the client.
+ */
+
+/*!
+ * Sends a close event to the client.
+ */
+void QWaylandXdgSurfaceV5::sendClose()
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ d->send_close();
+}
+
+uint QWaylandXdgSurfaceV5::sendMaximized(const QSize &size)
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure();
+
+ if (!conf.states.contains(QWaylandXdgSurfaceV5::State::MaximizedState))
+ conf.states.append(QWaylandXdgSurfaceV5::State::MaximizedState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::FullscreenState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::ResizingState);
+
+ return sendConfigure(size, conf.states);
+}
+
+uint QWaylandXdgSurfaceV5::sendUnmaximized(const QSize &size)
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure();
+
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::MaximizedState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::FullscreenState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::ResizingState);
+
+ return sendConfigure(size, conf.states);
+}
+
+uint QWaylandXdgSurfaceV5::sendFullscreen(const QSize &size)
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure();
+
+ if (!conf.states.contains(QWaylandXdgSurfaceV5::State::FullscreenState))
+ conf.states.append(QWaylandXdgSurfaceV5::State::FullscreenState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::MaximizedState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::ResizingState);
+
+ return sendConfigure(size, conf.states);
+}
+
+uint QWaylandXdgSurfaceV5::sendResizing(const QSize &maxSize)
+{
+ Q_D(QWaylandXdgSurfaceV5);
+ QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure();
+
+ if (!conf.states.contains(QWaylandXdgSurfaceV5::State::ResizingState))
+ conf.states.append(QWaylandXdgSurfaceV5::State::ResizingState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::MaximizedState);
+ conf.states.removeOne(QWaylandXdgSurfaceV5::State::FullscreenState);
+
+ return sendConfigure(maxSize, conf.states);
+}
+
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
+QWaylandQuickShellIntegration *QWaylandXdgSurfaceV5::createIntegration(QWaylandQuickShellSurfaceItem *item)
+{
+ return new QtWayland::XdgShellV5Integration(item);
+}
+#endif
+
+/*!
+ * \class QWaylandXdgPopupV5
+ * \inmodule QtWaylandCompositor
+ * \since 5.8
+ * \brief The QWaylandXdgPopupV5 class provides menus for an xdg surface
+ *
+ * This class is part of the QWaylandXdgShellV5 extension and provides a way to
+ * extend the functionality of an existing QWaylandSurface with features
+ * specific to desktop-style menus for an xdg surface.
+ *
+ * It corresponds to the Wayland interface xdg_popup.
+ */
+
+/*!
+ * Constructs a QWaylandXdgPopupV5.
+ */
+QWaylandXdgPopupV5::QWaylandXdgPopupV5()
+ : QWaylandShellSurfaceTemplate<QWaylandXdgPopupV5>(*new QWaylandXdgPopupV5Private)
+{
+}
+
+/*!
+ * Constructs a QWaylandXdgPopupV5, associating it with \a xdgShell at the specified \a position
+ * for \a surface and initializes it with the given \a parentSurface and \a resource.
+ */
+QWaylandXdgPopupV5::QWaylandXdgPopupV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface,
+ QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource)
+ : QWaylandShellSurfaceTemplate<QWaylandXdgPopupV5>(*new QWaylandXdgPopupV5Private)
+{
+ initialize(xdgShell, surface, parentSurface, position, resource);
+}
+
+/*!
+ * \qmlmethod void QtWaylandCompositor::XdgPopup::initialize(object surface, object parentSurface, object resource)
+ *
+ * Initializes the xdg popup, associating it with the given \a shell, \a surface,
+ * \a parentSurface and \a resource.
+ */
+
+/*!
+ * Initializes the QWaylandXdgPopupV5, associating it with the given \a shell \a surface,
+ * \a parentSurface and \a resource.
+ */
+void QWaylandXdgPopupV5::initialize(QWaylandXdgShellV5 *shell, QWaylandSurface *surface, QWaylandSurface *parentSurface,
+ const QPoint& position, const QWaylandResource &resource)
+{
+ Q_D(QWaylandXdgPopupV5);
+ d->m_surface = surface;
+ d->m_parentSurface = parentSurface;
+ d->m_xdgShell = shell;
+ d->m_position = position;
+ d->init(resource.resource());
+ setExtensionContainer(surface);
+ emit shellChanged();
+ emit surfaceChanged();
+ emit parentSurfaceChanged();
+ QWaylandCompositorExtension::initialize();
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgPopup::shell
+ *
+ * This property holds the shell associated with this XdgPopup.
+ */
+
+/*!
+ * \property QWaylandXdgPopupV5::shell
+ *
+ * This property holds the shell associated with this QWaylandXdgPopupV5.
+ */
+QWaylandXdgShellV5 *QWaylandXdgPopupV5::shell() const
+{
+ Q_D(const QWaylandXdgPopupV5);
+ return d->m_xdgShell;
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgPopup::surface
+ *
+ * This property holds the surface associated with this XdgPopup.
+ */
+
+/*!
+ * \property QWaylandXdgPopupV5::surface
+ *
+ * This property holds the surface associated with this QWaylandXdgPopupV5.
+ */
+QWaylandSurface *QWaylandXdgPopupV5::surface() const
+{
+ Q_D(const QWaylandXdgPopupV5);
+ return d->m_surface;
+}
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgPopup::parentSurface
+ *
+ * This property holds the surface associated with the parent of this XdgPopup.
+ */
+
+/*!
+ * \property QWaylandXdgPopupV5::parentSurface
+ *
+ * This property holds the surface associated with the parent of this
+ * QWaylandXdgPopupV5.
+ */
+QWaylandSurface *QWaylandXdgPopupV5::parentSurface() const
+{
+ Q_D(const QWaylandXdgPopupV5);
+ return d->m_parentSurface;
+}
+
+
+/*!
+ * \qmlproperty object QtWaylandCompositor::XdgPopup::position
+ *
+ * This property holds the location of the upper left corner of the surface
+ * relative to the upper left corner of the parent surface, in surface local
+ * coordinates.
+ */
+
+/*!
+ * \property QWaylandXdgPopupV5::position
+ *
+ * This property holds the location of the upper left corner of the surface
+ * relative to the upper left corner of the parent surface, in surface local
+ * coordinates.
+ */
+QPoint QWaylandXdgPopupV5::position() const
+{
+ Q_D(const QWaylandXdgPopupV5);
+ return d->m_position;
+}
+
+/*!
+ * \internal
+ */
+void QWaylandXdgPopupV5::initialize()
+{
+ QWaylandCompositorExtension::initialize();
+}
+
+/*!
+ * Returns the Wayland interface for the QWaylandXdgPopupV5.
+ */
+const wl_interface *QWaylandXdgPopupV5::interface()
+{
+ return QWaylandXdgPopupV5Private::interface();
+}
+
+QByteArray QWaylandXdgPopupV5::interfaceName()
+{
+ return QWaylandXdgPopupV5Private::interfaceName();
+}
+
+/*!
+ * Returns the surface role for the QWaylandXdgPopupV5.
+ */
+QWaylandSurfaceRole *QWaylandXdgPopupV5::role()
+{
+ return &QWaylandXdgPopupV5Private::s_role;
+}
+
+QWaylandXdgPopupV5 *QWaylandXdgPopupV5::fromResource(wl_resource *resource)
+{
+ auto popupResource = QWaylandXdgPopupV5Private::Resource::fromResource(resource);
+ if (!popupResource)
+ return nullptr;
+ return static_cast<QWaylandXdgPopupV5Private *>(popupResource->xdg_popup_object)->q_func();
+}
+
+void QWaylandXdgPopupV5::sendPopupDone()
+{
+ Q_D(QWaylandXdgPopupV5);
+ d->send_popup_done();
+}
+
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
+QWaylandQuickShellIntegration *QWaylandXdgPopupV5::createIntegration(QWaylandQuickShellSurfaceItem *item)
+{
+ return new QtWayland::XdgPopupV5Integration(item);
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshellv5.h
index c11ca1f3a..bcc740c7d 100644
--- a/src/compositor/extensions/qwaylandxdgshell.h
+++ b/src/compositor/extensions/qwaylandxdgshellv5.h
@@ -34,11 +34,12 @@
**
****************************************************************************/
-#ifndef QWAYLANDXDGSHELL_H
-#define QWAYLANDXDGSHELL_H
+#ifndef QWAYLANDXDGSHELLV5_H
+#define QWAYLANDXDGSHELLV5_H
#include <QtWaylandCompositor/QWaylandCompositorExtension>
#include <QtWaylandCompositor/QWaylandResource>
+#include <QtWaylandCompositor/QWaylandShell>
#include <QtWaylandCompositor/QWaylandShellSurface>
#include <QtCore/QRect>
@@ -47,27 +48,28 @@ struct wl_resource;
QT_BEGIN_NAMESPACE
-class QWaylandXdgShellPrivate;
-class QWaylandXdgSurface;
-class QWaylandXdgSurfacePrivate;
-class QWaylandXdgPopup;
-class QWaylandXdgPopupPrivate;
+class QWaylandXdgShellV5Private;
+class QWaylandXdgSurfaceV5;
+class QWaylandXdgSurfaceV5Private;
+class QWaylandXdgPopupV5;
+class QWaylandXdgPopupV5Private;
class QWaylandSurface;
class QWaylandSurfaceRole;
-class QWaylandInputDevice;
+class QWaylandSeat;
class QWaylandOutput;
class QWaylandClient;
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShell : public QWaylandCompositorExtensionTemplate<QWaylandXdgShell>
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellV5 : public QWaylandShellTemplate<QWaylandXdgShellV5>
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QWaylandXdgShell)
+ Q_DECLARE_PRIVATE(QWaylandXdgShellV5)
public:
- QWaylandXdgShell();
- QWaylandXdgShell(QWaylandCompositor *compositor);
+ QWaylandXdgShellV5();
+ QWaylandXdgShellV5(QWaylandCompositor *compositor);
void initialize() Q_DECL_OVERRIDE;
+ QWaylandClient *popupClient() const;
static const struct wl_interface *interface();
static QByteArray interfaceName();
@@ -77,24 +79,25 @@ public Q_SLOTS:
void closeAllPopups();
Q_SIGNALS:
- void createXdgSurface(QWaylandSurface *surface, const QWaylandResource &resource);
- void xdgSurfaceCreated(QWaylandXdgSurface *xdgSurface);
- void xdgPopupCreated(QWaylandXdgPopup *xdgPopup);
- void createXdgPopup(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandInputDevice *seat, const QPoint &position, const QWaylandResource &resource);
+ void xdgSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource);
+ void xdgSurfaceCreated(QWaylandXdgSurfaceV5 *xdgSurface);
+ void xdgPopupCreated(QWaylandXdgPopupV5 *xdgPopup);
+ void xdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandSeat *seat, const QPoint &position, const QWaylandResource &resource);
void pong(uint serial);
private Q_SLOTS:
- void handleDefaultInputDeviceChanged(QWaylandInputDevice *newDevice, QWaylandInputDevice *oldDevice);
+ void handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat);
void handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface);
};
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurface : public QWaylandShellSurfaceTemplate<QWaylandXdgSurface>
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfaceV5 : public QWaylandShellSurfaceTemplate<QWaylandXdgSurfaceV5>
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QWaylandXdgSurface)
+ Q_DECLARE_PRIVATE(QWaylandXdgSurfaceV5)
+ Q_PROPERTY(QWaylandXdgShellV5 *shell READ shell NOTIFY shellChanged)
Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged)
- Q_PROPERTY(QWaylandXdgSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged)
+ Q_PROPERTY(QWaylandXdgSurfaceV5 *parentSurface READ parentSurface NOTIFY parentSurfaceChanged)
Q_PROPERTY(QString title READ title NOTIFY titleChanged)
Q_PROPERTY(QString appId READ appId NOTIFY appIdChanged)
Q_PROPERTY(QRect windowGeometry READ windowGeometry NOTIFY windowGeometryChanged)
@@ -127,10 +130,10 @@ public:
};
Q_ENUM(ResizeEdge)
- QWaylandXdgSurface();
- QWaylandXdgSurface(QWaylandXdgShell* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource);
+ QWaylandXdgSurfaceV5();
+ QWaylandXdgSurfaceV5(QWaylandXdgShellV5* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource);
- Q_INVOKABLE void initialize(QWaylandXdgShell* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource);
+ Q_INVOKABLE void initialize(QWaylandXdgShellV5* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource);
QString title() const;
QString appId() const;
@@ -141,27 +144,32 @@ public:
bool resizing() const;
bool activated() const;
+ QWaylandXdgShellV5 *shell() const;
+
QWaylandSurface *surface() const;
- QWaylandXdgSurface *parentSurface() const;
+ QWaylandXdgSurfaceV5 *parentSurface() const;
static const struct wl_interface *interface();
static QByteArray interfaceName();
static QWaylandSurfaceRole *role();
- static QWaylandXdgSurface *fromResource(::wl_resource *resource);
+ static QWaylandXdgSurfaceV5 *fromResource(::wl_resource *resource);
Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edge);
Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector<uint> &states);
Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector<State> &states);
Q_INVOKABLE void sendClose();
- Q_INVOKABLE uint requestMaximized(const QSize &size);
- Q_INVOKABLE uint requestUnMaximized(const QSize &size = QSize(0, 0));
- Q_INVOKABLE uint requestFullscreen(const QSize &size);
- Q_INVOKABLE uint requestResizing(const QSize &maxSize);
+ Q_INVOKABLE uint sendMaximized(const QSize &size);
+ Q_INVOKABLE uint sendUnmaximized(const QSize &size = QSize(0, 0));
+ Q_INVOKABLE uint sendFullscreen(const QSize &size);
+ Q_INVOKABLE uint sendResizing(const QSize &maxSize);
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE;
+#endif
Q_SIGNALS:
+ void shellChanged();
void surfaceChanged();
void titleChanged();
void windowGeometryChanged();
@@ -174,9 +182,11 @@ Q_SIGNALS:
void resizingChanged();
void activatedChanged();
- void showWindowMenu(QWaylandInputDevice *inputDevice, const QPoint &localSurfacePosition);
- void startMove(QWaylandInputDevice *inputDevice);
- void startResize(QWaylandInputDevice *inputDevice, ResizeEdge edges);
+ void showWindowMenu(QWaylandSeat *seat, const QPoint &localSurfacePosition);
+ void startMove(QWaylandSeat *seat);
+ void startResize(QWaylandSeat *seat, ResizeEdge edges);
+ void setTopLevel();
+ void setTransient();
void setMaximized();
void unsetMaximized();
void setFullscreen(QWaylandOutput *output);
@@ -190,33 +200,47 @@ private:
private Q_SLOTS:
void handleSurfaceSizeChanged();
+ void handleBufferScaleChanged();
};
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandCompositorExtensionTemplate<QWaylandXdgPopup>
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupV5 : public QWaylandShellSurfaceTemplate<QWaylandXdgPopupV5>
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QWaylandXdgPopup)
+ Q_DECLARE_PRIVATE(QWaylandXdgPopupV5)
+ Q_PROPERTY(QWaylandXdgShellV5 *shell READ shell NOTIFY shellChanged)
Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged)
Q_PROPERTY(QWaylandSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged)
+ Q_PROPERTY(QPoint position READ position)
public:
- QWaylandXdgPopup();
- QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, const QWaylandResource &resource);
+ QWaylandXdgPopupV5();
+ QWaylandXdgPopupV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface,
+ const QPoint &position, const QWaylandResource &resource);
+
+ Qt::WindowType windowType() const override { return Qt::WindowType::Popup; }
+
+ Q_INVOKABLE void initialize(QWaylandXdgShellV5 *shell, QWaylandSurface *surface,
+ QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource);
- Q_INVOKABLE void initialize(QWaylandXdgShell *shell, QWaylandSurface *surface,
- QWaylandSurface *parentSurface, const QWaylandResource &resource);
+ QWaylandXdgShellV5 *shell() const;
QWaylandSurface *surface() const;
QWaylandSurface *parentSurface() const;
+ QPoint position() const;
static const struct wl_interface *interface();
static QByteArray interfaceName();
static QWaylandSurfaceRole *role();
- static QWaylandXdgPopup *fromResource(::wl_resource *resource);
+ static QWaylandXdgPopupV5 *fromResource(::wl_resource *resource);
Q_INVOKABLE void sendPopupDone();
+#ifdef QT_WAYLAND_COMPOSITOR_QUICK
+ QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE;
+#endif
+
Q_SIGNALS:
+ void shellChanged();
void surfaceChanged();
void parentSurfaceChanged();
diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshellv5_p.h
index 3165eb7ca..31aa2112c 100644
--- a/src/compositor/extensions/qwaylandxdgshell_p.h
+++ b/src/compositor/extensions/qwaylandxdgshellv5_p.h
@@ -34,13 +34,13 @@
**
****************************************************************************/
-#ifndef QWAYLANDXDGSHELL_P_H
-#define QWAYLANDXDGSHELL_P_H
+#ifndef QWAYLANDXDGSHELLV5_P_H
+#define QWAYLANDXDGSHELLV5_P_H
#include <QtWaylandCompositor/private/qwaylandcompositorextension_p.h>
#include <QtWaylandCompositor/private/qwayland-server-xdg-shell.h>
-#include <QtWaylandCompositor/QWaylandXdgShell>
+#include <QtWaylandCompositor/QWaylandXdgShellV5>
#include <QtCore/QSet>
@@ -57,47 +57,53 @@
QT_BEGIN_NAMESPACE
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellPrivate
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellV5Private
: public QWaylandCompositorExtensionPrivate
, public QtWaylandServer::xdg_shell
{
- Q_DECLARE_PUBLIC(QWaylandXdgShell)
+ Q_DECLARE_PUBLIC(QWaylandXdgShellV5)
public:
- QWaylandXdgShellPrivate();
+ QWaylandXdgShellV5Private();
void ping(Resource *resource, uint32_t serial);
- void registerSurface(QWaylandXdgSurface *xdgSurface);
- void unregisterXdgSurface(QWaylandXdgSurface *xdgSurface);
- void registerXdgPopup(QWaylandXdgPopup *xdgPopup);
- void unregisterXdgPopup(QWaylandXdgPopup *xdgPopup);
- static QWaylandXdgShellPrivate *get(QWaylandXdgShell *xdgShell) { return xdgShell->d_func(); }
+ void registerSurface(QWaylandXdgSurfaceV5 *xdgSurface);
+ void unregisterXdgSurface(QWaylandXdgSurfaceV5 *xdgSurface);
+ void registerXdgPopup(QWaylandXdgPopupV5 *xdgPopup);
+ void unregisterXdgPopup(QWaylandXdgPopupV5 *xdgPopup);
+ static QWaylandXdgShellV5Private *get(QWaylandXdgShellV5 *xdgShell) { return xdgShell->d_func(); }
bool isValidPopupParent(QWaylandSurface *parentSurface) const;
- QWaylandXdgPopup *topmostPopupForClient(struct wl_client* client) const;
+ QWaylandXdgPopupV5 *topmostPopupForClient(struct wl_client* client) const;
-private:
QSet<uint32_t> m_pings;
- QMultiMap<struct wl_client *, QWaylandXdgSurface *> m_xdgSurfaces;
- QMultiMap<struct wl_client *, QWaylandXdgPopup *> m_xdgPopups;
+ QMultiMap<struct wl_client *, QWaylandXdgSurfaceV5 *> m_xdgSurfaces;
+ QMultiMap<struct wl_client *, QWaylandXdgPopupV5 *> m_xdgPopups;
- QWaylandXdgSurface *xdgSurfaceFromSurface(QWaylandSurface *surface);
+ QWaylandXdgSurfaceV5 *xdgSurfaceFromSurface(QWaylandSurface *surface);
+protected:
void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE;
void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id,
struct ::wl_resource *surface) Q_DECL_OVERRIDE;
void xdg_shell_use_unstable_version(Resource *resource, int32_t version) Q_DECL_OVERRIDE;
void xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, struct ::wl_resource *surface,
- struct ::wl_resource *parent, struct ::wl_resource *seat,
+ struct ::wl_resource *parent, struct ::wl_resource *seatResource,
uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE;
void xdg_shell_pong(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE;
};
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfacePrivate
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfaceV5Private
: public QWaylandCompositorExtensionPrivate
, public QtWaylandServer::xdg_surface
{
- Q_DECLARE_PUBLIC(QWaylandXdgSurface)
+ Q_DECLARE_PUBLIC(QWaylandXdgSurfaceV5)
public:
- QWaylandXdgSurfacePrivate();
- static QWaylandXdgSurfacePrivate *get(QWaylandXdgSurface *xdgSurface) { return xdgSurface->d_func(); }
+ QWaylandXdgSurfaceV5Private();
+ static QWaylandXdgSurfaceV5Private *get(QWaylandXdgSurfaceV5 *xdgSurface) { return xdgSurface->d_func(); }
+
+ enum WindowType {
+ UnknownWindowType,
+ TopLevelWindowType,
+ TransientWindowType
+ };
struct ConfigureEvent {
QVector<uint> states;
@@ -107,11 +113,15 @@ public:
void handleFocusLost();
void handleFocusReceived();
+ QRect calculateFallbackWindowGeometry() const;
+ void updateFallbackWindowGeometry();
private:
- QWaylandXdgShell *m_xdgShell;
+ QWaylandXdgShellV5 *m_xdgShell;
QWaylandSurface *m_surface;
- QWaylandXdgSurface *m_parentSurface;
+ QWaylandXdgSurfaceV5 *m_parentSurface;
+
+ WindowType m_windowType;
QString m_title;
QString m_appId;
@@ -137,7 +147,7 @@ private:
void xdg_surface_set_minimized(Resource *resource) Q_DECL_OVERRIDE;
void xdg_surface_set_parent(Resource *resource, struct ::wl_resource *parent) Q_DECL_OVERRIDE;
void xdg_surface_set_app_id(Resource *resource, const QString &app_id) Q_DECL_OVERRIDE;
- void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seat,
+ void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seatResource,
uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE;
void xdg_surface_ack_configure(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE;
void xdg_surface_set_title(Resource *resource, const QString &title) Q_DECL_OVERRIDE;
@@ -147,20 +157,20 @@ private:
static QWaylandSurfaceRole s_role;
};
-class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupPrivate
+class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupV5Private
: public QWaylandCompositorExtensionPrivate
, public QtWaylandServer::xdg_popup
{
- Q_DECLARE_PUBLIC(QWaylandXdgPopup)
+ Q_DECLARE_PUBLIC(QWaylandXdgPopupV5)
public:
- QWaylandXdgPopupPrivate();
- static QWaylandXdgPopupPrivate *get(QWaylandXdgPopup *xdgPopup) { return xdgPopup->d_func(); }
+ QWaylandXdgPopupV5Private();
+ static QWaylandXdgPopupV5Private *get(QWaylandXdgPopupV5 *xdgPopup) { return xdgPopup->d_func(); }
-private:
QWaylandSurface *m_surface;
QWaylandSurface *m_parentSurface;
- QWaylandXdgShell *m_xdgShell;
+ QWaylandXdgShellV5 *m_xdgShell;
+ QPoint m_position;
void xdg_popup_destroy_resource(Resource *resource) Q_DECL_OVERRIDE;
void xdg_popup_destroy(xdg_popup::Resource *resource) Q_DECL_OVERRIDE;
diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp
new file mode 100644
index 000000000..b3170333f
--- /dev/null
+++ b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwaylandxdgshellv5integration_p.h"
+
+#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
+#include <QtWaylandCompositor/QWaylandCompositor>
+#include <QtWaylandCompositor/QWaylandSeat>
+#include <QtWaylandCompositor/private/qwaylandxdgshellv5_p.h>
+#include <QMouseEvent>
+#include <QGuiApplication>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+XdgShellV5Integration::XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item)
+ : QWaylandQuickShellIntegration(item)
+ , m_item(item)
+ , m_xdgSurface(qobject_cast<QWaylandXdgSurfaceV5 *>(item->shellSurface()))
+ , grabberState(GrabberState::Default)
+{
+ m_item->setSurface(m_xdgSurface->surface());
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::startMove, this, &XdgShellV5Integration::handleStartMove);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::startResize, this, &XdgShellV5Integration::handleStartResize);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::setTopLevel, this, &XdgShellV5Integration::handleSetTopLevel);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::setTransient, this, &XdgShellV5Integration::handleSetTransient);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::setMaximized, this, &XdgShellV5Integration::handleSetMaximized);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::unsetMaximized, this, &XdgShellV5Integration::handleUnsetMaximized);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::maximizedChanged, this, &XdgShellV5Integration::handleMaximizedChanged);
+ connect(m_xdgSurface, &QWaylandXdgSurfaceV5::activatedChanged, this, &XdgShellV5Integration::handleActivatedChanged);
+ connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellV5Integration::handleSurfaceSizeChanged);
+}
+
+bool XdgShellV5Integration::mouseMoveEvent(QMouseEvent *event)
+{
+ if (grabberState == GrabberState::Resize) {
+ Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event));
+ if (!resizeState.initialized) {
+ resizeState.initialMousePos = event->windowPos();
+ resizeState.initialized = true;
+ return true;
+ }
+ QPointF delta = m_item->mapToSurface(event->windowPos() - resizeState.initialMousePos);
+ QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges);
+ m_xdgSurface->sendResizing(newSize);
+ } else if (grabberState == GrabberState::Move) {
+ Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event));
+ QQuickItem *moveItem = m_item->moveItem();
+ if (!moveState.initialized) {
+ moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos());
+ moveState.initialized = true;
+ return true;
+ }
+ if (!moveItem->parentItem())
+ return true;
+ QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->windowPos());
+ moveItem->setPosition(parentPos - moveState.initialOffset);
+ }
+ return false;
+}
+
+bool XdgShellV5Integration::mouseReleaseEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+
+ if (grabberState == GrabberState::Resize) {
+ m_xdgSurface->sendUnmaximized();
+ grabberState = GrabberState::Default;
+ return true;
+ } else if (grabberState == GrabberState::Move) {
+ grabberState = GrabberState::Default;
+ return true;
+ }
+ return false;
+}
+
+void XdgShellV5Integration::handleStartMove(QWaylandSeat *seat)
+{
+ grabberState = GrabberState::Move;
+ moveState.seat = seat;
+ moveState.initialized = false;
+}
+
+void XdgShellV5Integration::handleStartResize(QWaylandSeat *seat, QWaylandXdgSurfaceV5::ResizeEdge edges)
+{
+ grabberState = GrabberState::Resize;
+ resizeState.seat = seat;
+ resizeState.resizeEdges = edges;
+ resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size();
+ resizeState.initialPosition = m_item->moveItem()->position();
+ resizeState.initialSurfaceSize = m_item->surface()->size();
+ resizeState.initialized = false;
+}
+
+void XdgShellV5Integration::handleSetTopLevel()
+{
+ if (m_xdgSurface->shell()->focusPolicy() == QWaylandShell::AutomaticFocus)
+ m_item->takeFocus();
+}
+
+void XdgShellV5Integration::handleSetTransient()
+{
+ if (m_xdgSurface->shell()->focusPolicy() == QWaylandShell::AutomaticFocus)
+ m_item->takeFocus();
+}
+
+void XdgShellV5Integration::handleSetMaximized()
+{
+ if (!m_item->view()->isPrimary())
+ return;
+
+ maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size();
+ maximizeState.initialPosition = m_item->moveItem()->position();
+
+ QWaylandOutput *output = m_item->view()->output();
+ m_xdgSurface->sendMaximized(output->availableGeometry().size() / output->scaleFactor());
+}
+
+void XdgShellV5Integration::handleUnsetMaximized()
+{
+ if (!m_item->view()->isPrimary())
+ return;
+
+ m_xdgSurface->sendUnmaximized(maximizeState.initialWindowSize);
+}
+
+void XdgShellV5Integration::handleMaximizedChanged()
+{
+ if (m_xdgSurface->maximized()) {
+ QWaylandOutput *output = m_item->view()->output();
+ m_item->moveItem()->setPosition(output->position() + output->availableGeometry().topLeft());
+ } else {
+ m_item->moveItem()->setPosition(maximizeState.initialPosition);
+ }
+}
+
+void XdgShellV5Integration::handleActivatedChanged()
+{
+ if (m_xdgSurface->activated())
+ m_item->raise();
+}
+
+void XdgShellV5Integration::handleSurfaceSizeChanged()
+{
+ if (grabberState == GrabberState::Resize) {
+ qreal x = resizeState.initialPosition.x();
+ qreal y = resizeState.initialPosition.y();
+ if (resizeState.resizeEdges & QWaylandXdgSurfaceV5::ResizeEdge::TopEdge)
+ y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height();
+
+ if (resizeState.resizeEdges & QWaylandXdgSurfaceV5::ResizeEdge::LeftEdge)
+ x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width();
+ m_item->moveItem()->setPosition(QPointF(x, y));
+ }
+}
+
+XdgPopupV5Integration::XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item)
+ : QWaylandQuickShellIntegration (item)
+ , m_xdgPopup(qobject_cast<QWaylandXdgPopupV5 *>(item->shellSurface()))
+ , m_xdgShell(QWaylandXdgPopupV5Private::get(m_xdgPopup)->m_xdgShell)
+{
+ item->setSurface(m_xdgPopup->surface());
+ item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor()));
+
+ QWaylandClient *client = m_xdgPopup->surface()->client();
+ QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); });
+
+ connect(m_xdgPopup, &QWaylandXdgPopupV5::destroyed, this, &XdgPopupV5Integration::handlePopupDestroyed);
+}
+
+void XdgPopupV5Integration::handlePopupDestroyed()
+{
+ QWaylandXdgShellV5Private *shellPrivate = QWaylandXdgShellV5Private::get(m_xdgShell);
+ auto popups = shellPrivate->m_xdgPopups;
+ if (popups.isEmpty())
+ QWaylandQuickShellEventFilter::cancelFilter();
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellv5integration_p.h
index df2fa8b8d..da4573c76 100644
--- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h
+++ b/src/compositor/extensions/qwaylandxdgshellv5integration_p.h
@@ -34,11 +34,11 @@
**
****************************************************************************/
-#ifndef QWAYLANDXDGSHELLINTEGRATION_H
-#define QWAYLANDXDGSHELLINTEGRATION_H
+#ifndef QWAYLANDXDGSHELLV5INTEGRATION_H
+#define QWAYLANDXDGSHELLV5INTEGRATION_H
#include <QtWaylandCompositor/private/qwaylandquickshellsurfaceitem_p.h>
-#include <QtWaylandCompositor/QWaylandXdgSurface>
+#include <QtWaylandCompositor/QWaylandXdgSurfaceV5>
QT_BEGIN_NAMESPACE
@@ -55,17 +55,19 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
-class XdgShellIntegration : public QWaylandQuickShellIntegration
+class XdgShellV5Integration : public QWaylandQuickShellIntegration
{
Q_OBJECT
public:
- XdgShellIntegration(QWaylandQuickShellSurfaceItem *item);
+ XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item);
bool mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
private Q_SLOTS:
- void handleStartMove(QWaylandInputDevice *inputDevice);
- void handleStartResize(QWaylandInputDevice *inputDevice, QWaylandXdgSurface::ResizeEdge edges);
+ void handleStartMove(QWaylandSeat *seat);
+ void handleStartResize(QWaylandSeat *seat, QWaylandXdgSurfaceV5::ResizeEdge edges);
+ void handleSetTopLevel();
+ void handleSetTransient();
void handleSetMaximized();
void handleUnsetMaximized();
void handleMaximizedChanged();
@@ -79,18 +81,18 @@ private:
Move
};
QWaylandQuickShellSurfaceItem *m_item;
- QWaylandXdgSurface *m_xdgSurface;
+ QWaylandXdgSurfaceV5 *m_xdgSurface;
GrabberState grabberState;
struct {
- QWaylandInputDevice *inputDevice;
+ QWaylandSeat *seat;
QPointF initialOffset;
bool initialized;
} moveState;
struct {
- QWaylandInputDevice *inputDevice;
- QWaylandXdgSurface::ResizeEdge resizeEdges;
+ QWaylandSeat *seat;
+ QWaylandXdgSurfaceV5::ResizeEdge resizeEdges;
QSizeF initialWindowSize;
QPointF initialMousePos;
QPointF initialPosition;
@@ -104,6 +106,20 @@ private:
} maximizeState;
};
+class XdgPopupV5Integration : public QWaylandQuickShellIntegration
+{
+ Q_OBJECT
+public:
+ XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item);
+
+private Q_SLOTS:
+ void handlePopupDestroyed();
+
+private:
+ QWaylandXdgPopupV5 *m_xdgPopup;
+ QWaylandXdgShellV5 *m_xdgShell;
+};
+
}
QT_END_NAMESPACE
diff --git a/src/compositor/extensions/qwlqtkey_p.h b/src/compositor/extensions/qwlqtkey_p.h
index 1b9c7391e..a4e67acfe 100644
--- a/src/compositor/extensions/qwlqtkey_p.h
+++ b/src/compositor/extensions/qwlqtkey_p.h
@@ -48,12 +48,12 @@
// We mean it.
//
-#include "wayland-util.h"
-
#include <QtWaylandCompositor/QWaylandCompositorExtensionTemplate>
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/private/qwayland-server-qtkey-extension.h>
+#include <wayland-util.h>
+
QT_BEGIN_NAMESPACE
class QWaylandSurface;
diff --git a/src/compositor/extensions/qwlqttouch.cpp b/src/compositor/extensions/qwlqttouch.cpp
index 17246b397..0d1120a4e 100644
--- a/src/compositor/extensions/qwlqttouch.cpp
+++ b/src/compositor/extensions/qwlqttouch.cpp
@@ -64,14 +64,14 @@ static inline int toFixed(qreal f)
return int(f * 10000);
}
-bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandView *view)
+bool TouchExtensionGlobal::postTouchEvent(QTouchEvent *event, QWaylandSurface *surface)
{
const QList<QTouchEvent::TouchPoint> points = event->touchPoints();
const int pointCount = points.count();
if (!pointCount)
return false;
- wl_client *surfaceClient = view->surface()->client()->client();
+ wl_client *surfaceClient = surface->client()->client();
uint32_t time = m_compositor->currentTimeMsecs();
const int rescount = m_resources.count();
diff --git a/src/compositor/extensions/qwlqttouch_p.h b/src/compositor/extensions/qwlqttouch_p.h
index 32d7658f0..f3697aa83 100644
--- a/src/compositor/extensions/qwlqttouch_p.h
+++ b/src/compositor/extensions/qwlqttouch_p.h
@@ -51,7 +51,8 @@
#include <QtWaylandCompositor/private/qwayland-server-touch-extension.h>
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/QWaylandCompositorExtensionTemplate>
-#include "wayland-util.h"
+
+#include <wayland-util.h>
QT_BEGIN_NAMESPACE
@@ -76,7 +77,7 @@ public:
TouchExtensionGlobal(QWaylandCompositor *compositor);
~TouchExtensionGlobal();
- bool postTouchEvent(QTouchEvent *event, QWaylandView *view);
+ bool postTouchEvent(QTouchEvent *event, QWaylandSurface *surface);
void setBehviorFlags(BehaviorFlags flags);
BehaviorFlags behaviorFlags() const { return m_flags; }
diff --git a/src/compositor/global/qwaylandcompositorextension.cpp b/src/compositor/global/qwaylandcompositorextension.cpp
index ddfd25837..6c7577ffc 100644
--- a/src/compositor/global/qwaylandcompositorextension.cpp
+++ b/src/compositor/global/qwaylandcompositorextension.cpp
@@ -96,6 +96,12 @@ void QWaylandCompositorExtension::initialize()
return;
}
+ if (!d->extension_container && parent()) {
+ QWaylandObject *parentObj = qobject_cast<QWaylandObject*>(parent());
+ if (parentObj)
+ setExtensionContainer(parentObj);
+ }
+
if (!d->extension_container) {
qWarning() << "QWaylandCompositorExtension:" << extensionInterface()->name << "requests to initialize with no extension container set";
return;
diff --git a/src/compositor/global/qwaylandcompositorextension.h b/src/compositor/global/qwaylandcompositorextension.h
index 0ba54c882..d666b4f2a 100644
--- a/src/compositor/global/qwaylandcompositorextension.h
+++ b/src/compositor/global/qwaylandcompositorextension.h
@@ -52,6 +52,7 @@ class QWaylandCompositorExtensionPrivate;
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandObject : public QObject
{
+ Q_OBJECT
public:
virtual ~QWaylandObject();
diff --git a/src/compositor/global/qwaylandcompositorextension_p.h b/src/compositor/global/qwaylandcompositorextension_p.h
index a9a670d66..d94896a57 100644
--- a/src/compositor/global/qwaylandcompositorextension_p.h
+++ b/src/compositor/global/qwaylandcompositorextension_p.h
@@ -48,9 +48,10 @@
// We mean it.
//
-#include "qwaylandcompositorextension.h"
#include <QtCore/private/qobject_p.h>
+#include <QtWaylandCompositor/QWaylandCompositorExtension>
+
QT_BEGIN_NAMESPACE
class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandCompositorExtensionPrivate : public QObjectPrivate
diff --git a/src/compositor/global/qwaylandquickextension.h b/src/compositor/global/qwaylandquickextension.h
index 32f4e6527..63c3d135e 100644
--- a/src/compositor/global/qwaylandquickextension.h
+++ b/src/compositor/global/qwaylandquickextension.h
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
Q_OBJECT \
Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \
Q_CLASSINFO("DefaultProperty", "data") \
+ Q_INTERFACES(QQmlParserStatus) \
public: \
QQmlListProperty<QObject> data() \
{ \
diff --git a/src/compositor/hardware_integration/hardware_integration.pri b/src/compositor/hardware_integration/hardware_integration.pri
index 2737a6f07..624190a6e 100644
--- a/src/compositor/hardware_integration/hardware_integration.pri
+++ b/src/compositor/hardware_integration/hardware_integration.pri
@@ -1,6 +1,4 @@
-isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
-
-!isEqual(QT_WAYLAND_GL_CONFIG,nogl) {
+contains(QT_CONFIG, opengl) {
CONFIG += wayland-scanner
WAYLANDSERVERSOURCES += \
../extensions/server-buffer-extension.xml \
@@ -24,7 +22,7 @@ isEmpty(QT_WAYLAND_GL_CONFIG):QT_WAYLAND_GL_CONFIG = $$(QT_WAYLAND_GL_CONFIG)
hardware_integration/qwlserverbufferintegrationplugin.cpp \
hardware_integration/qwlhwintegration.cpp \
- DEFINES += QT_COMPOSITOR_WAYLAND_GL
+ DEFINES += QT_WAYLAND_COMPOSITOR_GL
} else {
system(echo "Qt-Compositor configured as raster only compositor")
}
diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
index 90762437b..a7de2c0e3 100644
--- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
+++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h
@@ -57,6 +57,7 @@
QT_BEGIN_NAMESPACE
class QWaylandCompositor;
+class QOpenGLTexture;
namespace QtWayland {
class Display;
@@ -68,22 +69,11 @@ public:
virtual ~ClientBufferIntegration() { }
void setCompositor(QWaylandCompositor *compositor) { m_compositor = compositor; }
+ QWaylandCompositor *compositor() const { return m_compositor; }
virtual void initializeHardware(struct ::wl_display *display) = 0;
- virtual void initializeBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); }
- virtual QWaylandBufferRef::BufferFormatEgl bufferFormat(struct ::wl_resource *buffer) { Q_UNUSED(buffer); return QWaylandBufferRef::BufferFormatEgl_RGBA; }
- virtual uint textureForBuffer(struct ::wl_resource *buffer, int plane) { Q_UNUSED(buffer); Q_UNUSED(plane); return 0; }
-
- virtual void bindTextureToBuffer(struct ::wl_resource *buffer) = 0;
- virtual void updateTextureForBuffer(struct ::wl_resource *buffer) { Q_UNUSED(buffer); }
-
- virtual QWaylandSurface::Origin origin(struct ::wl_resource *) const { return QWaylandSurface::OriginBottomLeft; }
-
- virtual void *lockNativeBuffer(struct ::wl_resource *) const { return 0; }
- virtual void unlockNativeBuffer(void *) const { return; }
-
- virtual QSize bufferSize(struct ::wl_resource *) const { return QSize(); }
+ virtual ClientBuffer *createBufferFor(struct ::wl_resource *buffer) = 0;
protected:
QWaylandCompositor *m_compositor;
diff --git a/src/compositor/wayland_wrapper/qwlbuffermanager.cpp b/src/compositor/wayland_wrapper/qwlbuffermanager.cpp
new file mode 100644
index 000000000..765c9a03a
--- /dev/null
+++ b/src/compositor/wayland_wrapper/qwlbuffermanager.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwlbuffermanager_p.h"
+#include <QWaylandCompositor>
+#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
+#include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h>
+#include <QDebug>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+BufferManager::BufferManager(QWaylandCompositor *compositor)
+ : QObject(compositor)
+ , m_compositor(compositor)
+{
+
+}
+
+struct buffer_manager_destroy_listener : wl_listener
+{
+ buffer_manager_destroy_listener()
+ : d(0)
+ {
+ notify = BufferManager::destroy_listener_callback;
+ wl_list_init(&this->link);
+ }
+
+ BufferManager *d;
+};
+
+ClientBuffer *BufferManager::getBuffer(wl_resource *buffer_resource)
+{
+ if (!buffer_resource)
+ return nullptr;
+
+ auto it = m_buffers.find(buffer_resource);
+ if (it != m_buffers.end())
+ return it.value();
+
+ auto bufferIntegration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration();
+ ClientBuffer *newBuffer = nullptr;
+ if (bufferIntegration)
+ newBuffer = bufferIntegration->createBufferFor(buffer_resource);
+ if (!newBuffer)
+ newBuffer = new SharedMemoryBuffer(buffer_resource);
+ m_buffers[buffer_resource] = newBuffer;
+
+ auto *destroy_listener = new buffer_manager_destroy_listener;
+ destroy_listener->d = this;
+ wl_signal_add(&buffer_resource->destroy_signal, destroy_listener);
+ return newBuffer;
+}
+
+
+void BufferManager::destroy_listener_callback(wl_listener *listener, void *data)
+{
+ buffer_manager_destroy_listener *destroy_listener = static_cast<buffer_manager_destroy_listener *>(listener);
+ BufferManager *self = destroy_listener->d;
+ struct ::wl_resource *buffer = static_cast<struct ::wl_resource *>(data);
+
+ wl_list_remove(&destroy_listener->link);
+ delete destroy_listener;
+
+ Q_ASSERT(self);
+ Q_ASSERT(buffer);
+
+ ClientBuffer *clientBuffer = self->m_buffers.take(buffer);
+
+ if (!clientBuffer)
+ return;
+
+ clientBuffer->setDestroyed();
+}
+
+}
+QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlbuffermanager_p.h b/src/compositor/wayland_wrapper/qwlbuffermanager_p.h
new file mode 100644
index 000000000..e1325ef89
--- /dev/null
+++ b/src/compositor/wayland_wrapper/qwlbuffermanager_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QWLBUFFERMANAGER_H
+#define QWLBUFFERMANAGER_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/QObject>
+#include "qwlclientbuffer_p.h"
+QT_BEGIN_NAMESPACE
+
+class QWaylandCompositor;
+
+namespace QtWayland {
+
+class ClientBuffer;
+
+class Q_WAYLAND_COMPOSITOR_EXPORT BufferManager : public QObject
+{
+public:
+ BufferManager(QWaylandCompositor *compositor);
+ ClientBuffer *getBuffer(struct ::wl_resource *buffer_resource);
+private:
+ friend struct buffer_manager_destroy_listener;
+ static void destroy_listener_callback(wl_listener *listener, void *data);
+
+ QHash<struct ::wl_resource *, ClientBuffer*> m_buffers;
+ QWaylandCompositor *m_compositor;
+};
+
+}
+QT_END_NAMESPACE
+
+#endif // QWLBUFFERMANAGER_H
diff --git a/src/compositor/wayland_wrapper/qwlclientbuffer.cpp b/src/compositor/wayland_wrapper/qwlclientbuffer.cpp
new file mode 100644
index 000000000..589ab825b
--- /dev/null
+++ b/src/compositor/wayland_wrapper/qwlclientbuffer.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL3$
+** 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.
+**
+** 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.LGPLv3 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.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 later as published by the Free
+** Software Foundation and appearing in the file LICENSE.GPL included in
+** the packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 2.0 requirements will be
+** met: http://www.gnu.org/licenses/gpl-2.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwlclientbuffer_p.h"
+
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+#include "hardware_integration/qwlclientbufferintegration_p.h"
+#include <qpa/qplatformopenglcontext.h>
+#include <QOpenGLTexture>
+#endif
+
+#include <QtCore/QDebug>
+
+#include <wayland-server-protocol.h>
+#include "qwaylandsharedmemoryformathelper_p.h"
+
+#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QtWayland {
+
+ClientBuffer::ClientBuffer(struct ::wl_resource *buffer)
+ : m_buffer(buffer)
+ , m_textureDirty(false)
+ , m_committed(false)
+ , m_destroyed(false)
+{
+}
+
+
+ClientBuffer::~ClientBuffer()
+{
+ if (m_buffer && m_committed && !m_destroyed)
+ sendRelease();
+}
+
+void ClientBuffer::sendRelease()
+{
+ Q_ASSERT(m_buffer);
+ wl_buffer_send_release(m_buffer);
+ m_committed = false;
+}
+
+void ClientBuffer::setDestroyed()
+{
+ m_destroyed = true;
+ m_committed = false;
+ m_buffer = nullptr;
+
+ if (!m_refCount)
+ delete this;
+}
+
+void ClientBuffer::ref()
+{
+ m_refCount.ref();
+}
+
+void ClientBuffer::deref()
+{
+ if (!m_refCount.deref()) {
+ if (isCommitted() && m_buffer && !m_destroyed)
+ sendRelease();
+ if (m_destroyed)
+ delete this;
+ }
+}
+
+void ClientBuffer::setCommitted(QRegion &damage)
+{
+ m_damage = damage;
+ m_committed = true;
+ m_textureDirty = true;
+}
+
+QWaylandBufferRef::BufferFormatEgl ClientBuffer::bufferFormatEgl() const
+{
+ return QWaylandBufferRef::BufferFormatEgl_Null;
+}
+
+SharedMemoryBuffer::SharedMemoryBuffer(wl_resource *bufferResource)
+ : ClientBuffer(bufferResource)
+ , m_shmTexture(nullptr)
+{
+
+}
+
+QSize SharedMemoryBuffer::size() const
+{
+ if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
+ int width = wl_shm_buffer_get_width(shmBuffer);
+ int height = wl_shm_buffer_get_height(shmBuffer);
+ return QSize(width, height);
+ }
+ return QSize();
+}
+
+QWaylandSurface::Origin SharedMemoryBuffer::origin() const
+{
+ return QWaylandSurface::OriginTopLeft;
+}
+
+
+// TODO: support different color formats, and try to avoid QImage::convertToFormat()
+
+QImage SharedMemoryBuffer::image() const
+{
+ if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
+ int width = wl_shm_buffer_get_width(shmBuffer);
+ int height = wl_shm_buffer_get_height(shmBuffer);
+ int bytesPerLine = wl_shm_buffer_get_stride(shmBuffer);
+ uchar *data = static_cast<uchar *>(wl_shm_buffer_get_data(shmBuffer));
+ return QImage(data, width, height, bytesPerLine, QImage::Format_ARGB32_Premultiplied);
+ }
+
+ return QImage();
+}
+
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+QOpenGLTexture *SharedMemoryBuffer::toOpenGlTexture(int plane)
+{
+ Q_UNUSED(plane);
+ if (isSharedMemory()) {
+ if (!m_shmTexture) {
+ m_shmTexture = new QOpenGLTexture(QOpenGLTexture::Target2D);
+ m_shmTexture->create();
+ }
+ if (m_textureDirty) {
+ m_textureDirty = false;
+ m_shmTexture->bind();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ // TODO: partial texture upload
+ QImage image = this->image();
+ if (image.hasAlphaChannel()) {
+ if (image.format() != QImage::Format_RGBA8888)
+ image = image.convertToFormat(QImage::Format_RGBA8888);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
+ } else {
+ if (image.format() != QImage::Format_RGBX8888)
+ image = image.convertToFormat(QImage::Format_RGBX8888);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
+ }
+ //we can release the buffer after uploading, since we have a copy
+ if (isCommitted())
+ sendRelease();
+ }
+ return m_shmTexture;
+ }
+ return nullptr;
+}
+#endif
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h b/src/compositor/wayland_wrapper/qwlclientbuffer_p.h
index 95e7e8158..78e07ee98 100644
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer_p.h
+++ b/src/compositor/wayland_wrapper/qwlclientbuffer_p.h
@@ -34,8 +34,8 @@
**
****************************************************************************/
-#ifndef SURFACEBUFFER_H
-#define SURFACEBUFFER_H
+#ifndef QWLCLIENTBUFFER_P_H
+#define QWLCLIENTBUFFER_P_H
//
// W A R N I N G
@@ -63,81 +63,85 @@ QT_BEGIN_NAMESPACE
class QWaylandClientBufferIntegration;
class QWaylandBufferRef;
class QWaylandCompositor;
+class QOpenGLTexture;
namespace QtWayland {
struct surface_buffer_destroy_listener
{
struct wl_listener listener;
- class SurfaceBuffer *surfaceBuffer;
+ class ClientBuffer *surfaceBuffer;
};
-class SurfaceBuffer
+class Q_WAYLAND_COMPOSITOR_EXPORT ClientBuffer
{
public:
- SurfaceBuffer(QWaylandSurface *surface);
+ ClientBuffer(struct ::wl_resource *bufferResource);
- ~SurfaceBuffer();
+ virtual ~ClientBuffer();
- void initialize(struct ::wl_resource *bufferResource);
- void destructBufferState();
+ virtual QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const;
+ virtual QSize size() const = 0;
+ virtual QWaylandSurface::Origin origin() const = 0;
- inline bool isRegisteredWithBuffer() const { return m_is_registered_for_buffer; }
+ virtual quintptr lockNativeBuffer() { return 0; }
+ virtual void unlockNativeBuffer(quintptr native_buffer) const { Q_UNUSED(native_buffer); }
- void sendRelease();
- void disown();
-
- void setDisplayed();
+ virtual QImage image() const { return QImage(); }
inline bool isCommitted() const { return m_committed; }
- inline void setCommitted() { m_committed = true; }
- inline bool isDisplayed() const { return m_is_displayed; }
-
+ virtual void setCommitted(QRegion &damage);
bool isDestroyed() { return m_destroyed; }
inline struct ::wl_resource *waylandBufferHandle() const { return m_buffer; }
- void setDestroyIfUnused(bool destroy);
+ bool isSharedMemory() const { return wl_shm_buffer_get(m_buffer); }
- QSize size() const;
- QWaylandSurface::Origin origin() const;
- bool isShm() const { return wl_shm_buffer_get(m_buffer); }
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+ virtual QOpenGLTexture *toOpenGlTexture(int plane = 0) = 0;
+#endif
- QImage image() const;
- QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const;
- void bindToTexture() const;
- uint textureForPlane(int plane) const;
- void updateTexture() const;
+ static bool hasContent(ClientBuffer *buffer) { return buffer && buffer->waylandBufferHandle(); }
- static bool hasContent(SurfaceBuffer *buffer) { return buffer && buffer->waylandBufferHandle(); }
-private:
+protected:
void ref();
void deref();
- void destroyIfUnused();
+ void sendRelease();
+ void setDestroyed();
- QWaylandSurface *m_surface;
- QWaylandCompositor *m_compositor;
struct ::wl_resource *m_buffer;
- int m_bufferScale;
- struct surface_buffer_destroy_listener m_destroy_listener;
+ QRegion m_damage;
+ bool m_textureDirty;
+
+private:
bool m_committed;
- bool m_is_registered_for_buffer;
- bool m_surface_has_buffer;
bool m_destroyed;
- bool m_is_displayed;
-
QAtomicInt m_refCount;
- bool m_used;
- bool m_destroyIfUnused;
-
- static void destroy_listener_callback(wl_listener *listener, void *data);
friend class ::QWaylandBufferRef;
+ friend class BufferManager;
+};
+
+class Q_WAYLAND_COMPOSITOR_EXPORT SharedMemoryBuffer : public ClientBuffer
+{
+public:
+ SharedMemoryBuffer(struct ::wl_resource *bufferResource);
+
+ QSize size() const Q_DECL_OVERRIDE;
+ QWaylandSurface::Origin origin() const Q_DECL_OVERRIDE;
+ QImage image() const;
+
+#ifdef QT_WAYLAND_COMPOSITOR_GL
+ QOpenGLTexture *toOpenGlTexture(int plane = 0) Q_DECL_OVERRIDE;
+
+private:
+ QOpenGLTexture *m_shmTexture;
+#endif
};
}
QT_END_NAMESPACE
-#endif // SURFACEBUFFER_H
+#endif // QWLCLIENTBUFFER_P_H
diff --git a/src/compositor/wayland_wrapper/qwldatadevice.cpp b/src/compositor/wayland_wrapper/qwldatadevice.cpp
index dea72bdcd..0d196b82e 100644
--- a/src/compositor/wayland_wrapper/qwldatadevice.cpp
+++ b/src/compositor/wayland_wrapper/qwldatadevice.cpp
@@ -45,7 +45,7 @@
#include "qwaylandview.h"
#include <QtWaylandCompositor/QWaylandClient>
#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
-#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/private/qwaylandseat_p.h>
#include <QtWaylandCompositor/private/qwaylandpointer_p.h>
#include <QtCore/QPointF>
@@ -55,16 +55,17 @@ QT_BEGIN_NAMESPACE
namespace QtWayland {
-DataDevice::DataDevice(QWaylandInputDevice *inputDevice)
+DataDevice::DataDevice(QWaylandSeat *seat)
: wl_data_device()
- , m_compositor(inputDevice->compositor())
- , m_inputDevice(inputDevice)
+ , m_compositor(seat->compositor())
+ , m_seat(seat)
, m_selectionSource(0)
, m_dragClient(0)
, m_dragDataSource(0)
, m_dragFocus(0)
, m_dragFocusResource(0)
, m_dragIcon(0)
+ , m_dragOrigin(nullptr)
{
}
@@ -123,6 +124,11 @@ QWaylandSurface *DataDevice::dragIcon() const
return m_dragIcon;
}
+QWaylandSurface *DataDevice::dragOrigin() const
+{
+ return m_dragOrigin;
+}
+
void DataDevice::sourceDestroyed(DataSource *source)
{
if (m_selectionSource == source)
@@ -148,6 +154,7 @@ void DataDevice::drop()
} else {
m_dragDataSource->cancel();
}
+ m_dragOrigin = nullptr;
setDragIcon(nullptr);
}
@@ -160,11 +167,13 @@ void DataDevice::data_device_start_drag(Resource *resource, struct ::wl_resource
{
m_dragClient = resource->client();
m_dragDataSource = source ? DataSource::fromResource(source) : 0;
+ m_dragOrigin = QWaylandSurface::fromResource(origin);
+ QWaylandDrag *drag = m_seat->drag();
setDragIcon(icon ? QWaylandSurface::fromResource(icon) : nullptr);
- Q_EMIT m_inputDevice->drag()->dragStarted();
+ Q_EMIT drag->dragStarted();
+ Q_EMIT m_dragOrigin->dragStarted(drag);
Q_UNUSED(serial);
- Q_UNUSED(origin);
//### need to verify that we have an implicit grab with this serial
}
@@ -182,7 +191,7 @@ void DataDevice::data_device_set_selection(Resource *, struct ::wl_resource *sou
if (m_selectionSource)
m_selectionSource->setDevice(this);
- QWaylandClient *focusClient = m_inputDevice->keyboard()->focusClient();
+ QWaylandClient *focusClient = m_seat->keyboard()->focusClient();
Resource *resource = focusClient ? resourceMap().value(focusClient->client()) : 0;
if (resource && m_selectionSource) {
@@ -198,7 +207,7 @@ void DataDevice::setDragIcon(QWaylandSurface *icon)
if (icon == m_dragIcon)
return;
m_dragIcon = icon;
- Q_EMIT m_inputDevice->drag()->iconChanged();
+ Q_EMIT m_seat->drag()->iconChanged();
}
}
diff --git a/src/compositor/wayland_wrapper/qwldatadevice_p.h b/src/compositor/wayland_wrapper/qwldatadevice_p.h
index 2127603a8..17591ae27 100644
--- a/src/compositor/wayland_wrapper/qwldatadevice_p.h
+++ b/src/compositor/wayland_wrapper/qwldatadevice_p.h
@@ -49,7 +49,7 @@
//
#include <QtWaylandCompositor/private/qwayland-server-wayland.h>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
QT_BEGIN_NAMESPACE
@@ -57,19 +57,20 @@ namespace QtWayland {
class Compositor;
class DataSource;
-class InputDevice;
+class Seat;
class Surface;
class DataDevice : public QtWaylandServer::wl_data_device
{
public:
- DataDevice(QWaylandInputDevice *inputDevice);
+ DataDevice(QWaylandSeat *seat);
void setFocus(QWaylandClient *client);
void setDragFocus(QWaylandSurface *focus, const QPointF &localPosition);
QWaylandSurface *dragIcon() const;
+ QWaylandSurface *dragOrigin() const;
void sourceDestroyed(DataSource *source);
@@ -85,7 +86,7 @@ private:
void setDragIcon(QWaylandSurface *icon);
QWaylandCompositor *m_compositor;
- QWaylandInputDevice *m_inputDevice;
+ QWaylandSeat *m_seat;
DataSource *m_selectionSource;
@@ -96,6 +97,7 @@ private:
Resource *m_dragFocusResource;
QWaylandSurface *m_dragIcon;
+ QWaylandSurface *m_dragOrigin;
};
}
diff --git a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
index 2f40b0e43..5fed6ef18 100644
--- a/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
+++ b/src/compositor/wayland_wrapper/qwldatadevicemanager.cpp
@@ -39,7 +39,7 @@
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
-#include <QtWaylandCompositor/private/qwaylandinput_p.h>
+#include <QtWaylandCompositor/private/qwaylandseat_p.h>
#include "qwldatadevice_p.h"
#include "qwldatasource_p.h"
#include "qwldataoffer_p.h"
@@ -199,11 +199,11 @@ void DataDeviceManager::overrideSelection(const QMimeData &mimeData)
m_compositorOwnsSelection = true;
- QWaylandInputDevice *dev = m_compositor->defaultInputDevice();
+ QWaylandSeat *dev = m_compositor->defaultSeat();
QWaylandSurface *focusSurface = dev->keyboardFocus();
if (focusSurface)
offerFromCompositorToClient(
- QWaylandInputDevicePrivate::get(dev)->dataDevice()->resourceMap().value(focusSurface->waylandClient())->handle);
+ QWaylandSeatPrivate::get(dev)->dataDevice()->resourceMap().value(focusSurface->waylandClient())->handle);
}
bool DataDeviceManager::offerFromCompositorToClient(wl_resource *clientDataDeviceResource)
@@ -243,8 +243,8 @@ void DataDeviceManager::data_device_manager_create_data_source(Resource *resourc
void DataDeviceManager::data_device_manager_get_data_device(Resource *resource, uint32_t id, struct ::wl_resource *seat)
{
- QWaylandInputDevice *input_device = QWaylandInputDevice::fromSeatResource(seat);
- QWaylandInputDevicePrivate::get(input_device)->clientRequestedDataDevice(this, resource->client(), id);
+ QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat);
+ QWaylandSeatPrivate::get(input_device)->clientRequestedDataDevice(this, resource->client(), id);
}
void DataDeviceManager::comp_accept(wl_client *, wl_resource *, uint32_t, const char *)
diff --git a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp b/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
deleted file mode 100644
index 240ce01bc..000000000
--- a/src/compositor/wayland_wrapper/qwlsurfacebuffer.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtWaylandCompositor module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL3$
-** 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.
-**
-** 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.LGPLv3 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.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 later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwlsurfacebuffer_p.h"
-
-#ifdef QT_COMPOSITOR_WAYLAND_GL
-#include "hardware_integration/qwlclientbufferintegration_p.h"
-#include <qpa/qplatformopenglcontext.h>
-#endif
-
-#include <QtCore/QDebug>
-
-#include <wayland-server-protocol.h>
-#include "qwaylandshmformathelper_p.h"
-
-#include <QtWaylandCompositor/private/qwaylandcompositor_p.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace QtWayland {
-
-SurfaceBuffer::SurfaceBuffer(QWaylandSurface *surface)
- : m_surface(surface)
- , m_compositor(surface->compositor())
- , m_buffer(0)
- , m_committed(false)
- , m_is_registered_for_buffer(false)
- , m_surface_has_buffer(false)
- , m_destroyed(false)
- , m_is_displayed(false)
- , m_used(false)
- , m_destroyIfUnused(false)
-{
-}
-
-SurfaceBuffer::~SurfaceBuffer()
-{
- if (m_is_registered_for_buffer)
- destructBufferState();
-}
-
-void SurfaceBuffer::initialize(struct ::wl_resource *buffer)
-{
- m_buffer = buffer;
- m_committed = false;
- m_is_registered_for_buffer = true;
- m_surface_has_buffer = true;
- m_is_displayed = false;
- m_destroyed = false;
- m_destroy_listener.surfaceBuffer = this;
- m_destroy_listener.listener.notify = destroy_listener_callback;
- if (buffer) {
- if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
- integration->initializeBuffer(buffer);
- wl_signal_add(&buffer->destroy_signal, &m_destroy_listener.listener);
- }
-}
-
-void SurfaceBuffer::destructBufferState()
-{
- if (m_buffer) {
- if (m_committed)
- sendRelease();
- wl_list_remove(&m_destroy_listener.listener.link);
- }
- m_buffer = 0;
- m_committed = false;
- m_is_registered_for_buffer = false;
- m_is_displayed = false;
-}
-
-void SurfaceBuffer::sendRelease()
-{
- Q_ASSERT(m_buffer);
- wl_buffer_send_release(m_buffer);
-}
-
-void SurfaceBuffer::disown()
-{
- m_surface_has_buffer = false;
- destructBufferState();
- destroyIfUnused();
-}
-
-void SurfaceBuffer::setDisplayed()
-{
- m_is_displayed = true;
-}
-
-void SurfaceBuffer::destroy_listener_callback(wl_listener *listener, void *data)
-{
- Q_UNUSED(data);
- struct surface_buffer_destroy_listener *destroy_listener =
- reinterpret_cast<struct surface_buffer_destroy_listener *>(listener);
- SurfaceBuffer *d = destroy_listener->surfaceBuffer;
-
- // Mark the buffer as destroyed and clear m_buffer right away to avoid
- // touching it before it is properly cleaned up.
- d->m_destroyed = true;
- d->m_buffer = 0;
-}
-
-void SurfaceBuffer::ref()
-{
- m_used = m_refCount.ref();
-}
-
-void SurfaceBuffer::deref()
-{
- m_used = m_refCount.deref();
- if (!m_used)
- disown();
-}
-
-void SurfaceBuffer::setDestroyIfUnused(bool destroy)
-{
- m_destroyIfUnused = destroy;
- destroyIfUnused();
-}
-
-void SurfaceBuffer::destroyIfUnused()
-{
- if (!m_used && m_destroyIfUnused)
- delete this;
-}
-
-QSize SurfaceBuffer::size() const
-{
- if (!m_buffer)
- return QSize();
-
- if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
- int width = wl_shm_buffer_get_width(shmBuffer);
- int height = wl_shm_buffer_get_height(shmBuffer);
- return QSize(width, height);
- }
- if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) {
- return integration->bufferSize(m_buffer);
- }
-
- return QSize();
-}
-
-QWaylandSurface::Origin SurfaceBuffer::origin() const
-{
- if (isShm()) {
- return QWaylandSurface::OriginTopLeft;
- }
-
- if (ClientBufferIntegration *integration = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) {
- return integration->origin(m_buffer);
- }
- return QWaylandSurface::OriginTopLeft;
-}
-
-QImage SurfaceBuffer::image() const
-{
- if (wl_shm_buffer *shmBuffer = wl_shm_buffer_get(m_buffer)) {
- int width = wl_shm_buffer_get_width(shmBuffer);
- int height = wl_shm_buffer_get_height(shmBuffer);
- int bytesPerLine = wl_shm_buffer_get_stride(shmBuffer);
- uchar *data = static_cast<uchar *>(wl_shm_buffer_get_data(shmBuffer));
- return QImage(data, width, height, bytesPerLine, QImage::Format_ARGB32_Premultiplied);
- }
-
- return QImage();
-}
-
-QWaylandBufferRef::BufferFormatEgl SurfaceBuffer::bufferFormatEgl() const
-{
- Q_ASSERT(isShm() == false);
-
- if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
- return clientInt->bufferFormat(m_buffer);
-
- return QWaylandBufferRef::BufferFormatEgl_Null;
-}
-
-void SurfaceBuffer::bindToTexture() const
-{
- Q_ASSERT(m_compositor);
- if (isShm()) {
- QImage image = this->image();
- if (image.hasAlphaChannel()) {
- if (image.format() != QImage::Format_RGBA8888) {
- image = image.convertToFormat(QImage::Format_RGBA8888);
- }
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constBits());
- } else {
- if (image.format() != QImage::Format_RGBX8888) {
- image = image.convertToFormat(QImage::Format_RGBX8888);
- }
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image.constBits());
- }
- } else {
- if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration()) {
- clientInt->bindTextureToBuffer(m_buffer);
- }
- }
-}
-
-uint SurfaceBuffer::textureForPlane(int plane) const
-{
- if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
- return clientInt->textureForBuffer(m_buffer, plane);
-
- return 0;
-}
-
-void SurfaceBuffer::updateTexture() const
-{
- if (QtWayland::ClientBufferIntegration *clientInt = QWaylandCompositorPrivate::get(m_compositor)->clientBufferIntegration())
- clientInt->updateTextureForBuffer(m_buffer);
-}
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri
index f338ddc05..fa5d76291 100644
--- a/src/compositor/wayland_wrapper/wayland_wrapper.pri
+++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri
@@ -3,21 +3,23 @@ WAYLANDSERVERSOURCES += \
../3rdparty/protocol/wayland.xml \
HEADERS += \
+ wayland_wrapper/qwlbuffermanager_p.h \
+ wayland_wrapper/qwlclientbuffer_p.h \
wayland_wrapper/qwldatadevice_p.h \
wayland_wrapper/qwldatadevicemanager_p.h \
wayland_wrapper/qwldataoffer_p.h \
wayland_wrapper/qwldatasource_p.h \
wayland_wrapper/qwlregion_p.h \
- wayland_wrapper/qwlsurfacebuffer_p.h \
../shared/qwaylandxkb_p.h \
SOURCES += \
+ wayland_wrapper/qwlbuffermanager.cpp \
+ wayland_wrapper/qwlclientbuffer.cpp \
wayland_wrapper/qwldatadevice.cpp \
wayland_wrapper/qwldatadevicemanager.cpp \
wayland_wrapper/qwldataoffer.cpp \
wayland_wrapper/qwldatasource.cpp \
wayland_wrapper/qwlregion.cpp \
- wayland_wrapper/qwlsurfacebuffer.cpp \
../shared/qwaylandxkb.cpp \
INCLUDEPATH += wayland_wrapper
diff --git a/src/extensions/windowmanager.xml b/src/extensions/qt-windowmanager.xml
index 3d3bbd7fe..86ddff72e 100644
--- a/src/extensions/windowmanager.xml
+++ b/src/extensions/qt-windowmanager.xml
@@ -1,4 +1,4 @@
-<protocol name="windowmanager">
+<protocol name="qt_windowmanager">
<copyright>
Copyright (C) 2015 The Qt Company Ltd.
diff --git a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp
index fe7e17e86..4d56d66e6 100644
--- a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp
+++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp
@@ -43,7 +43,7 @@
#include <QtWaylandClient/private/qwaylandscreen_p.h>
#include "qwaylandbrcmglcontext.h"
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
#include <QtGui/QWindow>
#include <qpa/qwindowsysteminterface.h>
diff --git a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp
index a14f6b024..f5480b0ed 100644
--- a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp
+++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmglcontext.cpp
@@ -43,7 +43,7 @@
#include <QtWaylandClient/private/qwaylandwindow_p.h>
#include "qwaylandbrcmeglwindow.h"
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
#include <qpa/qplatformopenglcontext.h>
#include <QtGui/QSurfaceFormat>
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h
index 024809ff6..233ce78bd 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h
@@ -46,6 +46,6 @@
#include <wayland-egl.h>
#define EGL_EGLEXT_PROTOTYPES
-#include <QtPlatformSupport/private/qt_egl_p.h>
+#include <QtEglSupport/private/qt_egl_p.h>
#endif // QWAYLANDEGLINCLUDE_H
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
index 417fc75bd..236218e7f 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
@@ -42,7 +42,7 @@
#include <QtWaylandClient/private/qwaylandscreen_p.h>
#include "qwaylandglcontext.h"
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
#include <QDebug>
#include <QtGui/QWindow>
diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
index 72e7b0e6a..f70c75a33 100644
--- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
+++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp
@@ -47,7 +47,7 @@
#include "qwaylandeglwindow.h"
#include <QDebug>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qopengltexturecache_p.h>
#include <QtGui/private/qguiapplication_p.h>
diff --git a/src/hardwareintegration/client/wayland-egl/wayland-egl.pri b/src/hardwareintegration/client/wayland-egl/wayland-egl.pri
index 520c1eb0f..276b7b54f 100644
--- a/src/hardwareintegration/client/wayland-egl/wayland-egl.pri
+++ b/src/hardwareintegration/client/wayland-egl/wayland-egl.pri
@@ -8,7 +8,7 @@ INCLUDEPATH += $$PWD
DEFINES += QT_EGL_WAYLAND
CONFIG += egl
-QT += platformsupport-private
+QT += egl_support-private
SOURCES += $$PWD/qwaylandeglclientbufferintegration.cpp \
$$PWD/qwaylandglcontext.cpp \
diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp
index 5fca5610a..2a7de6b72 100644
--- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp
@@ -42,7 +42,7 @@
#include "qwaylandxcompositeeglwindow.h"
#include <QtCore/QDebug>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp
index 0194878a3..e2e2f5519 100644
--- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp
+++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp
@@ -44,7 +44,7 @@
#include <QtCore/QDebug>
#include <QtGui/QRegion>
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h
index f655dee21..83a643757 100644
--- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h
+++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.h
@@ -44,7 +44,7 @@
#include "qwaylandxcompositeeglclientbufferintegration.h"
-#include <QtPlatformSupport/private/qeglplatformcontext_p.h>
+#include <QtEglSupport/private/qeglplatformcontext_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp
index f9b6fc1de..cfc0cda10 100644
--- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp
+++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglwindow.cpp
@@ -40,8 +40,8 @@
#include "qwaylandxcompositeeglwindow.h"
#include "qwaylandxcompositebuffer.h"
-#include <QtPlatformSupport/private/qeglconvenience_p.h>
-#include <QtPlatformSupport/private/qxlibeglintegration_p.h>
+#include <QtEglSupport/private/qeglconvenience_p.h>
+#include <QtEglSupport/private/qxlibeglintegration_p.h>
#include "wayland-xcomposite-client-protocol.h"
diff --git a/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri b/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri
index 52653c4ae..3a5fcb543 100644
--- a/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri
+++ b/src/hardwareintegration/client/xcomposite-egl/xcomposite-egl.pri
@@ -8,7 +8,7 @@ include($$PWD/../xcomposite_share/xcomposite_share.pri)
LIBS += -lXcomposite -lX11
}
-QT += platformsupport-private
+QT += egl_support-private
CONFIG += egl
SOURCES += \
diff --git a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h
index 862ed928b..5847ea976 100644
--- a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h
+++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.h
@@ -43,7 +43,7 @@
#include <qpa/qplatformopenglcontext.h>
#include "qwaylandxcompositeglxintegration.h"
-#include <QtPlatformSupport/private/qglxconvenience_p.h>
+#include <QtGlxSupport/private/qglxconvenience_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri b/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri
index 11c051728..bc072bf05 100644
--- a/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri
+++ b/src/hardwareintegration/client/xcomposite-glx/xcomposite-glx.pri
@@ -8,7 +8,7 @@ include ($$PWD/../xcomposite_share/xcomposite_share.pri)
LIBS += -lXcomposite -lGL -lX11
}
-QT += platformsupport-private
+QT += glx_support-private
SOURCES += \
$$PWD/qwaylandxcompositeglxcontext.cpp \
diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp
index 508e88257..940ce82f5 100644
--- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp
+++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLContext>
+#include <QOpenGLTexture>
#include <qpa/qplatformscreen.h>
#include <QtGui/QWindow>
@@ -60,6 +61,9 @@ public:
: egl_display(EGL_NO_DISPLAY)
, valid(false)
{ }
+
+ static BrcmEglIntegrationPrivate *get(BrcmEglIntegration *integration);
+
EGLDisplay egl_display;
bool valid;
PFNEGLQUERYGLOBALIMAGEBRCMPROC eglQueryGlobalImageBRCM;
@@ -117,25 +121,46 @@ void BrcmEglIntegration::initializeHardware(struct ::wl_display *display)
}
}
-void BrcmEglIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
+QtWayland::ClientBuffer *BrcmEglIntegration::createBufferFor(wl_resource *buffer)
{
- Q_D(BrcmEglIntegration);
+ if (wl_shm_buffer_get(buffer))
+ return nullptr;
+ return new BrcmEglClientBuffer(this, buffer);
+}
+
+BrcmEglIntegrationPrivate *BrcmEglIntegrationPrivate::get(BrcmEglIntegration *integration)
+{
+ return integration->d_ptr.data();
+}
+
+QOpenGLTexture *BrcmEglClientBuffer::toOpenGlTexture(int plane)
+{
+ Q_UNUSED(plane);
+
+ auto d = BrcmEglIntegrationPrivate::get(m_integration);
if (!d->valid) {
qWarning("bindTextureToBuffer failed!");
- return;
+ return nullptr;
}
- BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer);
+ BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(m_buffer);
if (!d->eglQueryGlobalImageBRCM(brcmBuffer->handle(), brcmBuffer->handle() + 2)) {
qWarning("eglQueryGlobalImageBRCM failed!");
- return;
+ return nullptr;
}
EGLImageKHR image = d->eglCreateImageKHR(d->egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLClientBuffer)brcmBuffer->handle(), NULL);
if (image == EGL_NO_IMAGE_KHR)
qWarning("eglCreateImageKHR() failed: %x\n", eglGetError());
+ if (!m_texture) {
+ m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
+ m_texture->create();
+ }
+
+ m_texture->bind();
+
d->glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -144,6 +169,8 @@ void BrcmEglIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
d->eglDestroyImageKHR(d->egl_display, image);
+
+ return m_texture;
}
void BrcmEglIntegration::brcm_bind_resource(Resource *)
@@ -155,11 +182,29 @@ void BrcmEglIntegration::brcm_create_buffer(Resource *resource, uint32_t id, int
new BrcmBuffer(resource->client(), id, QSize(width, height), static_cast<EGLint *>(data->data), data->size / sizeof(EGLint));
}
-QSize BrcmEglIntegration::bufferSize(struct ::wl_resource *buffer) const
+BrcmEglClientBuffer::BrcmEglClientBuffer(BrcmEglIntegration *integration, wl_resource *buffer)
+ : ClientBuffer(buffer)
+ , m_integration(integration)
+ , m_texture(nullptr)
+{
+}
+
+QWaylandBufferRef::BufferFormatEgl BrcmEglClientBuffer::bufferFormatEgl() const
{
- BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(buffer);
+ return QWaylandBufferRef::BufferFormatEgl_RGBA;
+}
+QSize BrcmEglClientBuffer::size() const
+{
+ BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(m_buffer);
return brcmBuffer->size();
}
+QWaylandSurface::Origin BrcmEglClientBuffer::origin() const
+{
+ BrcmBuffer *brcmBuffer = BrcmBuffer::fromResource(m_buffer);
+ return brcmBuffer->isYInverted() ? QWaylandSurface::OriginTopLeft : QWaylandSurface::OriginBottomLeft;
+}
+
+
QT_END_NAMESPACE
diff --git a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h
index 48dd9c42e..a1d39e4fe 100644
--- a/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h
+++ b/src/hardwareintegration/compositor/brcm-egl/brcmeglintegration.h
@@ -42,6 +42,8 @@
#include <QtCore/QScopedPointer>
+#include <private/qwlclientbuffer_p.h>
+
QT_BEGIN_NAMESPACE
class BrcmEglIntegrationPrivate;
@@ -53,10 +55,7 @@ public:
BrcmEglIntegration();
void initializeHardware(struct ::wl_display *display) Q_DECL_OVERRIDE;
-
- void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
-
- QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
+ QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) Q_DECL_OVERRIDE;
protected:
void brcm_bind_resource(Resource *resource) Q_DECL_OVERRIDE;
@@ -67,6 +66,21 @@ private:
QScopedPointer<BrcmEglIntegrationPrivate> d_ptr;
};
+class BrcmEglClientBuffer : public QtWayland::ClientBuffer
+{
+public:
+ BrcmEglClientBuffer(BrcmEglIntegration *integration, wl_resource *buffer);
+
+ QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const Q_DECL_OVERRIDE;
+ QSize size() const Q_DECL_OVERRIDE;
+ QWaylandSurface::Origin origin() const Q_DECL_OVERRIDE;
+ QOpenGLTexture *toOpenGlTexture(int plane) Q_DECL_OVERRIDE;
+private:
+ BrcmEglIntegration *m_integration;
+ QOpenGLTexture *m_texture;
+};
+
+
QT_END_NAMESPACE
#endif // BRCMEGLINTEGRATION_H
diff --git a/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri b/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri
index 8dacc130b..f36474890 100644
--- a/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri
+++ b/src/hardwareintegration/compositor/wayland-egl/wayland-egl.pri
@@ -8,6 +8,7 @@ INCLUDEPATH += $$PWD
}
CONFIG += egl
+QT += egl_support-private
SOURCES += \
$$PWD/waylandeglclientbufferintegration.cpp
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
index 4416d103c..8b87db971 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformnativeinterface.h>
#include <QtGui/QGuiApplication>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLTexture>
#include <qpa/qplatformscreen.h>
#include <QtGui/QWindow>
#include <QtCore/QPointer>
@@ -48,7 +49,7 @@
#include <QMutex>
#include <QMutexLocker>
#include <QtCore/private/qcore_unix_p.h>
-#include <QtPlatformSupport/private/qeglstreamconvenience_p.h>
+#include <QtEglSupport/private/qeglstreamconvenience_p.h>
#ifndef GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
@@ -90,6 +91,10 @@
#define EGL_TEXTURE_Y_XUXV_WL 0x31D9
#endif
+#ifndef EGL_PLATFORM_X11_KHR
+#define EGL_PLATFORM_X11_KHR 0x31D5
+#endif
+
/* Needed for compatibility with Mesa older than 10.0. */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL_compat) (EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
@@ -110,17 +115,50 @@ typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenu
QT_BEGIN_NAMESPACE
+static const char *
+egl_error_string(EGLint code)
+{
+#define MYERRCODE(x) case x: return #x;
+ switch (code) {
+ MYERRCODE(EGL_SUCCESS)
+ MYERRCODE(EGL_NOT_INITIALIZED)
+ MYERRCODE(EGL_BAD_ACCESS)
+ MYERRCODE(EGL_BAD_ALLOC)
+ MYERRCODE(EGL_BAD_ATTRIBUTE)
+ MYERRCODE(EGL_BAD_CONTEXT)
+ MYERRCODE(EGL_BAD_CONFIG)
+ MYERRCODE(EGL_BAD_CURRENT_SURFACE)
+ MYERRCODE(EGL_BAD_DISPLAY)
+ MYERRCODE(EGL_BAD_SURFACE)
+ MYERRCODE(EGL_BAD_MATCH)
+ MYERRCODE(EGL_BAD_PARAMETER)
+ MYERRCODE(EGL_BAD_NATIVE_PIXMAP)
+ MYERRCODE(EGL_BAD_NATIVE_WINDOW)
+ MYERRCODE(EGL_CONTEXT_LOST)
+ default:
+ return "unknown";
+ }
+#undef MYERRCODE
+}
+
struct BufferState
{
BufferState();
+ enum EglMode {
+ ModeNone,
+ ModeEGLImage,
+ ModeEGLStream
+ };
+
EGLint egl_format;
QVarLengthArray<EGLImageKHR, 3> egl_images;
+ QOpenGLTexture *textures[3];
EGLStreamKHR egl_stream;
- GLuint eglstream_texture;
bool isYInverted;
QSize size;
+ EglMode eglMode;
};
class WaylandEglClientBufferIntegrationPrivate
@@ -128,18 +166,14 @@ class WaylandEglClientBufferIntegrationPrivate
public:
WaylandEglClientBufferIntegrationPrivate();
- void attach(struct ::wl_resource *buffer);
- void attach_egl_texture(struct ::wl_resource *buffer, EGLint format);
- void attach_egl_fd_texture(struct ::wl_resource *buffer, EGLNativeFileDescriptorKHR streamFd);
+ void initBuffer(WaylandEglClientBuffer *buffer);
+ void init_egl_texture(WaylandEglClientBuffer *buffer, EGLint format);
+ void init_egl_fd_texture(WaylandEglClientBuffer *buffer, EGLNativeFileDescriptorKHR streamFd);
void register_buffer(struct ::wl_resource *buffer, BufferState state);
- void bindBuffer(struct ::wl_resource *buffer);
-
- static void handle_buffer_destroy(wl_listener *listener, void *data);
EGLDisplay egl_display;
bool valid;
bool display_bound;
- QHash<struct ::wl_resource *, BufferState> buffers;
PFNEGLBINDWAYLANDDISPLAYWL egl_bind_wayland_display;
PFNEGLUNBINDWAYLANDDISPLAYWL egl_unbind_wayland_display;
@@ -151,25 +185,16 @@ public:
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC gl_egl_image_target_texture_2d;
QEGLStreamConvenience *funcs;
-};
-
-struct buffer_destroy_listener : wl_listener
-{
- buffer_destroy_listener()
- : d(0)
- {
- notify = WaylandEglClientBufferIntegrationPrivate::handle_buffer_destroy;
- wl_list_init(&this->link);
+ static WaylandEglClientBufferIntegrationPrivate *get(WaylandEglClientBufferIntegration *integration) {
+ return integration->d_ptr.data();
}
-
- WaylandEglClientBufferIntegrationPrivate *d;
};
BufferState::BufferState()
: egl_format(EGL_TEXTURE_RGBA)
, egl_stream(EGL_NO_STREAM_KHR)
- , eglstream_texture(0)
, isYInverted(true)
+ , eglMode(ModeNone)
{}
WaylandEglClientBufferIntegrationPrivate::WaylandEglClientBufferIntegrationPrivate()
@@ -183,21 +208,21 @@ WaylandEglClientBufferIntegrationPrivate::WaylandEglClientBufferIntegrationPriva
, egl_destroy_image(0)
, gl_egl_image_target_texture_2d(0)
, funcs(Q_NULLPTR)
-{}
+{
+}
-void WaylandEglClientBufferIntegrationPrivate::attach(struct ::wl_resource *buffer)
+void WaylandEglClientBufferIntegrationPrivate::initBuffer(WaylandEglClientBuffer *buffer)
{
EGLint format;
- EGLNativeFileDescriptorKHR streamFd = EGL_NO_FILE_DESCRIPTOR_KHR;
- if (egl_query_wayland_buffer(egl_display, buffer, EGL_TEXTURE_FORMAT, &format))
- attach_egl_texture(buffer, format);
- else if (egl_query_wayland_buffer(egl_display, buffer, EGL_WAYLAND_BUFFER_WL, &streamFd))
- attach_egl_fd_texture(buffer, streamFd);
+ if (egl_query_wayland_buffer(egl_display, buffer->waylandBufferHandle(), EGL_TEXTURE_FORMAT, &format))
+ init_egl_texture(buffer, format);
}
-void WaylandEglClientBufferIntegrationPrivate::attach_egl_texture(struct ::wl_resource *buffer, EGLint format)
+void WaylandEglClientBufferIntegrationPrivate::init_egl_texture(WaylandEglClientBuffer *buffer, EGLint format)
{
+// Non-streaming case
+
// Resolving GL functions may need a context current, so do it only here.
if (!gl_egl_image_target_texture_2d)
gl_egl_image_target_texture_2d = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
@@ -207,12 +232,13 @@ void WaylandEglClientBufferIntegrationPrivate::attach_egl_texture(struct ::wl_re
return;
}
- BufferState state;
+ BufferState &state = *buffer->d;
state.egl_format = format;
+ state.eglMode = BufferState::ModeEGLImage;
#if defined(EGL_WAYLAND_Y_INVERTED_WL)
EGLint isYInverted;
- EGLBoolean ret = egl_query_wayland_buffer(egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
+ EGLBoolean ret = egl_query_wayland_buffer(egl_display, buffer->waylandBufferHandle(), EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
// Yes, this looks strange, but the specification says that EGL_FALSE return
// value (not supported) should be treated the same as EGL_TRUE return value
// and EGL_TRUE in value.
@@ -244,21 +270,21 @@ void WaylandEglClientBufferIntegrationPrivate::attach_egl_texture(struct ::wl_re
EGLImageKHR image = egl_create_image(egl_display,
EGL_NO_CONTEXT,
EGL_WAYLAND_BUFFER_WL,
- buffer,
+ buffer->waylandBufferHandle(),
attribs);
if (image == EGL_NO_IMAGE_KHR)
qWarning("failed to create EGL image for plane %d", i);
state.egl_images << image;
+ state.textures[i] = nullptr;
}
-
- register_buffer(buffer, state);
}
-void WaylandEglClientBufferIntegrationPrivate::attach_egl_fd_texture(struct ::wl_resource *buffer, EGLNativeFileDescriptorKHR streamFd)
+void WaylandEglClientBufferIntegrationPrivate::init_egl_fd_texture(WaylandEglClientBuffer *buffer, EGLNativeFileDescriptorKHR streamFd)
{
- BufferState state;
+//EglStreams case
+ BufferState &state = *buffer->d;
state.egl_format = EGL_TEXTURE_EXTERNAL_WL;
state.isYInverted = false;
@@ -270,106 +296,37 @@ void WaylandEglClientBufferIntegrationPrivate::attach_egl_fd_texture(struct ::wl
qWarning("%s:%d: eglCreateStreamFromFileDescriptorKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
return;
}
+ state.eglMode = BufferState::ModeEGLStream;
if (!QOpenGLContext::currentContext())
qWarning("EglClientBufferIntegration: creating texture with no current context");
//TODO This texture might end up in a different context than the quick item which wants to use it, this needs to be fixed somehow.
- glGenTextures(1, &state.eglstream_texture);
+
+ auto texture = new QOpenGLTexture(static_cast<QOpenGLTexture::Target>(GL_TEXTURE_EXTERNAL_OES));
+ texture->create();
+ state.textures[0] = texture; // TODO: support multiple planes for the streaming case
+
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_EXTERNAL_OES, state.eglstream_texture);
+ texture->create();
+ texture->bind();
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture->textureId());
+
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- register_buffer(buffer, state);
-
- bindBuffer(buffer);
-}
-
-void WaylandEglClientBufferIntegrationPrivate::register_buffer(struct ::wl_resource *buffer, BufferState state)
-{
- Q_ASSERT(!buffers.contains(buffer));
-
- EGLint width, height;
- egl_query_wayland_buffer(egl_display, buffer, EGL_WIDTH, &width);
- egl_query_wayland_buffer(egl_display, buffer, EGL_HEIGHT, &height);
- state.size = QSize(width, height);
-
- buffers[buffer] = state;
-
- buffer_destroy_listener *destroy_listener = new buffer_destroy_listener;
- destroy_listener->d = this;
- wl_signal_add(&buffer->destroy_signal, destroy_listener);
-}
-
-void WaylandEglClientBufferIntegrationPrivate::bindBuffer(struct ::wl_resource *buffer)
-{
- if (!valid) {
- qWarning("QtCompositor: bindTextureToBuffer() failed");
- return;
- }
+ auto newStream = funcs->stream_consumer_gltexture(egl_display, state.egl_stream);
- if (!buffer || !buffers.contains(buffer))
- return;
-
- const BufferState state = buffers.value(buffer);
-
- if (state.egl_stream != EGL_NO_STREAM_KHR) {
- EGLint stream_state;
- funcs->query_stream(egl_display, state.egl_stream, EGL_STREAM_STATE_KHR, &stream_state);
-
- if (stream_state == EGL_STREAM_STATE_CREATED_KHR)
- if (funcs->stream_consumer_gltexture(egl_display, state.egl_stream) != EGL_TRUE)
- qWarning("%s:%d: eglStreamConsumerGLTextureExternalKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
- } else {
- GLint previousTexture = GL_TEXTURE0;
- glGetIntegerv(GL_ACTIVE_TEXTURE, &previousTexture);
-
- const GLenum target = (state.egl_format == EGL_TEXTURE_EXTERNAL_WL) ? GL_TEXTURE_EXTERNAL_OES
- : GL_TEXTURE_2D;
-
- for (int i = 0; i < state.egl_images.size(); i++) {
- glActiveTexture(GL_TEXTURE0 + i);
- glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl_egl_image_target_texture_2d(target, state.egl_images[i]);
- }
-
- glActiveTexture(previousTexture);
+ if (!newStream) {
+ EGLint code = eglGetError();
+ qWarning() << "Could not initialize EGLStream:" << egl_error_string(code) << hex << (long)code;
+ funcs->destroy_stream(egl_display, state.egl_stream);
+ state.egl_stream = EGL_NO_STREAM_KHR;
}
}
-void WaylandEglClientBufferIntegrationPrivate::handle_buffer_destroy(wl_listener *listener, void *data)
-{
- buffer_destroy_listener *destroy_listener = static_cast<buffer_destroy_listener *>(listener);
- WaylandEglClientBufferIntegrationPrivate *self = destroy_listener->d;
- struct ::wl_resource *buffer = static_cast<struct ::wl_resource *>(data);
-
- wl_list_remove(&destroy_listener->link);
- delete destroy_listener;
-
- if (!self->buffers.contains(buffer))
- return;
-
- Q_ASSERT(self);
- Q_ASSERT(buffer);
-
- BufferState state = self->buffers.take(buffer);
-
- // We would need to delete the texture of the egl_stream here, but we can't as this breaks the
- // texture of the new stream when the window is resized. It seems wayland takes care to delete the texture for us.
-
- for (int i = 0; i < state.egl_images.size(); i++)
- self->egl_destroy_image(self->egl_display, state.egl_images[i]);
-
- if (state.egl_stream != EGL_NO_STREAM_KHR)
- self->funcs->destroy_stream(self->egl_display, state.egl_stream);
-}
-
WaylandEglClientBufferIntegration::WaylandEglClientBufferIntegration()
: QtWayland::ClientBufferIntegration()
, d_ptr(new WaylandEglClientBufferIntegrationPrivate)
@@ -438,17 +395,27 @@ void WaylandEglClientBufferIntegration::initializeHardware(struct wl_display *di
d->valid = true;
}
-void WaylandEglClientBufferIntegration::initializeBuffer(struct ::wl_resource *buffer)
+QtWayland::ClientBuffer *WaylandEglClientBufferIntegration::createBufferFor(wl_resource *buffer)
{
- Q_D(WaylandEglClientBufferIntegration);
-
if (wl_shm_buffer_get(buffer))
- return;
-
- if (!buffer || d->buffers.contains(buffer))
- return;
+ return nullptr;
+ return new WaylandEglClientBuffer(this, buffer);
+}
- d->attach(buffer);
+WaylandEglClientBuffer::WaylandEglClientBuffer(WaylandEglClientBufferIntegration *integration, wl_resource *buffer)
+ : ClientBuffer(buffer)
+ , m_integration(integration)
+{
+ auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration);
+ d = new BufferState;
+ if (buffer && !wl_shm_buffer_get(buffer)) {
+ EGLint width, height;
+ p->egl_query_wayland_buffer(p->egl_display, buffer, EGL_WIDTH, &width);
+ p->egl_query_wayland_buffer(p->egl_display, buffer, EGL_HEIGHT, &height);
+ d->size = QSize(width, height);
+
+ p->initBuffer(this);
+ }
}
static QWaylandBufferRef::BufferFormatEgl formatFromEglFormat(EGLint format) {
@@ -470,117 +437,92 @@ static QWaylandBufferRef::BufferFormatEgl formatFromEglFormat(EGLint format) {
return QWaylandBufferRef::BufferFormatEgl_RGBA;
}
-QWaylandBufferRef::BufferFormatEgl WaylandEglClientBufferIntegration::bufferFormat(wl_resource *buffer)
-{
- Q_D(const WaylandEglClientBufferIntegration);
- return formatFromEglFormat(d->buffers.value(buffer).egl_format);
-}
-
-uint WaylandEglClientBufferIntegration::textureForBuffer(wl_resource *buffer, int plane)
+QWaylandBufferRef::BufferFormatEgl WaylandEglClientBuffer::bufferFormatEgl() const
{
- Q_UNUSED(plane)
- Q_D(WaylandEglClientBufferIntegration);
- if (!buffer)
- return 0;
-
- const BufferState state = d->buffers.value(buffer);
- return state.eglstream_texture;
-}
-
-void WaylandEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
-{
- Q_D(WaylandEglClientBufferIntegration);
- d->bindBuffer(buffer);
+ return formatFromEglFormat(d->egl_format);
}
-// Update is only needed for the EGLStream path as that requires calling acquire
-// on every frame. bindTextureToBuffer() is typically invoked only upon attach
-// so that is insufficient.
-void WaylandEglClientBufferIntegration::updateTextureForBuffer(struct ::wl_resource *buffer)
+QOpenGLTexture *WaylandEglClientBuffer::toOpenGlTexture(int plane)
{
- Q_D(WaylandEglClientBufferIntegration);
- if (!d->valid) {
- qWarning("QtCompositor: updateTextureForBuffer() failed");
- return;
+ if (!m_buffer)
+ return nullptr;
+
+ auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration);
+ auto texture = d->textures[plane];
+ const auto target = static_cast<QOpenGLTexture::Target>((d->eglMode == BufferState::ModeEGLStream || d->egl_format == EGL_TEXTURE_EXTERNAL_WL) ? GL_TEXTURE_EXTERNAL_OES
+ : GL_TEXTURE_2D);
+ if (!texture) {
+ texture = new QOpenGLTexture(target);
+ texture->create();
+ d->textures[plane] = texture;
}
- if (!buffer)
- return;
- const BufferState state = d->buffers.value(buffer);
+ if (d->eglMode == BufferState::ModeEGLStream) {
+ // EGLStream requires calling acquire on every frame.
+ if (d->egl_stream != EGL_NO_STREAM_KHR) {
- if (state.egl_stream != EGL_NO_STREAM_KHR) {
- EGLint stream_state;
- d->funcs->query_stream(d->egl_display, state.egl_stream, EGL_STREAM_STATE_KHR, &stream_state);
+ texture->bind();
- if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) {
- if (d->funcs->stream_consumer_acquire(d->egl_display, state.egl_stream) != EGL_TRUE)
- qWarning("%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
+ EGLint stream_state;
+ p->funcs->query_stream(p->egl_display, d->egl_stream, EGL_STREAM_STATE_KHR, &stream_state);
+
+ if (stream_state == EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR) {
+ if (p->funcs->stream_consumer_acquire(p->egl_display, d->egl_stream) != EGL_TRUE)
+ qWarning("%s:%d: eglStreamConsumerAcquireKHR failed: 0x%x", Q_FUNC_INFO, __LINE__, eglGetError());
+ }
}
+ } else if (m_textureDirty) {
+ texture->bind();
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ p->gl_egl_image_target_texture_2d(target, d->egl_images[plane]);
}
+ return texture;
}
-QWaylandSurface::Origin WaylandEglClientBufferIntegration::origin(struct ::wl_resource *buffer) const
+void WaylandEglClientBuffer::setCommitted(QRegion &damage)
{
- Q_D(const WaylandEglClientBufferIntegration);
-
- if (d->buffers.contains(buffer))
- return d->buffers[buffer].isYInverted ? QWaylandSurface::OriginTopLeft : QWaylandSurface::OriginBottomLeft;
-
-#if defined(EGL_WAYLAND_Y_INVERTED_WL)
- EGLint isYInverted;
- EGLBoolean ret = EGL_FALSE;
- if (buffer)
- ret = d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WAYLAND_Y_INVERTED_WL, &isYInverted);
- // Yes, this looks strange, but the specification says that EGL_FALSE return
- // value (not supported) should be treated the same as EGL_TRUE return value
- // and EGL_TRUE in value.
- if (ret == EGL_FALSE || isYInverted == EGL_TRUE)
- return QWaylandSurface::OriginTopLeft;
- return QWaylandSurface::OriginBottomLeft;
-#endif
-
- return QtWayland::ClientBufferIntegration::origin(buffer);
+ ClientBuffer::setCommitted(damage);
+ if (d->eglMode == BufferState::ModeNone) {
+ EGLNativeFileDescriptorKHR streamFd = EGL_NO_FILE_DESCRIPTOR_KHR;
+ auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration);
+ if (p->egl_query_wayland_buffer(p->egl_display, waylandBufferHandle(), EGL_WAYLAND_BUFFER_WL, &streamFd))
+ p->init_egl_fd_texture(this, streamFd);
+ }
}
+QWaylandSurface::Origin WaylandEglClientBuffer::origin() const
+{
+ return d->isYInverted ? QWaylandSurface::OriginTopLeft : QWaylandSurface::OriginBottomLeft;
+}
-void *WaylandEglClientBufferIntegration::lockNativeBuffer(struct ::wl_resource *buffer) const
+quintptr WaylandEglClientBuffer::lockNativeBuffer()
{
- Q_D(const WaylandEglClientBufferIntegration);
+ auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration);
- if (d->buffers.contains(buffer) && d->buffers[buffer].egl_stream != EGL_NO_STREAM_KHR)
+ if (d->egl_stream != EGL_NO_STREAM_KHR)
return 0;
- EGLImageKHR image = d->egl_create_image(d->egl_display, EGL_NO_CONTEXT,
+ EGLImageKHR image = p->egl_create_image(p->egl_display, EGL_NO_CONTEXT,
EGL_WAYLAND_BUFFER_WL,
- buffer, NULL);
- return image;
+ m_buffer, NULL);
+ return reinterpret_cast<quintptr>(image);
}
-void WaylandEglClientBufferIntegration::unlockNativeBuffer(void *native_buffer) const
+void WaylandEglClientBuffer::unlockNativeBuffer(quintptr native_buffer) const
{
- Q_D(const WaylandEglClientBufferIntegration);
-
if (!native_buffer)
return;
- EGLImageKHR image = static_cast<EGLImageKHR>(native_buffer);
- d->egl_destroy_image(d->egl_display, image);
+ auto *p = WaylandEglClientBufferIntegrationPrivate::get(m_integration);
+
+ EGLImageKHR image = reinterpret_cast<EGLImageKHR>(native_buffer);
+ p->egl_destroy_image(p->egl_display, image);
}
-QSize WaylandEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const
+QSize WaylandEglClientBuffer::size() const
{
- Q_D(const WaylandEglClientBufferIntegration);
-
- if (d->buffers.contains(buffer)) {
- return d->buffers[buffer].size;
- } else {
- int width, height;
- d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_WIDTH, &width);
- d->egl_query_wayland_buffer(d->egl_display, buffer, EGL_HEIGHT, &height);
-
- return QSize(width, height);
- }
+ return d->size;
}
QT_END_NAMESPACE
diff --git a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
index 74cad708d..c93ce1dd8 100644
--- a/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
+++ b/src/hardwareintegration/compositor/wayland-egl/waylandeglclientbufferintegration.h
@@ -39,6 +39,7 @@
#include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h>
#include <QtCore/QScopedPointer>
+#include <QtWaylandCompositor/private/qwlclientbuffer_p.h>
QT_BEGIN_NAMESPACE
@@ -52,22 +53,34 @@ public:
void initializeHardware(struct ::wl_display *display) Q_DECL_OVERRIDE;
- void initializeBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- QWaylandBufferRef::BufferFormatEgl bufferFormat(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- uint textureForBuffer(struct ::wl_resource *buffer, int plane) Q_DECL_OVERRIDE;
- void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- void updateTextureForBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
+ QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer);
- QWaylandSurface::Origin origin(struct ::wl_resource *) const Q_DECL_OVERRIDE;
+private:
+ Q_DISABLE_COPY(WaylandEglClientBufferIntegration)
+ QScopedPointer<WaylandEglClientBufferIntegrationPrivate> d_ptr;
+};
- void *lockNativeBuffer(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
- void unlockNativeBuffer(void *native_buffer) const Q_DECL_OVERRIDE;
+struct BufferState;
- QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
+class WaylandEglClientBuffer : public QtWayland::ClientBuffer
+{
+public:
+ QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const Q_DECL_OVERRIDE;
+ QSize size() const Q_DECL_OVERRIDE;
+ QWaylandSurface::Origin origin() const Q_DECL_OVERRIDE;
+ quintptr lockNativeBuffer() Q_DECL_OVERRIDE;
+ void unlockNativeBuffer(quintptr native_buffer) const Q_DECL_OVERRIDE;
+ QOpenGLTexture *toOpenGlTexture(int plane) Q_DECL_OVERRIDE;
+ void setCommitted(QRegion &damage) Q_DECL_OVERRIDE;
private:
- Q_DISABLE_COPY(WaylandEglClientBufferIntegration)
- QScopedPointer<WaylandEglClientBufferIntegrationPrivate> d_ptr;
+ friend class WaylandEglClientBufferIntegration;
+ friend class WaylandEglClientBufferIntegrationPrivate;
+
+ WaylandEglClientBuffer(WaylandEglClientBufferIntegration* integration, wl_resource *bufferResource);
+
+ BufferState *d;
+ WaylandEglClientBufferIntegration *m_integration;
};
QT_END_NAMESPACE
diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
index e858a8e78..1a478052b 100644
--- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
+++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.cpp
@@ -40,6 +40,7 @@
#include <QtWaylandCompositor/QWaylandCompositor>
#include <QtGui/QGuiApplication>
+#include <QtGui/QOpenGLTexture>
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformopenglcontext.h>
@@ -83,23 +84,38 @@ void XCompositeEglClientBufferIntegration::initializeHardware(struct ::wl_displa
} else {
qFatal("Platform integration doesn't have native interface");
}
- mScreen = XDefaultScreen(mDisplay);
new XCompositeHandler(m_compositor, mDisplay);
}
-void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
+QtWayland::ClientBuffer *XCompositeEglClientBufferIntegration::createBufferFor(wl_resource *buffer)
{
- XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
- Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());
+ if (wl_shm_buffer_get(buffer))
+ return nullptr;
+ return new XCompositeEglClientBuffer(this, buffer);
+}
+
+
+XCompositeEglClientBuffer::XCompositeEglClientBuffer(XCompositeEglClientBufferIntegration *integration, wl_resource *bufferResource)
+ : QtWayland::ClientBuffer(bufferResource)
+ , m_texture(nullptr)
+ , m_integration(integration)
+{
+}
+
+QOpenGLTexture *XCompositeEglClientBuffer::toOpenGlTexture(int plane)
+{
+ Q_UNUSED(plane);
+ XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(m_buffer);
+ Pixmap pixmap = XCompositeNameWindowPixmap(m_integration->xDisplay(), compositorBuffer->window());
QVector<EGLint> eglConfigSpec = eglbuildSpec();
EGLint matching = 0;
EGLConfig config;
- bool matched = eglChooseConfig(mEglDisplay,eglConfigSpec.constData(),&config,1,&matching);
+ bool matched = eglChooseConfig(m_integration->eglDisplay(),eglConfigSpec.constData(),&config,1,&matching);
if (!matched || !matching) {
qWarning("Could not retrieve a suitable EGL config");
- return;
+ return nullptr;
}
QVector<EGLint> attribList;
@@ -110,29 +126,37 @@ void XCompositeEglClientBufferIntegration::bindTextureToBuffer(struct ::wl_resou
attribList.append(EGL_TEXTURE_2D);
attribList.append(EGL_NONE);
- EGLSurface surface = eglCreatePixmapSurface(mEglDisplay,config,pixmap,attribList.constData());
+ EGLSurface surface = eglCreatePixmapSurface(m_integration->eglDisplay(),config,pixmap,attribList.constData());
if (surface == EGL_NO_SURFACE) {
qDebug() << "Failed to create eglsurface" << pixmap << compositorBuffer->window();
}
compositorBuffer->setOrigin(QWaylandSurface::OriginTopLeft);
- if (!eglBindTexImage(mEglDisplay,surface,EGL_BACK_BUFFER)) {
- qDebug() << "Failed to bind";
+ if (!m_texture) {
+ m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
+ m_texture->create();
+ }
+ m_texture->bind();
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ if (!eglBindTexImage(m_integration->eglDisplay(),surface,EGL_BACK_BUFFER)) {
+ qWarning() << "Failed to bind";
}
// eglDestroySurface(mEglDisplay,surface);
+ return m_texture;
}
-QWaylandSurface::Origin XCompositeEglClientBufferIntegration::origin(struct ::wl_resource *buffer) const
+
+QWaylandSurface::Origin XCompositeEglClientBuffer::origin() const
{
- XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
+ XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(m_buffer);
return compositorBuffer->origin();
}
-QSize XCompositeEglClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const
+QSize XCompositeEglClientBuffer::size() const
{
- XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
+ XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(m_buffer);
return compositorBuffer->size();
}
diff --git a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h
index c14e582ed..ec4ea284b 100644
--- a/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h
+++ b/src/hardwareintegration/compositor/xcomposite-egl/xcompositeeglintegration.h
@@ -40,7 +40,7 @@
#include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h>
#include <QtWaylandCompositor/QWaylandCompositor>
-
+#include <QtWaylandCompositor/private/qwlclientbuffer_p.h>
#include "xlibinclude.h"
#include <EGL/egl.h>
@@ -53,16 +53,30 @@ public:
XCompositeEglClientBufferIntegration();
void initializeHardware(struct ::wl_display *display) Q_DECL_OVERRIDE;
-
- void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- QWaylandSurface::Origin origin(struct ::wl_resource *) const Q_DECL_OVERRIDE;
-
- QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
+ QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) Q_DECL_OVERRIDE;
+ inline Display *xDisplay() const { return mDisplay; }
+ inline EGLDisplay eglDisplay() const { return mEglDisplay; }
private:
Display *mDisplay;
EGLDisplay mEglDisplay;
- int mScreen;
+};
+
+class XCompositeEglClientBuffer : public QtWayland::ClientBuffer
+{
+public:
+ XCompositeEglClientBuffer(XCompositeEglClientBufferIntegration *integration, wl_resource *bufferResource);
+
+ QSize size() const;
+ QWaylandSurface::Origin origin() const;
+ QOpenGLTexture *toOpenGlTexture(int plane) Q_DECL_OVERRIDE;
+ QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const Q_DECL_OVERRIDE {
+ return QWaylandBufferRef::BufferFormatEgl_RGBA;
+ }
+
+private:
+ QOpenGLTexture *m_texture;
+ XCompositeEglClientBufferIntegration *m_integration;
};
QT_END_NAMESPACE
diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp
index 6f70d2bbf..0b11c2630 100644
--- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp
+++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.cpp
@@ -41,6 +41,7 @@
#include <qpa/qplatformnativeinterface.h>
#include <qpa/qplatformintegration.h>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLTexture>
#include "xcompositebuffer.h"
#include "xcompositehandler.h"
@@ -109,14 +110,31 @@ void XCompositeGLXClientBufferIntegration::initializeHardware(struct ::wl_displa
delete glContext;
}
-void XCompositeGLXClientBufferIntegration::bindTextureToBuffer(struct ::wl_resource *buffer)
+QtWayland::ClientBuffer *XCompositeGLXClientBufferIntegration::createBufferFor(wl_resource *buffer)
{
- XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
- Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());
+ if (wl_shm_buffer_get(buffer))
+ return nullptr;
+ return new XCompositeGLXClientBuffer(this, buffer);
+}
+
+XCompositeGLXClientBuffer::XCompositeGLXClientBuffer(XCompositeGLXClientBufferIntegration *integration, wl_resource *bufferResource)
+ : QtWayland::ClientBuffer(bufferResource)
+ , m_texture(nullptr)
+ , m_integration(integration)
+ , m_glxPixmap(0)
+{
+}
+
+
+QOpenGLTexture *XCompositeGLXClientBuffer::toOpenGlTexture(int plane)
+{
+ Q_UNUSED(plane);
+ XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(m_buffer);
+ Pixmap pixmap = XCompositeNameWindowPixmap(m_integration->xDisplay(), compositorBuffer->window());
QVector<int> glxConfigSpec = qglx_buildSpec();
int numberOfConfigs;
- GLXFBConfig *configs = glXChooseFBConfig(mDisplay,mScreen,glxConfigSpec.constData(),&numberOfConfigs);
+ GLXFBConfig *configs = glXChooseFBConfig(m_integration->xDisplay(),m_integration->xScreen(),glxConfigSpec.constData(),&numberOfConfigs);
QVector<int> attribList;
attribList.append(GLX_TEXTURE_FORMAT_EXT);
@@ -124,28 +142,40 @@ void XCompositeGLXClientBufferIntegration::bindTextureToBuffer(struct ::wl_resou
attribList.append(GLX_TEXTURE_TARGET_EXT);
attribList.append(GLX_TEXTURE_2D_EXT);
attribList.append(0);
- GLXPixmap glxPixmap = glXCreatePixmap(mDisplay,*configs,pixmap,attribList.constData());
+
+ if (!m_glxPixmap)
+ m_glxPixmap = glXCreatePixmap(m_integration->xDisplay(), *configs, pixmap, attribList.constData());
uint inverted = 0;
- glXQueryDrawable(mDisplay, glxPixmap, GLX_Y_INVERTED_EXT,&inverted);
+ glXQueryDrawable(m_integration->xDisplay(), m_glxPixmap, GLX_Y_INVERTED_EXT,&inverted);
compositorBuffer->setOrigin(inverted ? QWaylandSurface::OriginBottomLeft : QWaylandSurface::OriginTopLeft);
XFree(configs);
+ auto tex = m_texture;
+ if (!m_texture) {
+ tex = new QOpenGLTexture(QOpenGLTexture::Target2D);
+ tex->create();
+ m_texture = tex;
+ }
+ tex->bind();
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ m_integration->m_glxBindTexImageEXT(m_integration->xDisplay(),m_glxPixmap,GLX_FRONT_EXT, 0);
- m_glxBindTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT, 0);
- //Do we need to change the api so that we do bind and release in the painevent?
- //The specification states that when deleting the texture the color buffer is deleted
-// m_glxReleaseTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT);
+ // TODO: release in the destructor?
+ // m_glxReleaseTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT);
+ return tex;
}
-QWaylandSurface::Origin XCompositeGLXClientBufferIntegration::origin(struct ::wl_resource *buffer) const
+
+QWaylandSurface::Origin XCompositeGLXClientBuffer::origin() const
{
- return XCompositeBuffer::fromResource(buffer)->origin();
+ XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(m_buffer);
+ return compositorBuffer->origin();
}
-QSize XCompositeGLXClientBufferIntegration::bufferSize(struct ::wl_resource *buffer) const
+QSize XCompositeGLXClientBuffer::size() const
{
- XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(buffer);
+ XCompositeBuffer *compositorBuffer = XCompositeBuffer::fromResource(m_buffer);
return compositorBuffer->size();
}
diff --git a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h
index 9caeb4645..7b63f976e 100644
--- a/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h
+++ b/src/hardwareintegration/compositor/xcomposite-glx/xcompositeglxintegration.h
@@ -38,7 +38,7 @@
#define XCOMPOSITEGLXINTEGRATION_H
#include <QtWaylandCompositor/private/qwlclientbufferintegration_p.h>
-
+#include <QtWaylandCompositor/private/qwlclientbuffer_p.h>
#include "xlibinclude.h"
#define GLX_GLXEXT_PROTOTYPES
@@ -56,21 +56,38 @@ public:
~XCompositeGLXClientBufferIntegration();
void initializeHardware(struct ::wl_display *display) Q_DECL_OVERRIDE;
+ QtWayland::ClientBuffer *createBufferFor(wl_resource *buffer) Q_DECL_OVERRIDE;
- void bindTextureToBuffer(struct ::wl_resource *buffer) Q_DECL_OVERRIDE;
- QWaylandSurface::Origin origin(struct ::wl_resource *) const Q_DECL_OVERRIDE;
-
- QSize bufferSize(struct ::wl_resource *buffer) const Q_DECL_OVERRIDE;
+ inline Display *xDisplay() const { return mDisplay; }
+ inline int xScreen() const { return mScreen; }
-private:
PFNGLXBINDTEXIMAGEEXTPROC m_glxBindTexImageEXT;
PFNGLXRELEASETEXIMAGEEXTPROC m_glxReleaseTexImageEXT;
+private:
Display *mDisplay;
int mScreen;
XCompositeHandler *mHandler;
};
+class XCompositeGLXClientBuffer : public QtWayland::ClientBuffer
+{
+public:
+ XCompositeGLXClientBuffer(XCompositeGLXClientBufferIntegration *integration, wl_resource *bufferResource);
+
+ QSize size() const;
+ QWaylandSurface::Origin origin() const;
+ QOpenGLTexture *toOpenGlTexture(int plane) Q_DECL_OVERRIDE;
+ QWaylandBufferRef::BufferFormatEgl bufferFormatEgl() const Q_DECL_OVERRIDE {
+ return QWaylandBufferRef::BufferFormatEgl_RGBA;
+ }
+
+private:
+ QOpenGLTexture *m_texture;
+ XCompositeGLXClientBufferIntegration *m_integration;
+ GLXPixmap m_glxPixmap;
+};
+
QT_END_NAMESPACE
#endif // XCOMPOSITEGLXINTEGRATION_H
diff --git a/src/imports/compositor/WaylandCursorItem.qml b/src/imports/compositor/WaylandCursorItem.qml
index 9eacff9be..931acbb08 100644
--- a/src/imports/compositor/WaylandCursorItem.qml
+++ b/src/imports/compositor/WaylandCursorItem.qml
@@ -39,17 +39,19 @@ import QtWayland.Compositor 1.0
WaylandQuickItem {
id: cursorItem
- property QtObject inputDevice
+ property QtObject seat
property int hotspotX: 0
property int hotspotY: 0
visible: cursorItem.surface != null
inputEventsEnabled: false
+ enabled: false
+ transform: Translate { x: -hotspotX; y: -hotspotY }
- onInputDeviceChanged: {
- if (!inputDevice)
+ onSeatChanged: {
+ if (!seat)
return;
- inputDevice.cursorSurfaceRequest.connect(setCursorSurface);
+ seat.cursorSurfaceRequest.connect(setCursorSurface);
}
function setCursorSurface(surface, hotspotX, hotspotY) {
@@ -57,4 +59,19 @@ WaylandQuickItem {
cursorItem.hotspotX = hotspotX;
cursorItem.hotspotY = hotspotY;
}
+
+ WaylandQuickItem {
+ id: dragIcon
+ property point offset
+
+ x: cursorItem.hotspotX + offset.x
+ y: cursorItem.hotspotY + offset.y
+ z: -1
+ surface: cursorItem.seat.drag.icon
+
+ Connections {
+ target: dragIcon.surface
+ onOffsetForNextFrame: dragIcon.offset = offset;
+ }
+ }
}
diff --git a/src/imports/compositor/plugins.qmltypes b/src/imports/compositor/plugins.qmltypes
index 8d07403c0..c88b3b479 100644
--- a/src/imports/compositor/plugins.qmltypes
+++ b/src/imports/compositor/plugins.qmltypes
@@ -14,6 +14,7 @@ Module {
exports: ["QtWayland.Compositor/WaylandClient 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
+ Property { name: "compositor"; type: "QWaylandCompositor"; isReadonly: true; isPointer: true }
Property { name: "userId"; type: "qlonglong"; isReadonly: true }
Property { name: "groupId"; type: "qlonglong"; isReadonly: true }
Property { name: "processId"; type: "qlonglong"; isReadonly: true }
@@ -26,22 +27,26 @@ Module {
}
Component {
name: "QWaylandCompositor"
- prototype: "QObject"
+ prototype: "QWaylandObject"
exports: ["QtWayland.Compositor/WaylandCompositorBase 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
Property { name: "socketName"; type: "QByteArray" }
+ Property { name: "created"; type: "bool"; isReadonly: true }
Property { name: "retainedSelection"; type: "bool" }
Property { name: "defaultOutput"; type: "QWaylandOutput"; isPointer: true }
Property { name: "useHardwareIntegrationExtension"; type: "bool" }
- Property {
- name: "defaultInputDevice"
- type: "QWaylandInputDevice"
- isReadonly: true
- isPointer: true
+ Property { name: "defaultSeat"; type: "QWaylandSeat"; isReadonly: true; isPointer: true }
+ Signal {
+ name: "socketNameChanged"
+ Parameter { name: "socketName"; type: "QByteArray" }
}
Signal {
- name: "createSurface"
+ name: "retainedSelectionChanged"
+ Parameter { name: "retainedSelection"; type: "bool" }
+ }
+ Signal {
+ name: "surfaceRequested"
Parameter { name: "client"; type: "QWaylandClient"; isPointer: true }
Parameter { name: "id"; type: "uint" }
Parameter { name: "version"; type: "int" }
@@ -60,9 +65,17 @@ Module {
Parameter { name: "parent"; type: "QWaylandSurface"; isPointer: true }
}
Signal {
- name: "defaultInputDeviceChanged"
- Parameter { name: "newDevice"; type: "QWaylandInputDevice"; isPointer: true }
- Parameter { name: "oldDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ name: "defaultSeatChanged"
+ Parameter { name: "newDevice"; type: "QWaylandSeat"; isPointer: true }
+ Parameter { name: "oldDevice"; type: "QWaylandSeat"; isPointer: true }
+ }
+ Signal {
+ name: "outputAdded"
+ Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true }
+ }
+ Signal {
+ name: "outputRemoved"
+ Parameter { name: "output"; type: "QWaylandOutput"; isPointer: true }
}
Method { name: "processWaylandEvents" }
Method {
@@ -81,42 +94,79 @@ Module {
}
Component {
name: "QWaylandCompositorExtension"
- prototype: "QObject"
+ prototype: "QWaylandObject"
exports: ["QtWayland.Compositor/WaylandExtension 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
}
Component {
- name: "QWaylandInputDevice"
+ name: "QWaylandDrag"
prototype: "QObject"
- exports: ["QtWayland.Compositor/WaylandInputDevice 1.0"]
+ exports: ["QtWayland.Compositor/WaylandDrag 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
- Enum {
- name: "CapabilityFlags"
- values: {
- "Pointer": 1,
- "Keyboard": 2,
- "Touch": 4,
- "DefaultCapabilities": 7
- }
+ Property { name: "icon"; type: "QWaylandSurface"; isReadonly: true; isPointer: true }
+ Property { name: "visible"; type: "bool"; isReadonly: true }
+ Signal { name: "dragStarted" }
+ Method {
+ name: "dragMove"
+ Parameter { name: "target"; type: "QWaylandSurface"; isPointer: true }
+ Parameter { name: "pos"; type: "QPointF" }
}
+ Method { name: "drop" }
+ Method { name: "cancelDrag" }
+ }
+ Component {
+ name: "QWaylandIviApplication"
+ prototype: "QWaylandCompositorExtension"
Signal {
- name: "mouseFocusChanged"
- Parameter { name: "newFocus"; type: "QWaylandView"; isPointer: true }
- Parameter { name: "oldFocus"; type: "QWaylandView"; isPointer: true }
+ name: "iviSurfaceRequested"
+ Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
+ Parameter { name: "iviId"; type: "uint" }
+ Parameter { name: "resource"; type: "QWaylandResource" }
}
Signal {
- name: "keyboardFocusChanged"
- Parameter { name: "newFocus"; type: "QWaylandSurface"; isPointer: true }
- Parameter { name: "oldFocus"; type: "QWaylandSurface"; isPointer: true }
+ name: "iviSurfaceCreated"
+ Parameter { name: "iviSurface"; type: "QWaylandIviSurface"; isPointer: true }
}
- Signal {
- name: "cursorSurfaceRequest"
+ }
+ Component {
+ name: "QWaylandIviApplicationQuickExtension"
+ defaultProperty: "data"
+ prototype: "QWaylandIviApplication"
+ exports: ["QtWayland.Compositor/IviApplication 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ }
+ Component {
+ name: "QWaylandIviSurface"
+ prototype: "QWaylandShellSurface"
+ exports: ["QtWayland.Compositor/IviSurface 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true }
+ Property { name: "iviId"; type: "uint"; isReadonly: true }
+ Method {
+ name: "initialize"
+ Parameter { name: "iviApplication"; type: "QWaylandIviApplication"; isPointer: true }
Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
- Parameter { name: "hotspotX"; type: "int" }
- Parameter { name: "hotspotY"; type: "int" }
+ Parameter { name: "iviId"; type: "uint" }
+ Parameter { name: "resource"; type: "QWaylandResource" }
}
+ Method {
+ name: "sendConfigure"
+ Parameter { name: "size"; type: "QSize" }
+ }
+ }
+ Component {
+ name: "QWaylandKeymap"
+ prototype: "QObject"
+ exports: ["QtWayland.Compositor/WaylandKeymap 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "layout"; type: "string" }
+ Property { name: "variant"; type: "string" }
+ Property { name: "options"; type: "string" }
+ Property { name: "rules"; type: "string" }
+ Property { name: "model"; type: "string" }
}
Component {
name: "QWaylandMouseTracker"
@@ -127,12 +177,16 @@ Module {
Property { name: "mouseX"; type: "double"; isReadonly: true }
Property { name: "mouseY"; type: "double"; isReadonly: true }
Property { name: "containsMouse"; type: "bool"; isReadonly: true }
- Property { name: "enableWSCursor"; type: "bool" }
+ Property { name: "windowSystemCursorEnabled"; type: "bool" }
Signal { name: "hoveredChanged" }
}
+ Component { name: "QWaylandObject"; prototype: "QObject" }
Component {
name: "QWaylandOutput"
- prototype: "QObject"
+ prototype: "QWaylandObject"
+ exports: ["QtWayland.Compositor/WaylandOutputBase 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
Enum {
name: "Subpixel"
values: {
@@ -162,7 +216,6 @@ Module {
Property { name: "manufacturer"; type: "string" }
Property { name: "model"; type: "string" }
Property { name: "position"; type: "QPoint" }
- Property { name: "mode"; type: "QWaylandOutput::Mode" }
Property { name: "geometry"; type: "QRect"; isReadonly: true }
Property { name: "availableGeometry"; type: "QRect" }
Property { name: "physicalSize"; type: "QSize" }
@@ -170,9 +223,29 @@ Module {
Property { name: "transform"; type: "QWaylandOutput::Transform" }
Property { name: "scaleFactor"; type: "int" }
Property { name: "sizeFollowsWindow"; type: "bool" }
+ Signal { name: "modeAdded" }
+ Signal { name: "currentModeChanged" }
Signal { name: "physicalSizeFollowsSizeChanged" }
Signal { name: "windowDestroyed" }
}
+ Component {
+ name: "QWaylandQtWindowManager"
+ prototype: "QWaylandCompositorExtension"
+ Property { name: "showIsFullScreen"; type: "bool" }
+ Signal {
+ name: "openUrl"
+ Parameter { name: "client"; type: "QWaylandClient"; isPointer: true }
+ Parameter { name: "url"; type: "QUrl" }
+ }
+ }
+ Component {
+ name: "QWaylandQtWindowManagerQuickExtension"
+ defaultProperty: "data"
+ prototype: "QWaylandQtWindowManager"
+ exports: ["QtWayland.Compositor/QtWindowManager 1.0"]
+ exportMetaObjectRevisions: [0]
+ Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
+ }
Component { name: "QWaylandQuickCompositor"; prototype: "QWaylandCompositor" }
Component {
name: "QWaylandQuickCompositorQuickExtensionContainer"
@@ -194,7 +267,6 @@ Module {
prototype: "QQuickItem"
exports: ["QtWayland.Compositor/WaylandQuickItem 1.0"]
exportMetaObjectRevisions: [0]
- Property { name: "view"; type: "QWaylandView"; isReadonly: true; isPointer: true }
Property { name: "compositor"; type: "QWaylandCompositor"; isReadonly: true; isPointer: true }
Property { name: "surface"; type: "QWaylandSurface"; isPointer: true }
Property { name: "paintEnabled"; type: "bool" }
@@ -204,6 +276,9 @@ Module {
Property { name: "focusOnClick"; type: "bool" }
Property { name: "sizeFollowsSurface"; type: "bool" }
Property { name: "subsurfaceHandler"; type: "QObject"; isPointer: true }
+ Property { name: "output"; type: "QWaylandOutput"; isPointer: true }
+ Property { name: "bufferLocked"; type: "bool" }
+ Property { name: "allowDiscardFrontBuffer"; type: "bool" }
Signal { name: "surfaceDestroyed" }
Signal {
name: "mouseMove"
@@ -212,7 +287,7 @@ Module {
Signal { name: "mouseRelease" }
Method {
name: "takeFocus"
- Parameter { name: "device"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "device"; type: "QWaylandSeat"; isPointer: true }
}
Method { name: "takeFocus" }
Method {
@@ -222,6 +297,11 @@ Module {
Method { name: "raise" }
Method { name: "lower" }
Method {
+ name: "mapToSurface"
+ type: "QPointF"
+ Parameter { name: "point"; type: "QPointF" }
+ }
+ Method {
name: "inputMethodQuery"
type: "QVariant"
Parameter { name: "query"; type: "Qt::InputMethodQuery" }
@@ -260,15 +340,65 @@ Module {
exportMetaObjectRevisions: [0]
}
Component {
+ name: "QWaylandSeat"
+ prototype: "QWaylandObject"
+ exports: ["QtWayland.Compositor/WaylandSeat 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "CapabilityFlags"
+ values: {
+ "Pointer": 1,
+ "Keyboard": 2,
+ "Touch": 4,
+ "DefaultCapabilities": 7
+ }
+ }
+ Property { name: "drag"; type: "QWaylandDrag"; isReadonly: true; isPointer: true }
+ Property { name: "keymap"; type: "QWaylandKeymap"; isReadonly: true; isPointer: true }
+ Signal {
+ name: "mouseFocusChanged"
+ Parameter { name: "newFocus"; type: "QWaylandView"; isPointer: true }
+ Parameter { name: "oldFocus"; type: "QWaylandView"; isPointer: true }
+ }
+ Signal {
+ name: "keyboardFocusChanged"
+ Parameter { name: "newFocus"; type: "QWaylandSurface"; isPointer: true }
+ Parameter { name: "oldFocus"; type: "QWaylandSurface"; isPointer: true }
+ }
+ Signal {
+ name: "cursorSurfaceRequest"
+ Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
+ Parameter { name: "hotspotX"; type: "int" }
+ Parameter { name: "hotspotY"; type: "int" }
+ }
+ }
+ Component {
+ name: "QWaylandShell"
+ prototype: "QWaylandCompositorExtension"
+ exports: ["QtWayland.Compositor/Shell 1.0"]
+ isCreatable: false
+ exportMetaObjectRevisions: [0]
+ Enum {
+ name: "FocusPolicy"
+ values: {
+ "AutomaticFocus": 0,
+ "ManualFocus": 1
+ }
+ }
+ Property { name: "focusPolicy"; type: "FocusPolicy" }
+ }
+ Component {
name: "QWaylandShellSurface"
prototype: "QWaylandCompositorExtension"
exports: ["QtWayland.Compositor/ShellSurface 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
+ Property { name: "windowType"; type: "Qt::WindowType"; isReadonly: true }
}
Component {
name: "QWaylandSurface"
- prototype: "QObject"
+ prototype: "QWaylandObject"
exports: ["QtWayland.Compositor/WaylandSurfaceBase 1.0"]
isCreatable: false
exportMetaObjectRevisions: [0]
@@ -284,9 +414,8 @@ Module {
Property { name: "bufferScale"; type: "int"; isReadonly: true }
Property { name: "contentOrientation"; type: "Qt::ScreenOrientation"; isReadonly: true }
Property { name: "origin"; type: "QWaylandSurface::Origin"; isReadonly: true }
- Property { name: "isMapped"; type: "bool"; isReadonly: true }
+ Property { name: "hasContent"; type: "bool"; isReadonly: true }
Property { name: "cursorSurface"; type: "bool" }
- Signal { name: "mappedChanged" }
Signal {
name: "damaged"
Parameter { name: "rect"; type: "QRegion" }
@@ -318,6 +447,10 @@ Module {
Parameter { name: "sibling"; type: "QWaylandSurface"; isPointer: true }
}
Signal {
+ name: "dragStarted"
+ Parameter { name: "drag"; type: "QWaylandDrag"; isPointer: true }
+ }
+ Signal {
name: "configure"
Parameter { name: "hasBuffer"; type: "bool" }
}
@@ -345,48 +478,18 @@ Module {
Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
}
Component {
- name: "QWaylandView"
- prototype: "QObject"
- exports: ["QtWayland.Compositor/WaylandView 1.0"]
- isCreatable: false
- exportMetaObjectRevisions: [0]
- Property { name: "renderObject"; type: "QObject"; isReadonly: true; isPointer: true }
- Property { name: "surface"; type: "QWaylandSurface"; isPointer: true }
- Property { name: "output"; type: "QWaylandOutput"; isPointer: true }
- Property { name: "bufferLock"; type: "bool" }
- Property { name: "discardFrontBuffers"; type: "bool" }
- Signal { name: "surfaceDestroyed" }
- }
- Component {
- name: "QWaylandWindowManagerExtension"
- prototype: "QWaylandCompositorExtension"
- Property { name: "showIsFullScreen"; type: "bool" }
- Signal {
- name: "openUrl"
- Parameter { name: "client"; type: "QWaylandClient"; isPointer: true }
- Parameter { name: "url"; type: "QUrl" }
- }
- }
- Component {
- name: "QWaylandWindowManagerExtensionQuickExtension"
- defaultProperty: "data"
- prototype: "QWaylandWindowManagerExtension"
- exports: ["QtWayland.Compositor/WindowManager 1.0"]
- exportMetaObjectRevisions: [0]
- Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
- }
- Component {
name: "QWaylandWlShell"
- prototype: "QWaylandCompositorExtension"
+ prototype: "QWaylandShell"
Signal {
- name: "createShellSurface"
+ name: "wlShellSurfaceRequested"
Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
Parameter { name: "resource"; type: "QWaylandResource" }
}
Signal {
- name: "shellSurfaceCreated"
+ name: "wlShellSurfaceCreated"
Parameter { name: "shellSurface"; type: "QWaylandWlShellSurface"; isPointer: true }
}
+ Method { name: "closeAllPopups" }
}
Component {
name: "QWaylandWlShellQuickExtension"
@@ -399,12 +502,8 @@ Module {
Component {
name: "QWaylandWlShellSurface"
prototype: "QWaylandShellSurface"
- exports: [
- "QtWayland.Compositor/WlShellSurface 1.0",
- "QtWayland.Compositor/WlShellSurfaceBase 1.0"
- ]
- isCreatable: false
- exportMetaObjectRevisions: [0, 0]
+ exports: ["QtWayland.Compositor/WlShellSurface 1.0"]
+ exportMetaObjectRevisions: [0]
Enum {
name: "FullScreenMethod"
values: {
@@ -428,25 +527,18 @@ Module {
"BottomRightEdge": 10
}
}
- Enum {
- name: "FocusPolicy"
- values: {
- "DefaultFocus": 0,
- "NoKeyboardFocus": 1
- }
- }
Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true }
+ Property { name: "shell"; type: "QWaylandWlShell"; isReadonly: true; isPointer: true }
Property { name: "title"; type: "string"; isReadonly: true }
Property { name: "className"; type: "string"; isReadonly: true }
- Property { name: "focusPolicy"; type: "FocusPolicy"; isReadonly: true }
Signal { name: "pong" }
Signal {
name: "startMove"
- Parameter { name: "inputDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
}
Signal {
name: "startResize"
- Parameter { name: "inputDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
Parameter { name: "edges"; type: "ResizeEdge" }
}
Signal { name: "setDefaultToplevel" }
@@ -454,7 +546,7 @@ Module {
name: "setTransient"
Parameter { name: "parentSurface"; type: "QWaylandSurface"; isPointer: true }
Parameter { name: "relativeToParent"; type: "QPoint" }
- Parameter { name: "focusPolicy"; type: "FocusPolicy" }
+ Parameter { name: "inactive"; type: "bool" }
}
Signal {
name: "setFullScreen"
@@ -464,7 +556,7 @@ Module {
}
Signal {
name: "setPopup"
- Parameter { name: "inputDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
Parameter { name: "parentSurface"; type: "QWaylandSurface"; isPointer: true }
Parameter { name: "relativeToParent"; type: "QPoint" }
}
@@ -494,26 +586,26 @@ Module {
Method { name: "sendPopupDone" }
}
Component {
- name: "QWaylandXdgShell"
- prototype: "QWaylandCompositorExtension"
+ name: "QWaylandXdgShellV5"
+ prototype: "QWaylandShell"
Signal {
- name: "createXdgSurface"
+ name: "xdgSurfaceRequested"
Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
Parameter { name: "resource"; type: "QWaylandResource" }
}
Signal {
name: "xdgSurfaceCreated"
- Parameter { name: "xdgSurface"; type: "QWaylandXdgSurface"; isPointer: true }
+ Parameter { name: "xdgSurface"; type: "QWaylandXdgSurfaceV5"; isPointer: true }
}
Signal {
name: "xdgPopupCreated"
- Parameter { name: "xdgPopup"; type: "QWaylandXdgPopup"; isPointer: true }
+ Parameter { name: "xdgPopup"; type: "QWaylandXdgPopupV5"; isPointer: true }
}
Signal {
- name: "createXdgPopup"
+ name: "xdgPopupRequested"
Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
Parameter { name: "parent"; type: "QWaylandSurface"; isPointer: true }
- Parameter { name: "seat"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
Parameter { name: "position"; type: "QPoint" }
Parameter { name: "resource"; type: "QWaylandResource" }
}
@@ -529,22 +621,18 @@ Module {
Method { name: "closeAllPopups" }
}
Component {
- name: "QWaylandXdgShellQuickExtension"
+ name: "QWaylandXdgShellV5QuickExtension"
defaultProperty: "data"
- prototype: "QWaylandXdgShell"
- exports: ["QtWayland.Compositor/XdgShell 1.0"]
+ prototype: "QWaylandXdgShellV5"
+ exports: ["QtWayland.Compositor/XdgShellV5 1.0"]
exportMetaObjectRevisions: [0]
Property { name: "data"; type: "QObject"; isList: true; isReadonly: true }
}
Component {
- name: "QWaylandXdgSurface"
+ name: "QWaylandXdgSurfaceV5"
prototype: "QWaylandShellSurface"
- exports: [
- "QtWayland.Compositor/XdgSurface 1.0",
- "QtWayland.Compositor/XdgSurfaceBase 1.0"
- ]
- isCreatable: false
- exportMetaObjectRevisions: [0, 0]
+ exports: ["QtWayland.Compositor/XdgSurfaceV5 1.0"]
+ exportMetaObjectRevisions: [0]
Enum {
name: "State"
values: {
@@ -568,8 +656,14 @@ Module {
"BottomRightEdge": 10
}
}
+ Property { name: "shell"; type: "QWaylandXdgShellV5"; isReadonly: true; isPointer: true }
Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true }
- Property { name: "parentSurface"; type: "QWaylandXdgSurface"; isReadonly: true; isPointer: true }
+ Property {
+ name: "parentSurface"
+ type: "QWaylandXdgSurfaceV5"
+ isReadonly: true
+ isPointer: true
+ }
Property { name: "title"; type: "string"; isReadonly: true }
Property { name: "appId"; type: "string"; isReadonly: true }
Property { name: "windowGeometry"; type: "QRect"; isReadonly: true }
@@ -580,18 +674,20 @@ Module {
Property { name: "activated"; type: "bool"; isReadonly: true }
Signal {
name: "showWindowMenu"
- Parameter { name: "inputDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
Parameter { name: "localSurfacePosition"; type: "QPoint" }
}
Signal {
name: "startMove"
- Parameter { name: "inputDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
}
Signal {
name: "startResize"
- Parameter { name: "inputDevice"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "seat"; type: "QWaylandSeat"; isPointer: true }
Parameter { name: "edges"; type: "ResizeEdge" }
}
+ Signal { name: "setTopLevel" }
+ Signal { name: "setTransient" }
Signal { name: "setMaximized" }
Signal { name: "unsetMaximized" }
Signal {
@@ -606,7 +702,7 @@ Module {
}
Method {
name: "initialize"
- Parameter { name: "xdgShell"; type: "QWaylandXdgShell"; isPointer: true }
+ Parameter { name: "xdgShell"; type: "QWaylandXdgShellV5"; isPointer: true }
Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true }
Parameter { name: "resource"; type: "QWaylandResource" }
}
@@ -631,23 +727,23 @@ Module {
}
Method { name: "sendClose" }
Method {
- name: "requestMaximized"
+ name: "sendMaximized"
type: "uint"
Parameter { name: "size"; type: "QSize" }
}
Method {
- name: "requestUnMaximized"
+ name: "sendUnmaximized"
type: "uint"
Parameter { name: "size"; type: "QSize" }
}
- Method { name: "requestUnMaximized"; type: "uint" }
+ Method { name: "sendUnmaximized"; type: "uint" }
Method {
- name: "requestFullscreen"
+ name: "sendFullscreen"
type: "uint"
Parameter { name: "size"; type: "QSize" }
}
Method {
- name: "requestResizing"
+ name: "sendResizing"
type: "uint"
Parameter { name: "maxSize"; type: "QSize" }
}
@@ -659,7 +755,7 @@ Module {
exportMetaObjectRevisions: [0]
isComposite: true
defaultProperty: "data"
- Property { name: "inputDevice"; type: "QObject"; isPointer: true }
+ Property { name: "seat"; type: "QObject"; isPointer: true }
Property { name: "hotspotX"; type: "int" }
Property { name: "hotspotY"; type: "int" }
Method {
@@ -669,7 +765,6 @@ Module {
Parameter { name: "hotspotX"; type: "QVariant" }
Parameter { name: "hotspotY"; type: "QVariant" }
}
- Property { name: "view"; type: "QWaylandView"; isReadonly: true; isPointer: true }
Property { name: "compositor"; type: "QWaylandCompositor"; isReadonly: true; isPointer: true }
Property { name: "surface"; type: "QWaylandSurface"; isPointer: true }
Property { name: "paintEnabled"; type: "bool" }
@@ -679,6 +774,9 @@ Module {
Property { name: "focusOnClick"; type: "bool" }
Property { name: "sizeFollowsSurface"; type: "bool" }
Property { name: "subsurfaceHandler"; type: "QObject"; isPointer: true }
+ Property { name: "output"; type: "QWaylandOutput"; isPointer: true }
+ Property { name: "bufferLocked"; type: "bool" }
+ Property { name: "allowDiscardFrontBuffer"; type: "bool" }
Signal { name: "surfaceDestroyed" }
Signal {
name: "mouseMove"
@@ -687,7 +785,7 @@ Module {
Signal { name: "mouseRelease" }
Method {
name: "takeFocus"
- Parameter { name: "device"; type: "QWaylandInputDevice"; isPointer: true }
+ Parameter { name: "device"; type: "QWaylandSeat"; isPointer: true }
}
Method { name: "takeFocus" }
Method {
@@ -697,6 +795,11 @@ Module {
Method { name: "raise" }
Method { name: "lower" }
Method {
+ name: "mapToSurface"
+ type: "QPointF"
+ Parameter { name: "point"; type: "QPointF" }
+ }
+ Method {
name: "inputMethodQuery"
type: "QVariant"
Parameter { name: "query"; type: "Qt::InputMethodQuery" }
diff --git a/src/imports/compositor/qwaylandmousetracker.cpp b/src/imports/compositor/qwaylandmousetracker.cpp
index a77d6b1a0..489dc7b55 100644
--- a/src/imports/compositor/qwaylandmousetracker.cpp
+++ b/src/imports/compositor/qwaylandmousetracker.cpp
@@ -45,7 +45,7 @@ class QWaylandMouseTrackerPrivate : public QQuickItemPrivate
Q_DECLARE_PUBLIC(QWaylandMouseTracker)
public:
QWaylandMouseTrackerPrivate()
- : enableWSCursor(false)
+ : windowSystemCursorEnabled(false)
, hovered(false)
{
QImage cursorImage(64,64,QImage::Format_ARGB32);
@@ -76,7 +76,7 @@ public:
}
QPointF mousePos;
- bool enableWSCursor;
+ bool windowSystemCursorEnabled;
QPixmap cursorPixmap;
bool hovered;
};
@@ -102,24 +102,24 @@ qreal QWaylandMouseTracker::mouseY() const
return d->mousePos.y();
}
-void QWaylandMouseTracker::setEnableWSCursor(bool enable)
+void QWaylandMouseTracker::setWindowSystemCursorEnabled(bool enable)
{
Q_D(QWaylandMouseTracker);
- if (d->enableWSCursor != enable) {
- d->enableWSCursor = enable;
+ if (d->windowSystemCursorEnabled != enable) {
+ d->windowSystemCursorEnabled = enable;
if (enable) {
unsetCursor();
} else {
setCursor(QCursor(d->cursorPixmap));
}
- emit enableWSCursorChanged();
+ emit windowSystemCursorEnabledChanged();
}
}
-bool QWaylandMouseTracker::enableWSCursor() const
+bool QWaylandMouseTracker::windowSystemCursorEnabled() const
{
Q_D(const QWaylandMouseTracker);
- return d->enableWSCursor;
+ return d->windowSystemCursorEnabled;
}
bool QWaylandMouseTracker::hovered() const
diff --git a/src/imports/compositor/qwaylandmousetracker_p.h b/src/imports/compositor/qwaylandmousetracker_p.h
index 1bc37a5e2..d90b037ff 100644
--- a/src/imports/compositor/qwaylandmousetracker_p.h
+++ b/src/imports/compositor/qwaylandmousetracker_p.h
@@ -53,21 +53,21 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandMouseTracker : public QQuickItem
Q_PROPERTY(qreal mouseY READ mouseY NOTIFY mouseYChanged)
Q_PROPERTY(bool containsMouse READ hovered NOTIFY hoveredChanged)
- Q_PROPERTY(bool enableWSCursor READ enableWSCursor WRITE setEnableWSCursor NOTIFY enableWSCursorChanged)
+ Q_PROPERTY(bool windowSystemCursorEnabled READ windowSystemCursorEnabled WRITE setWindowSystemCursorEnabled NOTIFY windowSystemCursorEnabledChanged)
public:
QWaylandMouseTracker(QQuickItem *parent = 0);
qreal mouseX() const;
qreal mouseY() const;
- void setEnableWSCursor(bool enable);
- bool enableWSCursor() const;
+ void setWindowSystemCursorEnabled(bool enable);
+ bool windowSystemCursorEnabled() const;
bool hovered() const;
signals:
void mouseXChanged();
void mouseYChanged();
- void enableWSCursorChanged();
+ void windowSystemCursorEnabledChanged();
void hoveredChanged();
protected:
diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp
index c992d3fcb..28c517fd5 100644
--- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp
+++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp
@@ -46,14 +46,18 @@
#include <QtWaylandCompositor/QWaylandQuickOutput>
#include <QtWaylandCompositor/QWaylandCompositorExtension>
#include <QtWaylandCompositor/QWaylandQuickExtension>
-#include <QtWaylandCompositor/QWaylandInputDevice>
+#include <QtWaylandCompositor/QWaylandSeat>
+#include <QtWaylandCompositor/QWaylandDrag>
+#include <QtWaylandCompositor/QWaylandKeymap>
#include <QtWaylandCompositor/QWaylandQuickShellSurfaceItem>
#include <QtWaylandCompositor/QWaylandResource>
-#include <QtWaylandCompositor/QWaylandWindowManagerExtension>
+#include <QtWaylandCompositor/QWaylandQtWindowManager>
#include <QtWaylandCompositor/QWaylandWlShell>
#include <QtWaylandCompositor/QWaylandTextInputManager>
-#include <QtWaylandCompositor/QWaylandXdgShell>
+#include <QtWaylandCompositor/QWaylandXdgShellV5>
+#include <QtWaylandCompositor/QWaylandIviApplication>
+#include <QtWaylandCompositor/QWaylandIviSurface>
#include <QtWaylandCompositor/qwaylandexport.h>
#include "qwaylandmousetracker_p.h"
@@ -61,9 +65,10 @@
QT_BEGIN_NAMESPACE
Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CONTAINER_CLASS(QWaylandQuickCompositor)
-Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandWindowManagerExtension)
+Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandQtWindowManager)
+Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandIviApplication)
Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandWlShell)
-Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShell)
+Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShellV5)
Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandTextInputManager)
class QmlUrlResolver
@@ -91,7 +96,7 @@ private:
class QWaylandCompositorPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface/1.0")
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
virtual void registerTypes(const char *uri)
{
@@ -116,25 +121,28 @@ public:
qmlRegisterType<QWaylandMouseTracker>(uri, 1, 0, "WaylandMouseTracker");
qmlRegisterType<QWaylandQuickOutput>(uri, 1, 0, "WaylandOutput");
qmlRegisterType<QWaylandQuickSurface>(uri, 1, 0, "WaylandSurface");
+ qmlRegisterType<QWaylandKeymap>(uri, 1, 0, "WaylandKeymap");
qmlRegisterUncreatableType<QWaylandCompositorExtension>(uri, 1, 0, "WaylandExtension", QObject::tr("Cannot create instance of WaylandExtension"));
qmlRegisterUncreatableType<QWaylandClient>(uri, 1, 0, "WaylandClient", QObject::tr("Cannot create instance of WaylandClient"));
- qmlRegisterUncreatableType<QWaylandView>(uri, 1, 0, "WaylandView", QObject::tr("Cannot create instance of WaylandView, it can be retrieved by accessor on WaylandQuickItem"));
- qmlRegisterUncreatableType<QWaylandInputDevice>(uri, 1, 0, "WaylandInputDevice", QObject::tr("Cannot create instance of WaylandInputDevice"));
+ qmlRegisterUncreatableType<QWaylandOutput>(uri, 1, 0, "WaylandOutputBase", QObject::tr("Cannot create instance of WaylandOutputBase, use WaylandOutput instead"));
+ qmlRegisterUncreatableType<QWaylandSeat>(uri, 1, 0, "WaylandSeat", QObject::tr("Cannot create instance of WaylandSeat"));
+ qmlRegisterUncreatableType<QWaylandDrag>(uri, 1, 0, "WaylandDrag", QObject::tr("Cannot create instance of WaylandDrag"));
qmlRegisterUncreatableType<QWaylandCompositor>(uri, 1, 0, "WaylandCompositorBase", QObject::tr("Cannot create instance of WaylandCompositorBase, use WaylandCompositor instead"));
qmlRegisterUncreatableType<QWaylandSurface>(uri, 1, 0, "WaylandSurfaceBase", QObject::tr("Cannot create instance of WaylandSurfaceBase, use WaylandSurface instead"));
+ qmlRegisterUncreatableType<QWaylandShell>(uri, 1, 0, "Shell", QObject::tr("Cannot create instance of Shell"));
qmlRegisterUncreatableType<QWaylandShellSurface>(uri, 1, 0, "ShellSurface", QObject::tr("Cannot create instance of ShellSurface"));
- qmlRegisterUncreatableType<QWaylandWlShellSurface>(uri, 1, 0, "WlShellSurfaceBase", QObject::tr("Cannot create instance of WlShellSurfaceBase, use WlShellSurface instead"));
- qmlRegisterUncreatableType<QWaylandXdgSurface>(uri, 1, 0, "XdgSurfaceBase", QObject::tr("Cannot create instance of XdgSurfaceBase, use XdgSurface instead"));
qmlRegisterUncreatableType<QWaylandResource>(uri, 1, 0, "WaylandResource", QObject::tr("Cannot create instance of WaylandResource"));
//This should probably be somewhere else
- qmlRegisterType<QWaylandWindowManagerExtensionQuickExtension>(uri, 1, 0, "WindowManager");
+ qmlRegisterType<QWaylandQtWindowManagerQuickExtension>(uri, 1, 0, "QtWindowManager");
+ qmlRegisterType<QWaylandIviApplicationQuickExtension>(uri, 1, 0, "IviApplication");
+ qmlRegisterType<QWaylandIviSurface>(uri, 1, 0, "IviSurface");
qmlRegisterType<QWaylandWlShellQuickExtension>(uri, 1, 0, "WlShell");
qmlRegisterType<QWaylandWlShellSurface>(uri, 1, 0, "WlShellSurface");
qmlRegisterType<QWaylandQuickShellSurfaceItem>(uri, 1, 0, "ShellSurfaceItem");
- qmlRegisterType<QWaylandXdgShellQuickExtension>(uri, 1, 0, "XdgShell");
- qmlRegisterType<QWaylandXdgSurface>(uri, 1, 0, "XdgSurface");
+ qmlRegisterType<QWaylandXdgShellV5QuickExtension>(uri, 1, 0, "XdgShellV5");
+ qmlRegisterType<QWaylandXdgSurfaceV5>(uri, 1, 0, "XdgSurfaceV5");
qmlRegisterType<QWaylandTextInputManagerQuickExtension>(uri, 1, 0, "TextInputManager");
}
};
diff --git a/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro
index 7374a5982..9ddd961c7 100644
--- a/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro
+++ b/src/plugins/hardwareintegration/compositor/wayland-egl/wayland-egl.pro
@@ -1,4 +1,4 @@
-QT = waylandcompositor waylandcompositor-private core-private gui-private platformsupport-private
+QT = waylandcompositor waylandcompositor-private core-private gui-private
OTHER_FILES += wayland-egl.json
diff --git a/src/shared/qwaylandshmformathelper_p.h b/src/shared/qwaylandsharedmemoryformathelper_p.h
index 58db42e26..7f2f77cc3 100644
--- a/src/shared/qwaylandshmformathelper_p.h
+++ b/src/shared/qwaylandsharedmemoryformathelper_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef QWAYLANDSHMFORMATHELPER_H
-#define QWAYLANDSHMFORMATHELPER_H
+#ifndef QWAYLANDSHAREDMEMORYFORMATHELPER_H
+#define QWAYLANDSHAREDMEMORYFORMATHELPER_H
#include <QtGui/QImage>
@@ -47,7 +47,7 @@
QT_BEGIN_NAMESPACE
-class QWaylandShmFormatHelper
+class QWaylandSharedMemoryFormatHelper
{
public:
static inline wl_shm_format fromQImageFormat(QImage::Format format);
@@ -100,7 +100,7 @@ private:
}
};
-wl_shm_format QWaylandShmFormatHelper::fromQImageFormat(QImage::Format format)
+wl_shm_format QWaylandSharedMemoryFormatHelper::fromQImageFormat(QImage::Format format)
{
Array array = getData();
if (array.size <= size_t(format))
@@ -108,7 +108,7 @@ wl_shm_format QWaylandShmFormatHelper::fromQImageFormat(QImage::Format format)
return array.data[format];
}
-QImage::Format QWaylandShmFormatHelper::fromWaylandShmFormat(wl_shm_format format)
+QImage::Format QWaylandSharedMemoryFormatHelper::fromWaylandShmFormat(wl_shm_format format)
{
Array array = getData();
for (size_t i = 0; i < array.size; i++) {
@@ -118,7 +118,7 @@ QImage::Format QWaylandShmFormatHelper::fromWaylandShmFormat(wl_shm_format forma
return QImage::Format_Invalid;
}
-QVector<wl_shm_format> QWaylandShmFormatHelper::supportedWaylandFormats()
+QVector<wl_shm_format> QWaylandSharedMemoryFormatHelper::supportedWaylandFormats()
{
QVector<wl_shm_format> retFormats;
Array array = getData();
@@ -133,4 +133,4 @@ QVector<wl_shm_format> QWaylandShmFormatHelper::supportedWaylandFormats()
QT_END_NAMESPACE
-#endif //QWAYLANDSHMFORMATHELPER_H
+#endif //QWAYLANDSHAREDMEMORYFORMATHELPER_H