diff options
73 files changed, 781 insertions, 1144 deletions
diff --git a/config.tests/dmabuf_client_buffer/dmabuf_client_buffer.pro b/config.tests/dmabuf_client_buffer/dmabuf_client_buffer.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/dmabuf_client_buffer/dmabuf_client_buffer.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/dmabuf_client_buffer/main.cpp b/config.tests/dmabuf_client_buffer/main.cpp deleted file mode 100644 index 71447dc8e..000000000 --- a/config.tests/dmabuf_client_buffer/main.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <EGL/egl.h> -#include <EGL/eglext.h> - -//If libdrm is available, the following files should exist -#include "drm_mode.h" -#include "drm_fourcc.h" - -int main() -{ -// test if DMA BUF is supported -#ifndef EGL_LINUX_DMA_BUF_EXT -#error DMA BUF Extension not available -#endif - -// test if DMA BUF import modifier extension is supported -#ifndef EGL_EXT_image_dma_buf_import_modifiers -#error DMA BUF Import modifier extension not available -#endif - - return 0; -} diff --git a/config.tests/dmabuf_server_buffer/dmabuf_server_buffer.pro b/config.tests/dmabuf_server_buffer/dmabuf_server_buffer.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/dmabuf_server_buffer/dmabuf_server_buffer.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/dmabuf_server_buffer/main.cpp b/config.tests/dmabuf_server_buffer/main.cpp deleted file mode 100644 index aa04d18fd..000000000 --- a/config.tests/dmabuf_server_buffer/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <drm_fourcc.h> - -int main() -{ -#ifdef EGL_LINUX_DMA_BUF_EXT - return 0; -#else -#error Requires EGL_LINUX_DMA_BUF_EXT - return 1; -#endif -} diff --git a/config.tests/drm_egl_server/drm_egl_server.pro b/config.tests/drm_egl_server/drm_egl_server.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/drm_egl_server/drm_egl_server.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/drm_egl_server/main.cpp b/config.tests/drm_egl_server/main.cpp deleted file mode 100644 index 0dbd42f90..000000000 --- a/config.tests/drm_egl_server/main.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <EGL/egl.h> -#include <EGL/eglext.h> - -int main() -{ -#ifdef EGL_MESA_drm_image - return 0; -#else -#error Requires EGL_MESA_drm_image to be defined - return 1; -#endif -} diff --git a/config.tests/glx/glx.pro b/config.tests/glx/glx.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/glx/glx.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/glx/main.cpp b/config.tests/glx/main.cpp deleted file mode 100644 index c902c55d7..000000000 --- a/config.tests/glx/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <GL/glx.h> - -int main(int argc, char **argv) -{ - Display *dpy = XOpenDisplay(0); - - int items = 0; - GLXFBConfig *fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), 0 , &items); - return 0; -} diff --git a/config.tests/libhybris_egl_server/libhybris_egl_server.pro b/config.tests/libhybris_egl_server/libhybris_egl_server.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/libhybris_egl_server/libhybris_egl_server.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/libhybris_egl_server/main.cpp b/config.tests/libhybris_egl_server/main.cpp deleted file mode 100644 index 368b57a12..000000000 --- a/config.tests/libhybris_egl_server/main.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jolla Ltd, author: <giulio.camuffo@jollamobile.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <EGL/egl.h> -#include <EGL/eglext.h> -#include <hybris/eglplatformcommon/hybris_nativebufferext.h> - -int main() -{ -#ifdef EGL_HYBRIS_native_buffer - return 0; -#else -#error Requires EGL_HYBRIS_native_buffer to be defined - return 1; -#endif -} diff --git a/config.tests/vulkan_server_buffer/main.cpp b/config.tests/vulkan_server_buffer/main.cpp deleted file mode 100644 index 5bd88d338..000000000 --- a/config.tests/vulkan_server_buffer/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <vulkan/vulkan.h> - -int main() -{ - VkExportMemoryAllocateInfoKHR exportAllocInfo = {}; - exportAllocInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR; - exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; - - return 0; -} diff --git a/config.tests/vulkan_server_buffer/vulkan_server_buffer.pro b/config.tests/vulkan_server_buffer/vulkan_server_buffer.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/vulkan_server_buffer/vulkan_server_buffer.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/wayland/main.cpp b/config.tests/wayland/main.cpp deleted file mode 100644 index 8cab379bf..000000000 --- a/config.tests/wayland/main.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <wayland-version.h> - -int main() -{ -#if WAYLAND_VERSION_MAJOR < 1 -# error Wayland 1.8.0 or higher required -#endif -#if WAYLAND_VERSION_MAJOR == 1 -# if WAYLAND_VERSION_MINOR < 8 -# error Wayland 1.8.0 or higher required -# endif -# if WAYLAND_VERSION_MINOR == 8 -# if WAYLAND_VERSION_MICRO < 0 -# error Wayland 1.8.0 or higher required -# endif -# endif -#endif - return 0; -} diff --git a/config.tests/wayland/wayland.pro b/config.tests/wayland/wayland.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/wayland/wayland.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/wayland_cursor/main.cpp b/config.tests/wayland_cursor/main.cpp deleted file mode 100644 index c9cf66196..000000000 --- a/config.tests/wayland_cursor/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <wayland-cursor.h> - -int main() -{ - struct wl_cursor_image *image = 0; - - return 0; -} diff --git a/config.tests/wayland_cursor/wayland_cursor.pro b/config.tests/wayland_cursor/wayland_cursor.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/wayland_cursor/wayland_cursor.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/wayland_egl/main.cpp b/config.tests/wayland_egl/main.cpp deleted file mode 100644 index c50056469..000000000 --- a/config.tests/wayland_egl/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <wayland-egl.h> - -int main() -{ - struct wl_egl_window *window = wl_egl_window_create(0,100,100); - - return 0; -} diff --git a/config.tests/wayland_egl/wayland_egl.pro b/config.tests/wayland_egl/wayland_egl.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/wayland_egl/wayland_egl.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/config.tests/xcomposite/main.cpp b/config.tests/xcomposite/main.cpp deleted file mode 100644 index 1867b204e..000000000 --- a/config.tests/xcomposite/main.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Compositor. -** -** $QT_BEGIN_LICENSE:BSD$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** BSD License Usage -** Alternatively, you may use this file under the terms of the BSD license -** as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of The Qt Company Ltd nor the names of its -** contributors may be used to endorse or promote products derived -** from this software without specific prior written permission. -** -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <X11/extensions/Xcomposite.h> - -int main (int argc, char **argv) -{ - XCompositeRedirectWindow((Display *)0,(Window) 0,CompositeRedirectManual); - - return 0; -} diff --git a/config.tests/xcomposite/xcomposite.pro b/config.tests/xcomposite/xcomposite.pro deleted file mode 100644 index 28dcadcbf..000000000 --- a/config.tests/xcomposite/xcomposite.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES += main.cpp diff --git a/dist/changes-5.12.5 b/dist/changes-5.12.5 new file mode 100644 index 000000000..cecbdafa7 --- /dev/null +++ b/dist/changes-5.12.5 @@ -0,0 +1,36 @@ +Qt 5.12.5 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.4. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Compositor * +**************************************************************************** + + - [QTBUG-76104] Fixed a build error when configured with -no-opengl. + +**************************************************************************** +* QPA plugin * +**************************************************************************** + + - [QTBUG-76124] Fixed a crash when closing multiple popups at once. + - [QTBUG-76368] Fixed a crash that sometimes happened when starting + a drag-and-drop operation. + - [QTBUG-74085] Fixed crash when using custom Wayland surface. + - [QTBUG-76397] Fixed stuttering when the GUI thread is busy. + - [QTBUG-76657] Fixed occasional update problem when re-showing a hidden window. + - Fixed bug that could truncate large clipboard pastings. diff --git a/dist/changes-5.13.1 b/dist/changes-5.13.1 new file mode 100644 index 000000000..404145e17 --- /dev/null +++ b/dist/changes-5.13.1 @@ -0,0 +1,35 @@ +Qt 5.13.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.13.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.13 series is binary compatible with the 5.12.x series. +Applications compiled for 5.12 will continue to run with 5.13. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Compositor * +**************************************************************************** + + - Fixed a build error when configured with -no-opengl. + +**************************************************************************** +* QPA plugin * +**************************************************************************** + + - Fixed a crash when closing multiple popups at once. + - Fixed a crash that sometimes happened when starting a drag-and-drop + operation. + - Fixed sizing issue with XDG shell on some compositors. + - Fixed stuttering when the GUI thread is busy. + - Fixed occasional update problem when re-showing a hidden window. diff --git a/src/client/configure.json b/src/client/configure.json index 403a2edcf..a25b61f55 100644 --- a/src/client/configure.json +++ b/src/client/configure.json @@ -61,25 +61,76 @@ "drm-egl-server": { "label": "DRM EGL Server", "type": "compile", - "test": "drm_egl_server", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h" + ], + "main": [ + "#ifdef EGL_MESA_drm_image", + "return 0;", + "#else", + "#error Requires EGL_MESA_drm_image to be defined", + "return 1;", + "#endif" + ] + }, "use": "egl" }, "libhybris-egl-server": { "label": "libhybris EGL Server", "type": "compile", - "test": "libhybris_egl_server", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h", + "hybris/eglplatformcommon/hybris_nativebufferext.h" + ], + "main": [ + "#ifdef EGL_HYBRIS_native_buffer", + "return 0;", + "#else", + "#error Requires EGL_HYBRIS_native_buffer to be defined", + "return 1;", + "#endif" + ] + }, "use": "egl" }, "dmabuf-server-buffer": { "label": "Linux dma-buf Buffer Sharing", "type": "compile", - "test": "dmabuf_server_buffer", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h", + "drm_fourcc.h" + ], + "main": [ + "#ifdef EGL_LINUX_DMA_BUF_EXT", + "return 0;", + "#else", + "#error Requires EGL_LINUX_DMA_BUF_EXT", + "return 1;", + "#endif" + ] + }, "use": "egl" }, "vulkan-server-buffer": { "label": "Vulkan Buffer Sharing", "type": "compile", - "test": "vulkan_server_buffer" + "test": { + "include": [ + "vulkan/vulkan.h" + ], + "main": [ + "VkExportMemoryAllocateInfoKHR exportAllocInfo = {};", + "exportAllocInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;", + "exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;", + "return 0;" + ] + } } }, @@ -140,7 +191,7 @@ }, "xcomposite-egl": { "label": "XComposite EGL", - "condition": "features.wayland-client && features.opengl && features.egl && features.xlib && libs.xcomposite", + "condition": "features.wayland-client && features.opengl && features.egl && features.xlib && libs.xcomposite && features.egl_x11", "output": [ "privateFeature" ] }, "xcomposite-glx": { diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp index e7afc3ca8..fc3c7077a 100644 --- a/src/client/qwaylanddatadevice.cpp +++ b/src/client/qwaylanddatadevice.cpp @@ -103,20 +103,23 @@ QWaylandDataOffer *QWaylandDataDevice::dragOffer() const return m_dragOffer.data(); } -void QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) +bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon) { - m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); - connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled); - auto *seat = m_display->currentInputDevice(); auto *origin = seat->pointerFocus(); if (!origin) origin = seat->touchFocus(); - if (origin) - start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); - else + if (!origin) { qCDebug(lcQpaWayland) << "Couldn't start a drag because the origin window could not be found."; + return false; + } + + m_dragSource.reset(new QWaylandDataSource(m_display->dndSelectionHandler(), mimeData)); + connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this, &QWaylandDataDevice::dragSourceCancelled); + + start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(), m_display->currentInputDevice()->serial()); + return true; } void QWaylandDataDevice::cancelDrag() diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h index 0a7f42538..16c3ad28e 100644 --- a/src/client/qwaylanddatadevice_p.h +++ b/src/client/qwaylanddatadevice_p.h @@ -89,7 +89,7 @@ public: #if QT_CONFIG(draganddrop) QWaylandDataOffer *dragOffer() const; - void startDrag(QMimeData *mimeData, QWaylandWindow *icon); + bool startDrag(QMimeData *mimeData, QWaylandWindow *icon); void cancelDrag(); #endif diff --git a/src/client/qwaylanddnd.cpp b/src/client/qwaylanddnd.cpp index b01a9db36..6535aa16b 100644 --- a/src/client/qwaylanddnd.cpp +++ b/src/client/qwaylanddnd.cpp @@ -66,8 +66,13 @@ void QWaylandDrag::startDrag() { QBasicDrag::startDrag(); QWaylandWindow *icon = static_cast<QWaylandWindow *>(shapedPixmapWindow()->handle()); - m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon); - icon->addAttachOffset(-drag()->hotSpot()); + if (m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(), icon)) { + icon->addAttachOffset(-drag()->hotSpot()); + } else { + // Cancelling immediately does not work, since the event loop for QDrag::exec is started + // after this function returns. + QMetaObject::invokeMethod(this, [this](){ cancelDrag(); }, Qt::QueuedConnection); + } } void QWaylandDrag::cancel() diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp index 068c058e7..e9afe05ed 100644 --- a/src/client/qwaylandinputcontext.cpp +++ b/src/client/qwaylandinputcontext.cpp @@ -119,7 +119,8 @@ void QWaylandTextInput::updateState(Qt::InputMethodQueries queries, uint32_t fla if (!QGuiApplication::focusWindow() || !QGuiApplication::focusWindow()->handle()) return; - auto *surface = static_cast<QWaylandWindow *>(QGuiApplication::focusWindow()->handle())->wlSurface(); + auto *window = static_cast<QWaylandWindow *>(QGuiApplication::focusWindow()->handle()); + auto *surface = window->wlSurface(); if (!surface || (surface != m_surface)) return; @@ -157,8 +158,10 @@ void QWaylandTextInput::updateState(Qt::InputMethodQueries queries, uint32_t fla if (queries & Qt::ImCursorRectangle) { const QRect &cRect = event.value(Qt::ImCursorRectangle).toRect(); - const QRect &tRect = QGuiApplication::inputMethod()->inputItemTransform().mapRect(cRect); - set_cursor_rectangle(tRect.x(), tRect.y(), tRect.width(), tRect.height()); + const QRect &windowRect = QGuiApplication::inputMethod()->inputItemTransform().mapRect(cRect); + const QMargins margins = window->frameMargins(); + const QRect &surfaceRect = windowRect.translated(margins.left(), margins.top()); + set_cursor_rectangle(surfaceRect.x(), surfaceRect.y(), surfaceRect.width(), surfaceRect.height()); } if (queries & Qt::ImPreferredLanguage) { diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index f2dee75e6..e39ccf25e 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -1200,7 +1200,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, QEvent::Type type = isDown ? QEvent::KeyPress : QEvent::KeyRelease; handleKey(time, type, qtkey, modifiers, code, sym, mNativeModifiers, text); - if (state == WL_KEYBOARD_KEY_STATE_PRESSED && xkb_keymap_key_repeats(mXkbKeymap.get(), code)) { + if (state == WL_KEYBOARD_KEY_STATE_PRESSED && xkb_keymap_key_repeats(mXkbKeymap.get(), code) && mRepeatRate > 0) { mRepeatKey.key = qtkey; mRepeatKey.code = code; mRepeatKey.time = time; @@ -1295,34 +1295,40 @@ void QWaylandInputDevice::Touch::touch_down(uint32_t serial, mParent->mSerial = serial; mFocus = window; mParent->mQDisplay->setLastInputDevice(mParent, serial, mFocus); - mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointPressed); + QPointF position(wl_fixed_to_double(x), wl_fixed_to_double(y)); + mParent->handleTouchPoint(id, Qt::TouchPointPressed, position); } void QWaylandInputDevice::Touch::touch_up(uint32_t serial, uint32_t time, int32_t id) { Q_UNUSED(serial); Q_UNUSED(time); - mFocus = nullptr; - mParent->handleTouchPoint(id, 0, 0, Qt::TouchPointReleased); + mParent->handleTouchPoint(id, Qt::TouchPointReleased); + + if (allTouchPointsReleased()) { + mFocus = nullptr; - // As of Weston 1.5.90 there is no touch_frame after the last touch_up - // (i.e. when the last finger is released). To accommodate for this, issue a - // touch_frame. This cannot hurt since it is safe to call the touch_frame - // handler multiple times when there are no points left. - if (allTouchPointsReleased()) + // As of Weston 7.0.0 there is no touch_frame after the last touch_up + // (i.e. when the last finger is released). To accommodate for this, issue a + // touch_frame. This cannot hurt since it is safe to call the touch_frame + // handler multiple times when there are no points left. + // See: https://gitlab.freedesktop.org/wayland/weston/issues/44 + // TODO: change logging category to lcQpaWaylandInput in newer versions. + qCDebug(lcQpaWayland, "Generating fake frame event to work around Weston bug"); touch_frame(); + } } void QWaylandInputDevice::Touch::touch_motion(uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y) { Q_UNUSED(time); - mParent->handleTouchPoint(id, wl_fixed_to_double(x), wl_fixed_to_double(y), Qt::TouchPointMoved); + QPointF position(wl_fixed_to_double(x), wl_fixed_to_double(y)); + mParent->handleTouchPoint(id, Qt::TouchPointMoved, position); } void QWaylandInputDevice::Touch::touch_cancel() { - mPrevTouchPoints.clear(); - mTouchPoints.clear(); + mPendingTouchPoints.clear(); QWaylandTouchExtension *touchExt = mParent->mQDisplay->touchExtension(); if (touchExt) @@ -1331,22 +1337,18 @@ void QWaylandInputDevice::Touch::touch_cancel() QWindowSystemInterface::handleTouchCancelEvent(nullptr, mParent->mTouchDevice); } -void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::TouchPointState state) +void QWaylandInputDevice::handleTouchPoint(int id, Qt::TouchPointState state, const QPointF &surfacePosition) { - QWindowSystemInterface::TouchPoint tp; - - // Find out the coordinates for Released events. - bool coordsOk = false; - if (state == Qt::TouchPointReleased) - for (int i = 0; i < mTouch->mPrevTouchPoints.count(); ++i) - if (mTouch->mPrevTouchPoints.at(i).id == id) { - tp.area = mTouch->mPrevTouchPoints.at(i).area; - coordsOk = true; - break; - } + auto end = mTouch->mPendingTouchPoints.end(); + auto it = std::find_if(mTouch->mPendingTouchPoints.begin(), end, [id](auto tp){ return tp.id == id; }); + if (it == end) { + it = mTouch->mPendingTouchPoints.insert(end, QWindowSystemInterface::TouchPoint()); + it->id = id; + } + QWindowSystemInterface::TouchPoint &tp = *it; - if (!coordsOk) { - // x and y are surface relative. + // Only moved and pressed needs to update/set position + if (state == Qt::TouchPointMoved || state == Qt::TouchPointPressed) { // We need a global (screen) position. QWaylandWindow *win = mTouch->mFocus; @@ -1360,63 +1362,46 @@ void QWaylandInputDevice::handleTouchPoint(int id, double x, double y, Qt::Touch tp.area = QRectF(0, 0, 8, 8); QMargins margins = win->frameMargins(); - tp.area.moveCenter(win->window()->mapToGlobal(QPoint(x - margins.left(), y - margins.top()))); + QPointF localPosition = surfacePosition - QPointF(margins.left(), margins.top()); + // TODO: This doesn't account for high dpi scaling for the delta, but at least it matches + // what we have for mouse input. + QPointF delta = localPosition - localPosition.toPoint(); + QPointF globalPosition = win->window()->mapToGlobal(localPosition.toPoint()) + delta; + tp.area.moveCenter(globalPosition); } tp.state = state; - tp.id = id; tp.pressure = tp.state == Qt::TouchPointReleased ? 0 : 1; - mTouch->mTouchPoints.append(tp); } bool QWaylandInputDevice::Touch::allTouchPointsReleased() { - for (int i = 0; i < mTouchPoints.count(); ++i) - if (mTouchPoints.at(i).state != Qt::TouchPointReleased) + for (const auto &tp : qAsConst(mPendingTouchPoints)) { + if (tp.state != Qt::TouchPointReleased) return false; - + } return true; } void QWaylandInputDevice::Touch::releasePoints() { - for (const QWindowSystemInterface::TouchPoint &previousPoint : qAsConst(mPrevTouchPoints)) { - QWindowSystemInterface::TouchPoint tp = previousPoint; + if (mPendingTouchPoints.empty()) + return; + + for (QWindowSystemInterface::TouchPoint &tp : mPendingTouchPoints) tp.state = Qt::TouchPointReleased; - mTouchPoints.append(tp); - } + touch_frame(); } void QWaylandInputDevice::Touch::touch_frame() { - // Copy all points, that are in the previous but not in the current list, as stationary. - for (int i = 0; i < mPrevTouchPoints.count(); ++i) { - const QWindowSystemInterface::TouchPoint &prevPoint(mPrevTouchPoints.at(i)); - if (prevPoint.state == Qt::TouchPointReleased) - continue; - bool found = false; - for (int j = 0; j < mTouchPoints.count(); ++j) - if (mTouchPoints.at(j).id == prevPoint.id) { - found = true; - break; - } - if (!found) { - QWindowSystemInterface::TouchPoint p = prevPoint; - p.state = Qt::TouchPointStationary; - mTouchPoints.append(p); - } - } - - if (mTouchPoints.isEmpty()) { - mPrevTouchPoints.clear(); - return; - } + // TODO: early return if no events? QWindow *window = mFocus ? mFocus->window() : nullptr; if (mFocus) { - const QWindowSystemInterface::TouchPoint &tp = mTouchPoints.last(); + const QWindowSystemInterface::TouchPoint &tp = mPendingTouchPoints.last(); // When the touch event is received, the global pos is calculated with the margins // in mind. Now we need to adjust again to get the correct local pos back. QMargins margins = window->frameMargins(); @@ -1425,14 +1410,21 @@ void QWaylandInputDevice::Touch::touch_frame() if (mFocus->touchDragDecoration(mParent, localPos, tp.area.center(), tp.state, mParent->modifiers())) return; } - QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mTouchPoints); - if (allTouchPointsReleased()) - mPrevTouchPoints.clear(); - else - mPrevTouchPoints = mTouchPoints; + QWindowSystemInterface::handleTouchEvent(window, mParent->mTouchDevice, mPendingTouchPoints); + + // Prepare state for next frame + const auto prevTouchPoints = mPendingTouchPoints; + mPendingTouchPoints.clear(); + for (const auto &prevPoint: prevTouchPoints) { + // All non-released touch points should be part of the next touch event + if (prevPoint.state != Qt::TouchPointReleased) { + QWindowSystemInterface::TouchPoint tp = prevPoint; + tp.state = Qt::TouchPointStationary; // ... as stationary (unless proven otherwise) + mPendingTouchPoints.append(tp); + } + } - mTouchPoints.clear(); } } diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 7fbb5667f..60d6f2c17 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -188,7 +188,7 @@ private: uint32_t mSerial = 0; void seat_capabilities(uint32_t caps) override; - void handleTouchPoint(int id, double x, double y, Qt::TouchPointState state); + void handleTouchPoint(int id, Qt::TouchPointState state, const QPointF &surfacePosition = QPoint()); QTouchDevice *mTouchDevice = nullptr; @@ -389,8 +389,7 @@ public: QWaylandInputDevice *mParent = nullptr; QPointer<QWaylandWindow> mFocus; - QList<QWindowSystemInterface::TouchPoint> mTouchPoints; - QList<QWindowSystemInterface::TouchPoint> mPrevTouchPoints; + QList<QWindowSystemInterface::TouchPoint> mPendingTouchPoints; }; class QWaylandPointerEvent diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index f6a80e18f..ce72c3340 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -86,7 +86,7 @@ #include "qwaylandinputdeviceintegration_p.h" #include "qwaylandinputdeviceintegrationfactory_p.h" -#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE +#if QT_CONFIG(accessibility_atspi_bridge) #include <QtLinuxAccessibilitySupport/private/bridge_p.h> #endif @@ -98,38 +98,6 @@ QT_BEGIN_NAMESPACE namespace QtWaylandClient { -class GenericWaylandTheme: public QGenericUnixTheme -{ -public: - static QStringList themeNames() - { - QStringList result; - - if (QGuiApplication::desktopSettingsAware()) { - const QByteArray desktopEnvironment = QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment(); - - if (desktopEnvironment == QByteArrayLiteral("KDE")) { -#if QT_CONFIG(settings) - result.push_back(QStringLiteral("kde")); -#endif - } else if (!desktopEnvironment.isEmpty() && - desktopEnvironment != QByteArrayLiteral("UNKNOWN") && - desktopEnvironment != QByteArrayLiteral("GNOME") && - desktopEnvironment != QByteArrayLiteral("UNITY") && - desktopEnvironment != QByteArrayLiteral("MATE") && - desktopEnvironment != QByteArrayLiteral("XFCE") && - desktopEnvironment != QByteArrayLiteral("LXDE")) - // Ignore X11 desktop environments - result.push_back(QString::fromLocal8Bit(desktopEnvironment.toLower())); - } - - if (result.isEmpty()) - result.push_back(QLatin1String(QGenericUnixTheme::name)); - - return result; - } -}; - QWaylandIntegration::QWaylandIntegration() #if defined(Q_OS_MACOS) : mFontDb(new QCoreTextFontDatabaseEngineFactory<QCoreTextFontEngine>) @@ -271,7 +239,7 @@ QVariant QWaylandIntegration::styleHint(StyleHint hint) const QPlatformAccessibility *QWaylandIntegration::accessibility() const { if (!mAccessibility) { -#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE +#if QT_CONFIG(accessibility_atspi_bridge) Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QWaylandIntegration", "Initializing accessibility without event-dispatcher!"); mAccessibility.reset(new QSpiAccessibleBridge()); @@ -302,12 +270,12 @@ QList<int> QWaylandIntegration::possibleKeys(const QKeyEvent *event) const QStringList QWaylandIntegration::themeNames() const { - return GenericWaylandTheme::themeNames(); + return QGenericUnixTheme::themeNames(); } QPlatformTheme *QWaylandIntegration::createPlatformTheme(const QString &name) const { - return GenericWaylandTheme::createUnixTheme(name); + return QGenericUnixTheme::createUnixTheme(name); } // May be called from non-GUI threads diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 60317cda7..ccf4f8dac 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -201,10 +201,13 @@ void QWaylandWindow::initWindow() void QWaylandWindow::initializeWlSurface() { Q_ASSERT(!mSurface); - mSurface.reset(new QWaylandSurface(mDisplay)); - connect(mSurface.data(), &QWaylandSurface::screensChanged, - this, &QWaylandWindow::handleScreensChanged); - mSurface->m_window = this; + { + QWriteLocker lock(&mSurfaceLock); + mSurface.reset(new QWaylandSurface(mDisplay)); + connect(mSurface.data(), &QWaylandSurface::screensChanged, + this, &QWaylandWindow::handleScreensChanged); + mSurface->m_window = this; + } emit wlSurfaceCreated(); } @@ -242,6 +245,7 @@ void QWaylandWindow::reset(bool sendDestroyEvent) mSubSurfaceWindow = nullptr; if (mSurface) { emit wlSurfaceDestroyed(); + QWriteLocker lock(&mSurfaceLock); mSurface.reset(); } @@ -617,10 +621,11 @@ QMutex QWaylandWindow::mFrameSyncMutex; bool QWaylandWindow::waitForFrameSync(int timeout) { - QMutexLocker locker(&mFrameSyncMutex); if (!mWaitingForFrameCallback) return true; + QMutexLocker locker(&mFrameSyncMutex); + wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(mFrameCallback), mFrameQueue); mDisplay->dispatchQueueWhile(mFrameQueue, [&]() { return mWaitingForFrameCallback; }, timeout); @@ -1135,6 +1140,9 @@ void QWaylandWindow::requestUpdate() void QWaylandWindow::handleUpdate() { // TODO: Should sync subsurfaces avoid requesting frame callbacks? + QReadLocker lock(&mSurfaceLock); + if (!mSurface) + return; if (mFrameCallback) { wl_callback_destroy(mFrameCallback); diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 471ace4cd..52e57c72a 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -53,6 +53,8 @@ #include <QtCore/QWaitCondition> #include <QtCore/QMutex> +#include <QtCore/QReadWriteLock> + #include <QtGui/QIcon> #include <QtCore/QVariant> #include <QtCore/QLoggingCategory> @@ -274,6 +276,8 @@ private: static QMutex mFrameSyncMutex; static QWaylandWindow *mMouseGrab; + QReadWriteLock mSurfaceLock; + friend class QWaylandSubSurface; }; diff --git a/src/compositor/compositor_api/compositor_api.pri b/src/compositor/compositor_api/compositor_api.pri index 9c44d0ec1..bbc3a03e7 100644 --- a/src/compositor/compositor_api/compositor_api.pri +++ b/src/compositor/compositor_api/compositor_api.pri @@ -64,9 +64,7 @@ qtConfig(draganddrop) { compositor_api/qwaylanddrag.cpp } -qtHaveModule(quick) { - DEFINES += QT_WAYLAND_COMPOSITOR_QUICK - +qtConfig(wayland-compositor-quick) { SOURCES += \ compositor_api/qwaylandquickcompositor.cpp \ compositor_api/qwaylandquicksurface.cpp \ diff --git a/src/compositor/compositor_api/qwaylandquickchildren.h b/src/compositor/compositor_api/qwaylandquickchildren.h index 7d821ab50..cee7a67ec 100644 --- a/src/compositor/compositor_api/qwaylandquickchildren.h +++ b/src/compositor/compositor_api/qwaylandquickchildren.h @@ -51,16 +51,15 @@ // We mean it. // -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#include <QtWaylandCompositor/qtwaylandcompositorglobal.h> +#if QT_CONFIG(wayland_compositor_quick) #include <QtQml/QQmlListProperty> #include <QtCore/QVector> #endif -#include <QtCore/qglobal.h> - QT_BEGIN_NAMESPACE -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) #define Q_WAYLAND_COMPOSITOR_DECLARE_QUICK_CHILDREN(className) \ Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) \ Q_CLASSINFO("DefaultProperty", "data") \ diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index ee15a0871..ecea8125e 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -477,7 +477,7 @@ void QWaylandQuickItem::mousePressEvent(QMouseEvent *event) return; } - if (!inputRegionContains(event->pos())) { + if (!inputRegionContains(event->localPos())) { event->ignore(); return; } @@ -489,7 +489,7 @@ void QWaylandQuickItem::mousePressEvent(QMouseEvent *event) seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos()); seat->sendMousePressEvent(event->button()); - d->hoverPos = event->pos(); + d->hoverPos = event->localPos(); } /*! @@ -515,7 +515,7 @@ void QWaylandQuickItem::mouseMoveEvent(QMouseEvent *event) #endif // QT_CONFIG(draganddrop) { seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->localPos()), event->windowPos()); - d->hoverPos = event->pos(); + d->hoverPos = event->localPos(); } } else { emit mouseMove(event->windowPos()); @@ -552,14 +552,14 @@ void QWaylandQuickItem::mouseReleaseEvent(QMouseEvent *event) void QWaylandQuickItem::hoverEnterEvent(QHoverEvent *event) { Q_D(QWaylandQuickItem); - if (!inputRegionContains(event->pos())) { + if (!inputRegionContains(event->posF())) { event->ignore(); return; } if (d->shouldSendInputEvents()) { QWaylandSeat *seat = compositor()->seatFor(event); - seat->sendMouseMoveEvent(d->view.data(), event->pos(), mapToScene(event->pos())); - d->hoverPos = event->pos(); + seat->sendMouseMoveEvent(d->view.data(), event->posF(), mapToScene(event->posF())); + d->hoverPos = event->posF(); } else { event->ignore(); } @@ -572,16 +572,16 @@ void QWaylandQuickItem::hoverMoveEvent(QHoverEvent *event) { Q_D(QWaylandQuickItem); if (surface()) { - if (!inputRegionContains(event->pos())) { + if (!inputRegionContains(event->posF())) { event->ignore(); return; } } if (d->shouldSendInputEvents()) { QWaylandSeat *seat = compositor()->seatFor(event); - if (event->pos() != d->hoverPos) { - seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->pos()), mapToScene(event->pos())); - d->hoverPos = event->pos(); + if (event->posF() != d->hoverPos) { + seat->sendMouseMoveEvent(d->view.data(), mapToSurface(event->posF()), mapToScene(event->posF())); + d->hoverPos = event->posF(); } } else { event->ignore(); @@ -667,10 +667,10 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event) if (d->shouldSendInputEvents() && d->touchEventsEnabled) { QWaylandSeat *seat = compositor()->seatFor(event); - QPoint pointPos; + QPointF pointPos; const QList<QTouchEvent::TouchPoint> &points = event->touchPoints(); if (!points.isEmpty()) - pointPos = points.at(0).pos().toPoint(); + pointPos = points.at(0).pos(); if (event->type() == QEvent::TouchBegin && !inputRegionContains(pointPos)) { event->ignore(); @@ -1063,7 +1063,7 @@ void QWaylandQuickItem::setFocusOnClick(bool focus) bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition) const { if (QWaylandSurface *s = surface()) - return s->inputRegionContains(mapToSurface(localPosition).toPoint()); + return s->inputRegionContains(mapToSurface(localPosition)); return false; } diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h index 2ec02ca6d..832272a37 100644 --- a/src/compositor/compositor_api/qwaylandquickitem_p.h +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -173,7 +173,7 @@ public: bool focusOnClick = true; bool sizeFollowsSurface = true; bool belowParent = false; - QPoint hoverPos; + QPointF hoverPos; QMatrix4x4 lastMatrix; QQuickWindow *connectedWindow = nullptr; diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 2265b41c0..0d4cae642 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -67,6 +67,7 @@ #include <QtGui/QScreen> #include <QtCore/QDebug> +#include <QtCore/QtMath> QT_BEGIN_NAMESPACE @@ -708,6 +709,24 @@ bool QWaylandSurface::inputRegionContains(const QPoint &p) const } /*! + * Returns \c true if the QWaylandSurface's input region contains the point \a position. + * Otherwise returns \c false. + * + * \since 5.14 + */ +bool QWaylandSurface::inputRegionContains(const QPointF &position) const +{ + Q_D(const QWaylandSurface); + // QRegion::contains operates in integers. If a region has a rect (0,0,10,10), (0,0) is + // inside while (10,10) is outside. Therefore, we can't use QPoint::toPoint(), which will + // round upwards, meaning the point (-0.25,-0.25) would be rounded to (0,0) and count as + // being inside the region, and similarly, a point (9.75,9.75) inside the region would be + // rounded upwards and count as being outside the region. + const QPoint floored(qFloor(position.x()), qFloor(position.y())); + return d->inputRegion.contains(floored); +} + +/*! * \qmlmethod void QtWaylandCompositor::WaylandSurface::destroy() * * Destroys the WaylandSurface. @@ -766,6 +785,7 @@ bool QWaylandSurface::isCursorSurface() const /*! * \qmlproperty bool QtWaylandCompositor::WaylandSurface::inhibitsIdle + * \since 5.14 * * This property holds whether this surface is intended to inhibit the idle * behavior of the compositor such as screen blanking, locking and screen saving. @@ -775,6 +795,7 @@ bool QWaylandSurface::isCursorSurface() const /*! * \property QWaylandSurface::inhibitsIdle + * \since 5.14 * * This property holds whether this surface is intended to inhibit the idle * behavior of the compositor such as screen blanking, locking and screen saving. diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index f8cdc4434..64265617f 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -131,6 +131,7 @@ public: QWaylandCompositor *compositor() const; bool inputRegionContains(const QPoint &p) const; + bool inputRegionContains(const QPointF &position) const; Q_INVOKABLE void destroy(); Q_INVOKABLE bool isDestroyed() const; @@ -184,7 +185,7 @@ Q_SIGNALS: void subsurfacePlaceBelow(QWaylandSurface *sibling); void dragStarted(QWaylandDrag *drag); void cursorSurfaceChanged(); - void inhibitsIdleChanged(); + Q_REVISION(14) void inhibitsIdleChanged(); void configure(bool hasBuffer); void redraw(); diff --git a/src/compositor/configure.json b/src/compositor/configure.json index db80543f7..9527bbf67 100644 --- a/src/compositor/configure.json +++ b/src/compositor/configure.json @@ -28,6 +28,7 @@ "test": { "tail": [ "extern \"C\" {", + "#include <math.h> /* may fail because of 'private:' in c++ type_traits.h */", "#define private priv", "#include <wayland-kms.h>", "#undef private", @@ -67,30 +68,99 @@ }, "drm-egl-server": { "type": "compile", - "test": "drm_egl_server", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h" + ], + "main": [ + "#ifdef EGL_MESA_drm_image", + "return 0;", + "#else", + "#error Requires EGL_MESA_drm_image to be defined", + "return 1;", + "#endif" + ] + }, "use": "egl" }, "libhybris-egl-server": { "type": "compile", - "test": "libhybris_egl_server", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h", + "hybris/eglplatformcommon/hybris_nativebufferext.h" + ], + "main": [ + "#ifdef EGL_HYBRIS_native_buffer", + "return 0;", + "#else", + "#error Requires EGL_HYBRIS_native_buffer to be defined", + "return 1;", + "#endif" + ] + }, "use": "egl" }, "dmabuf-server-buffer": { "label": "Linux dma-buf Buffer Sharing", "type": "compile", - "test": "dmabuf_server_buffer", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h", + "drm_fourcc.h" + ], + "main": [ + "#ifdef EGL_LINUX_DMA_BUF_EXT", + "return 0;", + "#else", + "#error Requires EGL_LINUX_DMA_BUF_EXT", + "return 1;", + "#endif" + ] + }, "use": "egl" }, "dmabuf-client-buffer": { "label": "Linux Client dma-buf Buffer Sharing", "type": "compile", - "test": "dmabuf_client_buffer", + "test": { + "include": [ + "EGL/egl.h", + "EGL/eglext.h", + "drm_mode.h", + "drm_fourcc.h" + ], + "main": [ + "// test if DMA BUF is supported", + "#ifndef EGL_LINUX_DMA_BUF_EXT", + "#error DMA BUF Extension not available", + "#endif", + "// test if DMA BUF import modifier extension is supported", + "#ifndef EGL_EXT_image_dma_buf_import_modifiers", + "#error DMA BUF Import modifier extension not available", + "#endif", + "return 0;" + ] + }, "use": "egl" }, "vulkan-server-buffer": { "label": "Vulkan Buffer Sharing", "type": "compile", - "test": "vulkan_server_buffer" + "test": { + "include": [ + "vulkan/vulkan.h" + ], + "main": [ + "VkExportMemoryAllocateInfoKHR exportAllocInfo = {};", + "exportAllocInfo.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR;", + "exportAllocInfo.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR;", + "return 0;" + ] + } } }, @@ -158,6 +228,12 @@ "label": "VSP2 hardware layer integration", "condition": "features.wayland-server && features.eglfs_vsp2 && libs.wayland-kms", "output": [ "privateFeature" ] + }, + "wayland-compositor-quick": { + "label": "QtQuick integration for wayland compositor", + "purpose": "Allows QtWayland compositor types to be used with QtQuick", + "condition": "features.wayland-server && module.quick && features.opengl", + "output": [ "publicFeature" ] } }, diff --git a/src/compositor/extensions/qwaylandivisurface.cpp b/src/compositor/extensions/qwaylandivisurface.cpp index 0ae488def..f1d58f739 100644 --- a/src/compositor/extensions/qwaylandivisurface.cpp +++ b/src/compositor/extensions/qwaylandivisurface.cpp @@ -40,7 +40,7 @@ #include "qwaylandivisurface.h" #include "qwaylandivisurface_p.h" #include "qwaylandiviapplication_p.h" -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) #include "qwaylandivisurfaceintegration_p.h" #endif @@ -208,7 +208,7 @@ void QWaylandIviSurface::sendConfigure(const QSize &size) d->send_configure(size.width(), size.height()); } -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *QWaylandIviSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::IviSurfaceIntegration(item); diff --git a/src/compositor/extensions/qwaylandivisurface.h b/src/compositor/extensions/qwaylandivisurface.h index 65d5bbc86..525ad9571 100644 --- a/src/compositor/extensions/qwaylandivisurface.h +++ b/src/compositor/extensions/qwaylandivisurface.h @@ -78,7 +78,7 @@ public: Q_INVOKABLE void sendConfigure(const QSize &size); -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; #endif diff --git a/src/compositor/extensions/qwaylandquickshellintegration.cpp b/src/compositor/extensions/qwaylandquickshellintegration.cpp index 961b7b111..d56d6c22a 100644 --- a/src/compositor/extensions/qwaylandquickshellintegration.cpp +++ b/src/compositor/extensions/qwaylandquickshellintegration.cpp @@ -48,8 +48,46 @@ * Shell surface implementations should inherit from this class in order to provide * an integration between the shell surface and QtQuick. * - * \sa QWaylandShellSurface - * \sa QWaylandShellSurfaceItem + * Shell integration is installed as an event filter for a QWaylandQuickShellSurfaceItem. + * Reimplement the event filter method and return \c true when you want to filter the + * event out, otherwise return \c false. + * + * Example: + * + * \code + * class MyShellIntegration : public QWaylandQuickShellIntegration + * { + * Q_OBJECT + * public: + * MyShellIntegration(QObject *parent = nullptr); + * + * protected: + * bool eventFilter(QObject *object, QEvent *event) override; + * }; + * + * MyShellIntegration::MyShellIntegration(QObject *parent) + * : QWaylandQuickShellIntegration(parent) + * { + * } + * + * bool MyShellIntegration::eventFilter(QObject *object, QEvent *event) + * { + * QWaylandQuickShellSurfaceItem *shellSurfaceItem = qobject_cast<QWaylandQuickShellSurfaceItem *>(object); + * if (!shellSurfaceItem) + * return QWaylandQuickShellIntegration::eventFilter(object, event); + * + * if (event->type() == QEvent::MouseMove) { + * QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + * qDebug() << "Mouse moved on" << shellSurfaceItem << "pos:" << mouseEvent->pos(); + * return true; + * } + * + * return QWaylandQuickShellIntegration::eventFilter(object, event); + * } + * \endcode + * + * \sa QWaylandQuickShellSurfaceItem + * \sa QObject::eventFilter() */ QWaylandQuickShellIntegration::QWaylandQuickShellIntegration(QObject *parent) @@ -57,200 +95,6 @@ QWaylandQuickShellIntegration::QWaylandQuickShellIntegration(QObject *parent) { } -/*! - * This method can be reimplemented in a subclass to receive touch events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::touchEvent() - */ -bool QWaylandQuickShellIntegration::touchEvent(QTouchEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive hover-enter events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Hover events are only provided if \l {QWaylandQuickShellSurfaceItem::} {acceptHoverEvents()} - * is \a true. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::hoverEnterEvent() - */ -bool QWaylandQuickShellIntegration::hoverEnterEvent(QHoverEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive hover-leave events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Hover events are only provided if \l {QWaylandQuickShellSurfaceItem::} {acceptHoverEvents()} - * is \a true. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::hoverLeaveEvent() - */ -bool QWaylandQuickShellIntegration::hoverLeaveEvent(QHoverEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive hover-move events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Hover events are only provided if \l {QWaylandQuickShellSurfaceItem::} {acceptHoverEvents()} - * is \a true. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::hoverMoveEvent() - */ -bool QWaylandQuickShellIntegration::hoverMoveEvent(QHoverEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive key press events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::keyPressEvent() - */ -bool QWaylandQuickShellIntegration::keyPressEvent(QKeyEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive key release events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::keyReleaseEvent() - */ -bool QWaylandQuickShellIntegration::keyReleaseEvent(QKeyEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive mouse double click events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::mouseDoubleClickEvent() - */ -bool QWaylandQuickShellIntegration::mouseDoubleClickEvent(QMouseEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive mouse move events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::mouseMoveEvent() - */ -bool QWaylandQuickShellIntegration::mouseMoveEvent(QMouseEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive mouse press events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::mousePressEvent() - */ -bool QWaylandQuickShellIntegration::mousePressEvent(QMouseEvent *event) -{ - Q_UNUSED(event); - return false; -} - -/*! - * This method can be reimplemented in a subclass to receive mouse release events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::mouseReleaseEvent() - */ -bool QWaylandQuickShellIntegration::mouseReleaseEvent(QMouseEvent *event) -{ - Q_UNUSED(event); - return false; -} - -#if QT_CONFIG(wheelevent) -/*! - * This method can be reimplemented in a subclass to receive wheel events - * for a shell surface. - * - * The event information is provided by the \a event parameter. - * - * Return \a false if you want QWaylandQuickShellSurfaceItem to handle - * the event. - * - * \sa QWaylandQuickShellSurfaceItem::wheelEvent() - */ -bool QWaylandQuickShellIntegration::wheelEvent(QWheelEvent *event) +QWaylandQuickShellIntegration::~QWaylandQuickShellIntegration() { - Q_UNUSED(event); - return false; } -#endif diff --git a/src/compositor/extensions/qwaylandquickshellintegration.h b/src/compositor/extensions/qwaylandquickshellintegration.h index e1a4c2384..00696681b 100644 --- a/src/compositor/extensions/qwaylandquickshellintegration.h +++ b/src/compositor/extensions/qwaylandquickshellintegration.h @@ -41,7 +41,6 @@ #define QWAYLANDQUICKSHELLINTEGRATION_H #include <QtCore/QObject> -#include <QtGui/QMouseEvent> #include <QtWaylandCompositor/qtwaylandcompositorglobal.h> QT_BEGIN_NAMESPACE @@ -50,25 +49,8 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandQuickShellIntegration : public QObject { Q_OBJECT public: - explicit QWaylandQuickShellIntegration(QObject *parent = nullptr); - - virtual bool touchEvent(QTouchEvent *event); - - virtual bool hoverEnterEvent(QHoverEvent *event); - virtual bool hoverLeaveEvent(QHoverEvent *event); - virtual bool hoverMoveEvent(QHoverEvent *event); - - virtual bool keyPressEvent(QKeyEvent *event); - virtual bool keyReleaseEvent(QKeyEvent *event); - - virtual bool mouseDoubleClickEvent(QMouseEvent *event); - virtual bool mouseMoveEvent(QMouseEvent *event); - virtual bool mousePressEvent(QMouseEvent *event); - virtual bool mouseReleaseEvent(QMouseEvent *event); - -#if QT_CONFIG(wheelevent) - virtual bool wheelEvent(QWheelEvent *event); -#endif + QWaylandQuickShellIntegration(QObject *parent = nullptr); + ~QWaylandQuickShellIntegration() override; }; QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp index 110c3d0a3..bda536017 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp @@ -96,7 +96,11 @@ QWaylandQuickShellSurfaceItem::QWaylandQuickShellSurfaceItem(QQuickItem *parent) QWaylandQuickShellSurfaceItem::~QWaylandQuickShellSurfaceItem() { Q_D(QWaylandQuickShellSurfaceItem); - delete d->m_shellIntegration; + + if (d->m_shellIntegration) { + removeEventFilter(d->m_shellIntegration); + delete d->m_shellIntegration; + } } /*! @@ -137,12 +141,15 @@ void QWaylandQuickShellSurfaceItem::setShellSurface(QWaylandShellSurface *shellS d->m_shellSurface = shellSurface; if (d->m_shellIntegration) { + removeEventFilter(d->m_shellIntegration); delete d->m_shellIntegration; d->m_shellIntegration = nullptr; } - if (shellSurface) + if (shellSurface) { d->m_shellIntegration = shellSurface->createIntegration(this); + installEventFilter(d->m_shellIntegration); + } emit shellSurfaceChanged(); } @@ -208,86 +215,6 @@ void QWaylandQuickShellSurfaceItem::setAutoCreatePopupItems(bool enabled) emit autoCreatePopupItemsChanged(); } -void QWaylandQuickShellSurfaceItem::touchEvent(QTouchEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->touchEvent(event)) - QWaylandQuickItem::touchEvent(event); -} - -void QWaylandQuickShellSurfaceItem::hoverEnterEvent(QHoverEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->hoverEnterEvent(event)) - QWaylandQuickItem::hoverEnterEvent(event); -} - -void QWaylandQuickShellSurfaceItem::hoverLeaveEvent(QHoverEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->hoverLeaveEvent(event)) - QWaylandQuickItem::hoverLeaveEvent(event); -} - -void QWaylandQuickShellSurfaceItem::hoverMoveEvent(QHoverEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->hoverMoveEvent(event)) - QWaylandQuickItem::hoverMoveEvent(event); -} - - -void QWaylandQuickShellSurfaceItem::keyPressEvent(QKeyEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->keyPressEvent(event)) - QWaylandQuickItem::keyPressEvent(event); -} - -void QWaylandQuickShellSurfaceItem::keyReleaseEvent(QKeyEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->keyReleaseEvent(event)) - QWaylandQuickItem::keyReleaseEvent(event); -} - -void QWaylandQuickShellSurfaceItem::mouseDoubleClickEvent(QMouseEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->mouseDoubleClickEvent(event)) - QWaylandQuickItem::mouseDoubleClickEvent(event); -} - -void QWaylandQuickShellSurfaceItem::mouseMoveEvent(QMouseEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->mouseMoveEvent(event)) - QWaylandQuickItem::mouseMoveEvent(event); -} - -void QWaylandQuickShellSurfaceItem::mousePressEvent(QMouseEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->mousePressEvent(event)) - QWaylandQuickItem::mousePressEvent(event); -} - -void QWaylandQuickShellSurfaceItem::mouseReleaseEvent(QMouseEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->mouseReleaseEvent(event)) - QWaylandQuickItem::mouseReleaseEvent(event); -} - -#if QT_CONFIG(wheelevent) -void QWaylandQuickShellSurfaceItem::wheelEvent(QWheelEvent *event) -{ - Q_D(QWaylandQuickShellSurfaceItem); - if (!d->m_shellIntegration->wheelEvent(event)) - QWaylandQuickItem::wheelEvent(event); -} -#endif - /*! \class QWaylandQuickShellEventFilter \brief QWaylandQuickShellEventFilter implements a Wayland popup grab diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h index 73a4900bb..51c0425e6 100644 --- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.h +++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.h @@ -75,24 +75,6 @@ Q_SIGNALS: protected: QWaylandQuickShellSurfaceItem(QWaylandQuickShellSurfaceItemPrivate &dd, QQuickItem *parent); - - void touchEvent(QTouchEvent *event) override; - - void hoverEnterEvent(QHoverEvent *event) override; - void hoverLeaveEvent(QHoverEvent *event) override; - void hoverMoveEvent(QHoverEvent *event) override; - - void keyPressEvent(QKeyEvent *event) override; - void keyReleaseEvent(QKeyEvent *event) override; - - void mouseDoubleClickEvent(QMouseEvent *event) override; - void mouseMoveEvent(QMouseEvent *event) override; - void mousePressEvent(QMouseEvent *event) override; - void mouseReleaseEvent(QMouseEvent *event) override; - -#if QT_CONFIG(wheelevent) - void wheelEvent(QWheelEvent *event) override; -#endif }; QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandshellsurface.cpp b/src/compositor/extensions/qwaylandshellsurface.cpp index cb6d03646..7b59801e9 100644 --- a/src/compositor/extensions/qwaylandshellsurface.cpp +++ b/src/compositor/extensions/qwaylandshellsurface.cpp @@ -69,7 +69,7 @@ * \sa QWaylandSurface, QWaylandWlShellSurface, QWaylandXdgSurfaceV5, QWaylandIviSurface */ -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) /*! * \fn QWaylandQuickShellIntegration *QWaylandShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) * diff --git a/src/compositor/extensions/qwaylandshellsurface.h b/src/compositor/extensions/qwaylandshellsurface.h index aca02e2fa..6b943f368 100644 --- a/src/compositor/extensions/qwaylandshellsurface.h +++ b/src/compositor/extensions/qwaylandshellsurface.h @@ -54,7 +54,7 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandShellSurface : public QWaylandComposit Q_OBJECT Q_PROPERTY(Qt::WindowType windowType READ windowType NOTIFY windowTypeChanged) public: -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) virtual QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) = 0; #endif QWaylandShellSurface(QWaylandObject *waylandObject) : QWaylandCompositorExtension(waylandObject) {} diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp index 8cd2c7310..ea228cab2 100644 --- a/src/compositor/extensions/qwaylandwlshell.cpp +++ b/src/compositor/extensions/qwaylandwlshell.cpp @@ -41,7 +41,7 @@ #include "qwaylandwlshell.h" #include "qwaylandwlshell_p.h" -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) #include "qwaylandwlshellintegration_p.h" #endif #include <QtWaylandCompositor/private/qwaylandutils_p.h> @@ -587,7 +587,7 @@ void QWaylandWlShellSurface::sendPopupDone() d->send_popup_done(); } -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *QWaylandWlShellSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::WlShellIntegration(item); diff --git a/src/compositor/extensions/qwaylandwlshell.h b/src/compositor/extensions/qwaylandwlshell.h index 421888000..b37773e28 100644 --- a/src/compositor/extensions/qwaylandwlshell.h +++ b/src/compositor/extensions/qwaylandwlshell.h @@ -140,7 +140,7 @@ public: Q_INVOKABLE void sendConfigure(const QSize &size, ResizeEdge edges); Q_INVOKABLE void sendPopupDone(); -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; #endif diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index b732069c4..724580e24 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -289,7 +289,19 @@ void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset) moveItem->setPosition(moveItem->position() + m_item->mapFromSurface(offset)); } -bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) +bool WlShellIntegration::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseMove) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseMoveEvent(mouseEvent); + } else if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseReleaseEvent(mouseEvent); + } + return QWaylandQuickShellIntegration::eventFilter(object, event); +} + +bool WlShellIntegration::filterMouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); @@ -318,7 +330,7 @@ bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) return false; } -bool WlShellIntegration::mouseReleaseEvent(QMouseEvent *event) +bool WlShellIntegration::filterMouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); if (grabberState != GrabberState::Default) { diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h index 8af54dfc4..eb23a62fc 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration_p.h +++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h @@ -65,8 +65,9 @@ class WlShellIntegration : public QWaylandQuickShellIntegration public: WlShellIntegration(QWaylandQuickShellSurfaceItem *item); ~WlShellIntegration() override; - bool mouseMoveEvent(QMouseEvent *event) override; - bool mouseReleaseEvent(QMouseEvent *event) override; + +protected: + bool eventFilter(QObject *object, QEvent *event) override; private Q_SLOTS: void handleStartMove(QWaylandSeat *seat); @@ -130,6 +131,9 @@ private: QPointF normalPosition; QPointF finalPosition; + + bool filterMouseMoveEvent(QMouseEvent *event); + bool filterMouseReleaseEvent(QMouseEvent *event); }; } diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index eece3f3d6..1b8a3c2e2 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -37,7 +37,7 @@ #include "qwaylandxdgshell.h" #include "qwaylandxdgshell_p.h" -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) #include "qwaylandxdgshellintegration_p.h" #endif #include <QtWaylandCompositor/private/qwaylandutils_p.h> @@ -693,7 +693,7 @@ QWaylandXdgSurface *QWaylandXdgSurface::fromResource(wl_resource *resource) return nullptr; } -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) { Q_D(const QWaylandXdgSurface); diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h index f45038eb9..2e3e28180 100644 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ b/src/compositor/extensions/qwaylandxdgshell.h @@ -119,7 +119,7 @@ public: static QByteArray interfaceName(); static QWaylandXdgSurface *fromResource(::wl_resource *resource); -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; #endif diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index 3de52944b..336ede3cc 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -77,7 +77,19 @@ XdgToplevelIntegration::XdgToplevelIntegration(QWaylandQuickShellSurfaceItem *it connect(m_toplevel, &QObject::destroyed, this, &XdgToplevelIntegration::handleToplevelDestroyed); } -bool XdgToplevelIntegration::mouseMoveEvent(QMouseEvent *event) +bool XdgToplevelIntegration::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseMove) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseMoveEvent(mouseEvent); + } else if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseReleaseEvent(mouseEvent); + } + return QWaylandQuickShellIntegration::eventFilter(object, event); +} + +bool XdgToplevelIntegration::filterMouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); @@ -105,7 +117,7 @@ bool XdgToplevelIntegration::mouseMoveEvent(QMouseEvent *event) return false; } -bool XdgToplevelIntegration::mouseReleaseEvent(QMouseEvent *event) +bool XdgToplevelIntegration::filterMouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h index 34e3873d5..cd6bad572 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellintegration_p.h @@ -63,8 +63,9 @@ class XdgToplevelIntegration : public QWaylandQuickShellIntegration Q_OBJECT public: XdgToplevelIntegration(QWaylandQuickShellSurfaceItem *item); - bool mouseMoveEvent(QMouseEvent *event) override; - bool mouseReleaseEvent(QMouseEvent *event) override; + +protected: + bool eventFilter(QObject *object, QEvent *event) override; private Q_SLOTS: void handleStartMove(QWaylandSeat *seat); @@ -120,6 +121,9 @@ private: // will be hooked to geometry-changed or available- // geometry-changed. } nonwindowedState; + + bool filterMouseMoveEvent(QMouseEvent *event); + bool filterMouseReleaseEvent(QMouseEvent *event); }; class XdgPopupIntegration : public QWaylandQuickShellIntegration diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp index a40c21682..e38e68eb0 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp @@ -40,7 +40,7 @@ #include "qwaylandxdgshellv5.h" #include "qwaylandxdgshellv5_p.h" -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) #include "qwaylandxdgshellv5integration_p.h" #endif #include <QtWaylandCompositor/private/qwaylandutils_p.h> @@ -1317,7 +1317,7 @@ uint QWaylandXdgSurfaceV5::sendResizing(const QSize &maxSize) return sendConfigure(maxSize, conf.states); } -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *QWaylandXdgSurfaceV5::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::XdgShellV5Integration(item); @@ -1517,7 +1517,7 @@ void QWaylandXdgPopupV5::sendPopupDone() d->send_popup_done(); } -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *QWaylandXdgPopupV5::createIntegration(QWaylandQuickShellSurfaceItem *item) { return new QtWayland::XdgPopupV5Integration(item); diff --git a/src/compositor/extensions/qwaylandxdgshellv5.h b/src/compositor/extensions/qwaylandxdgshellv5.h index f989d04c7..66e9ceb05 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.h +++ b/src/compositor/extensions/qwaylandxdgshellv5.h @@ -171,7 +171,7 @@ public: Q_INVOKABLE uint sendFullscreen(const QSize &size); Q_INVOKABLE uint sendResizing(const QSize &maxSize); -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; #endif @@ -243,7 +243,7 @@ public: Q_INVOKABLE void sendPopupDone(); -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; #endif diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp index 1d63632a3..4907a0611 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp @@ -82,7 +82,19 @@ XdgShellV5Integration::~XdgShellV5Integration() m_item->setSurface(nullptr); } -bool XdgShellV5Integration::mouseMoveEvent(QMouseEvent *event) +bool XdgShellV5Integration::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseMove) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseMoveEvent(mouseEvent); + } else if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseReleaseEvent(mouseEvent); + } + return QWaylandQuickShellIntegration::eventFilter(object, event); +} + +bool XdgShellV5Integration::filterMouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); @@ -110,7 +122,7 @@ bool XdgShellV5Integration::mouseMoveEvent(QMouseEvent *event) return false; } -bool XdgShellV5Integration::mouseReleaseEvent(QMouseEvent *event) +bool XdgShellV5Integration::filterMouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration_p.h b/src/compositor/extensions/qwaylandxdgshellv5integration_p.h index 5d0e1e142..99983c866 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5integration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellv5integration_p.h @@ -64,8 +64,9 @@ class XdgShellV5Integration : public QWaylandQuickShellIntegration public: XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item); ~XdgShellV5Integration() override; - bool mouseMoveEvent(QMouseEvent *event) override; - bool mouseReleaseEvent(QMouseEvent *event) override; + +protected: + bool eventFilter(QObject *object, QEvent *event) override; private Q_SLOTS: void handleStartMove(QWaylandSeat *seat); @@ -108,6 +109,9 @@ private: QSize initialWindowSize; QPointF initialPosition; } maximizeState; + + bool filterMouseMoveEvent(QMouseEvent *event); + bool filterMouseReleaseEvent(QMouseEvent *event); }; class XdgPopupV5Integration : public QWaylandQuickShellIntegration diff --git a/src/compositor/extensions/qwaylandxdgshellv6.cpp b/src/compositor/extensions/qwaylandxdgshellv6.cpp index 96d6f5509..934dccb06 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv6.cpp @@ -37,7 +37,7 @@ #include "qwaylandxdgshellv6.h" #include "qwaylandxdgshellv6_p.h" -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) #include "qwaylandxdgshellv6integration_p.h" #endif #include <QtWaylandCompositor/private/qwaylandutils_p.h> @@ -698,7 +698,7 @@ QWaylandXdgSurfaceV6 *QWaylandXdgSurfaceV6::fromResource(wl_resource *resource) return nullptr; } -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *QWaylandXdgSurfaceV6::createIntegration(QWaylandQuickShellSurfaceItem *item) { Q_D(const QWaylandXdgSurfaceV6); diff --git a/src/compositor/extensions/qwaylandxdgshellv6.h b/src/compositor/extensions/qwaylandxdgshellv6.h index 64c82306c..71f82521a 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6.h +++ b/src/compositor/extensions/qwaylandxdgshellv6.h @@ -119,7 +119,7 @@ public: static QByteArray interfaceName(); static QWaylandXdgSurfaceV6 *fromResource(::wl_resource *resource); -#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#if QT_CONFIG(wayland_compositor_quick) QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) override; #endif diff --git a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp index 66dbc6841..e424af193 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp @@ -77,7 +77,19 @@ XdgToplevelV6Integration::XdgToplevelV6Integration(QWaylandQuickShellSurfaceItem connect(m_toplevel, &QObject::destroyed, this, &XdgToplevelV6Integration::handleToplevelDestroyed); } -bool XdgToplevelV6Integration::mouseMoveEvent(QMouseEvent *event) +bool XdgToplevelV6Integration::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseMove) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseMoveEvent(mouseEvent); + } else if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); + return filterMouseReleaseEvent(mouseEvent); + } + return QWaylandQuickShellIntegration::eventFilter(object, event); +} + +bool XdgToplevelV6Integration::filterMouseMoveEvent(QMouseEvent *event) { if (grabberState == GrabberState::Resize) { Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); @@ -105,7 +117,7 @@ bool XdgToplevelV6Integration::mouseMoveEvent(QMouseEvent *event) return false; } -bool XdgToplevelV6Integration::mouseReleaseEvent(QMouseEvent *event) +bool XdgToplevelV6Integration::filterMouseReleaseEvent(QMouseEvent *event) { Q_UNUSED(event); diff --git a/src/compositor/extensions/qwaylandxdgshellv6integration_p.h b/src/compositor/extensions/qwaylandxdgshellv6integration_p.h index 049b901c9..9df2885f1 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6integration_p.h +++ b/src/compositor/extensions/qwaylandxdgshellv6integration_p.h @@ -63,8 +63,9 @@ class XdgToplevelV6Integration : public QWaylandQuickShellIntegration Q_OBJECT public: XdgToplevelV6Integration(QWaylandQuickShellSurfaceItem *item); - bool mouseMoveEvent(QMouseEvent *event) override; - bool mouseReleaseEvent(QMouseEvent *event) override; + +protected: + bool eventFilter(QObject *object, QEvent *event) override; private Q_SLOTS: void handleStartMove(QWaylandSeat *seat); @@ -120,6 +121,9 @@ private: // will be hooked to geometry-changed or available- // geometry-changed. } nonwindowedState; + + bool filterMouseMoveEvent(QMouseEvent *event); + bool filterMouseReleaseEvent(QMouseEvent *event); }; class XdgPopupV6Integration : public QWaylandQuickShellIntegration diff --git a/src/imports/compositor/compositor.pro b/src/imports/compositor/compositor.pro index f5c7567a0..59dd7824c 100644 --- a/src/imports/compositor/compositor.pro +++ b/src/imports/compositor/compositor.pro @@ -14,8 +14,6 @@ COMPOSITOR_QML_FILES += \ WaylandOutputWindow.qml \ WaylandCursorItem.qml -DEFINES += QT_WAYLAND_COMPOSITOR_QUICK - # Create the resource file GENERATED_RESOURCE_FILE = $$OUT_PWD/compositor.qrc diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp index e81aa9038..dc3cfdbfa 100644 --- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp +++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp @@ -342,7 +342,7 @@ void QWaylandXdgSurfaceV6::requestWindowStates(Qt::WindowStates states) if (m_toplevel) m_toplevel->requestWindowStates(states); else - qCWarning(lcQpaWayland) << "Non-toplevel surfaces can't request window states"; + qCDebug(lcQpaWayland) << "Ignoring window states requested by non-toplevel."; } void QWaylandXdgSurfaceV6::setToplevel() diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index ca8da80b7..bd1f5a210 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -377,7 +377,7 @@ void QWaylandXdgSurface::requestWindowStates(Qt::WindowStates states) if (m_toplevel) m_toplevel->requestWindowStates(states); else - qCWarning(lcQpaWayland) << "Non-toplevel surfaces can't request window states"; + qCDebug(lcQpaWayland) << "Ignoring window states requested by non-toplevel zxdg_surface_v6."; } void QWaylandXdgSurface::setToplevel() diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro index 61bf67853..4b1eb2458 100644 --- a/tests/auto/client/client.pro +++ b/tests/auto/client/client.pro @@ -11,6 +11,7 @@ SUBDIRS += \ seatv5 \ surface \ wl_connect \ + xdgdecorationv1 \ xdgoutput \ xdgshell \ xdgshellv6 diff --git a/tests/auto/client/datadevicev1/tst_datadevicev1.cpp b/tests/auto/client/datadevicev1/tst_datadevicev1.cpp index 35ac72528..e3babceb5 100644 --- a/tests/auto/client/datadevicev1/tst_datadevicev1.cpp +++ b/tests/auto/client/datadevicev1/tst_datadevicev1.cpp @@ -30,9 +30,8 @@ #include <QtGui/QRasterWindow> #include <QtGui/QOpenGLWindow> - -//TODO: move? #include <QtGui/QClipboard> +#include <QtGui/QDrag> using namespace MockCompositor; @@ -60,6 +59,7 @@ private slots: void pasteUtf8(); void destroysPreviousSelection(); void destroysSelectionWithSurface(); + void dragWithoutFocus(); }; void tst_datadevicev1::initTestCase() @@ -215,5 +215,22 @@ void tst_datadevicev1::destroysSelectionWithSurface() QCOMPOSITOR_TRY_COMPARE(dataDevice()->m_sentSelectionOffers.size(), 0); } +// The application should not crash if it attempts to start a drag operation +// when it doesn't have input focus (QTBUG-76368) +void tst_datadevicev1::dragWithoutFocus() +{ + QRasterWindow window; + window.resize(64, 64); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + + auto *mimeData = new QMimeData; + const QByteArray data("testData"); + mimeData->setData("text/plain", data); + QDrag drag(&window); + drag.setMimeData(mimeData); + drag.exec(); +} + QCOMPOSITOR_TEST_MAIN(tst_datadevicev1) #include "tst_datadevicev1.moc" diff --git a/tests/auto/client/seatv4/tst_seatv4.cpp b/tests/auto/client/seatv4/tst_seatv4.cpp index 40f8742a2..2e17bef87 100644 --- a/tests/auto/client/seatv4/tst_seatv4.cpp +++ b/tests/auto/client/seatv4/tst_seatv4.cpp @@ -72,6 +72,7 @@ private slots: void usesEnterSerial(); void focusDestruction(); void mousePress(); + void mousePressFloat(); void simpleAxis_data(); void simpleAxis(); void invalidPointerEvents(); @@ -208,6 +209,30 @@ void tst_seatv4::mousePress() QTRY_VERIFY(window.m_pressed); } +void tst_seatv4::mousePressFloat() +{ + class Window : public QRasterWindow { + public: + void mousePressEvent(QMouseEvent *e) override { m_position = e->localPos(); } + QPointF m_position; + }; + + Window window; + window.resize(64, 64); + window.show(); + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + + exec([&] { + auto *surface = xdgSurface()->m_surface; + pointer()->sendEnter(surface, {32.75, 32.25}); + pointer()->sendButton(client(), BTN_LEFT, 1); + pointer()->sendButton(client(), BTN_LEFT, 0); + }); + QMargins m = window.frameMargins(); + QPointF pressedPosition(32.75 -m.left(), 32.25 - m.top()); + QTRY_COMPARE(window.m_position, pressedPosition); +} + void tst_seatv4::simpleAxis_data() { QTest::addColumn<uint>("axis"); diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp index ca8de31ac..ae7c3db2f 100644 --- a/tests/auto/client/seatv5/tst_seatv5.cpp +++ b/tests/auto/client/seatv5/tst_seatv5.cpp @@ -68,6 +68,7 @@ private slots: // Touch tests void createsTouch(); void singleTap(); + void singleTapFloat(); }; void tst_seatv5::bindsToSeat() @@ -431,5 +432,36 @@ void tst_seatv5::singleTap() } } +void tst_seatv5::singleTapFloat() +{ + TouchWindow window; + QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial); + + exec([=] { + auto *t = touch(); + auto *c = client(); + t->sendDown(xdgToplevel()->surface(), {32.75, 32.25}, 1); + t->sendFrame(c); + t->sendUp(c, 1); + t->sendFrame(c); + }); + + QTRY_VERIFY(!window.m_events.empty()); + { + auto e = window.m_events.takeFirst(); + QCOMPARE(e.type, QEvent::TouchBegin); + QCOMPARE(e.touchPointStates, Qt::TouchPointState::TouchPointPressed); + QCOMPARE(e.touchPoints.length(), 1); + QCOMPARE(e.touchPoints.first().pos(), QPointF(32.75-window.frameMargins().left(), 32.25-window.frameMargins().top())); + } + { + auto e = window.m_events.takeFirst(); + QCOMPARE(e.type, QEvent::TouchEnd); + QCOMPARE(e.touchPointStates, Qt::TouchPointState::TouchPointReleased); + QCOMPARE(e.touchPoints.length(), 1); + QCOMPARE(e.touchPoints.first().pos(), QPointF(32.75-window.frameMargins().left(), 32.25-window.frameMargins().top())); + } +} + QCOMPOSITOR_TEST_MAIN(tst_seatv5) #include "tst_seatv5.moc" diff --git a/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp b/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp new file mode 100644 index 000000000..386713cf5 --- /dev/null +++ b/tests/auto/client/xdgdecorationv1/tst_xdgdecorationv1.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mockcompositor.h" + +#include <qwayland-server-xdg-decoration-unstable-v1.h> + +#include <QtGui/QRasterWindow> +#include <QtGui/QOpenGLWindow> +#include <QtGui/QClipboard> +#include <QtCore/private/qcore_unix_p.h> + +#include <fcntl.h> + +using namespace MockCompositor; + +constexpr int xdgDecorationVersion = 1; // protocol VERSION, not the name suffix (_v1) + +class XdgDecorationManagerV1; +class XdgToplevelDecorationV1 : public QObject, public QtWaylandServer::zxdg_toplevel_decoration_v1 +{ + Q_OBJECT +public: + explicit XdgToplevelDecorationV1(XdgDecorationManagerV1 *manager, XdgToplevel *toplevel, int id, int version) + : zxdg_toplevel_decoration_v1(toplevel->resource()->client(), id, version) + , m_manager(manager) + , m_toplevel(toplevel) + { + } + void sendConfigure(mode mode) + { + if (!m_configureSent) { + // Attaching buffers before the configure is a protocol error + QVERIFY(!m_toplevel->surface()->m_pending.buffer); + QVERIFY(!m_toplevel->surface()->m_committed.buffer); + } + send_configure(mode); + m_configureSent = true; + } + void zxdg_toplevel_decoration_v1_destroy(Resource *resource) override + { + wl_resource_destroy(resource->handle); + } + void zxdg_toplevel_decoration_v1_destroy_resource(Resource *resource) override; + void zxdg_toplevel_decoration_v1_set_mode(Resource *resource, uint32_t mode) override + { + Q_UNUSED(resource); + m_unsetModeRequested = false; + m_requestedMode = XdgToplevelDecorationV1::mode(mode); + } + void zxdg_toplevel_decoration_v1_unset_mode(Resource *resource) override + { + Q_UNUSED(resource); + m_unsetModeRequested = true; + m_requestedMode = mode(0); + } + XdgDecorationManagerV1 *m_manager = nullptr; + XdgToplevel *m_toplevel = nullptr; + mode m_requestedMode = mode(0); + bool m_unsetModeRequested = false; + bool m_configureSent = false; +}; + +class XdgDecorationManagerV1 : public Global, public QtWaylandServer::zxdg_decoration_manager_v1 +{ + Q_OBJECT +public: + explicit XdgDecorationManagerV1(CoreCompositor *compositor, int version = 1) + : QtWaylandServer::zxdg_decoration_manager_v1(compositor->m_display, version) + , m_version(version) + {} + bool isClean() override { return m_decorations.empty(); } + XdgToplevelDecorationV1 *decorationFor(XdgToplevel *toplevel) + { + return m_decorations.value(toplevel, nullptr); + } + + int m_version = 1; // TODO: Remove on libwayland upgrade + QMap<XdgToplevel *, XdgToplevelDecorationV1 *> m_decorations; + +protected: + void zxdg_decoration_manager_v1_destroy(Resource *resource) override + { + //TODO: Should the decorations be destroyed at this point? + wl_resource_destroy(resource->handle); + } + + void zxdg_decoration_manager_v1_get_toplevel_decoration(Resource *resource, uint32_t id, ::wl_resource *toplevelResource) override + { + auto *toplevel = fromResource<XdgToplevel>(toplevelResource); + QVERIFY(toplevel); + QVERIFY(!decorationFor(toplevel)); + + // Attaching buffers before the configure is a protocol error + QVERIFY(!toplevel->surface()->m_pending.buffer); + QVERIFY(!toplevel->surface()->m_committed.buffer); + + m_decorations[toplevel] = new XdgToplevelDecorationV1(this, toplevel, id, resource->version()); + } +}; + +void XdgToplevelDecorationV1::zxdg_toplevel_decoration_v1_destroy_resource(QtWaylandServer::zxdg_toplevel_decoration_v1::Resource *resource) +{ + Q_UNUSED(resource); + int removed = m_manager->m_decorations.remove(m_toplevel); + Q_ASSERT(removed == 1); + delete this; +} + +class XdgDecorationCompositor : public DefaultCompositor { +public: + explicit XdgDecorationCompositor() + { + exec([this] { + m_config.autoConfigure = true; + add<XdgDecorationManagerV1>(xdgDecorationVersion); + }); + } + XdgToplevelDecorationV1 *toplevelDecoration(int i = 0) { + return get<XdgDecorationManagerV1>()->decorationFor(xdgToplevel(i)); + } +}; + +class tst_xdgdecorationv1 : public QObject, private XdgDecorationCompositor +{ + Q_OBJECT +private slots: + void initTestCase(); + void cleanup() { QTRY_VERIFY2(isClean(), qPrintable(dirtyMessage())); } + void clientSidePreferredByCompositor(); +}; + +void tst_xdgdecorationv1::initTestCase() +{ + if (qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_WINDOWDECORATION")) + QSKIP("This test doesn't make sense when QT_WAYLAND_DISABLE_WINDOWDECORATION is set in the environment"); +} + +void tst_xdgdecorationv1::clientSidePreferredByCompositor() +{ + QRasterWindow window; + window.show(); + QCOMPOSITOR_TRY_COMPARE(get<XdgDecorationManagerV1>()->resourceMap().size(), 1); + QCOMPOSITOR_TRY_COMPARE(get<XdgDecorationManagerV1>()->resourceMap().first()->version(), xdgDecorationVersion); + QCOMPOSITOR_TRY_VERIFY(toplevelDecoration()); // The client creates a toplevel object + + // Check that we don't assume decorations before the server has configured them + QVERIFY(window.frameMargins().isNull()); + + QCOMPOSITOR_TRY_VERIFY(xdgToplevel()); + QCOMPOSITOR_TRY_VERIFY(toplevelDecoration()->m_unsetModeRequested); + QVERIFY(window.frameMargins().isNull()); // We're still waiting for a configure + exec([=] { + toplevelDecoration()->sendConfigure(XdgToplevelDecorationV1::mode_client_side); + xdgToplevel()->sendCompleteConfigure(); + }); + QTRY_VERIFY(!window.frameMargins().isNull()); +} + +QCOMPOSITOR_TEST_MAIN(tst_xdgdecorationv1) +#include "tst_xdgdecorationv1.moc" diff --git a/tests/auto/client/xdgdecorationv1/xdgdecorationv1.pro b/tests/auto/client/xdgdecorationv1/xdgdecorationv1.pro new file mode 100644 index 000000000..0b5537205 --- /dev/null +++ b/tests/auto/client/xdgdecorationv1/xdgdecorationv1.pro @@ -0,0 +1,7 @@ +include (../shared/shared.pri) + +WAYLANDSERVERSOURCES += \ + $$PWD/../../../../src/3rdparty/protocol/xdg-decoration-unstable-v1.xml + +TARGET = tst_xdgdecorationv1 +SOURCES += tst_xdgdecorationv1.cpp diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index f4f63228c..7fbe8979b 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -909,6 +909,11 @@ void tst_WaylandCompositor::inputRegion() QVERIFY(!waylandSurface->inputRegionContains(QPoint(1, 6))); QVERIFY(!waylandSurface->inputRegionContains(QPoint(4, 2))); + QVERIFY(!waylandSurface->inputRegionContains(QPointF(0.99, 1.99))); + QVERIFY(waylandSurface->inputRegionContains(QPointF(1, 2))); + QVERIFY(waylandSurface->inputRegionContains(QPointF(3.99, 4.99))); + QVERIFY(!waylandSurface->inputRegionContains(QPointF(4, 5))); + // Setting a nullptr input region means we want all events wl_surface_set_input_region(surface, nullptr); wl_surface_commit(surface); |