diff options
104 files changed, 1382 insertions, 254 deletions
diff --git a/.gitignore b/.gitignore index bb3819ca3..b1a806210 100644 --- a/.gitignore +++ b/.gitignore @@ -65,8 +65,11 @@ src/plugins/shellintegration/ivi-shell/qwayland-ivi-application.h src/plugins/shellintegration/ivi-shell/qwayland-ivi-application.cpp src/plugins/shellintegration/ivi-shell/qwayland-ivi-controller.h src/plugins/shellintegration/ivi-shell/qwayland-ivi-controller.cpp +src/plugins/shellintegration/fullscreen-shell-v1/qwayland-fullscreen-shell-unstable-v1.cpp +src/plugins/shellintegration/fullscreen-shell-v1/qwayland-fullscreen-shell-unstable-v1.h src/imports/compositor/compositor.qrc tests/auto/client/client/tst_client +tests/auto/client/fullscreenshellv1/tst_client_fullscreenshell1 tests/auto/compositor/compositor/tst_compositor tests/auto/compositor/compositor/qwayland-*.cpp tests/auto/compositor/compositor/qwayland-*.h diff --git a/.qmake.conf b/.qmake.conf index 097d8b948..f8cda0e7d 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.12.0 +MODULE_VERSION = 5.13.0 @@ -10,7 +10,7 @@ QtWaylandCompositor API: To build the QtWayland module you need the external dependencies: xkbcommon 0.2.0 - http://xkbcommon.org/ -wayland 1.6.0 - http://wayland.freedesktop.org/ +wayland 1.8.0 - http://wayland.freedesktop.org/ QtWaylandCompositor supports loading client buffer integrations that don't use the wayland-egl interfaces. These client buffer integrations are picked up by diff --git a/config.tests/wayland/main.cpp b/config.tests/wayland/main.cpp index 9e0002db5..8cab379bf 100644 --- a/config.tests/wayland/main.cpp +++ b/config.tests/wayland/main.cpp @@ -53,15 +53,15 @@ int main() { #if WAYLAND_VERSION_MAJOR < 1 -# error Wayland 1.6.0 or higher required +# error Wayland 1.8.0 or higher required #endif #if WAYLAND_VERSION_MAJOR == 1 -# if WAYLAND_VERSION_MINOR < 6 -# error Wayland 1.6.0 or higher required +# if WAYLAND_VERSION_MINOR < 8 +# error Wayland 1.8.0 or higher required # endif -# if WAYLAND_VERSION_MINOR == 6 +# if WAYLAND_VERSION_MINOR == 8 # if WAYLAND_VERSION_MICRO < 0 -# error Wayland 1.6.0 or higher required +# error Wayland 1.8.0 or higher required # endif # endif #endif diff --git a/examples/wayland/minimal-cpp/compositor.h b/examples/wayland/minimal-cpp/compositor.h index f06421320..3c0c80e0e 100644 --- a/examples/wayland/minimal-cpp/compositor.h +++ b/examples/wayland/minimal-cpp/compositor.h @@ -71,11 +71,11 @@ public: QOpenGLTexture *getTexture(); int iviId() const { return m_iviId; } - QRect globalGeometry() const { return QRect(globalPosition(), surface()->size()); } + QRect globalGeometry() const { return QRect(globalPosition(), surface()->destinationSize()); } void setGlobalPosition(const QPoint &globalPos) { m_pos = globalPos; m_positionSet = true; } QPoint globalPosition() const { return m_pos; } QPoint mapToLocal(const QPoint &globalPos) const; - QSize size() const { return surface() ? surface()->size() : QSize(); } + QSize size() const { return surface() ? surface()->destinationSize() : QSize(); } void initPosition(const QSize &screenSize, const QSize &surfaceSize); diff --git a/examples/wayland/minimal-cpp/window.cpp b/examples/wayland/minimal-cpp/window.cpp index 673e15fd8..f345bd51f 100644 --- a/examples/wayland/minimal-cpp/window.cpp +++ b/examples/wayland/minimal-cpp/window.cpp @@ -95,7 +95,7 @@ void Window::paintGL() GLuint textureId = texture->textureId(); QWaylandSurface *surface = view->surface(); if (surface && surface->hasContent()) { - QSize s = surface->size(); + QSize s = surface->destinationSize(); view->initPosition(size(), s); QPointF pos = view->globalPosition(); QRectF surfaceGeometry(pos, s); diff --git a/examples/wayland/qwindow-compositor/compositor.cpp b/examples/wayland/qwindow-compositor/compositor.cpp index f25e67d87..199de22e2 100644 --- a/examples/wayland/qwindow-compositor/compositor.cpp +++ b/examples/wayland/qwindow-compositor/compositor.cpp @@ -79,7 +79,7 @@ QOpenGLTexture *View::getTexture() if (newContent) { m_texture = buf.toOpenGLTexture(); if (surface()) { - m_size = surface()->size(); + m_size = surface()->destinationSize(); m_origin = buf.origin() == QWaylandSurface::OriginTopLeft ? QOpenGLTextureBlitter::OriginTopLeft : QOpenGLTextureBlitter::OriginBottomLeft; @@ -96,7 +96,7 @@ QOpenGLTextureBlitter::Origin View::textureOrigin() const QSize View::size() const { - return surface() ? surface()->size() : m_size; + return surface() ? surface()->destinationSize() : m_size; } bool View::isCursor() const diff --git a/examples/wayland/qwindow-compositor/compositor.h b/examples/wayland/qwindow-compositor/compositor.h index 2a395a1ab..8f18dc53d 100644 --- a/examples/wayland/qwindow-compositor/compositor.h +++ b/examples/wayland/qwindow-compositor/compositor.h @@ -82,7 +82,7 @@ public: void setParentView(View *parent) { m_parentView = parent; } View *parentView() const { return m_parentView; } QPointF parentPosition() const { return m_parentView ? (m_parentView->position() + m_parentView->parentPosition()) : QPointF(); } - QSize windowSize() { return m_xdgSurface ? m_xdgSurface->windowGeometry().size() : surface() ? surface()->size() : m_size; } + QSize windowSize() { return m_xdgSurface ? m_xdgSurface->windowGeometry().size() : surface() ? surface()->destinationSize() : m_size; } QPoint offset() const { return m_offset; } qreal animationFactor() const {return m_animationFactor; } diff --git a/examples/wayland/qwindow-compositor/window.cpp b/examples/wayland/qwindow-compositor/window.cpp index 80aeec4c3..b8b8e52ec 100644 --- a/examples/wayland/qwindow-compositor/window.cpp +++ b/examples/wayland/qwindow-compositor/window.cpp @@ -180,7 +180,7 @@ void Window::startResize(int edge, bool anchored) m_grabState = ResizeGrab; m_resizeEdge = edge; m_resizeAnchored = anchored; - m_resizeAnchorPosition = getAnchorPosition(m_mouseView->position(), edge, m_mouseView->surface()->size()); + m_resizeAnchorPosition = getAnchorPosition(m_mouseView->position(), edge, m_mouseView->surface()->destinationSize()); } void Window::startDrag(View *dragIcon) diff --git a/features/wayland-scanner-client-wayland-protocol-include.prf b/features/wayland-scanner-client-wayland-protocol-include.prf new file mode 100644 index 000000000..9c5d2d1ed --- /dev/null +++ b/features/wayland-scanner-client-wayland-protocol-include.prf @@ -0,0 +1,53 @@ +# Special version of WAYLANDCLIENTSOURCES to be used with protocols that +# have requests that create objects with interfaces defined in the core +# wayland protocol. +# +# E.g. the xcomposite protocol has a request which creates a wl_buffer. With +# the regular wayland-scanner.prf compilation would fail because +# wl_buffer_interface is not defined. +# +# This version solves the problem by prepending +# #include <QtWaylandClient/private/wayland-wayland-client-protocol.h> +# to the wayland-scanner generated files. + +isEmpty(QMAKE_WAYLAND_SCANNER):error("QMAKE_WAYLAND_SCANNER not defined for this mkspec") + +!isEmpty(MODULE_INCNAME) { + WAYLAND_INCLUDE_DIR = $$MODULE_INCNAME/private +} + +wayland_client_header.name = wayland ${QMAKE_FILE_BASE} +wayland_client_header.input = WAYLANDCLIENTSOURCES +wayland_client_header.variable_out = HEADERS +wayland_client_header.output = wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)} +# XXX: Prepend the necessary include in the generated header +wayland_client_header.commands = echo \"$${LITERAL_HASH}include <QtWaylandClient/private/wayland-wayland-client-protocol.h>\" > ${QMAKE_FILE_OUT} && $$QMAKE_WAYLAND_SCANNER --include-core-only client-header < ${QMAKE_FILE_IN} >> ${QMAKE_FILE_OUT} +QMAKE_EXTRA_COMPILERS += wayland_client_header + +wayland_code.name = wayland ${QMAKE_FILE_BASE} +wayland_code.input = WAYLANDCLIENTSOURCES +wayland_code.variable_out = SOURCES +wayland_code.output = wayland-${QMAKE_FILE_BASE}-protocol.c +wayland_code.commands = $$QMAKE_WAYLAND_SCANNER --include-core-only code < ${QMAKE_FILE_IN} > ${QMAKE_FILE_OUT} +silent:wayland_code.commands = @echo Wayland code header ${QMAKE_FILE_IN} && $$wayland_code.commands +QMAKE_EXTRA_COMPILERS += wayland_code + +qtPrepareTool(QMAKE_QTWAYLANDSCANNER, qtwaylandscanner) + +qtwayland_client_header.name = qtwayland ${QMAKE_FILE_BASE} +qtwayland_client_header.input = WAYLANDCLIENTSOURCES +qtwayland_client_header.variable_out = HEADERS +qtwayland_client_header.depends += $$QMAKE_QTWAYLANDSCANNER_EXE wayland-${QMAKE_FILE_BASE}-client-protocol$${first(QMAKE_EXT_H)} +qtwayland_client_header.output = qwayland-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)} +qtwayland_client_header.commands = $$QMAKE_QTWAYLANDSCANNER client-header ${QMAKE_FILE_IN} $$WAYLAND_INCLUDE_DIR > ${QMAKE_FILE_OUT} +silent:qtwayland_client_header.commands = @echo QtWayland client header ${QMAKE_FILE_IN} && $$qtwayland_client_header.commands +QMAKE_EXTRA_COMPILERS += qtwayland_client_header + +qtwayland_client_code.name = qtwayland ${QMAKE_FILE_BASE} +qtwayland_client_code.input = WAYLANDCLIENTSOURCES +qtwayland_client_code.variable_out = SOURCES +qtwayland_client_code.depends += $$QMAKE_QTWAYLANDSCANNER_EXE qwayland-${QMAKE_FILE_BASE}$${first(QMAKE_EXT_H)} +qtwayland_client_code.output = qwayland-${QMAKE_FILE_BASE}.cpp +qtwayland_client_code.commands = $$QMAKE_QTWAYLANDSCANNER client-code ${QMAKE_FILE_IN} $$WAYLAND_INCLUDE_DIR > ${QMAKE_FILE_OUT} +silent:qtwayland_client_code.commands = @echo QtWayland client code ${QMAKE_FILE_IN} && $$qtwayland_client_code.commands +QMAKE_EXTRA_COMPILERS += qtwayland_client_code diff --git a/src/3rdparty/protocol/fullscreen-shell-unstable-v1.xml b/src/3rdparty/protocol/fullscreen-shell-unstable-v1.xml new file mode 100644 index 000000000..1bca7b7c7 --- /dev/null +++ b/src/3rdparty/protocol/fullscreen-shell-unstable-v1.xml @@ -0,0 +1,245 @@ +<?xml version="1.0" encoding="UTF-8"?> +<protocol name="fullscreen_shell_unstable_v1"> + + <copyright> + Copyright © 2016 Yong Bakos + Copyright © 2015 Jason Ekstrand + Copyright © 2015 Jonas Ã…dahl + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + </copyright> + + <interface name="zwp_fullscreen_shell_v1" version="1"> + <description summary="displays a single surface per output"> + Displays a single surface per output. + + This interface provides a mechanism for a single client to display + simple full-screen surfaces. While there technically may be multiple + clients bound to this interface, only one of those clients should be + shown at a time. + + To present a surface, the client uses either the present_surface or + present_surface_for_mode requests. Presenting a surface takes effect + on the next wl_surface.commit. See the individual requests for + details about scaling and mode switches. + + The client can have at most one surface per output at any time. + Requesting a surface to be presented on an output that already has a + surface replaces the previously presented surface. Presenting a null + surface removes its content and effectively disables the output. + Exactly what happens when an output is "disabled" is + compositor-specific. The same surface may be presented on multiple + outputs simultaneously. + + Once a surface is presented on an output, it stays on that output + until either the client removes it or the compositor destroys the + output. This way, the client can update the output's contents by + simply attaching a new buffer. + + Warning! The protocol described in this file is experimental and + backward incompatible changes may be made. Backward compatible changes + may be added together with the corresponding interface version bump. + Backward incompatible changes are done by bumping the version number in + the protocol and interface names and resetting the interface version. + Once the protocol is to be declared stable, the 'z' prefix and the + version number in the protocol and interface names are removed and the + interface version number is reset. + </description> + + <request name="release" type="destructor"> + <description summary="release the wl_fullscreen_shell interface"> + Release the binding from the wl_fullscreen_shell interface. + + This destroys the server-side object and frees this binding. If + the client binds to wl_fullscreen_shell multiple times, it may wish + to free some of those bindings. + </description> + </request> + + <enum name="capability"> + <description summary="capabilities advertised by the compositor"> + Various capabilities that can be advertised by the compositor. They + are advertised one-at-a-time when the wl_fullscreen_shell interface is + bound. See the wl_fullscreen_shell.capability event for more details. + + ARBITRARY_MODES: + This is a hint to the client that indicates that the compositor is + capable of setting practically any mode on its outputs. If this + capability is provided, wl_fullscreen_shell.present_surface_for_mode + will almost never fail and clients should feel free to set whatever + mode they like. If the compositor does not advertise this, it may + still support some modes that are not advertised through wl_global.mode + but it is less likely. + + CURSOR_PLANE: + This is a hint to the client that indicates that the compositor can + handle a cursor surface from the client without actually compositing. + This may be because of a hardware cursor plane or some other mechanism. + If the compositor does not advertise this capability then setting + wl_pointer.cursor may degrade performance or be ignored entirely. If + CURSOR_PLANE is not advertised, it is recommended that the client draw + its own cursor and set wl_pointer.cursor(NULL). + </description> + <entry name="arbitrary_modes" value="1" summary="compositor is capable of almost any output mode"/> + <entry name="cursor_plane" value="2" summary="compositor has a separate cursor plane"/> + </enum> + + <event name="capability"> + <description summary="advertises a capability of the compositor"> + Advertises a single capability of the compositor. + + When the wl_fullscreen_shell interface is bound, this event is emitted + once for each capability advertised. Valid capabilities are given by + the wl_fullscreen_shell.capability enum. If clients want to take + advantage of any of these capabilities, they should use a + wl_display.sync request immediately after binding to ensure that they + receive all the capability events. + </description> + <arg name="capability" type="uint"/> + </event> + + <enum name="present_method"> + <description summary="different method to set the surface fullscreen"> + Hints to indicate to the compositor how to deal with a conflict + between the dimensions of the surface and the dimensions of the + output. The compositor is free to ignore this parameter. + </description> + <entry name="default" value="0" summary="no preference, apply default policy"/> + <entry name="center" value="1" summary="center the surface on the output"/> + <entry name="zoom" value="2" summary="scale the surface, preserving aspect ratio, to the largest size that will fit on the output" /> + <entry name="zoom_crop" value="3" summary="scale the surface, preserving aspect ratio, to fully fill the output cropping if needed" /> + <entry name="stretch" value="4" summary="scale the surface to the size of the output ignoring aspect ratio" /> + </enum> + + <request name="present_surface"> + <description summary="present surface for display"> + Present a surface on the given output. + + If the output is null, the compositor will present the surface on + whatever display (or displays) it thinks best. In particular, this + may replace any or all surfaces currently presented so it should + not be used in combination with placing surfaces on specific + outputs. + + The method parameter is a hint to the compositor for how the surface + is to be presented. In particular, it tells the compositor how to + handle a size mismatch between the presented surface and the + output. The compositor is free to ignore this parameter. + + The "zoom", "zoom_crop", and "stretch" methods imply a scaling + operation on the surface. This will override any kind of output + scaling, so the buffer_scale property of the surface is effectively + ignored. + </description> + <arg name="surface" type="object" interface="wl_surface" allow-null="true"/> + <arg name="method" type="uint"/> + <arg name="output" type="object" interface="wl_output" allow-null="true"/> + </request> + + <request name="present_surface_for_mode"> + <description summary="present surface for display at a particular mode"> + Presents a surface on the given output for a particular mode. + + If the current size of the output differs from that of the surface, + the compositor will attempt to change the size of the output to + match the surface. The result of the mode-switch operation will be + returned via the provided wl_fullscreen_shell_mode_feedback object. + + If the current output mode matches the one requested or if the + compositor successfully switches the mode to match the surface, + then the mode_successful event will be sent and the output will + contain the contents of the given surface. If the compositor + cannot match the output size to the surface size, the mode_failed + will be sent and the output will contain the contents of the + previously presented surface (if any). If another surface is + presented on the given output before either of these has a chance + to happen, the present_cancelled event will be sent. + + Due to race conditions and other issues unknown to the client, no + mode-switch operation is guaranteed to succeed. However, if the + mode is one advertised by wl_output.mode or if the compositor + advertises the ARBITRARY_MODES capability, then the client should + expect that the mode-switch operation will usually succeed. + + If the size of the presented surface changes, the resulting output + is undefined. The compositor may attempt to change the output mode + to compensate. However, there is no guarantee that a suitable mode + will be found and the client has no way to be notified of success + or failure. + + The framerate parameter specifies the desired framerate for the + output in mHz. The compositor is free to ignore this parameter. A + value of 0 indicates that the client has no preference. + + If the value of wl_output.scale differs from wl_surface.buffer_scale, + then the compositor may choose a mode that matches either the buffer + size or the surface size. In either case, the surface will fill the + output. + </description> + <arg name="surface" type="object" interface="wl_surface"/> + <arg name="output" type="object" interface="wl_output"/> + <arg name="framerate" type="int"/> + <arg name="feedback" type="new_id" interface="zwp_fullscreen_shell_mode_feedback_v1"/> + </request> + + <enum name="error"> + <description summary="wl_fullscreen_shell error values"> + These errors can be emitted in response to wl_fullscreen_shell requests. + </description> + <entry name="invalid_method" value="0" summary="present_method is not known"/> + </enum> + </interface> + + <interface name="zwp_fullscreen_shell_mode_feedback_v1" version="1"> + <event name="mode_successful"> + <description summary="mode switch succeeded"> + This event indicates that the attempted mode switch operation was + successful. A surface of the size requested in the mode switch + will fill the output without scaling. + + Upon receiving this event, the client should destroy the + wl_fullscreen_shell_mode_feedback object. + </description> + </event> + + <event name="mode_failed"> + <description summary="mode switch failed"> + This event indicates that the attempted mode switch operation + failed. This may be because the requested output mode is not + possible or it may mean that the compositor does not want to allow it. + + Upon receiving this event, the client should destroy the + wl_fullscreen_shell_mode_feedback object. + </description> + </event> + + <event name="present_cancelled"> + <description summary="mode switch cancelled"> + This event indicates that the attempted mode switch operation was + cancelled. Most likely this is because the client requested a + second mode switch before the first one completed. + + Upon receiving this event, the client should destroy the + wl_fullscreen_shell_mode_feedback object. + </description> + </event> + </interface> + +</protocol> diff --git a/src/3rdparty/protocol/qt_attribution.json b/src/3rdparty/protocol/qt_attribution.json index e5bf91e10..615e95a9f 100644 --- a/src/3rdparty/protocol/qt_attribution.json +++ b/src/3rdparty/protocol/qt_attribution.json @@ -1,5 +1,24 @@ [ { + "Id": "wayland-fullscreen-protocol", + "Name": "Wayland Fullscreen Shell Protocol", + "QDocModule": "qtwaylandcompositor", + "QtUsage": "Used in the Qt Wayland platform plugin.", + "Files": "fullscreen-shell-unstable-v1.xml", + + "Description": "A Wayland shell for displaying a single surface per output", + "Homepage": "https://wayland.freedesktop.org", + "Version": "unstable v1", + "DownloadLocation": "https://cgit.freedesktop.org/wayland/wayland-protocols", + "LicenseId": "MIT", + "License": "MIT License", + "LicenseFile": "MIT_LICENSE.txt", + "Copyright": "Copyright © 2016 Yong Bakos +Copyright © 2015 Jason Ekstrand +Copyright © 2015 Jonas Ã…dahl" + }, + + { "Id": "wayland-protocol", "Name": "Wayland Protocol", "QDocModule": "qtwaylandcompositor", diff --git a/src/client/client.pro b/src/client/client.pro index 45bbb976b..42e7cae8c 100644 --- a/src/client/client.pro +++ b/src/client/client.pro @@ -18,6 +18,9 @@ CONFIG += link_pkgconfig wayland-scanner qtConfig(xkbcommon-evdev): \ QMAKE_USE_PRIVATE += xkbcommon_evdev +qtHaveModule(linuxaccessibility_support_private): \ + QT += linuxaccessibility_support_private + QMAKE_USE += wayland-client INCLUDEPATH += $$PWD/../shared @@ -29,9 +32,7 @@ WAYLANDCLIENTSOURCES += \ ../extensions/qt-windowmanager.xml \ ../3rdparty/protocol/text-input-unstable-v2.xml \ ../3rdparty/protocol/xdg-output-unstable-v1.xml \ - -WAYLANDCLIENTSOURCES_SYSTEM += \ - ../3rdparty/protocol/wayland.xml \ + ../3rdparty/protocol/wayland.xml SOURCES += qwaylandintegration.cpp \ qwaylandnativeinterface.cpp \ diff --git a/src/client/configure.json b/src/client/configure.json index 1f86a4936..b5146680e 100644 --- a/src/client/configure.json +++ b/src/client/configure.json @@ -87,6 +87,36 @@ "condition": "features.draganddrop || features.clipboard", "output": [ "privateFeature" ] }, + "wayland-client-fullscreen-shell-v1": { + "label": "fullscreen-shell-v1", + "condition": "features.wayland-client", + "output": [ "privateFeature" ] + }, + "wayland-client-ivi-shell": { + "label": "ivi-shell", + "condition": "features.wayland-client", + "output": [ "privateFeature" ] + }, + "wayland-client-wl-shell": { + "label": "wl-shell (deprecated)", + "condition": "features.wayland-client", + "output": [ "privateFeature" ] + }, + "wayland-client-xdg-shell": { + "label": "xdg-shell", + "condition": "features.wayland-client", + "output": [ "privateFeature" ] + }, + "wayland-client-xdg-shell-v5": { + "label": "xdg-shell unstable v5 (deprecated)", + "condition": "features.wayland-client", + "output": [ "privateFeature" ] + }, + "wayland-client-xdg-shell-v6": { + "label": "xdg-shell unstable v6", + "condition": "features.wayland-client", + "output": [ "privateFeature" ] + }, "wayland-egl": { "label": "EGL", "condition": "features.wayland-client && features.opengl && features.egl && libs.wayland-egl", @@ -151,6 +181,17 @@ "wayland-shm-emulation-server-buffer" ] }, + { + "section": "Qt Wayland Client Shell Integrations", + "condition": "features.wayland-client", + "entries": [ + "wayland-client-xdg-shell", + "wayland-client-xdg-shell-v5", + "wayland-client-xdg-shell-v6", + "wayland-client-ivi-shell", + "wayland-client-wl-shell" + ] + }, "wayland-client" ] } diff --git a/src/client/qwaylandabstractdecoration.cpp b/src/client/qwaylandabstractdecoration.cpp index 479a85750..503ad41fc 100644 --- a/src/client/qwaylandabstractdecoration.cpp +++ b/src/client/qwaylandabstractdecoration.cpp @@ -145,11 +145,11 @@ void QWaylandAbstractDecoration::setMouseButtons(Qt::MouseButtons mb) d->m_mouseButtons = mb; } -void QWaylandAbstractDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons) +void QWaylandAbstractDecoration::startResize(QWaylandInputDevice *inputDevice, Qt::Edges edges, Qt::MouseButtons buttons) { Q_D(QWaylandAbstractDecoration); if (isLeftClicked(buttons) && d->m_wayland_window->shellSurface()) { - d->m_wayland_window->shellSurface()->resize(inputDevice, resize); + d->m_wayland_window->shellSurface()->resize(inputDevice, edges); inputDevice->removeMouseButtonFromState(Qt::LeftButton); } } diff --git a/src/client/qwaylandabstractdecoration_p.h b/src/client/qwaylandabstractdecoration_p.h index 84a6d4dd7..f5b1854dd 100644 --- a/src/client/qwaylandabstractdecoration_p.h +++ b/src/client/qwaylandabstractdecoration_p.h @@ -61,8 +61,6 @@ #include <QtGui/QImage> #include <QtWaylandClient/qtwaylandclientglobal.h> -#include <wayland-client.h> - #include <QtCore/QDebug> QT_BEGIN_NAMESPACE @@ -105,7 +103,7 @@ protected: void setMouseButtons(Qt::MouseButtons mb); - void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons); + void startResize(QWaylandInputDevice *inputDevice, Qt::Edges edges, Qt::MouseButtons buttons); void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons); bool isLeftClicked(Qt::MouseButtons newMouseButtonState); diff --git a/src/client/qwaylandbuffer_p.h b/src/client/qwaylandbuffer_p.h index eea090f35..945f1279a 100644 --- a/src/client/qwaylandbuffer_p.h +++ b/src/client/qwaylandbuffer_p.h @@ -56,8 +56,7 @@ #include <QtCore/QSize> #include <QtCore/QRect> -#include <wayland-client.h> -#include <wayland-client-protocol.h> +#include <QtWaylandClient/private/wayland-wayland-client-protocol.h> QT_BEGIN_NAMESPACE diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index a2957e0dd..bd75b6bcd 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -272,10 +272,13 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin inputDevice->setTextInput(new QWaylandTextInput(this, mTextInputManager->get_text_input(inputDevice->wl_seat()))); } } else if (interface == QStringLiteral("qt_hardware_integration")) { - mHardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id)); - // make a roundtrip here since we need to receive the events sent by - // qt_hardware_integration before creating windows - forceRoundTrip(); + bool disableHardwareIntegration = qEnvironmentVariableIntValue("QT_WAYLAND_DISABLE_HW_INTEGRATION"); + if (!disableHardwareIntegration) { + mHardwareIntegration.reset(new QWaylandHardwareIntegration(registry, id)); + // make a roundtrip here since we need to receive the events sent by + // qt_hardware_integration before creating windows + forceRoundTrip(); + } } else if (interface == QLatin1String("zxdg_output_manager_v1")) { mXdgOutputManager.reset(new QtWayland::zxdg_output_manager_v1(registry, id, 1)); for (auto *screen : qAsConst(mScreens)) diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index 0dd8d7aff..d03ea294a 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -59,8 +59,6 @@ #include <QtCore/QWaitCondition> #include <QtCore/QLoggingCategory> -#include <wayland-client.h> - #include <QtWaylandClient/private/qwayland-wayland.h> #include <QtWaylandClient/private/qtwaylandclientglobal_p.h> #include <QtWaylandClient/private/qwaylandshm_p.h> diff --git a/src/client/qwaylandextendedsurface_p.h b/src/client/qwaylandextendedsurface_p.h index cd604f342..d71ac6be9 100644 --- a/src/client/qwaylandextendedsurface_p.h +++ b/src/client/qwaylandextendedsurface_p.h @@ -56,7 +56,6 @@ #include <QtWaylandClient/qtwaylandclientglobal.h> -#include <wayland-client.h> #include <QtWaylandClient/private/qwayland-surface-extension.h> QT_BEGIN_NAMESPACE diff --git a/src/client/qwaylandinputcontext_p.h b/src/client/qwaylandinputcontext_p.h index 93300e1f5..10132dfe1 100644 --- a/src/client/qwaylandinputcontext_p.h +++ b/src/client/qwaylandinputcontext_p.h @@ -62,6 +62,9 @@ #include <QtWaylandClient/private/qwayland-text-input-unstable-v2.h> #include <qwaylandinputmethodeventbuilder_p.h> +struct wl_callback; +struct wl_callback_listener; + QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(qLcQpaInputMethods) diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 37c6fbe9f..5b5ad7a32 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -781,7 +781,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, #if QT_CONFIG(xkbcommon_evdev) mRepeatSym = sym; #endif - mRepeatTimer.setInterval(400); + mRepeatTimer.setInterval(mRepeatDelay); mRepeatTimer.start(); } else if (mRepeatCode == code) { mRepeatTimer.stop(); @@ -790,7 +790,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, void QWaylandInputDevice::Keyboard::repeatKey() { - mRepeatTimer.setInterval(25); + mRepeatTimer.setInterval(mRepeatRate); sendKey(mFocus->window(), mRepeatTime, QEvent::KeyRelease, mRepeatKey, modifiers(), mRepeatCode, #if QT_CONFIG(xkbcommon_evdev) mRepeatSym, mNativeModifiers, @@ -830,6 +830,12 @@ void QWaylandInputDevice::Keyboard::keyboard_modifiers(uint32_t serial, #endif } +void QWaylandInputDevice::Keyboard::keyboard_repeat_info(int32_t rate, int32_t delay) +{ + mRepeatRate = rate; + mRepeatDelay = delay; +} + void QWaylandInputDevice::Touch::touch_down(uint32_t serial, uint32_t time, struct wl_surface *surface, diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 4b12cc089..d1ff0da23 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -61,8 +61,6 @@ #include <qpa/qplatformscreen.h> #include <qpa/qwindowsysteminterface.h> -#include <wayland-client.h> - #include <QtWaylandClient/private/qwayland-wayland.h> #if QT_CONFIG(xkbcommon_evdev) @@ -206,6 +204,7 @@ public: uint32_t mods_latched, uint32_t mods_locked, uint32_t group) override; + void keyboard_repeat_info(int32_t rate, int32_t delay) override; QWaylandInputDevice *mParent = nullptr; QPointer<QWaylandWindow> mFocus; @@ -221,6 +220,8 @@ public: int mRepeatKey; uint32_t mRepeatCode; uint32_t mRepeatTime; + int mRepeatRate = 25; + int mRepeatDelay = 400; QString mRepeatText; #if QT_CONFIG(xkbcommon_evdev) xkb_keysym_t mRepeatSym; diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp index e935ef31f..073258d41 100644 --- a/src/client/qwaylandintegration.cpp +++ b/src/client/qwaylandintegration.cpp @@ -86,6 +86,10 @@ #include "qwaylandinputdeviceintegration_p.h" #include "qwaylandinputdeviceintegrationfactory_p.h" +#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE +#include <QtLinuxAccessibilitySupport/private/bridge_p.h> +#endif + QT_BEGIN_NAMESPACE namespace QtWaylandClient { @@ -129,9 +133,6 @@ QWaylandIntegration::QWaylandIntegration() : mFontDb(new QGenericUnixFontDatabase()) #endif , mNativeInterface(new QWaylandNativeInterface(this)) -#if QT_CONFIG(accessibility) - , mAccessibility(new QPlatformAccessibility()) -#endif { initializeInputDeviceIntegration(); mDisplay.reset(new QWaylandDisplay(this)); @@ -277,6 +278,15 @@ QVariant QWaylandIntegration::styleHint(StyleHint hint) const #if QT_CONFIG(accessibility) QPlatformAccessibility *QWaylandIntegration::accessibility() const { + if (!mAccessibility) { +#ifndef QT_NO_ACCESSIBILITY_ATSPI_BRIDGE + Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QXcbIntegration", + "Initializing accessibility without event-dispatcher!"); + mAccessibility.reset(new QSpiAccessibleBridge()); +#else + mAccessibility.reset(new QPlatformAccessibility()); +#endif + } return mAccessibility.data(); } #endif @@ -329,16 +339,13 @@ void QWaylandIntegration::initializeClientBufferIntegration() { mClientBufferIntegrationInitialized = true; - QString targetKey; - bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION"); - disableHardwareIntegration = disableHardwareIntegration || !mDisplay->hardwareIntegration(); - if (disableHardwareIntegration) { - QByteArray clientBufferIntegrationName = qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION"); - if (clientBufferIntegrationName.isEmpty()) - clientBufferIntegrationName = QByteArrayLiteral("wayland-egl"); - targetKey = QString::fromLocal8Bit(clientBufferIntegrationName); - } else { - targetKey = mDisplay->hardwareIntegration()->clientBufferIntegration(); + QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_CLIENT_BUFFER_INTEGRATION")); + + if (targetKey.isEmpty()) { + if (mDisplay->hardwareIntegration()) + targetKey = mDisplay->hardwareIntegration()->clientBufferIntegration(); + else + targetKey = QLatin1Literal("wayland-egl"); } if (targetKey.isEmpty()) { @@ -347,29 +354,28 @@ void QWaylandIntegration::initializeClientBufferIntegration() } QStringList keys = QWaylandClientBufferIntegrationFactory::keys(); - if (keys.contains(targetKey)) { + qCDebug(lcQpaWayland) << "Available client buffer integrations:" << keys; + + if (keys.contains(targetKey)) mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList())); - } - if (mClientBufferIntegration) + + if (mClientBufferIntegration) { + qCDebug(lcQpaWayland) << "Initializing client buffer integration" << targetKey; mClientBufferIntegration->initialize(mDisplay.data()); - else - qWarning("Failed to load client buffer integration: %s\n", qPrintable(targetKey)); + } else { + qCWarning(lcQpaWayland) << "Failed to load client buffer integration:" << targetKey; + qCWarning(lcQpaWayland) << "Available client buffer integrations:" << keys; + } } void QWaylandIntegration::initializeServerBufferIntegration() { mServerBufferIntegrationInitialized = true; - QString targetKey; + QString targetKey = QString::fromLocal8Bit(qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION")); - bool disableHardwareIntegration = qEnvironmentVariableIsSet("QT_WAYLAND_DISABLE_HW_INTEGRATION"); - disableHardwareIntegration = disableHardwareIntegration || !mDisplay->hardwareIntegration(); - if (disableHardwareIntegration) { - QByteArray serverBufferIntegrationName = qgetenv("QT_WAYLAND_SERVER_BUFFER_INTEGRATION"); - targetKey = QString::fromLocal8Bit(serverBufferIntegrationName); - } else { + if (targetKey.isEmpty() && mDisplay->hardwareIntegration()) targetKey = mDisplay->hardwareIntegration()->serverBufferIntegration(); - } if (targetKey.isEmpty()) { qWarning("Failed to determine what server buffer integration to use"); @@ -377,13 +383,18 @@ void QWaylandIntegration::initializeServerBufferIntegration() } QStringList keys = QWaylandServerBufferIntegrationFactory::keys(); - if (keys.contains(targetKey)) { + qCDebug(lcQpaWayland) << "Available server buffer integrations:" << keys; + + if (keys.contains(targetKey)) mServerBufferIntegration.reset(QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList())); - } - if (mServerBufferIntegration) + + if (mServerBufferIntegration) { + qCDebug(lcQpaWayland) << "Initializing server buffer integration" << targetKey; mServerBufferIntegration->initialize(mDisplay.data()); - else - qWarning("Failed to load server buffer integration %s\n", qPrintable(targetKey)); + } else { + qCWarning(lcQpaWayland) << "Failed to load server buffer integration: " << targetKey; + qCWarning(lcQpaWayland) << "Available server buffer integrations:" << keys; + } } void QWaylandIntegration::initializeShellIntegration() @@ -411,7 +422,7 @@ void QWaylandIntegration::initializeShellIntegration() Q_FOREACH (QString preferredShell, preferredShells) { mShellIntegration.reset(createShellIntegration(preferredShell)); if (mShellIntegration) { - qDebug("Using the '%s' shell integration", qPrintable(preferredShell)); + qCDebug(lcQpaWayland, "Using the '%s' shell integration", qPrintable(preferredShell)); break; } } diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h index a5a3d7b69..944f635bb 100644 --- a/src/client/qwaylandintegration_p.h +++ b/src/client/qwaylandintegration_p.h @@ -145,7 +145,7 @@ private: QScopedPointer<QPlatformNativeInterface> mNativeInterface; QScopedPointer<QPlatformInputContext> mInputContext; #if QT_CONFIG(accessibility) - QScopedPointer<QPlatformAccessibility> mAccessibility; + mutable QScopedPointer<QPlatformAccessibility> mAccessibility; #endif bool mFailed = false; bool mClientBufferIntegrationInitialized = false; diff --git a/src/client/qwaylandshellsurface_p.h b/src/client/qwaylandshellsurface_p.h index 6bc3258c7..f683d9e01 100644 --- a/src/client/qwaylandshellsurface_p.h +++ b/src/client/qwaylandshellsurface_p.h @@ -54,8 +54,6 @@ #include <QtCore/QSize> #include <QObject> -#include <wayland-client.h> - #include <QtWaylandClient/private/qwayland-wayland.h> #include <QtWaylandClient/qtwaylandclientglobal.h> @@ -75,8 +73,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandShellSurface : public QObject public: explicit QWaylandShellSurface(QWaylandWindow *window); ~QWaylandShellSurface() override {} - virtual void resize(QWaylandInputDevice * /*inputDevice*/, enum wl_shell_surface_resize /*edges*/) - {} + virtual void resize(QWaylandInputDevice * /*inputDevice*/, Qt::Edges /*edges*/) {} virtual bool move(QWaylandInputDevice *) { return false; } virtual void setTitle(const QString & /*title*/) {} diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp index 3fe2ce80c..34044ec9b 100644 --- a/src/client/qwaylandshmbackingstore.cpp +++ b/src/client/qwaylandshmbackingstore.cpp @@ -49,8 +49,7 @@ #include <QtGui/QPainter> #include <QMutexLocker> -#include <wayland-client.h> -#include <wayland-client-protocol.h> +#include <QtWaylandClient/private/wayland-wayland-client-protocol.h> #include <unistd.h> #include <sys/mman.h> diff --git a/src/client/qwaylandsubsurface_p.h b/src/client/qwaylandsubsurface_p.h index e9a7cb20e..76da10b24 100644 --- a/src/client/qwaylandsubsurface_p.h +++ b/src/client/qwaylandsubsurface_p.h @@ -51,8 +51,6 @@ // We mean it. // -#include <wayland-client.h> - #include <QtCore/qglobal.h> #include <QtCore/qmutex.h> diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 4ac2ca51e..8e8726f02 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -67,8 +67,6 @@ #include <QtCore/QDebug> -#include <wayland-client.h> - QT_BEGIN_NAMESPACE namespace QtWaylandClient { diff --git a/src/client/qwaylandwindowmanagerintegration_p.h b/src/client/qwaylandwindowmanagerintegration_p.h index 1319abd91..31de6ddd3 100644 --- a/src/client/qwaylandwindowmanagerintegration_p.h +++ b/src/client/qwaylandwindowmanagerintegration_p.h @@ -54,7 +54,6 @@ #include <QtCore/QObject> #include <QtCore/QScopedPointer> -#include <wayland-client.h> #include <QtServiceSupport/private/qgenericunixservices_p.h> #include <QtWaylandClient/private/qwayland-qt-windowmanager.h> diff --git a/src/compositor/compositor_api/qwaylandclient.cpp b/src/compositor/compositor_api/qwaylandclient.cpp index 7f0b225b2..d26dfc6d5 100644 --- a/src/compositor/compositor_api/qwaylandclient.cpp +++ b/src/compositor/compositor_api/qwaylandclient.cpp @@ -44,7 +44,7 @@ #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> -#include <wayland-server.h> +#include <wayland-server-core.h> #include <wayland-util.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylanddestroylistener_p.h b/src/compositor/compositor_api/qwaylanddestroylistener_p.h index 7c6001c36..0bbeb69c0 100644 --- a/src/compositor/compositor_api/qwaylanddestroylistener_p.h +++ b/src/compositor/compositor_api/qwaylanddestroylistener_p.h @@ -55,7 +55,7 @@ #include <QtCore/private/qobject_p.h> -#include <wayland-server.h> +#include <wayland-server-core.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/compositor_api/qwaylandpointer.cpp b/src/compositor/compositor_api/qwaylandpointer.cpp index 77e736a58..96263e0c2 100644 --- a/src/compositor/compositor_api/qwaylandpointer.cpp +++ b/src/compositor/compositor_api/qwaylandpointer.cpp @@ -239,7 +239,7 @@ uint QWaylandPointer::sendMouseReleaseEvent(Qt::MouseButton button) /*! * Sets the current mouse focus to \a view and sends a mouse move event to it with the - * local position \a localPos and output space position \a outputSpacePos. + * local position \a localPos in surface coordinates and output space position \a outputSpacePos. */ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &localPos, const QPointF &outputSpacePos) { @@ -253,7 +253,7 @@ void QWaylandPointer::sendMouseMoveEvent(QWaylandView *view, const QPointF &loca if (view) { // We adjust if the mouse position is on the edge // to work around Qt's event propagation - QSizeF size(view->surface()->size()); + QSizeF size(view->surface()->destinationSize()); if (d->localPosition.x() == size.width()) d->localPosition.rx() -= 0.01; if (d->localPosition.y() == size.height()) @@ -294,7 +294,7 @@ QWaylandView *QWaylandPointer::mouseFocus() const } /*! - * Returns the current local position of the QWaylandPointer. + * Returns the current local position of the QWaylandPointer in surface coordinates. */ QPointF QWaylandPointer::currentLocalPosition() const { diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index a5de3a903..8e1b84921 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -64,7 +64,7 @@ #include <QtCore/QMutexLocker> #include <QtCore/QMutex> -#include <wayland-server.h> +#include <wayland-server-core.h> #include <QThread> #ifndef GL_TEXTURE_EXTERNAL_OES @@ -886,7 +886,7 @@ void QWaylandQuickItem::handleSurfaceChanged() if (d->oldSurface) { disconnect(d->oldSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged); disconnect(d->oldSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); - disconnect(d->oldSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); + disconnect(d->oldSurface, &QWaylandSurface::destinationSizeChanged, this, &QWaylandQuickItem::updateSize); disconnect(d->oldSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); disconnect(d->oldSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); disconnect(d->oldSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); @@ -903,7 +903,7 @@ void QWaylandQuickItem::handleSurfaceChanged() if (QWaylandSurface *newSurface = d->view->surface()) { connect(newSurface, &QWaylandSurface::hasContentChanged, this, &QWaylandQuickItem::surfaceMappedChanged); connect(newSurface, &QWaylandSurface::parentChanged, this, &QWaylandQuickItem::parentChanged); - connect(newSurface, &QWaylandSurface::sizeChanged, this, &QWaylandQuickItem::updateSize); + connect(newSurface, &QWaylandSurface::destinationSizeChanged, this, &QWaylandQuickItem::updateSize); connect(newSurface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandQuickItem::updateSize); connect(newSurface, &QWaylandSurface::configure, this, &QWaylandQuickItem::updateBuffer); connect(newSurface, &QWaylandSurface::redraw, this, &QQuickItem::update); @@ -992,7 +992,7 @@ void QWaylandQuickItem::updateSize() QSize size(0, 0); if (surface()) - size = surface()->size() * (d->scaleFactor() / surface()->bufferScale()); + size = surface()->destinationSize() * d->scaleFactor(); setImplicitSize(size.width(), size.height()); if (d->sizeFollowsSurface) @@ -1061,16 +1061,32 @@ bool QWaylandQuickItem::inputRegionContains(const QPointF &localPosition) QPointF QWaylandQuickItem::mapToSurface(const QPointF &point) const { Q_D(const QWaylandQuickItem); - if (!surface() || surface()->size().isEmpty()) + if (!surface() || surface()->destinationSize().isEmpty()) return point / d->scaleFactor(); - qreal xScale = width() / surface()->size().width() * surface()->bufferScale(); - qreal yScale = height() / surface()->size().height() * surface()->bufferScale(); + qreal xScale = width() / surface()->destinationSize().width(); + qreal yScale = height() / surface()->destinationSize().height(); return QPointF(point.x() / xScale, point.y() / yScale); } /*! + * Maps the given \a point in the Wayland surfaces's coordinate system to the equivalent + * point within this item's coordinate system, and returns the mapped coordinate. + */ +QPointF QWaylandQuickItem::mapFromSurface(const QPointF &point) const +{ + Q_D(const QWaylandQuickItem); + if (!surface() || surface()->destinationSize().isEmpty()) + return point * d->scaleFactor(); + + qreal xScale = width() / surface()->destinationSize().width(); + qreal yScale = height() / surface()->destinationSize().height(); + + return QPointF(point.x() * xScale, point.y() * yScale); +} + +/*! * \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::sizeFollowsSurface * * This property specifies whether the size of the item should always match diff --git a/src/compositor/compositor_api/qwaylandquickitem.h b/src/compositor/compositor_api/qwaylandquickitem.h index 23708353e..6f47c29a4 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.h +++ b/src/compositor/compositor_api/qwaylandquickitem.h @@ -102,6 +102,7 @@ public: bool inputRegionContains(const QPointF &localPosition) const; bool inputRegionContains(const QPointF &localPosition); Q_INVOKABLE QPointF mapToSurface(const QPointF &point) const; + Q_INVOKABLE QPointF mapFromSurface(const QPointF &point) const; bool sizeFollowsSurface() const; void setSizeFollowsSurface(bool sizeFollowsSurface); diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 13ae28220..59e741c84 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -234,19 +234,21 @@ void QWaylandSurfacePrivate::surface_commit(Resource *) // Needed in order to know whether we want to emit signals later QSize oldBufferSize = bufferSize; + QSize oldDestinationSize = destinationSize; bool oldHasContent = hasContent; int oldBufferScale = bufferScale; // Update all internal state if (pending.buffer.hasBuffer() || pending.newlyAttached) bufferRef = pending.buffer; + bufferScale = pending.bufferScale; bufferSize = bufferRef.size(); - damage = pending.damage.intersected(QRect(QPoint(), bufferSize)); + destinationSize = pending.destinationSize.isEmpty() ? bufferSize / bufferScale : pending.destinationSize; + damage = pending.damage.intersected(QRect(QPoint(), destinationSize)); hasContent = bufferRef.hasContent(); - bufferScale = pending.bufferScale; frameCallbacks << pendingFrameCallbacks; - inputRegion = pending.inputRegion.intersected(QRect(QPoint(), bufferSize)); - opaqueRegion = pending.opaqueRegion.intersected(QRect(QPoint(), bufferSize)); + inputRegion = pending.inputRegion.intersected(QRect(QPoint(), destinationSize)); + opaqueRegion = pending.opaqueRegion.intersected(QRect(QPoint(), destinationSize)); QPoint offsetForNextFrame = pending.offset; // Clear per-commit state @@ -268,12 +270,19 @@ void QWaylandSurfacePrivate::surface_commit(Resource *) emit q->damaged(damage); - if (oldBufferSize != bufferSize) + if (oldBufferSize != bufferSize) { + emit q->bufferSizeChanged(); +#if QT_DEPRECATED_SINCE(5, 13) emit q->sizeChanged(); +#endif + } if (oldBufferScale != bufferScale) emit q->bufferScaleChanged(); + if (oldDestinationSize != destinationSize) + emit q->destinationSizeChanged(); + if (oldHasContent != hasContent) emit q->hasContentChanged(); @@ -448,21 +457,76 @@ bool QWaylandSurface::hasContent() const } /*! + * \qmlproperty size QtWaylandCompositor::WaylandSurface::destinationSize + * + * This property holds the size of this WaylandSurface in surface coordinates. + * + * \sa bufferScale + * \sa bufferSize + */ + +/*! + * \property QWaylandSurface::destinationSize + * + * This property holds the size of this WaylandSurface in surface coordinates. + * + * \sa bufferScale + * \sa bufferSize + */ +QSize QWaylandSurface::destinationSize() const +{ + Q_D(const QWaylandSurface); + return d->destinationSize; +} + +/*! + * \qmlproperty size QtWaylandCompositor::WaylandSurface::bufferSize + * + * This property holds the size of the current buffer of this WaylandSurface in pixels, + * not in surface coordinates. + * + * For the size in surface coordinates, use \l destinationSize instead. + * + * \sa destinationSize + * \sa bufferScale + */ + +/*! + * \property QWaylandSurface::bufferSize + * + * This property holds the size of the current buffer of this QWaylandSurface in pixels, + * not in surface coordinates. + * + * For the size in surface coordinates, use \l destinationSize instead. + * + * \sa destinationSize + * \sa bufferScale + */ +QSize QWaylandSurface::bufferSize() const +{ + Q_D(const QWaylandSurface); + return d->bufferSize; +} + +#if QT_DEPRECATED_SINCE(5, 13) +/*! * \qmlproperty size QtWaylandCompositor::WaylandSurface::size + * \obsolete use bufferSize or destinationSize instead * - * This property holds the WaylandSurface's size in pixels. + * This property has been deprecated, use \l bufferSize or \l destinationSize instead. */ /*! * \property QWaylandSurface::size + * \obsolete use bufferSize or destinationSize instead * - * This property holds the QWaylandSurface's size in pixels. + * This property has been deprecated, use \l bufferSize or \l destinationSize instead. */ QSize QWaylandSurface::size() const { - Q_D(const QWaylandSurface); - return d->bufferSize; + return bufferSize(); } +#endif /*! * \qmlproperty size QtWaylandCompositor::WaylandSurface::bufferScale diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index c208c16d4..cd08a3d2a 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -81,7 +81,10 @@ class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandSurface : public QWaylandObject Q_OBJECT Q_DECLARE_PRIVATE(QWaylandSurface) Q_PROPERTY(QWaylandClient *client READ client CONSTANT) - Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) + Q_PROPERTY(QSize destinationSize READ destinationSize NOTIFY destinationSizeChanged) +#if QT_DEPRECATED_SINCE(5, 13) + Q_PROPERTY(QSize size READ size NOTIFY sizeChanged) // Qt 6: Remove +#endif Q_PROPERTY(int bufferScale READ bufferScale NOTIFY bufferScaleChanged) Q_PROPERTY(Qt::ScreenOrientation contentOrientation READ contentOrientation NOTIFY contentOrientationChanged) Q_PROPERTY(QWaylandSurface::Origin origin READ origin NOTIFY originChanged) @@ -110,7 +113,11 @@ public: bool hasContent() const; - QSize size() const; + QSize destinationSize() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED QSize size() const; +#endif + QSize bufferSize() const; int bufferScale() const; Qt::ScreenOrientation contentOrientation() const; @@ -155,7 +162,11 @@ Q_SIGNALS: void damaged(const QRegion &rect); void parentChanged(QWaylandSurface *newParent, QWaylandSurface *oldParent); void childAdded(QWaylandSurface *child); - void sizeChanged(); + void destinationSizeChanged(); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED void sizeChanged(); +#endif + void bufferSizeChanged(); void bufferScaleChanged(); void offsetForNextFrame(const QPoint &offset); void contentOrientationChanged(); diff --git a/src/compositor/compositor_api/qwaylandsurface_p.h b/src/compositor/compositor_api/qwaylandsurface_p.h index df868de63..b34367801 100644 --- a/src/compositor/compositor_api/qwaylandsurface_p.h +++ b/src/compositor/compositor_api/qwaylandsurface_p.h @@ -152,6 +152,7 @@ public: //member variables bool newlyAttached; QRegion inputRegion; int bufferScale; + QSize destinationSize; QRegion opaqueRegion; } pending; @@ -166,6 +167,7 @@ public: //member variables QRegion inputRegion; QRegion opaqueRegion; + QSize destinationSize; QSize bufferSize; int bufferScale = 1; bool isCursorSurface = false; diff --git a/src/compositor/extensions/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-server-protocol_p.h b/src/compositor/extensions/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-server-protocol_p.h index b979f048c..493fd52d4 100644 --- a/src/compositor/extensions/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-server-protocol_p.h +++ b/src/compositor/extensions/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-server-protocol_p.h @@ -6,7 +6,7 @@ #include <stdint.h> #include <stddef.h> -#include "wayland-server.h" +#include "wayland-server-core.h" #ifdef __cplusplus extern "C" { diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h index e8d568fce..f8a29bac8 100644 --- a/src/compositor/extensions/qwaylandwlshell_p.h +++ b/src/compositor/extensions/qwaylandwlshell_p.h @@ -46,7 +46,7 @@ #include <QtWaylandCompositor/QWaylandWlShellSurface> #include <QtWaylandCompositor/QWaylandSeat> -#include <wayland-server.h> +#include <wayland-server-core.h> #include <QHash> #include <QPoint> #include <QSet> diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp index 896b1587d..99a2e7655 100644 --- a/src/compositor/extensions/qwaylandwlshellintegration.cpp +++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp @@ -84,8 +84,7 @@ void WlShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandWlShellSu grabberState = GrabberState::Resize; resizeState.seat = seat; resizeState.resizeEdges = edges; - float scaleFactor = m_item->view()->output()->scaleFactor(); - resizeState.initialSize = m_shellSurface->surface()->size() / scaleFactor; + resizeState.initialSize = m_shellSurface->surface()->destinationSize(); resizeState.initialized = false; } @@ -217,9 +216,7 @@ void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *par t.clear(&t); m_item->setRotation(0); m_item->setScale(1.0); - auto scaleFactor = m_item->output()->scaleFactor() / devicePixelRatio(); - m_item->setX(relativeToParent.x() * scaleFactor); - m_item->setY(relativeToParent.y() * scaleFactor); + m_item->setPosition(m_item->mapFromSurface(relativeToParent)); m_item->setParentItem(parentItem); } @@ -267,7 +264,7 @@ void WlShellIntegration::handleShellSurfaceDestroyed() void WlShellIntegration::handleSurfaceHasContentChanged() { - if (m_shellSurface && m_shellSurface->surface()->size().isEmpty() + if (m_shellSurface && m_shellSurface->surface()->destinationSize().isEmpty() && m_shellSurface->windowType() == Qt::WindowType::Popup) { handlePopupClosed(); } @@ -287,9 +284,8 @@ void WlShellIntegration::adjustOffsetForNextFrame(const QPointF &offset) if (!m_item->view()->isPrimary()) return; - float scaleFactor = m_item->view()->output()->scaleFactor(); QQuickItem *moveItem = m_item->moveItem(); - moveItem->setPosition(moveItem->position() + offset * scaleFactor / devicePixelRatio()); + moveItem->setPosition(moveItem->position() + m_item->mapFromSurface(offset)); } bool WlShellIntegration::mouseMoveEvent(QMouseEvent *event) diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp index bd332287e..d0df8f066 100644 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ b/src/compositor/extensions/qwaylandxdgshell.cpp @@ -311,7 +311,7 @@ QRect QWaylandXdgSurfacePrivate::calculateFallbackWindowGeometry() const { // TODO: The unset window geometry should include subsurfaces as well, so this solution // won't work too well on those kinds of clients. - return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale()); + return QRect(QPoint(), m_surface->destinationSize()); } void QWaylandXdgSurfacePrivate::updateFallbackWindowGeometry() @@ -510,7 +510,7 @@ void QWaylandXdgSurface::initialize(QWaylandXdgShell *xdgShell, QWaylandSurface d->init(resource.resource()); setExtensionContainer(surface); d->m_windowGeometry = d->calculateFallbackWindowGeometry(); - connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged); + connect(surface, &QWaylandSurface::destinationSizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged); connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurface::handleBufferScaleChanged); emit shellChanged(); emit surfaceChanged(); diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp index cc8faf6c7..3de52944b 100644 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellintegration.cpp @@ -73,7 +73,7 @@ XdgToplevelIntegration::XdgToplevelIntegration(QWaylandQuickShellSurfaceItem *it connect(m_xdgSurface->shell(), &QWaylandXdgShell::popupCreated, this, [item](QWaylandXdgPopup *popup, QWaylandXdgSurface *){ handlePopupCreated(item, popup); }); - connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgToplevelIntegration::handleSurfaceSizeChanged); + connect(m_xdgSurface->surface(), &QWaylandSurface::destinationSizeChanged, this, &XdgToplevelIntegration::handleSurfaceSizeChanged); connect(m_toplevel, &QObject::destroyed, this, &XdgToplevelIntegration::handleToplevelDestroyed); } @@ -130,7 +130,7 @@ void XdgToplevelIntegration::handleStartResize(QWaylandSeat *seat, Qt::Edges edg resizeState.resizeEdges = edges; resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); resizeState.initialPosition = m_item->moveItem()->position(); - resizeState.initialSurfaceSize = m_item->surface()->size(); + resizeState.initialSurfaceSize = m_item->surface()->destinationSize(); resizeState.initialized = false; } @@ -247,14 +247,14 @@ void XdgToplevelIntegration::handleActivatedChanged() void XdgToplevelIntegration::handleSurfaceSizeChanged() { if (grabberState == GrabberState::Resize) { - qreal x = resizeState.initialPosition.x(); - qreal y = resizeState.initialPosition.y(); + qreal dx = 0; + qreal dy = 0; if (resizeState.resizeEdges & Qt::TopEdge) - y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height(); - + dy = resizeState.initialSurfaceSize.height() - m_item->surface()->destinationSize().height(); if (resizeState.resizeEdges & Qt::LeftEdge) - x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); - m_item->moveItem()->setPosition(QPointF(x, y)); + dx = resizeState.initialSurfaceSize.width() - m_item->surface()->destinationSize().width(); + QPointF offset = m_item->mapFromSurface({dx, dy}); + m_item->moveItem()->setPosition(resizeState.initialPosition + offset); } } @@ -285,11 +285,11 @@ void XdgPopupIntegration::handleGeometryChanged() { if (m_item->view()->output()) { const QPoint windowOffset = m_popup->parentXdgSurface()->windowGeometry().topLeft(); - const QPoint position = m_popup->unconstrainedPosition() + windowOffset; + const QPoint surfacePosition = m_popup->unconstrainedPosition() + windowOffset; + const QPoint itemPosition = m_item->mapFromSurface(surfacePosition).toPoint(); //TODO: positioner size or other size...? - const float scaleFactor = m_item->view()->output()->scaleFactor(); //TODO check positioner constraints etc... sliding, flipping - m_item->moveItem()->setPosition(position * scaleFactor); + m_item->moveItem()->setPosition(itemPosition); } else { qWarning() << "XdgPopupIntegration popup item without output" << m_item; } diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp index a6e88aabb..2e3b76dc7 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp @@ -249,7 +249,7 @@ QRect QWaylandXdgSurfaceV5Private::calculateFallbackWindowGeometry() const { // TODO: The unset window geometry should include subsurfaces as well, so this solution // won't work too well on those kinds of clients. - return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale()); + return QRect(QPoint(), m_surface->destinationSize()); } void QWaylandXdgSurfaceV5Private::updateFallbackWindowGeometry() @@ -837,7 +837,7 @@ void QWaylandXdgSurfaceV5::initialize(QWaylandXdgShellV5 *xdgShell, QWaylandSurf d->init(resource.resource()); setExtensionContainer(surface); d->m_windowGeometry = d->calculateFallbackWindowGeometry(); - connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurfaceV5::handleSurfaceSizeChanged); + connect(surface, &QWaylandSurface::destinationSizeChanged, this, &QWaylandXdgSurfaceV5::handleSurfaceSizeChanged); connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurfaceV5::handleBufferScaleChanged); emit shellChanged(); emit surfaceChanged(); diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp index ea04a33d2..1d63632a3 100644 --- a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp @@ -71,7 +71,7 @@ XdgShellV5Integration::XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item connect(m_xdgSurface, &QWaylandXdgSurfaceV5::unsetMaximized, this, &XdgShellV5Integration::handleUnsetMaximized); connect(m_xdgSurface, &QWaylandXdgSurfaceV5::maximizedChanged, this, &XdgShellV5Integration::handleMaximizedChanged); connect(m_xdgSurface, &QWaylandXdgSurfaceV5::activatedChanged, this, &XdgShellV5Integration::handleActivatedChanged); - connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellV5Integration::handleSurfaceSizeChanged); + connect(m_xdgSurface->surface(), &QWaylandSurface::destinationSizeChanged, this, &XdgShellV5Integration::handleSurfaceSizeChanged); connect(m_xdgSurface->shell(), &QWaylandXdgShellV5::xdgPopupCreated, this, [item](QWaylandXdgPopupV5 *popup){ handlePopupCreated(item, popup); }); @@ -139,7 +139,7 @@ void XdgShellV5Integration::handleStartResize(QWaylandSeat *seat, QWaylandXdgSur resizeState.resizeEdges = edges; resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); resizeState.initialPosition = m_item->moveItem()->position(); - resizeState.initialSurfaceSize = m_item->surface()->size(); + resizeState.initialSurfaceSize = m_item->surface()->destinationSize(); resizeState.initialized = false; } @@ -194,14 +194,14 @@ void XdgShellV5Integration::handleActivatedChanged() void XdgShellV5Integration::handleSurfaceSizeChanged() { if (grabberState == GrabberState::Resize) { - qreal x = resizeState.initialPosition.x(); - qreal y = resizeState.initialPosition.y(); + qreal dx = 0; + qreal dy = 0; if (resizeState.resizeEdges & QWaylandXdgSurfaceV5::ResizeEdge::TopEdge) - y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height(); - + dy = resizeState.initialSurfaceSize.height() - m_item->surface()->destinationSize().height(); if (resizeState.resizeEdges & QWaylandXdgSurfaceV5::ResizeEdge::LeftEdge) - x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); - m_item->moveItem()->setPosition(QPointF(x, y)); + dx = resizeState.initialSurfaceSize.width() - m_item->surface()->destinationSize().width(); + QPointF offset = m_item->mapFromSurface({dx, dy}); + m_item->moveItem()->setPosition(resizeState.initialPosition + offset); } } @@ -212,10 +212,12 @@ XdgPopupV5Integration::XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item , m_xdgShell(QWaylandXdgPopupV5Private::get(m_xdgPopup)->m_xdgShell) { item->setSurface(m_xdgPopup->surface()); - if (item->view()->output()) - item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor())); - else + if (item->view()->output()) { + QPoint position = item->mapFromSurface(m_xdgPopup->position()).toPoint(); + item->moveItem()->setPosition(position); + } else { qWarning() << "XdgPopupV5Integration popup item without output" << item; + } QWaylandClient *client = m_xdgPopup->surface()->client(); auto shell = m_xdgShell; diff --git a/src/compositor/extensions/qwaylandxdgshellv6.cpp b/src/compositor/extensions/qwaylandxdgshellv6.cpp index 8338fe6e2..e6741bfbc 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv6.cpp @@ -316,7 +316,7 @@ QRect QWaylandXdgSurfaceV6Private::calculateFallbackWindowGeometry() const { // TODO: The unset window geometry should include subsurfaces as well, so this solution // won't work too well on those kinds of clients. - return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale()); + return QRect(QPoint(), m_surface->destinationSize()); } void QWaylandXdgSurfaceV6Private::updateFallbackWindowGeometry() @@ -515,7 +515,7 @@ void QWaylandXdgSurfaceV6::initialize(QWaylandXdgShellV6 *xdgShell, QWaylandSurf d->init(resource.resource()); setExtensionContainer(surface); d->m_windowGeometry = d->calculateFallbackWindowGeometry(); - connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurfaceV6::handleSurfaceSizeChanged); + connect(surface, &QWaylandSurface::destinationSizeChanged, this, &QWaylandXdgSurfaceV6::handleSurfaceSizeChanged); connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurfaceV6::handleBufferScaleChanged); emit shellChanged(); emit surfaceChanged(); diff --git a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp index 61a9092a3..66dbc6841 100644 --- a/src/compositor/extensions/qwaylandxdgshellv6integration.cpp +++ b/src/compositor/extensions/qwaylandxdgshellv6integration.cpp @@ -73,7 +73,7 @@ XdgToplevelV6Integration::XdgToplevelV6Integration(QWaylandQuickShellSurfaceItem connect(m_xdgSurface->shell(), &QWaylandXdgShellV6::popupCreated, this, [item](QWaylandXdgPopupV6 *popup, QWaylandXdgSurfaceV6 *){ handlePopupCreated(item, popup); }); - connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgToplevelV6Integration::handleSurfaceSizeChanged); + connect(m_xdgSurface->surface(), &QWaylandSurface::destinationSizeChanged, this, &XdgToplevelV6Integration::handleSurfaceSizeChanged); connect(m_toplevel, &QObject::destroyed, this, &XdgToplevelV6Integration::handleToplevelDestroyed); } @@ -130,7 +130,7 @@ void XdgToplevelV6Integration::handleStartResize(QWaylandSeat *seat, Qt::Edges e resizeState.resizeEdges = edges; resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); resizeState.initialPosition = m_item->moveItem()->position(); - resizeState.initialSurfaceSize = m_item->surface()->size(); + resizeState.initialSurfaceSize = m_item->surface()->destinationSize(); resizeState.initialized = false; } @@ -247,14 +247,14 @@ void XdgToplevelV6Integration::handleActivatedChanged() void XdgToplevelV6Integration::handleSurfaceSizeChanged() { if (grabberState == GrabberState::Resize) { - qreal x = resizeState.initialPosition.x(); - qreal y = resizeState.initialPosition.y(); + qreal dx = 0; + qreal dy = 0; if (resizeState.resizeEdges & Qt::TopEdge) - y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height(); - + dy = resizeState.initialSurfaceSize.height() - m_item->surface()->destinationSize().height(); if (resizeState.resizeEdges & Qt::LeftEdge) - x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); - m_item->moveItem()->setPosition(QPointF(x, y)); + dx = resizeState.initialSurfaceSize.width() - m_item->surface()->destinationSize().width(); + QPointF offset = m_item->mapFromSurface({dx, dy}); + m_item->moveItem()->setPosition(resizeState.initialPosition + offset); } } @@ -285,11 +285,11 @@ void XdgPopupV6Integration::handleGeometryChanged() { if (m_item->view()->output()) { const QPoint windowOffset = m_popup->parentXdgSurface()->windowGeometry().topLeft(); - const QPoint position = m_popup->unconstrainedPosition() + windowOffset; + const QPoint surfacePosition = m_popup->unconstrainedPosition() + windowOffset; + const QPoint itemPosition = m_item->mapFromSurface(surfacePosition).toPoint(); //TODO: positioner size or other size...? - const float scaleFactor = m_item->view()->output()->scaleFactor(); //TODO check positioner constraints etc... sliding, flipping - m_item->moveItem()->setPosition(position * scaleFactor); + m_item->moveItem()->setPosition(itemPosition); } else { qWarning() << "XdgPopupV6Integration popup item without output" << m_item; } diff --git a/src/compositor/global/qwaylandcompositorextension.cpp b/src/compositor/global/qwaylandcompositorextension.cpp index e50df48bd..912985399 100644 --- a/src/compositor/global/qwaylandcompositorextension.cpp +++ b/src/compositor/global/qwaylandcompositorextension.cpp @@ -44,7 +44,7 @@ #include <QtCore/QCoreApplication> #include <QtCore/QDebug> -#include <wayland-server.h> +#include <wayland-server-core.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h index 13a69fce9..7b458fbc2 100644 --- a/src/compositor/hardware_integration/qwlclientbufferintegration_p.h +++ b/src/compositor/hardware_integration/qwlclientbufferintegration_p.h @@ -55,7 +55,7 @@ #include <QtWaylandCompositor/qwaylandsurface.h> #include <QtWaylandCompositor/qwaylandbufferref.h> #include <QtCore/QSize> -#include <wayland-server.h> +#include <wayland-server-core.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/qwlclientbuffer.cpp b/src/compositor/wayland_wrapper/qwlclientbuffer.cpp index 7df9ead3c..cb1ee3da0 100644 --- a/src/compositor/wayland_wrapper/qwlclientbuffer.cpp +++ b/src/compositor/wayland_wrapper/qwlclientbuffer.cpp @@ -47,7 +47,7 @@ #include <QtCore/QDebug> -#include <wayland-server-protocol.h> +#include <QtWaylandCompositor/private/wayland-wayland-server-protocol.h> #include "qwaylandsharedmemoryformathelper_p.h" #include <QtWaylandCompositor/private/qwaylandcompositor_p.h> diff --git a/src/compositor/wayland_wrapper/qwlclientbuffer_p.h b/src/compositor/wayland_wrapper/qwlclientbuffer_p.h index ac8c1ed01..cd5c1e1d3 100644 --- a/src/compositor/wayland_wrapper/qwlclientbuffer_p.h +++ b/src/compositor/wayland_wrapper/qwlclientbuffer_p.h @@ -59,7 +59,7 @@ #include <QtWaylandCompositor/QWaylandSurface> #include <QtWaylandCompositor/QWaylandBufferRef> -#include <wayland-server.h> +#include <wayland-server-core.h> QT_BEGIN_NAMESPACE diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index e19ea253a..3e29fb100 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -1,6 +1,6 @@ CONFIG += wayland-scanner -WAYLANDSERVERSOURCES_SYSTEM += \ - ../3rdparty/protocol/wayland.xml \ +WAYLANDSERVERSOURCES += \ + ../3rdparty/protocol/wayland.xml HEADERS += \ wayland_wrapper/qwlbuffermanager_p.h \ diff --git a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.h b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.h index 5e8a3bf46..9a614f58e 100644 --- a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.h +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglintegration.h @@ -41,7 +41,7 @@ #define QWAYLANDBRCMEGLINTEGRATION_H #include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h> -#include <wayland-client.h> +#include <wayland-client-core.h> #include <EGL/egl.h> #include <EGL/eglext.h> diff --git a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp index 5cd52f676..31adf100b 100644 --- a/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp +++ b/src/hardwareintegration/client/brcm-egl/qwaylandbrcmeglwindow.cpp @@ -50,7 +50,6 @@ #include <EGL/eglext_brcm.h> -#include <wayland-client.h> #include "wayland-brcm-client-protocol.h" QT_BEGIN_NAMESPACE diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp index 4b3a635c7..3a34d2561 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglclientbufferintegration.cpp @@ -42,7 +42,7 @@ #include "qwaylandeglwindow.h" #include "qwaylandglcontext.h" -#include <wayland-client.h> +#include <wayland-client-core.h> #include <QtCore/QDebug> #include <private/qeglconvenience_p.h> @@ -65,7 +65,7 @@ static const char *qwaylandegl_threadedgl_blacklist_vendor[] = { QWaylandEglClientBufferIntegration::QWaylandEglClientBufferIntegration() { - qDebug() << "Using Wayland-EGL"; + qCDebug(lcQpaWayland) << "Using Wayland-EGL"; } @@ -87,7 +87,7 @@ void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display) m_eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, display->wl_display(), nullptr); } else { - qWarning("The EGL implementation does not support the Wayland platform"); + qCWarning(lcQpaWayland) << "The EGL implementation does not support the Wayland platform"; return; } } else { @@ -102,13 +102,13 @@ void QWaylandEglClientBufferIntegration::initialize(QWaylandDisplay *display) m_display = display; if (m_eglDisplay == EGL_NO_DISPLAY) { - qWarning("EGL not available"); + qCWarning(lcQpaWayland) << "EGL not available"; return; } EGLint major,minor; if (!eglInitialize(m_eglDisplay, &major, &minor)) { - qWarning("failed to initialize EGL display"); + qCWarning(lcQpaWayland) << "Failed to initialize EGL display" << hex << eglGetError(); m_eglDisplay = EGL_NO_DISPLAY; return; } diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h index 233ce78bd..e9998b832 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglinclude.h @@ -41,7 +41,7 @@ #define QWAYLANDEGLINCLUDE_H #include <string.h> -#include <wayland-client.h> +#include <wayland-client-core.h> #include <wayland-egl.h> diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h index 88e893a74..9e6cb876c 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h @@ -62,7 +62,7 @@ public: void ensureSize() override; void updateSurface(bool create); - virtual void setGeometry(const QRect &rect) override; + void setGeometry(const QRect &rect) override; QRect contentsRect() const; EGLSurface eglSurface() const; diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp index aa5367e02..104a4df91 100644 --- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.cpp @@ -118,7 +118,7 @@ const struct qt_xcomposite_listener QWaylandXCompositeEGLClientBufferIntegration QWaylandXCompositeEGLClientBufferIntegration::rootInformation }; -void QWaylandXCompositeEGLClientBufferIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) +void QWaylandXCompositeEGLClientBufferIntegration::wlDisplayHandleGlobal(void *data, ::wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); if (interface == "qt_xcomposite") { diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.h b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.h index ee55d6892..7037ee2d0 100644 --- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.h +++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglclientbufferintegration.h @@ -41,7 +41,7 @@ #define QWAYLANDXCOMPOSITEEGLCLIENTBUFFERINTEGRATION_H #include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h> -#include <wayland-client.h> +#include <wayland-client-core.h> #include <QtCore/QTextStream> #include <QtCore/QDataStream> @@ -64,6 +64,7 @@ struct qt_xcomposite; struct qt_xcomposite_listener; +struct wl_registry; QT_BEGIN_NAMESPACE @@ -100,7 +101,7 @@ private: int mScreen; Window mRootWindow; - static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, + static void wlDisplayHandleGlobal(void *data, struct ::wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); static const struct ::qt_xcomposite_listener xcomposite_listener; diff --git a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.cpp b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.cpp index 090cfb8a0..8be47fa2e 100644 --- a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.cpp +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.cpp @@ -109,7 +109,7 @@ const struct qt_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite QWaylandXCompositeGLXIntegration::rootInformation }; -void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(void *data, wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) +void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(void *data, ::wl_registry *registry, uint32_t id, const QString &interface, uint32_t version) { Q_UNUSED(version); if (interface == "qt_xcomposite") { diff --git a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.h b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.h index 26f2bad6f..809690816 100644 --- a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.h +++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxintegration.h @@ -41,7 +41,7 @@ #define QWAYLANDXCOMPOSITEGLXINTEGRATION_H #include <QtWaylandClient/private/qwaylandclientbufferintegration_p.h> -#include <wayland-client.h> +#include <wayland-client-core.h> #include <QtCore/QTextStream> #include <QtCore/QDataStream> @@ -59,6 +59,7 @@ struct qt_xcomposite; struct qt_xcomposite_listener; +struct wl_registry; QT_BEGIN_NAMESPACE @@ -93,7 +94,7 @@ private: int mScreen = 0; Window mRootWindow = 0; - static void wlDisplayHandleGlobal(void *data, struct wl_registry *registry, uint32_t id, + static void wlDisplayHandleGlobal(void *data, struct ::wl_registry *registry, uint32_t id, const QString &interface, uint32_t version); static const struct qt_xcomposite_listener xcomposite_listener; diff --git a/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.cpp b/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.cpp index 5f1818cdf..33d9a6038 100644 --- a/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.cpp +++ b/src/hardwareintegration/client/xcomposite_share/qwaylandxcompositebuffer.cpp @@ -39,7 +39,6 @@ #include "qwaylandxcompositebuffer.h" -#include <wayland-client.h> #include "wayland-xcomposite-client-protocol.h" QT_BEGIN_NAMESPACE diff --git a/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri index f255f5c57..a9120c261 100644 --- a/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri +++ b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri @@ -1,7 +1,7 @@ INCLUDEPATH += $$PWD QMAKE_USE += xcomposite -CONFIG += wayland-scanner +CONFIG += wayland-scanner-client-wayland-protocol-include WAYLANDCLIENTSOURCES += $$PWD/../../../extensions/xcomposite.xml HEADERS += \ diff --git a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp index 5a42c00dc..af9059603 100644 --- a/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp +++ b/src/hardwareintegration/compositor/libhybris-egl-server/libhybriseglserverbufferintegration.cpp @@ -42,7 +42,7 @@ #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLTexture> #include <hybris/eglplatformcommon/hybris_nativebufferext.h> -#include <wayland-server.h> +#include <wayland-server-core.h> QT_BEGIN_NAMESPACE LibHybrisEglServerBuffer::LibHybrisEglServerBuffer(LibHybrisEglServerBufferIntegration *integration, const QImage &qimage, QtWayland::ServerBuffer::Format format) diff --git a/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.h b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.h index bb43ed1af..28168994c 100644 --- a/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.h +++ b/src/hardwareintegration/compositor/xcomposite_share/xcompositehandler.h @@ -45,7 +45,7 @@ #include "xlibinclude.h" #include "qwayland-server-xcomposite.h" -#include <wayland-server.h> +#include <wayland-server-core.h> QT_BEGIN_NAMESPACE diff --git a/src/plugins/decorations/bradient/main.cpp b/src/plugins/decorations/bradient/main.cpp index 3fa723446..83dc8604b 100644 --- a/src/plugins/decorations/bradient/main.cpp +++ b/src/plugins/decorations/bradient/main.cpp @@ -315,19 +315,19 @@ void QWaylandBradientDecoration::processMouseTop(QWaylandInputDevice *inputDevic #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); #endif - startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b); + startResize(inputDevice, Qt::TopEdge | Qt::LeftEdge, b); } else if (local.x() > window()->width() + margins().left()) { //top right bit #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); #endif - startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b); + startResize(inputDevice, Qt::TopEdge | Qt::RightEdge, b); } else { //top resize bit #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor); #endif - startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b); + startResize(inputDevice, Qt::TopEdge, b); } } else if (local.x() <= margins().left()) { processMouseLeft(inputDevice, local, b, mods); @@ -358,19 +358,19 @@ void QWaylandBradientDecoration::processMouseBottom(QWaylandInputDevice *inputDe #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor); #endif - startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b); + startResize(inputDevice, Qt::BottomEdge | Qt::LeftEdge, b); } else if (local.x() > window()->width() + margins().left()) { //bottom right bit #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor); #endif - startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b); + startResize(inputDevice, Qt::BottomEdge | Qt::RightEdge, b); } else { //bottom bit #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor); #endif - startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b); + startResize(inputDevice, Qt::BottomEdge, b); } } @@ -381,7 +381,7 @@ void QWaylandBradientDecoration::processMouseLeft(QWaylandInputDevice *inputDevi #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SplitHCursor); #endif - startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b); + startResize(inputDevice, Qt::LeftEdge, b); } void QWaylandBradientDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods) @@ -391,7 +391,7 @@ void QWaylandBradientDecoration::processMouseRight(QWaylandInputDevice *inputDev #if QT_CONFIG(cursor) waylandWindow()->setMouseCursor(inputDevice, Qt::SplitHCursor); #endif - startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b); + startResize(inputDevice, Qt::RightEdge, b); } class QWaylandBradientDecorationPlugin : public QWaylandDecorationPlugin diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/fullscreen-shell-v1.json b/src/plugins/shellintegration/fullscreen-shell-v1/fullscreen-shell-v1.json new file mode 100644 index 000000000..f32637bcc --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/fullscreen-shell-v1.json @@ -0,0 +1,3 @@ +{ + "Keys": [ "fullscreen-shell-v1" ] +} diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/fullscreen-shell-v1.pro b/src/plugins/shellintegration/fullscreen-shell-v1/fullscreen-shell-v1.pro new file mode 100644 index 000000000..a522f87a8 --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/fullscreen-shell-v1.pro @@ -0,0 +1,23 @@ +QT += gui-private waylandclient-private +CONFIG += wayland-scanner + +QMAKE_USE += wayland-client + +WAYLANDCLIENTSOURCES += \ + ../../../3rdparty/protocol/fullscreen-shell-unstable-v1.xml + +HEADERS += \ + qwaylandfullscreenshellv1integration.h \ + qwaylandfullscreenshellv1surface.h + +SOURCES += \ + main.cpp \ + qwaylandfullscreenshellv1integration.cpp \ + qwaylandfullscreenshellv1surface.cpp + +OTHER_FILES += \ + fullscreen-shell-v1.json + +PLUGIN_TYPE = wayland-shell-integration +PLUGIN_CLASS_NAME = QWaylandFullScreenShellV1IntegrationPlugin +load(qt_plugin) diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/main.cpp b/src/plugins/shellintegration/fullscreen-shell-v1/main.cpp new file mode 100644 index 000000000..dfcd997da --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/main.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/private/qwaylandshellintegrationplugin_p.h> + +#include "qwaylandfullscreenshellv1integration.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class QWaylandFullScreenShellV1IntegrationPlugin : public QWaylandShellIntegrationPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID QWaylandShellIntegrationFactoryInterface_iid FILE "fullscreen-shell-v1.json") +public: + QWaylandShellIntegration *create(const QString &key, const QStringList ¶mList) override; +}; + +QWaylandShellIntegration *QWaylandFullScreenShellV1IntegrationPlugin::create(const QString &key, const QStringList ¶mList) +{ + Q_UNUSED(paramList); + + if (key == QLatin1String("fullscreen-shell-v1")) + return new QWaylandFullScreenShellV1Integration(); + return nullptr; +} + +} // namespace QtWaylandClient + +QT_END_NAMESPACE + +#include "main.moc" diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp new file mode 100644 index 000000000..0cd2cb1e8 --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandfullscreenshellv1integration.h" +#include "qwaylandfullscreenshellv1surface.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +bool QWaylandFullScreenShellV1Integration::initialize(QWaylandDisplay *display) +{ + for (const QWaylandDisplay::RegistryGlobal &global : display->globals()) { + if (global.interface == QLatin1String("zwp_fullscreen_shell_v1") && !m_shell) { + m_shell.reset(new QtWayland::zwp_fullscreen_shell_v1(display->wl_registry(), global.id, global.version)); + break; + } + } + + if (!m_shell) { + qCDebug(lcQpaWayland) << "Couldn't find global zwp_fullscreen_shell_v1 for fullscreen-shell"; + return false; + } + + return QWaylandShellIntegration::initialize(display); +} + +QWaylandShellSurface *QWaylandFullScreenShellV1Integration::createShellSurface(QWaylandWindow *window) +{ + return new QWaylandFullScreenShellV1Surface(m_shell.data(), window); +} + +} // namespace QtWaylandClient + +QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h new file mode 100644 index 000000000..131f9e720 --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1integration.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDFULLSCREENSHELLV1INTEGRATION_H +#define QWAYLANDFULLSCREENSHELLV1INTEGRATION_H + +#include <wayland-client.h> +#include <QtWaylandClient/private/qwayland-wayland.h> +#include <QtWaylandClient/private/qwaylandshellintegration_p.h> + +#include "qwayland-fullscreen-shell-unstable-v1.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class Q_WAYLAND_CLIENT_EXPORT QWaylandFullScreenShellV1Integration : public QWaylandShellIntegration +{ +public: + bool initialize(QWaylandDisplay *display) override; + QWaylandShellSurface *createShellSurface(QWaylandWindow *window) override; + +private: + QScopedPointer<QtWayland::zwp_fullscreen_shell_v1> m_shell; +}; + +} // namespace QtWaylandClient + +QT_END_NAMESPACE + +#endif // QWAYLANDFULLSCREENSHELLV1INTEGRATION_H diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp new file mode 100644 index 000000000..9a829f6e9 --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtWaylandClient/private/qwaylandscreen_p.h> + +#include "qwaylandfullscreenshellv1surface.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +QWaylandFullScreenShellV1Surface::QWaylandFullScreenShellV1Surface(QtWayland::zwp_fullscreen_shell_v1 *shell, QWaylandWindow *window) + : QWaylandShellSurface(window) + , m_shell(shell) + , m_window(window) +{ + auto screen = static_cast<QWaylandScreen *>(m_window->screen()); + m_shell->present_surface(m_window->object(), + QtWayland::zwp_fullscreen_shell_v1::present_method_default, + screen->output()); +} + +} // namespace QtWaylandClient + +QT_END_NAMESPACE diff --git a/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.h b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.h new file mode 100644 index 000000000..718e1e861 --- /dev/null +++ b/src/plugins/shellintegration/fullscreen-shell-v1/qwaylandfullscreenshellv1surface.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Contact: http://www.qt-project.org/legal +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDFULLSCREENSHELLV1SURFACE_H +#define QWAYLANDFULLSCREENSHELLV1SURFACE_H + +#include <QtWaylandClient/qtwaylandclientglobal.h> +#include <QtWaylandClient/private/qwaylandshellsurface_p.h> +#include <QtWaylandClient/private/qwaylandwindow_p.h> + +#include "qwayland-fullscreen-shell-unstable-v1.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +class Q_WAYLAND_CLIENT_EXPORT QWaylandFullScreenShellV1Surface : public QWaylandShellSurface +{ +public: + QWaylandFullScreenShellV1Surface(QtWayland::zwp_fullscreen_shell_v1 *shell, QWaylandWindow *window); + +private: + QtWayland::zwp_fullscreen_shell_v1 *m_shell = nullptr; + QWaylandWindow *m_window = nullptr; +}; + +} // namespace QtWaylandClient + +QT_END_NAMESPACE + +#endif // QWAYLANDFULLSCREENSHELLV1SURFACE_H diff --git a/src/plugins/shellintegration/shellintegration.pro b/src/plugins/shellintegration/shellintegration.pro index 48b6efa36..39c57940a 100644 --- a/src/plugins/shellintegration/shellintegration.pro +++ b/src/plugins/shellintegration/shellintegration.pro @@ -1,9 +1,9 @@ TEMPLATE = subdirs +QT_FOR_CONFIG += waylandclient-private -SUBDIRS += \ - ivi-shell \ - xdg-shell \ - xdg-shell-v5 \ - xdg-shell-v6 \ - wl-shell \ - +qtConfig(wayland-client-fullscreen-shell-v1): SUBDIRS += fullscreen-shell-v1 +qtConfig(wayland-client-ivi-shell): SUBDIRS += ivi-shell +qtConfig(wayland-client-wl-shell): SUBDIRS += wl-shell +qtConfig(wayland-client-xdg-shell): SUBDIRS += xdg-shell +qtConfig(wayland-client-xdg-shell-v5): SUBDIRS += xdg-shell-v5 +qtConfig(wayland-client-xdg-shell-v6): SUBDIRS += xdg-shell-v6 diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h index 80a7507d4..3d76cc310 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellintegration_p.h @@ -51,7 +51,6 @@ // We mean it. // -#include <wayland-client.h> #include <private/qwayland-wayland.h> #include <QtWaylandClient/private/qwaylandshellintegration_p.h> diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp index 88a63655c..4506c312a 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface.cpp @@ -76,11 +76,10 @@ QWaylandWlShellSurface::~QWaylandWlShellSurface() delete m_extendedWindow; } -void QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) +void QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) { - resize(inputDevice->wl_seat(), - inputDevice->serial(), - edges); + enum resize resizeEdges = convertToResizeEdges(edges); + resize(inputDevice->wl_seat(), inputDevice->serial(), resizeEdges); } bool QWaylandWlShellSurface::move(QWaylandInputDevice *inputDevice) @@ -193,6 +192,14 @@ void QWaylandWlShellSurface::requestWindowStates(Qt::WindowStates states) m_pending.states = states & ~Qt::WindowMinimized; } +enum QWaylandWlShellSurface::resize QWaylandWlShellSurface::convertToResizeEdges(Qt::Edges edges) +{ + return static_cast<enum resize>( + ((edges & Qt::TopEdge) ? resize_top : 0) + | ((edges & Qt::BottomEdge) ? resize_bottom : 0) + | ((edges & Qt::LeftEdge) ? resize_left : 0) + | ((edges & Qt::RightEdge) ? resize_right : 0)); +} void QWaylandWlShellSurface::setTopLevel() { diff --git a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h index 57e06525a..324c10aac 100644 --- a/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h +++ b/src/plugins/shellintegration/wl-shell/qwaylandwlshellsurface_p.h @@ -53,8 +53,6 @@ #include <QtCore/QSize> -#include <wayland-client.h> - #include <QtWaylandClient/qtwaylandclientglobal.h> #include <QtWaylandClient/private/qwayland-wayland.h> #include <QtWaylandClient/private/qwaylandshellsurface_p.h> @@ -78,7 +76,7 @@ public: ~QWaylandWlShellSurface() override; using QtWayland::wl_shell_surface::resize; - void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) override; + void resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) override; using QtWayland::wl_shell_surface::move; bool move(QWaylandInputDevice *inputDevice) override; @@ -99,6 +97,7 @@ protected: void requestWindowStates(Qt::WindowStates states) override; private: + static enum resize convertToResizeEdges(Qt::Edges edges); void setTopLevel(); void updateTransientParent(QWindow *parent); void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, uint serial); diff --git a/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5.cpp b/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5.cpp index 0115eb1da..51979acf7 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5.cpp +++ b/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5.cpp @@ -25,6 +25,7 @@ * DEALINGS IN THE SOFTWARE. */ #include "qwayland-xdg-shell-unstable-v5_p.h" +#include <QtWaylandClient/private/wayland-wayland-client-protocol.h> QT_BEGIN_NAMESPACE QT_WARNING_PUSH diff --git a/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5_p.h b/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5_p.h index 3d8a6c13d..8fb1ea7b8 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5_p.h +++ b/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/qwayland-xdg-shell-unstable-v5_p.h @@ -31,6 +31,8 @@ #include <QByteArray> #include <QString> +struct wl_registry; + QT_BEGIN_NAMESPACE QT_WARNING_PUSH QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") diff --git a/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-client-protocol_p.h b/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-client-protocol_p.h index 46644610b..8877e8830 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-client-protocol_p.h +++ b/src/plugins/shellintegration/xdg-shell-v5/pregenerated/3rdparty/wayland-xdg-shell-unstable-v5-client-protocol_p.h @@ -7,7 +7,7 @@ #include <stdint.h> #include <stddef.h> -#include "wayland-client.h" +#include "wayland-client-core.h" #ifdef __cplusplus extern "C" { diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h index ff8e5639f..7494f6a67 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h +++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgpopupv5_p.h @@ -53,8 +53,6 @@ #include "qwayland-xdg-shell-unstable-v5_p.h" -#include <wayland-client.h> - #include <QtWaylandClient/qtwaylandclientglobal.h> #include <QtWaylandClient/private/qwaylandshellsurface_p.h> diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5_p.h index 67e5d32a7..2b0a59f17 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5_p.h +++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgshellv5_p.h @@ -56,8 +56,6 @@ #include <QtCore/QSize> #include <QtCore/QVector> -#include <wayland-client.h> - #include <QtWaylandClient/qtwaylandclientglobal.h> #include <QtWaylandClient/private/qwaylandshellsurface_p.h> diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp index 61a865cb2..b691ee747 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp +++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5.cpp @@ -73,18 +73,19 @@ QWaylandXdgSurfaceV5::~QWaylandXdgSurfaceV5() delete m_extendedWindow; } -void QWaylandXdgSurfaceV5::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) +QtWayland::xdg_surface_v5::resize_edge QWaylandXdgSurfaceV5::convertToResizeEdges(Qt::Edges edges) { - // May need some conversion if types get incompatibles, ATM they're identical - enum resize_edge const * const arg = reinterpret_cast<enum resize_edge const *>(&edges); - resize(inputDevice, *arg); + return static_cast<enum resize_edge>( + ((edges & Qt::TopEdge) ? resize_edge_top : 0) + | ((edges & Qt::BottomEdge) ? resize_edge_bottom : 0) + | ((edges & Qt::LeftEdge) ? resize_edge_left : 0) + | ((edges & Qt::RightEdge) ? resize_edge_right : 0)); } -void QWaylandXdgSurfaceV5::resize(QWaylandInputDevice *inputDevice, enum resize_edge edges) +void QWaylandXdgSurfaceV5::resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) { - resize(inputDevice->wl_seat(), - inputDevice->serial(), - edges); + resize_edge resizeEdges = convertToResizeEdges(edges); + resize(inputDevice->wl_seat(), inputDevice->serial(), resizeEdges); } bool QWaylandXdgSurfaceV5::move(QWaylandInputDevice *inputDevice) diff --git a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5_p.h b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5_p.h index b938047ec..231a56d84 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5_p.h +++ b/src/plugins/shellintegration/xdg-shell-v5/qwaylandxdgsurfacev5_p.h @@ -59,8 +59,6 @@ #include <QtCore/QSize> #include <QtCore/QMargins> -#include <wayland-client.h> - QT_BEGIN_NAMESPACE class QWindow; @@ -81,9 +79,8 @@ public: ~QWaylandXdgSurfaceV5() override; using QtWayland::xdg_surface_v5::resize; - void resize(QWaylandInputDevice *inputDevice, enum resize_edge edges); - - void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) override; + static resize_edge convertToResizeEdges(Qt::Edges edges); + void resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) override; using QtWayland::xdg_surface_v5::move; bool move(QWaylandInputDevice *inputDevice) override; diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp index fb33b4ab4..947388535 100644 --- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp +++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6.cpp @@ -157,6 +157,15 @@ void QWaylandXdgSurfaceV6::Toplevel::requestWindowStates(Qt::WindowStates states } } +QtWayland::zxdg_toplevel_v6::resize_edge QWaylandXdgSurfaceV6::Toplevel::convertToResizeEdges(Qt::Edges edges) +{ + return static_cast<enum resize_edge>( + ((edges & Qt::TopEdge) ? resize_edge_top : 0) + | ((edges & Qt::BottomEdge) ? resize_edge_bottom : 0) + | ((edges & Qt::LeftEdge) ? resize_edge_left : 0) + | ((edges & Qt::RightEdge) ? resize_edge_right : 0)); +} + QWaylandXdgSurfaceV6::Popup::Popup(QWaylandXdgSurfaceV6 *xdgSurface, QWaylandXdgSurfaceV6 *parent, QtWayland::zxdg_positioner_v6 *positioner) : zxdg_popup_v6(xdgSurface->get_popup(parent->object(), positioner->object())) @@ -226,19 +235,13 @@ QWaylandXdgSurfaceV6::~QWaylandXdgSurfaceV6() destroy(); } -void QWaylandXdgSurfaceV6::resize(QWaylandInputDevice *inputDevice, zxdg_toplevel_v6_resize_edge edges) +void QWaylandXdgSurfaceV6::resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) { Q_ASSERT(m_toplevel && m_toplevel->isInitialized()); - m_toplevel->resize(inputDevice->wl_seat(), inputDevice->serial(), edges); + auto resizeEdges = Toplevel::convertToResizeEdges(edges); + m_toplevel->resize(inputDevice->wl_seat(), inputDevice->serial(), resizeEdges); } -void QWaylandXdgSurfaceV6::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) -{ - auto xdgEdges = reinterpret_cast<enum zxdg_toplevel_v6_resize_edge const *>(&edges); - resize(inputDevice, *xdgEdges); -} - - bool QWaylandXdgSurfaceV6::move(QWaylandInputDevice *inputDevice) { if (m_toplevel && m_toplevel->isInitialized()) { diff --git a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6_p.h b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6_p.h index 659aad047..5a2867379 100644 --- a/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6_p.h +++ b/src/plugins/shellintegration/xdg-shell-v6/qwaylandxdgshellv6_p.h @@ -60,8 +60,6 @@ #include <QtCore/QSize> #include <QtGui/QRegion> -#include <wayland-client.h> - QT_BEGIN_NAMESPACE class QWindow; @@ -79,8 +77,7 @@ public: QWaylandXdgSurfaceV6(QWaylandXdgShellV6 *shell, ::zxdg_surface_v6 *surface, QWaylandWindow *window); ~QWaylandXdgSurfaceV6() override; - void resize(QWaylandInputDevice *inputDevice, enum zxdg_toplevel_v6_resize_edge edges); - void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) override; + void resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) override; bool move(QWaylandInputDevice *inputDevice) override; void setTitle(const QString &title) override; void setAppId(const QString &appId) override; @@ -108,6 +105,9 @@ private: void zxdg_toplevel_v6_close() override; void requestWindowStates(Qt::WindowStates states); + + static resize_edge convertToResizeEdges(Qt::Edges edges); + struct { QSize size = {0, 0}; Qt::WindowStates states = Qt::WindowNoState; diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp index 6c98dc6ad..34cad810a 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell.cpp @@ -185,6 +185,15 @@ void QWaylandXdgSurface::Toplevel::requestWindowStates(Qt::WindowStates states) } } +QtWayland::xdg_toplevel::resize_edge QWaylandXdgSurface::Toplevel::convertToResizeEdges(Qt::Edges edges) +{ + return static_cast<enum resize_edge>( + ((edges & Qt::TopEdge) ? resize_edge_top : 0) + | ((edges & Qt::BottomEdge) ? resize_edge_bottom : 0) + | ((edges & Qt::LeftEdge) ? resize_edge_left : 0) + | ((edges & Qt::RightEdge) ? resize_edge_right : 0)); +} + QWaylandXdgSurface::Popup::Popup(QWaylandXdgSurface *xdgSurface, QWaylandXdgSurface *parent, QtWayland::xdg_positioner *positioner) : xdg_popup(xdgSurface->get_popup(parent->object(), positioner->object())) @@ -254,19 +263,13 @@ QWaylandXdgSurface::~QWaylandXdgSurface() destroy(); } -void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, xdg_toplevel_resize_edge edges) +void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) { Q_ASSERT(m_toplevel && m_toplevel->isInitialized()); - m_toplevel->resize(inputDevice->wl_seat(), inputDevice->serial(), edges); + auto resizeEdges = Toplevel::convertToResizeEdges(edges); + m_toplevel->resize(inputDevice->wl_seat(), inputDevice->serial(), resizeEdges); } -void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) -{ - auto xdgEdges = reinterpret_cast<enum xdg_toplevel_resize_edge const *>(&edges); - resize(inputDevice, *xdgEdges); -} - - bool QWaylandXdgSurface::move(QWaylandInputDevice *inputDevice) { if (m_toplevel && m_toplevel->isInitialized()) { diff --git a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h index 741b83cfd..1dc1def23 100644 --- a/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h +++ b/src/plugins/shellintegration/xdg-shell/qwaylandxdgshell_p.h @@ -62,8 +62,6 @@ #include <QtCore/QSize> #include <QtGui/QRegion> -#include <wayland-client.h> - QT_BEGIN_NAMESPACE class QWindow; @@ -82,8 +80,7 @@ public: QWaylandXdgSurface(QWaylandXdgShell *shell, ::xdg_surface *surface, QWaylandWindow *window); ~QWaylandXdgSurface() override; - void resize(QWaylandInputDevice *inputDevice, enum xdg_toplevel_resize_edge edges); - void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) override; + void resize(QWaylandInputDevice *inputDevice, Qt::Edges edges) override; bool move(QWaylandInputDevice *inputDevice) override; void setTitle(const QString &title) override; void setAppId(const QString &appId) override; @@ -114,6 +111,9 @@ private: void requestWindowFlags(Qt::WindowFlags flags); void requestWindowStates(Qt::WindowStates states); + + static resize_edge convertToResizeEdges(Qt::Edges edges); + struct { QSize size = {0, 0}; Qt::WindowStates states = Qt::WindowNoState; diff --git a/src/qtwaylandscanner/qtwaylandscanner.cpp b/src/qtwaylandscanner/qtwaylandscanner.cpp index f2e2d24de..bc0262bc0 100644 --- a/src/qtwaylandscanner/qtwaylandscanner.cpp +++ b/src/qtwaylandscanner/qtwaylandscanner.cpp @@ -440,7 +440,7 @@ bool Scanner::process() printf("#ifndef %s\n", inclusionGuard.constData()); printf("#define %s\n", inclusionGuard.constData()); printf("\n"); - printf("#include \"wayland-server.h\"\n"); + printf("#include \"wayland-server-core.h\"\n"); if (m_headerPath.isEmpty()) printf("#include \"wayland-%s-server-protocol.h\"\n", QByteArray(m_protocolName).replace('_', '-').constData()); else @@ -768,6 +768,7 @@ bool Scanner::process() printf(" void %s::destroy_func(struct ::wl_resource *client_resource)\n", interfaceName); printf(" {\n"); printf(" Resource *resource = Resource::fromResource(client_resource);\n"); + printf(" Q_ASSERT(resource);\n"); printf(" %s *that = resource->%s_object;\n", interfaceName, interfaceNameStripped); printf(" that->m_resource_map.remove(resource->client(), resource);\n"); printf(" that->%s_destroy_resource(resource);\n", interfaceNameStripped); @@ -938,6 +939,8 @@ bool Scanner::process() printf("#include <QByteArray>\n"); printf("#include <QString>\n"); printf("\n"); + printf("struct wl_registry;\n"); + printf("\n"); printf("QT_BEGIN_NAMESPACE\n"); printf("QT_WARNING_PUSH\n"); printf("QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n"); @@ -1055,6 +1058,22 @@ bool Scanner::process() printf("QT_WARNING_DISABLE_GCC(\"-Wmissing-field-initializers\")\n"); printf("\n"); printf("namespace QtWayland {\n"); + printf("\n"); + + // wl_registry_bind is part of the protocol, so we can't use that... instead we use core + // libwayland API to do the same thing a wayland-scanner generated wl_registry_bind would. + printf("static inline void *wlRegistryBind(struct ::wl_registry *registry, uint32_t name, const struct ::wl_interface *interface, uint32_t version)\n"); + printf("{\n"); + printf(" const uint32_t bindOpCode = 0;\n"); + printf("#if (WAYLAND_VERSION_MAJOR == 1 && WAYLAND_VERSION_MINOR > 10) || WAYLAND_VERSION_MAJOR > 1\n"); + printf(" return (void *) wl_proxy_marshal_constructor_versioned((struct wl_proxy *) registry,\n"); + printf(" bindOpCode, interface, version, name, interface->name, version, nullptr);\n"); + printf("#else\n"); + printf(" return (void *) wl_proxy_marshal_constructor((struct wl_proxy *) registry,\n"); + printf(" bindOpCode, interface, name, interface->name, version, nullptr);\n"); + printf("#endif\n"); + printf("}\n"); + printf("\n"); for (int j = 0; j < interfaces.size(); ++j) { const WaylandInterface &interface = interfaces.at(j); @@ -1095,7 +1114,7 @@ bool Scanner::process() printf(" void %s::init(struct ::wl_registry *registry, int id, int version)\n", interfaceName); printf(" {\n"); - printf(" m_%s = static_cast<struct ::%s *>(wl_registry_bind(registry, id, &%s_interface, version));\n", interfaceName, interfaceName, interfaceName); + printf(" m_%s = static_cast<struct ::%s *>(wlRegistryBind(registry, id, &%s_interface, version));\n", interfaceName, interfaceName, interfaceName); if (hasEvents) printf(" init_listener();\n"); printf(" }\n"); diff --git a/tests/auto/client/client.pro b/tests/auto/client/client.pro index 9fd8fc3f9..14ce4407d 100644 --- a/tests/auto/client/client.pro +++ b/tests/auto/client/client.pro @@ -2,6 +2,7 @@ TEMPLATE=subdirs SUBDIRS += \ client \ + fullscreenshellv1 \ iviapplication \ xdgshellv6 \ wl_connect diff --git a/tests/auto/client/fullscreenshellv1/fullscreenshellv1.pro b/tests/auto/client/fullscreenshellv1/fullscreenshellv1.pro new file mode 100644 index 000000000..8ce6dfe5c --- /dev/null +++ b/tests/auto/client/fullscreenshellv1/fullscreenshellv1.pro @@ -0,0 +1,4 @@ +include (../shared/shared.pri) + +TARGET = tst_client_fullscreenshell1 +SOURCES += tst_fullscreenshellv1.cpp diff --git a/tests/auto/client/fullscreenshellv1/tst_fullscreenshellv1.cpp b/tests/auto/client/fullscreenshellv1/tst_fullscreenshellv1.cpp new file mode 100644 index 000000000..f93d9fbc5 --- /dev/null +++ b/tests/auto/client/fullscreenshellv1/tst_fullscreenshellv1.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** Copyright (C) 2017 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 <QWindow> + +#include <QtTest/QtTest> + +static const QSize screenSize(1600, 1200); + +class TestWindow : public QWindow +{ +public: + TestWindow() + { + setSurfaceType(QSurface::RasterSurface); + setGeometry(0, 0, 800, 600); + create(); + } +}; + +class tst_WaylandClientFullScreenShellV1 : public QObject +{ + Q_OBJECT +public: + tst_WaylandClientFullScreenShellV1(MockCompositor *c) + : m_compositor(c) + { + QSocketNotifier *notifier = new QSocketNotifier(m_compositor->waylandFileDescriptor(), QSocketNotifier::Read, this); + connect(notifier, &QSocketNotifier::activated, this, &tst_WaylandClientFullScreenShellV1::processWaylandEvents); + // connect to the event dispatcher to make sure to flush out the outgoing message queue + connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::awake, this, &tst_WaylandClientFullScreenShellV1::processWaylandEvents); + connect(QCoreApplication::eventDispatcher(), &QAbstractEventDispatcher::aboutToBlock, this, &tst_WaylandClientFullScreenShellV1::processWaylandEvents); + } + +public slots: + void processWaylandEvents() + { + m_compositor->processWaylandEvents(); + } + + void cleanup() + { + // make sure the surfaces from the last test are properly cleaned up + // and don't show up as false positives in the next test + QTRY_VERIFY(!m_compositor->fullScreenShellV1Surface()); + } + +private slots: + void createDestroyWindow(); + +private: + MockCompositor *m_compositor = nullptr; +}; + +void tst_WaylandClientFullScreenShellV1::createDestroyWindow() +{ + TestWindow window; + window.show(); + + QTRY_VERIFY(m_compositor->fullScreenShellV1Surface()); + + window.destroy(); + QTRY_VERIFY(!m_compositor->fullScreenShellV1Surface()); +} + +int main(int argc, char **argv) +{ + setenv("XDG_RUNTIME_DIR", ".", 1); + setenv("QT_QPA_PLATFORM", "wayland", 1); // force QGuiApplication to use wayland plugin + setenv("QT_WAYLAND_SHELL_INTEGRATION", "fullscreen-shell-v1", 1); + setenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1", 1); // window decorations don't make much sense here + + MockCompositor compositor; + compositor.setOutputMode(screenSize); + + QGuiApplication app(argc, argv); + compositor.applicationInitialized(); + + tst_WaylandClientFullScreenShellV1 tc(&compositor); + return QTest::qExec(&tc, argc, argv); +} + +#include <tst_fullscreenshellv1.moc> diff --git a/tests/auto/client/shared/mockcompositor.cpp b/tests/auto/client/shared/mockcompositor.cpp index 797c05c44..df24b4091 100644 --- a/tests/auto/client/shared/mockcompositor.cpp +++ b/tests/auto/client/shared/mockcompositor.cpp @@ -299,6 +299,16 @@ QSharedPointer<MockXdgToplevelV6> MockCompositor::xdgToplevelV6(int index) return result; } +QSharedPointer<MockSurface> MockCompositor::fullScreenShellV1Surface(int index) +{ + QSharedPointer<MockSurface> result; + lock(); + if (Impl::Surface *surface = m_compositor->fullScreenShellV1()->surfaces().value(index, nullptr)) + result = surface->mockSurface(); + unlock(); + return result; +} + MockCompositor::Command MockCompositor::makeCommand(Command::Callback callback, void *target) { Command command; @@ -382,6 +392,7 @@ Compositor::Compositor() m_iviApplication.reset(new IviApplication(m_display)); m_wlShell.reset(new WlShell(m_display)); m_xdgShellV6.reset(new XdgShellV6(m_display)); + m_fullScreenShellV1.reset(new FullScreenShellV1(m_display)); m_loop = wl_display_get_event_loop(m_display); m_fd = wl_event_loop_get_fd(m_loop); @@ -459,6 +470,11 @@ XdgShellV6 *Compositor::xdgShellV6() const return m_xdgShellV6.data(); } +FullScreenShellV1 *Compositor::fullScreenShellV1() const +{ + return m_fullScreenShellV1.data(); +} + uint32_t Compositor::nextSerial() { return wl_display_next_serial(m_display); @@ -474,6 +490,7 @@ void Compositor::removeSurface(Surface *surface) m_surfaces.removeOne(surface); m_keyboard->handleSurfaceDestroyed(surface); m_pointer->handleSurfaceDestroyed(surface); + m_fullScreenShellV1->removeSurface(surface); } Surface *Compositor::resolveSurface(const QVariant &v) diff --git a/tests/auto/client/shared/mockcompositor.h b/tests/auto/client/shared/mockcompositor.h index 51b6f4bfb..4bab1ed67 100644 --- a/tests/auto/client/shared/mockcompositor.h +++ b/tests/auto/client/shared/mockcompositor.h @@ -31,10 +31,11 @@ #include "mockxdgshellv6.h" #include "mockiviapplication.h" +#include "mockfullscreenshellv1.h" #include <pthread.h> #include <qglobal.h> -#include <wayland-server.h> +#include <wayland-server-core.h> #include <QImage> #include <QMutex> @@ -76,6 +77,7 @@ public: IviApplication *iviApplication() const; XdgShellV6 *xdgShellV6() const; + FullScreenShellV1 *fullScreenShellV1() const; void addSurface(Surface *surface); void removeSurface(Surface *surface); @@ -121,7 +123,6 @@ private: wl_display *m_display = nullptr; wl_event_loop *m_loop = nullptr; - wl_shm *m_shm = nullptr; int m_fd = -1; uint32_t m_time = 0; @@ -136,6 +137,7 @@ private: QScopedPointer<IviApplication> m_iviApplication; QScopedPointer<WlShell> m_wlShell; QScopedPointer<XdgShellV6> m_xdgShellV6; + QScopedPointer<FullScreenShellV1> m_fullScreenShellV1; }; void registerResource(wl_list *list, wl_resource *resource); @@ -252,6 +254,7 @@ public: QSharedPointer<MockOutput> output(int index = 0); QSharedPointer<MockIviSurface> iviSurface(int index = 0); QSharedPointer<MockXdgToplevelV6> xdgToplevelV6(int index = 0); + QSharedPointer<MockSurface> fullScreenShellV1Surface(int index = 0); void lock(); void unlock(); diff --git a/tests/auto/client/shared/mockfullscreenshellv1.cpp b/tests/auto/client/shared/mockfullscreenshellv1.cpp new file mode 100644 index 000000000..22c49cde6 --- /dev/null +++ b/tests/auto/client/shared/mockfullscreenshellv1.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** 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 "mockfullscreenshellv1.h" +#include "mocksurface.h" + +namespace Impl { + +void FullScreenShellV1::zwp_fullscreen_shell_v1_present_surface(Resource *resource, struct ::wl_resource *surface, uint32_t method, struct ::wl_resource *output) +{ + Q_UNUSED(resource) + Q_UNUSED(method) + Q_UNUSED(output) + + m_surfaces.append(Surface::fromResource(surface)); +} + +} // namespace Impl diff --git a/tests/auto/client/shared/mockfullscreenshellv1.h b/tests/auto/client/shared/mockfullscreenshellv1.h new file mode 100644 index 000000000..819bbc186 --- /dev/null +++ b/tests/auto/client/shared/mockfullscreenshellv1.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2018 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> +** 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$ +** +****************************************************************************/ + +#ifndef MOCKFULLSCREENSHELLV1_H +#define MOCKFULLSCREENSHELLV1_H + +#include <qwayland-server-fullscreen-shell-unstable-v1.h> + +#include <QVector> + +namespace Impl { + +class Surface; +class FullScreenShellV1; + +class FullScreenShellV1 : public QtWaylandServer::zwp_fullscreen_shell_v1 +{ +public: + explicit FullScreenShellV1(::wl_display *display) : zwp_fullscreen_shell_v1(display, 1) {} + + QVector<Surface *> surfaces() const { return m_surfaces; } + void removeSurface(Surface *surface) { m_surfaces.removeOne(surface); } + +protected: + void zwp_fullscreen_shell_v1_present_surface(Resource *resource, struct ::wl_resource *surface, uint32_t method, struct ::wl_resource *output) override; + +private: + QVector<Surface *> m_surfaces; +}; + +} // namespace Impl + +#endif // MOCKFULLSCREENSHELLV1_H diff --git a/tests/auto/client/shared/shared.pri b/tests/auto/client/shared/shared.pri index f3cb4d5a2..db71de528 100644 --- a/tests/auto/client/shared/shared.pri +++ b/tests/auto/client/shared/shared.pri @@ -8,12 +8,14 @@ CONFIG += wayland-scanner WAYLANDSERVERSOURCES += \ ../../../../src/3rdparty/protocol/ivi-application.xml \ ../../../../src/3rdparty/protocol/wayland.xml \ - ../../../../src/3rdparty/protocol/xdg-shell-unstable-v6.xml + ../../../../src/3rdparty/protocol/xdg-shell-unstable-v6.xml \ + ../../../../src/3rdparty/protocol/fullscreen-shell-unstable-v1.xml INCLUDEPATH += ../shared SOURCES += \ ../shared/mockcompositor.cpp \ + ../shared/mockfullscreenshellv1.cpp \ ../shared/mockinput.cpp \ ../shared/mockiviapplication.cpp \ ../shared/mockwlshell.cpp \ @@ -23,6 +25,7 @@ SOURCES += \ HEADERS += \ ../shared/mockcompositor.h \ + ../shared/mockfullscreenshellv1.h \ ../shared/mockinput.h \ ../shared/mockiviapplication.h \ ../shared/mockwlshell.h \ diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro index d69db4ca5..29443f7a9 100644 --- a/tests/auto/compositor/compositor/compositor.pro +++ b/tests/auto/compositor/compositor/compositor.pro @@ -13,6 +13,7 @@ qtConfig(xkbcommon-evdev): \ WAYLANDCLIENTSOURCES += \ ../../../../src/3rdparty/protocol/xdg-shell-unstable-v5.xml \ ../../../../src/3rdparty/protocol/ivi-application.xml \ + ../../../../src/3rdparty/protocol/wayland.xml SOURCES += \ tst_compositor.cpp \ diff --git a/tests/auto/compositor/compositor/mockclient.h b/tests/auto/compositor/compositor/mockclient.h index 6bfb652ed..1d9f32774 100644 --- a/tests/auto/compositor/compositor/mockclient.h +++ b/tests/auto/compositor/compositor/mockclient.h @@ -26,7 +26,7 @@ ** ****************************************************************************/ -#include <wayland-client.h> +#include "wayland-wayland-client-protocol.h" #include <qwayland-xdg-shell-unstable-v5.h> #include <wayland-ivi-application-client-protocol.h> diff --git a/tests/auto/compositor/compositor/mockkeyboard.h b/tests/auto/compositor/compositor/mockkeyboard.h index 1090db597..fd7f06aee 100644 --- a/tests/auto/compositor/compositor/mockkeyboard.h +++ b/tests/auto/compositor/compositor/mockkeyboard.h @@ -30,7 +30,7 @@ #define MOCKKEYBOARD_H #include <QObject> -#include <wayland-client.h> +#include "wayland-wayland-client-protocol.h" class MockKeyboard : public QObject { diff --git a/tests/auto/compositor/compositor/mockpointer.h b/tests/auto/compositor/compositor/mockpointer.h index 2054040fd..db6b2b69c 100644 --- a/tests/auto/compositor/compositor/mockpointer.h +++ b/tests/auto/compositor/compositor/mockpointer.h @@ -30,7 +30,7 @@ #define MOCKPOINTER_H #include <QObject> -#include <wayland-client.h> +#include "wayland-wayland-client-protocol.h" class MockPointer : public QObject { diff --git a/tests/auto/compositor/compositor/mockseat.h b/tests/auto/compositor/compositor/mockseat.h index f8c103ed4..0d0f4074c 100644 --- a/tests/auto/compositor/compositor/mockseat.h +++ b/tests/auto/compositor/compositor/mockseat.h @@ -32,7 +32,7 @@ #include "mockkeyboard.h" #include <QObject> -#include <wayland-client.h> +#include "wayland-wayland-client-protocol.h" class MockSeat : public QObject { diff --git a/tests/auto/compositor/compositor/testcompositor.cpp b/tests/auto/compositor/compositor/testcompositor.cpp index 710bb7b3a..22ecf28cb 100644 --- a/tests/auto/compositor/compositor/testcompositor.cpp +++ b/tests/auto/compositor/compositor/testcompositor.cpp @@ -30,7 +30,7 @@ #include "testseat.h" #include "testkeyboardgrabber.h" -#include <wayland-server.h> +#include <wayland-server-core.h> TestCompositor::TestCompositor(bool createInputDev) : shell(new QWaylandWlShell(this)) diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index 2c0e46b23..78e01af7e 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -68,6 +68,7 @@ private slots: void seatKeyboardFocus(); void seatMouseFocus(); void inputRegion(); + void defaultInputRegionHiDpi(); void singleClient(); void multipleClients(); void geometry(); @@ -411,6 +412,7 @@ void tst_WaylandCompositor::mapSurface() QSignalSpy hasContentSpy(waylandSurface, SIGNAL(hasContentChanged())); QCOMPARE(waylandSurface->size(), QSize()); + QCOMPARE(waylandSurface->destinationSize(), QSize()); QCOMPARE(waylandSurface->hasContent(), false); QSize size(256, 256); @@ -425,6 +427,7 @@ void tst_WaylandCompositor::mapSurface() QTRY_COMPARE(hasContentSpy.count(), 1); QCOMPARE(waylandSurface->hasContent(), true); QCOMPARE(waylandSurface->size(), size); + QCOMPARE(waylandSurface->destinationSize(), size); wl_surface_destroy(surface); } @@ -455,6 +458,7 @@ void tst_WaylandCompositor::mapSurfaceHiDpi() auto verifyComittedState = [=]() { QCOMPARE(waylandSurface->size(), bufferSize); + QCOMPARE(waylandSurface->destinationSize(), surfaceSize); QCOMPARE(waylandSurface->bufferScale(), bufferScale); QCOMPARE(waylandSurface->hasContent(), true); }; @@ -473,6 +477,9 @@ void tst_WaylandCompositor::mapSurfaceHiDpi() QObject::connect(waylandSurface, &QWaylandSurface::sizeChanged, verifyComittedState); QSignalSpy sizeSpy(waylandSurface, SIGNAL(sizeChanged())); + QObject::connect(waylandSurface, &QWaylandSurface::destinationSizeChanged, verifyComittedState); + QSignalSpy destinationSizeSpy(waylandSurface, SIGNAL(destinationSizeChanged())); + QObject::connect(waylandSurface, &QWaylandSurface::bufferScaleChanged, verifyComittedState); QSignalSpy bufferScaleSpy(waylandSurface, SIGNAL(bufferScaleChanged())); @@ -484,6 +491,7 @@ void tst_WaylandCompositor::mapSurfaceHiDpi() // No state should be applied before the commit QCOMPARE(waylandSurface->size(), QSize()); + QCOMPARE(waylandSurface->destinationSize(), QSize()); QCOMPARE(waylandSurface->hasContent(), false); QCOMPARE(waylandSurface->bufferScale(), 1); QCOMPARE(offsetSpy.count(), 0); @@ -492,6 +500,7 @@ void tst_WaylandCompositor::mapSurfaceHiDpi() QTRY_COMPARE(hasContentSpy.count(), 1); QTRY_COMPARE(sizeSpy.count(), 1); + QTRY_COMPARE(destinationSizeSpy.count(), 1); QTRY_COMPARE(bufferScaleSpy.count(), 1); QTRY_COMPARE(offsetSpy.count(), 1); @@ -776,6 +785,33 @@ void tst_WaylandCompositor::inputRegion() QVERIFY(!waylandSurface->inputRegionContains(QPoint(1, 2))); } +void tst_WaylandCompositor::defaultInputRegionHiDpi() +{ + TestCompositor compositor(true); + compositor.create(); + + MockClient client; + wl_surface *surface = client.createSurface(); + + int bufferScale = 2; + QSize surfaceSize(16, 16); + QSize bufferSize = surfaceSize * bufferScale; + ShmBuffer buffer(bufferSize, client.shm); + wl_surface_attach(surface, buffer.handle, 0, 0); + wl_surface_damage(surface, 0, 0, surfaceSize.width(), surfaceSize.height()); + wl_surface_set_buffer_scale(surface, bufferScale); + wl_surface_commit(surface); + + QTRY_COMPARE(compositor.surfaces.size(), 1); + QWaylandSurface *waylandSurface = compositor.surfaces.at(0); + + QCOMPARE(waylandSurface->bufferScale(), bufferScale); + QVERIFY(waylandSurface->inputRegionContains(QPoint(0, 0))); + QVERIFY(waylandSurface->inputRegionContains(QPoint(15, 15))); + QVERIFY(!waylandSurface->inputRegionContains(QPoint(-1, -1))); + QVERIFY(!waylandSurface->inputRegionContains(QPoint(16, 16))); +} + class XdgTestCompositor: public TestCompositor { Q_OBJECT public: |