From da61739728b2df7981b898da5dbdd4b74be068fc Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Mon, 29 Aug 2016 15:15:29 +0200 Subject: Rename the QWaylandXdg* classes to QWaylandXdg*V5 This frees the QWaylandXdg name for the hopefully coming stable version of xdg-shell. Change-Id: I9beb9b035c6497fb45bee5c9104485b564ca0619 Reviewed-by: Johan Helsing --- src/compositor/extensions/extensions.pri | 10 +- src/compositor/extensions/qwaylandxdgshell.cpp | 1190 -------------------- src/compositor/extensions/qwaylandxdgshell.h | 251 ----- src/compositor/extensions/qwaylandxdgshell_p.h | 183 --- .../extensions/qwaylandxdgshellintegration.cpp | 195 ---- .../extensions/qwaylandxdgshellintegration_p.h | 125 -- src/compositor/extensions/qwaylandxdgshellv5.cpp | 1190 ++++++++++++++++++++ src/compositor/extensions/qwaylandxdgshellv5.h | 251 +++++ src/compositor/extensions/qwaylandxdgshellv5_p.h | 183 +++ .../extensions/qwaylandxdgshellv5integration.cpp | 195 ++++ .../extensions/qwaylandxdgshellv5integration_p.h | 125 ++ src/imports/compositor/plugins.qmltypes | 16 +- .../compositor/qwaylandquickcompositorplugin.cpp | 8 +- 13 files changed, 1961 insertions(+), 1961 deletions(-) delete mode 100644 src/compositor/extensions/qwaylandxdgshell.cpp delete mode 100644 src/compositor/extensions/qwaylandxdgshell.h delete mode 100644 src/compositor/extensions/qwaylandxdgshell_p.h delete mode 100644 src/compositor/extensions/qwaylandxdgshellintegration.cpp delete mode 100644 src/compositor/extensions/qwaylandxdgshellintegration_p.h create mode 100644 src/compositor/extensions/qwaylandxdgshellv5.cpp create mode 100644 src/compositor/extensions/qwaylandxdgshellv5.h create mode 100644 src/compositor/extensions/qwaylandxdgshellv5_p.h create mode 100644 src/compositor/extensions/qwaylandxdgshellv5integration.cpp create mode 100644 src/compositor/extensions/qwaylandxdgshellv5integration_p.h (limited to 'src') diff --git a/src/compositor/extensions/extensions.pri b/src/compositor/extensions/extensions.pri index bb0abe885..d5a14f549 100644 --- a/src/compositor/extensions/extensions.pri +++ b/src/compositor/extensions/extensions.pri @@ -21,8 +21,8 @@ HEADERS += \ extensions/qwaylandtextinputmanager_p.h \ extensions/qwaylandqtwindowmanager.h \ extensions/qwaylandqtwindowmanager_p.h \ - extensions/qwaylandxdgshell.h \ - extensions/qwaylandxdgshell_p.h \ + extensions/qwaylandxdgshellv5.h \ + extensions/qwaylandxdgshellv5_p.h \ extensions/qwaylandshellsurface.h \ SOURCES += \ @@ -33,19 +33,19 @@ SOURCES += \ extensions/qwaylandtextinput.cpp \ extensions/qwaylandtextinputmanager.cpp \ extensions/qwaylandqtwindowmanager.cpp \ - extensions/qwaylandxdgshell.cpp \ + extensions/qwaylandxdgshellv5.cpp \ qtHaveModule(quick):contains(QT_CONFIG, opengl) { HEADERS += \ extensions/qwaylandquickshellsurfaceitem.h \ extensions/qwaylandquickshellsurfaceitem_p.h \ extensions/qwaylandwlshellintegration_p.h \ - extensions/qwaylandxdgshellintegration_p.h \ + extensions/qwaylandxdgshellv5integration_p.h \ SOURCES += \ extensions/qwaylandquickshellsurfaceitem.cpp \ extensions/qwaylandwlshellintegration.cpp \ - extensions/qwaylandxdgshellintegration.cpp \ + extensions/qwaylandxdgshellv5integration.cpp \ } diff --git a/src/compositor/extensions/qwaylandxdgshell.cpp b/src/compositor/extensions/qwaylandxdgshell.cpp deleted file mode 100644 index ab2c60ecc..000000000 --- a/src/compositor/extensions/qwaylandxdgshell.cpp +++ /dev/null @@ -1,1190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandxdgshell.h" -#include "qwaylandxdgshell_p.h" - -#ifdef QT_WAYLAND_COMPOSITOR_QUICK -#include "qwaylandxdgshellintegration_p.h" -#endif - -#include -#include -#include -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -QWaylandSurfaceRole QWaylandXdgSurfacePrivate::s_role("xdg_surface"); -QWaylandSurfaceRole QWaylandXdgPopupPrivate::s_role("xdg_popup"); - -QWaylandXdgShellPrivate::QWaylandXdgShellPrivate() - : QWaylandCompositorExtensionPrivate() - , xdg_shell() -{ -} - -void QWaylandXdgShellPrivate::ping(Resource *resource, uint32_t serial) -{ - m_pings.insert(serial); - send_ping(resource->handle, serial); -} - -void QWaylandXdgShellPrivate::registerSurface(QWaylandXdgSurface *xdgSurface) -{ - m_xdgSurfaces.insert(xdgSurface->surface()->client()->client(), xdgSurface); -} - -void QWaylandXdgShellPrivate::unregisterXdgSurface(QWaylandXdgSurface *xdgSurface) -{ - auto xdgSurfacePrivate = QWaylandXdgSurfacePrivate::get(xdgSurface); - if (!m_xdgSurfaces.remove(xdgSurfacePrivate->resource()->client(), xdgSurface)) - qWarning("%s Unexpected state. Can't find registered xdg surface\n", Q_FUNC_INFO); -} - -void QWaylandXdgShellPrivate::registerXdgPopup(QWaylandXdgPopup *xdgPopup) -{ - m_xdgPopups.insert(xdgPopup->surface()->client()->client(), xdgPopup); -} - -void QWaylandXdgShellPrivate::unregisterXdgPopup(QWaylandXdgPopup *xdgPopup) -{ - auto xdgPopupPrivate = QWaylandXdgPopupPrivate::get(xdgPopup); - if (!m_xdgPopups.remove(xdgPopupPrivate->resource()->client(), xdgPopup)) - qWarning("%s Unexpected state. Can't find registered xdg popup\n", Q_FUNC_INFO); -} - -bool QWaylandXdgShellPrivate::isValidPopupParent(QWaylandSurface *parentSurface) const -{ - QWaylandXdgPopup *topmostPopup = topmostPopupForClient(parentSurface->client()->client()); - if (topmostPopup && topmostPopup->surface() != parentSurface) { - return false; - } - - QWaylandSurfaceRole *parentRole = parentSurface->role(); - if (parentRole != QWaylandXdgSurface::role() && parentRole != QWaylandXdgPopup::role()) { - return false; - } - - return true; -} - -QWaylandXdgPopup *QWaylandXdgShellPrivate::topmostPopupForClient(wl_client *client) const -{ - QList clientPopups = m_xdgPopups.values(client); - return clientPopups.empty() ? nullptr : clientPopups.last(); -} - -QWaylandXdgSurface *QWaylandXdgShellPrivate::xdgSurfaceFromSurface(QWaylandSurface *surface) -{ - Q_FOREACH (QWaylandXdgSurface *xdgSurface, m_xdgSurfaces) { - if (surface == xdgSurface->surface()) - return xdgSurface; - } - return nullptr; -} - -void QWaylandXdgShellPrivate::xdg_shell_destroy(Resource *resource) -{ - if (!m_xdgSurfaces.values(resource->client()).empty()) - wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_DEFUNCT_SURFACES, - "xdg_shell was destroyed before children"); - - wl_resource_destroy(resource->handle); -} - -void QWaylandXdgShellPrivate::xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, - wl_resource *surface_res) -{ - Q_Q(QWaylandXdgShell); - QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); - - if (xdgSurfaceFromSurface(surface)) { - wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_ROLE, - "An active xdg_surface already exists for wl_surface@%d", - wl_resource_get_id(surface->resource())); - return; - } - - if (!surface->setRole(QWaylandXdgSurface::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) - return; - - QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface, - wl_resource_get_version(resource->handle), id)); - - emit q->xdgSurfaceRequested(surface, xdgSurfaceResource); - - QWaylandXdgSurface *xdgSurface = QWaylandXdgSurface::fromResource(xdgSurfaceResource.resource()); - if (!xdgSurface) { - // A QWaylandXdgSurface was not created in response to the xdgSurfaceRequested signal, so we - // create one as fallback here instead. - xdgSurface = new QWaylandXdgSurface(q, surface, xdgSurfaceResource); - } - - registerSurface(xdgSurface); - emit q->xdgSurfaceCreated(xdgSurface); -} - -void QWaylandXdgShellPrivate::xdg_shell_use_unstable_version(Resource *resource, int32_t version) -{ - if (xdg_shell::version_current != version) { - wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, - "incompatible version, server is %d, but client wants %d", - xdg_shell::version_current, version); - } -} - -void QWaylandXdgShellPrivate::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, - wl_resource *surface_res, wl_resource *parent, - wl_resource *seatResource, uint32_t serial, - int32_t x, int32_t y) -{ - Q_UNUSED(serial); - Q_Q(QWaylandXdgShell); - QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); - QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); - - if (!isValidPopupParent(parentSurface)) { - wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_INVALID_POPUP_PARENT, - "the client specified an invalid popup parent surface"); - return; - } - - if (!surface->setRole(QWaylandXdgPopup::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) { - return; - } - - QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface, - wl_resource_get_version(resource->handle), id)); - QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); - QPoint position(x, y); - emit q->xdgPopupRequested(surface, parentSurface, seat, position, xdgPopupResource); - - QWaylandXdgPopup *xdgPopup = QWaylandXdgPopup::fromResource(xdgPopupResource.resource()); - if (!xdgPopup) { - // A QWaylandXdgPopup was not created in response to the xdgPopupRequested signal, so we - // create one as fallback here instead. - xdgPopup = new QWaylandXdgPopup(q, surface, parentSurface, position, xdgPopupResource); - } - - registerXdgPopup(xdgPopup); - emit q->xdgPopupCreated(xdgPopup); -} - -void QWaylandXdgShellPrivate::xdg_shell_pong(Resource *resource, uint32_t serial) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgShell); - if (m_pings.remove(serial)) - emit q->pong(serial); - else - qWarning("Received an unexpected pong!"); -} - -QWaylandXdgSurfacePrivate::QWaylandXdgSurfacePrivate() - : QWaylandCompositorExtensionPrivate() - , xdg_surface() - , m_surface(nullptr) - , m_parentSurface(nullptr) - , m_windowType(UnknownWindowType) - , m_unsetWindowGeometry(true) - , m_lastAckedConfigure({{}, QSize(0, 0), 0}) -{ -} - -void QWaylandXdgSurfacePrivate::handleFocusLost() -{ - Q_Q(QWaylandXdgSurface); - QWaylandXdgSurfacePrivate::ConfigureEvent current = lastSentConfigure(); - current.states.removeOne(QWaylandXdgSurface::State::ActivatedState); - q->sendConfigure(current.size, current.states); -} - -void QWaylandXdgSurfacePrivate::handleFocusReceived() -{ - Q_Q(QWaylandXdgSurface); - - QWaylandXdgSurfacePrivate::ConfigureEvent current = lastSentConfigure(); - if (!current.states.contains(QWaylandXdgSurface::State::ActivatedState)) { - current.states.push_back(QWaylandXdgSurface::State::ActivatedState); - } - - q->sendConfigure(current.size, current.states); -} - -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()); -} - -void QWaylandXdgSurfacePrivate::updateFallbackWindowGeometry() -{ - Q_Q(QWaylandXdgSurface); - if (!m_unsetWindowGeometry) - return; - - const QRect unsetGeometry = calculateFallbackWindowGeometry(); - if (unsetGeometry == m_windowGeometry) - return; - - m_windowGeometry = unsetGeometry; - emit q->windowGeometryChanged(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_destroy_resource(Resource *resource) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - QWaylandXdgShellPrivate::get(m_xdgShell)->unregisterXdgSurface(q); - delete q; -} - -void QWaylandXdgSurfacePrivate::xdg_surface_destroy(Resource *resource) -{ - wl_resource_destroy(resource->handle); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_move(Resource *resource, wl_resource *seat, uint32_t serial) -{ - Q_UNUSED(resource); - Q_UNUSED(serial); - - Q_Q(QWaylandXdgSurface); - QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); - emit q->startMove(input_device); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_resize(Resource *resource, wl_resource *seat, - uint32_t serial, uint32_t edges) -{ - Q_UNUSED(resource); - Q_UNUSED(serial); - - Q_Q(QWaylandXdgSurface); - QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); - emit q->startResize(input_device, QWaylandXdgSurface::ResizeEdge(edges)); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_maximized(Resource *resource) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - emit q->setMaximized(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_unset_maximized(Resource *resource) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - emit q->unsetMaximized(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_fullscreen(Resource *resource, wl_resource *output_res) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - QWaylandOutput *output = output_res ? QWaylandOutput::fromResource(output_res) : nullptr; - emit q->setFullscreen(output); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_unset_fullscreen(Resource *resource) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - emit q->unsetFullscreen(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_minimized(Resource *resource) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - emit q->setMinimized(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_parent(Resource *resource, wl_resource *parent) -{ - Q_UNUSED(resource); - QWaylandXdgSurface *parentSurface = nullptr; - if (parent) { - parentSurface = static_cast( - QWaylandXdgSurfacePrivate::Resource::fromResource(parent)->xdg_surface_object)->q_func(); - } - - Q_Q(QWaylandXdgSurface); - - if (m_parentSurface != parentSurface) { - m_parentSurface = parentSurface; - emit q->parentSurfaceChanged(); - } - - if (m_parentSurface && m_windowType != TransientWindowType) { - // There's a parent now, which means the surface is transient - m_windowType = TransientWindowType; - emit q->setTransient(); - } else if (!m_parentSurface && m_windowType != TopLevelWindowType) { - // When the surface has no parent it is toplevel - m_windowType = TopLevelWindowType; - emit q->setTopLevel(); - } -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_app_id(Resource *resource, const QString &app_id) -{ - Q_UNUSED(resource); - if (app_id == m_appId) - return; - Q_Q(QWaylandXdgSurface); - m_appId = app_id; - emit q->appIdChanged(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_show_window_menu(Resource *resource, wl_resource *seatResource, - uint32_t serial, int32_t x, int32_t y) -{ - Q_UNUSED(resource); - Q_UNUSED(serial); - QPoint position(x, y); - auto seat = QWaylandSeat::fromSeatResource(seatResource); - Q_Q(QWaylandXdgSurface); - emit q->showWindowMenu(seat, position); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_ack_configure(Resource *resource, uint32_t serial) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgSurface); - - ConfigureEvent config; - Q_FOREVER { - if (m_pendingConfigures.empty()) { - qWarning("Received an unexpected ack_configure!"); - return; - } - - config = m_pendingConfigures.takeFirst(); - - if (config.serial == serial) - break; - } - - QVector changedStates; - std::set_symmetric_difference( - m_lastAckedConfigure.states.begin(), m_lastAckedConfigure.states.end(), - config.states.begin(), config.states.end(), - std::back_inserter(changedStates)); - - m_lastAckedConfigure = config; - - if (!changedStates.empty()) { - Q_FOREACH (uint state, changedStates) { - switch (state) { - case QWaylandXdgSurface::State::MaximizedState: - emit q->maximizedChanged(); - break; - case QWaylandXdgSurface::State::FullscreenState: - emit q->fullscreenChanged(); - break; - case QWaylandXdgSurface::State::ResizingState: - emit q->resizingChanged(); - break; - case QWaylandXdgSurface::State::ActivatedState: - emit q->activatedChanged(); - break; - } - } - emit q->statesChanged(); - } - - emit q->ackConfigure(serial); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_title(Resource *resource, const QString &title) -{ - Q_UNUSED(resource); - if (title == m_title) - return; - Q_Q(QWaylandXdgSurface); - m_title = title; - emit q->titleChanged(); -} - -void QWaylandXdgSurfacePrivate::xdg_surface_set_window_geometry(Resource *resource, - int32_t x, int32_t y, - int32_t width, int32_t height) -{ - Q_UNUSED(resource); - - if (width <= 0 || height <= 0) { - qWarning() << "Invalid (non-positive) dimensions received in set_window_geometry"; - return; - } - - m_unsetWindowGeometry = false; - - QRect geometry(x, y, width, height); - - Q_Q(QWaylandXdgSurface); - if ((q->maximized() || q->fullscreen()) && m_lastAckedConfigure.size != geometry.size()) - qWarning() << "Client window geometry did not obey last acked configure"; - - if (geometry == m_windowGeometry) - return; - - m_windowGeometry = geometry; - emit q->windowGeometryChanged(); -} - -QWaylandXdgPopupPrivate::QWaylandXdgPopupPrivate() - : QWaylandCompositorExtensionPrivate() - , xdg_popup() - , m_surface(nullptr) - , m_parentSurface(nullptr) - , m_xdgShell(nullptr) -{ -} - -void QWaylandXdgPopupPrivate::xdg_popup_destroy_resource(Resource *resource) -{ - Q_UNUSED(resource); - Q_Q(QWaylandXdgPopup); - QWaylandXdgShellPrivate::get(m_xdgShell)->unregisterXdgPopup(q); - delete q; -} - -void QWaylandXdgPopupPrivate::xdg_popup_destroy(Resource *resource) -{ - //TODO: post error if not topmost popup - wl_resource_destroy(resource->handle); -} - -/*! - * Constructs a QWaylandXdgShell object. - */ -QWaylandXdgShell::QWaylandXdgShell() - : QWaylandCompositorExtensionTemplate(*new QWaylandXdgShellPrivate()) -{ } - -/*! - * Constructs a QWaylandXdgShell object for the provided \a compositor. - */ -QWaylandXdgShell::QWaylandXdgShell(QWaylandCompositor *compositor) - : QWaylandCompositorExtensionTemplate(compositor, *new QWaylandXdgShellPrivate()) -{ } - -/*! - * Initializes the shell extension. - */ -void QWaylandXdgShell::initialize() -{ - Q_D(QWaylandXdgShell); - QWaylandCompositorExtensionTemplate::initialize(); - QWaylandCompositor *compositor = static_cast(extensionContainer()); - if (!compositor) { - qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgShell"; - return; - } - d->init(compositor->display(), 1); - - handleSeatChanged(compositor->defaultSeat(), nullptr); - - connect(compositor, &QWaylandCompositor::defaultSeatChanged, - this, &QWaylandXdgShell::handleSeatChanged); -} - -/*! - * Returns the Wayland interface for the QWaylandXdgShell. - */ -const struct wl_interface *QWaylandXdgShell::interface() -{ - return QWaylandXdgShellPrivate::interface(); -} - -QByteArray QWaylandXdgShell::interfaceName() -{ - return QWaylandXdgShellPrivate::interfaceName(); -} - -/*! - * \qmlmethod void QtWaylandCompositor::XdgSurface::ping() - * - * Sends a ping event to the client. If the client replies to the event the - * \a pong signal will be emitted. - */ - -/*! - * Sends a ping event to the client. If the client replies to the event the - * \a pong signal will be emitted. - */ -uint QWaylandXdgShell::ping(QWaylandClient *client) -{ - Q_D(QWaylandXdgShell); - - QWaylandCompositor *compositor = static_cast(extensionContainer()); - Q_ASSERT(compositor); - - uint32_t serial = compositor->nextSerial(); - - QWaylandXdgShellPrivate::Resource *clientResource = d->resourceMap().value(client->client(), nullptr); - Q_ASSERT(clientResource); - - d->ping(clientResource, serial); - return serial; -} - -void QWaylandXdgShell::closeAllPopups() -{ - Q_D(QWaylandXdgShell); - Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) { - QList popups = d->m_xdgPopups.values(client); - std::reverse(popups.begin(), popups.end()); - Q_FOREACH (QWaylandXdgPopup *currentTopmostPopup, popups) { - currentTopmostPopup->sendPopupDone(); - } - } -} - -void QWaylandXdgShell::handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat) -{ - if (oldSeat != nullptr) { - disconnect(oldSeat, &QWaylandSeat::keyboardFocusChanged, - this, &QWaylandXdgShell::handleFocusChanged); - } - - if (newSeat != nullptr) { - connect(newSeat, &QWaylandSeat::keyboardFocusChanged, - this, &QWaylandXdgShell::handleFocusChanged); - } -} - -void QWaylandXdgShell::handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) -{ - Q_D(QWaylandXdgShell); - - QWaylandXdgSurface *newXdgSurface = d->xdgSurfaceFromSurface(newSurface); - QWaylandXdgSurface *oldXdgSurface = d->xdgSurfaceFromSurface(oldSurface); - - if (newXdgSurface) - QWaylandXdgSurfacePrivate::get(newXdgSurface)->handleFocusReceived(); - - if (oldXdgSurface) - QWaylandXdgSurfacePrivate::get(oldXdgSurface)->handleFocusLost(); -} - -/*! - * \class QWaylandXdgSurface - * \inmodule QtWaylandCompositor - * \preliminary - * \brief The QWaylandXdgSurface class provides desktop-style compositor-specific features to an xdg surface. - * - * This class is part of the QWaylandXdgShell extension and provides a way to - * extend the functionality of an existing QWaylandSurface with features - * specific to desktop-style compositors, such as resizing and moving the - * surface. - * - * It corresponds to the Wayland interface xdg_surface. - */ - -/*! - * \qmlsignal QtWaylandCompositor::XdgSurface::setTopLevel() - * - * This signal is emitted when the parent surface is unset, effectively - * making the window top level. - */ - -/*! - * \qmlsignal QtWaylandCompositor::XdgSurface::setTransient() - * - * This signal is emitted when the parent surface is set, effectively - * making the window transient. - */ - -/*! - * Constructs a QWaylandXdgSurface. - */ -QWaylandXdgSurface::QWaylandXdgSurface() - : QWaylandShellSurfaceTemplate(*new QWaylandXdgSurfacePrivate) -{ -} - -/*! - * Constructs a QWaylandXdgSurface for \a surface and initializes it with the - * given \a xdgShell, \a surface, and resource \a res. - */ -QWaylandXdgSurface::QWaylandXdgSurface(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, const QWaylandResource &res) - : QWaylandShellSurfaceTemplate(*new QWaylandXdgSurfacePrivate) -{ - initialize(xdgShell, surface, res); -} - -/*! - * \qmlmethod void QtWaylandCompositor::XdgSurface::initialize(object surface, object client, int id) - * - * Initializes the XdgSurface, associating it with the given \a surface, - * \a client, and \a id. - */ - -/*! - * Initializes the QWaylandXdgSurface, associating it with the given \a xdgShell, \a surface - * and \a resource. - */ -void QWaylandXdgSurface::initialize(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, const QWaylandResource &resource) -{ - Q_D(QWaylandXdgSurface); - d->m_xdgShell = xdgShell; - d->m_surface = surface; - d->init(resource.resource()); - setExtensionContainer(surface); - d->m_windowGeometry = d->calculateFallbackWindowGeometry(); - connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurface::handleSurfaceSizeChanged); - connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurface::handleBufferScaleChanged); - emit shellChanged(); - emit surfaceChanged(); - emit windowGeometryChanged(); - QWaylandCompositorExtension::initialize(); -} - -/*! - * \internal - */ -void QWaylandXdgSurface::initialize() -{ - QWaylandCompositorExtension::initialize(); -} - -QList QWaylandXdgSurface::statesAsInts() const -{ - QList list; - Q_FOREACH (uint state, states()) { - list << static_cast(state); - } - return list; -} - -void QWaylandXdgSurface::handleSurfaceSizeChanged() -{ - Q_D(QWaylandXdgSurface); - d->updateFallbackWindowGeometry(); -} - -void QWaylandXdgSurface::handleBufferScaleChanged() -{ - Q_D(QWaylandXdgSurface); - d->updateFallbackWindowGeometry(); -} - -/*! - * \qmlproperty object QtWaylandCompositor::XdgSurface::shell - * - * This property holds the shell associated with this XdgSurface. - */ - -/*! - * \property QWaylandXdgSurface::shell - * - * This property holds the shell associated with this QWaylandXdgSurface. - */ -QWaylandXdgShell *QWaylandXdgSurface::shell() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_xdgShell; -} - -/*! - * \qmlproperty object QtWaylandCompositor::XdgSurface::surface - * - * This property holds the surface associated with this XdgSurface. - */ - -/*! - * \property QWaylandXdgSurface::surface - * - * This property holds the surface associated with this QWaylandXdgSurface. - */ -QWaylandSurface *QWaylandXdgSurface::surface() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_surface; -} - -/*! - * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface - * - * This property holds the XdgSurface parent of this XdgSurface. - * When a parent surface is set, the parentSurfaceChanged() signal - * is guaranteed to be emitted before setTopLevel() and setTransient(). - * - * \sa QtWaylandCompositor::XdgSurface::setTopLevel() - * \sa QtWaylandCompositor::XdgSurface::setTransient() - */ - -/*! - * \property QWaylandXdgSurface::parentSurface - * - * This property holds the XdgSurface parent of this XdgSurface. - * When a parent surface is set, the parentSurfaceChanged() signal - * is guaranteed to be emitted before setTopLevel() and setTransient(). - * - * \sa QWaylandXdgSurface::setTopLevel() - * \sa QWaylandXdgSurface::setTransient() - */ -QWaylandXdgSurface *QWaylandXdgSurface::parentSurface() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_parentSurface; -} - -/*! - * \qmlproperty string QtWaylandCompositor::XdgSurface::title - * - * This property holds the title of the XdgSurface. - */ - -/*! - * \property QWaylandXdgSurface::title - * - * This property holds the title of the QWaylandXdgSurface. - */ -QString QWaylandXdgSurface::title() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_title; -} - -/*! - * \property QWaylandXdgSurface::appId - * - * This property holds the app id of the QWaylandXdgSurface. - */ -QString QWaylandXdgSurface::appId() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_appId; -} - -/*! - * \property QWaylandXdgSurface::windowGeometry - * - * This property holds the window geometry of the QWaylandXdgSurface. The window - * geometry describes the window's visible bounds from the user's perspective. - * The geometry includes title bars and borders if drawn by the client, but - * excludes drop shadows. It is meant to be used for aligning and tiling - * windows. - */ -QRect QWaylandXdgSurface::windowGeometry() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_windowGeometry; -} - -/*! - * \property QWaylandXdgSurface::states - * - * This property holds the last states the client acknowledged for this QWaylandXdgSurface. - */ -QVector QWaylandXdgSurface::states() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_lastAckedConfigure.states; -} - -bool QWaylandXdgSurface::maximized() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::MaximizedState); -} - -bool QWaylandXdgSurface::fullscreen() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::FullscreenState); -} - -bool QWaylandXdgSurface::resizing() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::ResizingState); -} - -bool QWaylandXdgSurface::activated() const -{ - Q_D(const QWaylandXdgSurface); - return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurface::State::ActivatedState); -} - -/*! - * Returns the Wayland interface for the QWaylandXdgSurface. - */ -const wl_interface *QWaylandXdgSurface::interface() -{ - return QWaylandXdgSurfacePrivate::interface(); -} - -QByteArray QWaylandXdgSurface::interfaceName() -{ - return QWaylandXdgSurfacePrivate::interfaceName(); -} - -/*! - * Returns the surface role for the QWaylandXdgSurface. - */ -QWaylandSurfaceRole *QWaylandXdgSurface::role() -{ - return &QWaylandXdgSurfacePrivate::s_role; -} - -/*! - * Returns the QWaylandXdgSurface corresponding to the \a resource. - */ -QWaylandXdgSurface *QWaylandXdgSurface::fromResource(wl_resource *resource) -{ - auto xsResource = QWaylandXdgSurfacePrivate::Resource::fromResource(resource); - if (!xsResource) - return nullptr; - return static_cast(xsResource->xdg_surface_object)->q_func(); -} - -QSize QWaylandXdgSurface::sizeForResize(const QSizeF &size, const QPointF &delta, - QWaylandXdgSurface::ResizeEdge edge) -{ - qreal width = size.width(); - qreal height = size.height(); - if (edge & LeftEdge) - width -= delta.x(); - else if (edge & RightEdge) - width += delta.x(); - - if (edge & TopEdge) - height -= delta.y(); - else if (edge & BottomEdge) - height += delta.y(); - - return QSizeF(width, height).toSize(); -} - -/*! - * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, List) - * - * Sends a configure event to the client. Known states are enumerated in XdgSurface::State - */ - -/*! - * Sends a configure event to the client. Known states are enumerated in QWaylandXdgSurface::State - */ -uint QWaylandXdgSurface::sendConfigure(const QSize &size, const QVector &states) -{ - Q_D(QWaylandXdgSurface); - auto statesBytes = QByteArray::fromRawData((char *)states.data(), states.size() * sizeof(State)); - QWaylandCompositor *compositor = static_cast(extensionContainer()); - Q_ASSERT(compositor); - uint32_t serial = compositor->nextSerial(); - d->m_pendingConfigures.append(QWaylandXdgSurfacePrivate::ConfigureEvent{states, size, serial}); - d->send_configure(size.width(), size.height(), statesBytes, serial); - return serial; -} - -uint QWaylandXdgSurface::sendConfigure(const QSize &size, const QVector &states) -{ - QVector asUints; - Q_FOREACH (QWaylandXdgSurface::State state, states) { - asUints << state; - } - return sendConfigure(size, asUints); -} - -/*! - * \qmlmethod void QtWaylandCompositor::XdgSurface::sendClose() - * - * Sends a close event to the client. - */ - -/*! - * Sends a close event to the client. - */ -void QWaylandXdgSurface::sendClose() -{ - Q_D(QWaylandXdgSurface); - d->send_close(); -} - -uint QWaylandXdgSurface::sendMaximized(const QSize &size) -{ - Q_D(QWaylandXdgSurface); - QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); - - if (!conf.states.contains(QWaylandXdgSurface::State::MaximizedState)) - conf.states.append(QWaylandXdgSurface::State::MaximizedState); - conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState); - conf.states.removeOne(QWaylandXdgSurface::State::ResizingState); - - return sendConfigure(size, conf.states); -} - -uint QWaylandXdgSurface::sendUnmaximized(const QSize &size) -{ - Q_D(QWaylandXdgSurface); - QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); - - conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState); - conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState); - conf.states.removeOne(QWaylandXdgSurface::State::ResizingState); - - return sendConfigure(size, conf.states); -} - -uint QWaylandXdgSurface::sendFullscreen(const QSize &size) -{ - Q_D(QWaylandXdgSurface); - QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); - - if (!conf.states.contains(QWaylandXdgSurface::State::FullscreenState)) - conf.states.append(QWaylandXdgSurface::State::FullscreenState); - conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState); - conf.states.removeOne(QWaylandXdgSurface::State::ResizingState); - - return sendConfigure(size, conf.states); -} - -uint QWaylandXdgSurface::sendResizing(const QSize &maxSize) -{ - Q_D(QWaylandXdgSurface); - QWaylandXdgSurfacePrivate::ConfigureEvent conf = d->lastSentConfigure(); - - if (!conf.states.contains(QWaylandXdgSurface::State::ResizingState)) - conf.states.append(QWaylandXdgSurface::State::ResizingState); - conf.states.removeOne(QWaylandXdgSurface::State::MaximizedState); - conf.states.removeOne(QWaylandXdgSurface::State::FullscreenState); - - return sendConfigure(maxSize, conf.states); -} - -#ifdef QT_WAYLAND_COMPOSITOR_QUICK -QWaylandQuickShellIntegration *QWaylandXdgSurface::createIntegration(QWaylandQuickShellSurfaceItem *item) -{ - return new QtWayland::XdgShellIntegration(item); -} -#endif - -/*! - * \class QWaylandXdgPopup - * \inmodule QtWaylandCompositor - * \preliminary - * \brief The QWaylandXdgPopup class provides menus for an xdg surface - * - * This class is part of the QWaylandXdgShell extension and provides a way to - * extend the functionality of an existing QWaylandSurface with features - * specific to desktop-style menus for an xdg surface. - * - * It corresponds to the Wayland interface xdg_popup. - */ - -/*! - * Constructs a QWaylandXdgPopup. - */ -QWaylandXdgPopup::QWaylandXdgPopup() - : QWaylandShellSurfaceTemplate(*new QWaylandXdgPopupPrivate) -{ -} - -/*! - * Constructs a QWaylandXdgPopup for \a surface and initializes it with the - * given \a parentSurface and \a resource. - */ -QWaylandXdgPopup::QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource) - : QWaylandShellSurfaceTemplate(*new QWaylandXdgPopupPrivate) -{ - initialize(xdgShell, surface, parentSurface, position, resource); -} - -/*! - * \qmlmethod void QtWaylandCompositor::XdgPopup::initialize(object surface, object parentSurface, object resource) - * - * Initializes the xdg popup, associating it with the given \a shell, \a surface, - * \a parentSurface and \a resource. - */ - -/*! - * Initializes the QWaylandXdgPopup, associating it with the given \a shell \a surface, - * \a parentSurface and \a resource. - */ -void QWaylandXdgPopup::initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, QWaylandSurface *parentSurface, - const QPoint& position, const QWaylandResource &resource) -{ - Q_D(QWaylandXdgPopup); - d->m_surface = surface; - d->m_parentSurface = parentSurface; - d->m_xdgShell = shell; - d->m_position = position; - d->init(resource.resource()); - setExtensionContainer(surface); - emit shellChanged(); - emit surfaceChanged(); - emit parentSurfaceChanged(); - QWaylandCompositorExtension::initialize(); -} - -/*! - * \qmlproperty object QtWaylandCompositor::XdgPopup::shell - * - * This property holds the shell associated with this XdgPopup. - */ - -/*! - * \property QWaylandXdgPopup::shell - * - * This property holds the shell associated with this QWaylandXdgPopup. - */ -QWaylandXdgShell *QWaylandXdgPopup::shell() const -{ - Q_D(const QWaylandXdgPopup); - return d->m_xdgShell; -} - -/*! - * \qmlproperty object QtWaylandCompositor::XdgPopup::surface - * - * This property holds the surface associated with this XdgPopup. - */ - -/*! - * \property QWaylandXdgPopup::surface - * - * This property holds the surface associated with this QWaylandXdgPopup. - */ -QWaylandSurface *QWaylandXdgPopup::surface() const -{ - Q_D(const QWaylandXdgPopup); - return d->m_surface; -} - -/*! - * \qmlproperty object QtWaylandCompositor::XdgPopup::parentSurface - * - * This property holds the surface associated with the parent of this XdgPopup. - */ - -/*! - * \property QWaylandXdgPopup::parentSurface - * - * This property holds the surface associated with the parent of this - * QWaylandXdgPopup. - */ -QWaylandSurface *QWaylandXdgPopup::parentSurface() const -{ - Q_D(const QWaylandXdgPopup); - return d->m_parentSurface; -} - - -/*! - * \qmlproperty object QtWaylandCompositor::XdgPopup::position - * - * This property holds the location of the upper left corner of the surface - * relative to the upper left corner of the parent surface, in surface local - * coordinates. - */ - -/*! - * \property QWaylandXdgPopup::position - * - * This property holds the location of the upper left corner of the surface - * relative to the upper left corner of the parent surface, in surface local - * coordinates. - */ -QPoint QWaylandXdgPopup::position() const -{ - Q_D(const QWaylandXdgPopup); - return d->m_position; -} - -/*! - * \internal - */ -void QWaylandXdgPopup::initialize() -{ - QWaylandCompositorExtension::initialize(); -} - -/*! - * Returns the Wayland interface for the QWaylandXdgPopup. - */ -const wl_interface *QWaylandXdgPopup::interface() -{ - return QWaylandXdgPopupPrivate::interface(); -} - -QByteArray QWaylandXdgPopup::interfaceName() -{ - return QWaylandXdgPopupPrivate::interfaceName(); -} - -/*! - * Returns the surface role for the QWaylandXdgPopup. - */ -QWaylandSurfaceRole *QWaylandXdgPopup::role() -{ - return &QWaylandXdgPopupPrivate::s_role; -} - -QWaylandXdgPopup *QWaylandXdgPopup::fromResource(wl_resource *resource) -{ - auto popupResource = QWaylandXdgPopupPrivate::Resource::fromResource(resource); - if (!popupResource) - return nullptr; - return static_cast(popupResource->xdg_popup_object)->q_func(); -} - -void QWaylandXdgPopup::sendPopupDone() -{ - Q_D(QWaylandXdgPopup); - d->send_popup_done(); -} - -#ifdef QT_WAYLAND_COMPOSITOR_QUICK -QWaylandQuickShellIntegration *QWaylandXdgPopup::createIntegration(QWaylandQuickShellSurfaceItem *item) -{ - return new QtWayland::XdgPopupIntegration(item); -} -#endif - -QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshell.h b/src/compositor/extensions/qwaylandxdgshell.h deleted file mode 100644 index 4a1ec5d06..000000000 --- a/src/compositor/extensions/qwaylandxdgshell.h +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDXDGSHELL_H -#define QWAYLANDXDGSHELL_H - -#include -#include -#include - -#include - -struct wl_resource; - -QT_BEGIN_NAMESPACE - -class QWaylandXdgShellPrivate; -class QWaylandXdgSurface; -class QWaylandXdgSurfacePrivate; -class QWaylandXdgPopup; -class QWaylandXdgPopupPrivate; - -class QWaylandSurface; -class QWaylandSurfaceRole; -class QWaylandSeat; -class QWaylandOutput; -class QWaylandClient; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShell : public QWaylandCompositorExtensionTemplate -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandXdgShell) -public: - QWaylandXdgShell(); - QWaylandXdgShell(QWaylandCompositor *compositor); - - void initialize() Q_DECL_OVERRIDE; - - static const struct wl_interface *interface(); - static QByteArray interfaceName(); - -public Q_SLOTS: - uint ping(QWaylandClient *client); - void closeAllPopups(); - -Q_SIGNALS: - void xdgSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); - void xdgSurfaceCreated(QWaylandXdgSurface *xdgSurface); - void xdgPopupCreated(QWaylandXdgPopup *xdgPopup); - void xdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandSeat *seat, const QPoint &position, const QWaylandResource &resource); - void pong(uint serial); - -private Q_SLOTS: - void handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat); - void handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); - -}; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurface : public QWaylandShellSurfaceTemplate -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandXdgSurface) - Q_PROPERTY(QWaylandXdgShell *shell READ shell NOTIFY shellChanged) - Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) - Q_PROPERTY(QWaylandXdgSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) - Q_PROPERTY(QString title READ title NOTIFY titleChanged) - Q_PROPERTY(QString appId READ appId NOTIFY appIdChanged) - Q_PROPERTY(QRect windowGeometry READ windowGeometry NOTIFY windowGeometryChanged) - - Q_PROPERTY(QList states READ statesAsInts NOTIFY statesChanged) - Q_PROPERTY(bool maximized READ maximized NOTIFY maximizedChanged) - Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged) - Q_PROPERTY(bool resizing READ resizing NOTIFY resizingChanged) - Q_PROPERTY(bool activated READ activated NOTIFY activatedChanged) - -public: - enum State : uint { - MaximizedState = 1, - FullscreenState = 2, - ResizingState = 3, - ActivatedState = 4 - }; - Q_ENUM(State) - - enum ResizeEdge : uint { - NoneEdge = 0, - TopEdge = 1, - BottomEdge = 2, - LeftEdge = 4, - TopLeftEdge = 5, - BottomLeftEdge = 6, - RightEdge = 8, - TopRightEdge = 9, - BottomRightEdge = 10 - }; - Q_ENUM(ResizeEdge) - - QWaylandXdgSurface(); - QWaylandXdgSurface(QWaylandXdgShell* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource); - - Q_INVOKABLE void initialize(QWaylandXdgShell* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource); - - QString title() const; - QString appId() const; - QRect windowGeometry() const; - QVector states() const; - bool maximized() const; - bool fullscreen() const; - bool resizing() const; - bool activated() const; - - QWaylandXdgShell *shell() const; - - QWaylandSurface *surface() const; - QWaylandXdgSurface *parentSurface() const; - - static const struct wl_interface *interface(); - static QByteArray interfaceName(); - static QWaylandSurfaceRole *role(); - static QWaylandXdgSurface *fromResource(::wl_resource *resource); - - Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edge); - Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector &states); - Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector &states); - Q_INVOKABLE void sendClose(); - - Q_INVOKABLE uint sendMaximized(const QSize &size); - Q_INVOKABLE uint sendUnmaximized(const QSize &size = QSize(0, 0)); - Q_INVOKABLE uint sendFullscreen(const QSize &size); - Q_INVOKABLE uint sendResizing(const QSize &maxSize); - -#ifdef QT_WAYLAND_COMPOSITOR_QUICK - QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; -#endif - -Q_SIGNALS: - void shellChanged(); - void surfaceChanged(); - void titleChanged(); - void windowGeometryChanged(); - void appIdChanged(); - void parentSurfaceChanged(); - - void statesChanged(); - void maximizedChanged(); - void fullscreenChanged(); - void resizingChanged(); - void activatedChanged(); - - void showWindowMenu(QWaylandSeat *seat, const QPoint &localSurfacePosition); - void startMove(QWaylandSeat *seat); - void startResize(QWaylandSeat *seat, ResizeEdge edges); - void setTopLevel(); - void setTransient(); - void setMaximized(); - void unsetMaximized(); - void setFullscreen(QWaylandOutput *output); - void unsetFullscreen(); - void setMinimized(); - void ackConfigure(uint serial); - -private: - void initialize() override; - QList statesAsInts() const; - -private Q_SLOTS: - void handleSurfaceSizeChanged(); - void handleBufferScaleChanged(); -}; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopup : public QWaylandShellSurfaceTemplate -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QWaylandXdgPopup) - Q_PROPERTY(QWaylandXdgShell *shell READ shell NOTIFY shellChanged) - Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) - Q_PROPERTY(QWaylandSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) - Q_PROPERTY(QPoint position READ position) - -public: - QWaylandXdgPopup(); - QWaylandXdgPopup(QWaylandXdgShell *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, - const QPoint &position, const QWaylandResource &resource); - - Qt::WindowType windowType() const override { return Qt::WindowType::Popup; } - - Q_INVOKABLE void initialize(QWaylandXdgShell *shell, QWaylandSurface *surface, - QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource); - - QWaylandXdgShell *shell() const; - - QWaylandSurface *surface() const; - QWaylandSurface *parentSurface() const; - QPoint position() const; - - static const struct wl_interface *interface(); - static QByteArray interfaceName(); - static QWaylandSurfaceRole *role(); - static QWaylandXdgPopup *fromResource(::wl_resource *resource); - - Q_INVOKABLE void sendPopupDone(); - -#ifdef QT_WAYLAND_COMPOSITOR_QUICK - QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; -#endif - -Q_SIGNALS: - void shellChanged(); - void surfaceChanged(); - void parentSurfaceChanged(); - -private: - void initialize() override; -}; - -QT_END_NAMESPACE - -#endif /*QWAYLANDXDGSHELL_H*/ diff --git a/src/compositor/extensions/qwaylandxdgshell_p.h b/src/compositor/extensions/qwaylandxdgshell_p.h deleted file mode 100644 index d7244c704..000000000 --- a/src/compositor/extensions/qwaylandxdgshell_p.h +++ /dev/null @@ -1,183 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDXDGSHELL_P_H -#define QWAYLANDXDGSHELL_P_H - -#include -#include - -#include - -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -QT_BEGIN_NAMESPACE - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellPrivate - : public QWaylandCompositorExtensionPrivate - , public QtWaylandServer::xdg_shell -{ - Q_DECLARE_PUBLIC(QWaylandXdgShell) -public: - QWaylandXdgShellPrivate(); - void ping(Resource *resource, uint32_t serial); - void registerSurface(QWaylandXdgSurface *xdgSurface); - void unregisterXdgSurface(QWaylandXdgSurface *xdgSurface); - void registerXdgPopup(QWaylandXdgPopup *xdgPopup); - void unregisterXdgPopup(QWaylandXdgPopup *xdgPopup); - static QWaylandXdgShellPrivate *get(QWaylandXdgShell *xdgShell) { return xdgShell->d_func(); } - bool isValidPopupParent(QWaylandSurface *parentSurface) const; - QWaylandXdgPopup *topmostPopupForClient(struct wl_client* client) const; - - QSet m_pings; - QMultiMap m_xdgSurfaces; - QMultiMap m_xdgPopups; - - QWaylandXdgSurface *xdgSurfaceFromSurface(QWaylandSurface *surface); - -protected: - void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE; - void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, - struct ::wl_resource *surface) Q_DECL_OVERRIDE; - void xdg_shell_use_unstable_version(Resource *resource, int32_t version) Q_DECL_OVERRIDE; - void xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, struct ::wl_resource *surface, - struct ::wl_resource *parent, struct ::wl_resource *seatResource, - uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; - void xdg_shell_pong(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; -}; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfacePrivate - : public QWaylandCompositorExtensionPrivate - , public QtWaylandServer::xdg_surface -{ - Q_DECLARE_PUBLIC(QWaylandXdgSurface) -public: - QWaylandXdgSurfacePrivate(); - static QWaylandXdgSurfacePrivate *get(QWaylandXdgSurface *xdgSurface) { return xdgSurface->d_func(); } - - enum WindowType { - UnknownWindowType, - TopLevelWindowType, - TransientWindowType - }; - - struct ConfigureEvent { - QVector states; - QSize size; - uint serial; - }; - - void handleFocusLost(); - void handleFocusReceived(); - QRect calculateFallbackWindowGeometry() const; - void updateFallbackWindowGeometry(); - -private: - QWaylandXdgShell *m_xdgShell; - QWaylandSurface *m_surface; - QWaylandXdgSurface *m_parentSurface; - - WindowType m_windowType; - - QString m_title; - QString m_appId; - QRect m_windowGeometry; - bool m_unsetWindowGeometry; - - QList m_pendingConfigures; - ConfigureEvent m_lastAckedConfigure; - ConfigureEvent lastSentConfigure() const { return m_pendingConfigures.empty() ? m_lastAckedConfigure : m_pendingConfigures.first(); } - - void xdg_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - - void xdg_surface_destroy(Resource *resource) Q_DECL_OVERRIDE; - void xdg_surface_move(Resource *resource, struct ::wl_resource *seat, - uint32_t serial) Q_DECL_OVERRIDE; - void xdg_surface_resize(Resource *resource, struct ::wl_resource *seat, uint32_t serial, - uint32_t edges) Q_DECL_OVERRIDE; - void xdg_surface_set_maximized(Resource *resource) Q_DECL_OVERRIDE; - void xdg_surface_unset_maximized(Resource *resource) Q_DECL_OVERRIDE; - void xdg_surface_set_fullscreen(Resource *resource, - struct ::wl_resource *output) Q_DECL_OVERRIDE; - void xdg_surface_unset_fullscreen(Resource *resource) Q_DECL_OVERRIDE; - void xdg_surface_set_minimized(Resource *resource) Q_DECL_OVERRIDE; - void xdg_surface_set_parent(Resource *resource, struct ::wl_resource *parent) Q_DECL_OVERRIDE; - void xdg_surface_set_app_id(Resource *resource, const QString &app_id) Q_DECL_OVERRIDE; - void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seatResource, - uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; - void xdg_surface_ack_configure(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; - void xdg_surface_set_title(Resource *resource, const QString &title) Q_DECL_OVERRIDE; - void xdg_surface_set_window_geometry(Resource *resource, int32_t x, int32_t y, - int32_t width, int32_t height) Q_DECL_OVERRIDE; - - static QWaylandSurfaceRole s_role; -}; - -class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupPrivate - : public QWaylandCompositorExtensionPrivate - , public QtWaylandServer::xdg_popup -{ - Q_DECLARE_PUBLIC(QWaylandXdgPopup) - -public: - QWaylandXdgPopupPrivate(); - static QWaylandXdgPopupPrivate *get(QWaylandXdgPopup *xdgPopup) { return xdgPopup->d_func(); } - - QWaylandSurface *m_surface; - QWaylandSurface *m_parentSurface; - QWaylandXdgShell *m_xdgShell; - QPoint m_position; - - void xdg_popup_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; - void xdg_popup_destroy(xdg_popup::Resource *resource) Q_DECL_OVERRIDE; - - static QWaylandSurfaceRole s_role; -}; - -QT_END_NAMESPACE - -#endif // QWAYLANDXDGSHELL_P_H diff --git a/src/compositor/extensions/qwaylandxdgshellintegration.cpp b/src/compositor/extensions/qwaylandxdgshellintegration.cpp deleted file mode 100644 index 90c7a7b36..000000000 --- a/src/compositor/extensions/qwaylandxdgshellintegration.cpp +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qwaylandxdgshellintegration_p.h" - -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -namespace QtWayland { - -XdgShellIntegration::XdgShellIntegration(QWaylandQuickShellSurfaceItem *item) - : QWaylandQuickShellIntegration(item) - , m_item(item) - , m_xdgSurface(qobject_cast(item->shellSurface())) - , grabberState(GrabberState::Default) -{ - m_item->setSurface(m_xdgSurface->surface()); - connect(m_xdgSurface, &QWaylandXdgSurface::startMove, this, &XdgShellIntegration::handleStartMove); - connect(m_xdgSurface, &QWaylandXdgSurface::startResize, this, &XdgShellIntegration::handleStartResize); - connect(m_xdgSurface, &QWaylandXdgSurface::setMaximized, this, &XdgShellIntegration::handleSetMaximized); - connect(m_xdgSurface, &QWaylandXdgSurface::unsetMaximized, this, &XdgShellIntegration::handleUnsetMaximized); - connect(m_xdgSurface, &QWaylandXdgSurface::maximizedChanged, this, &XdgShellIntegration::handleMaximizedChanged); - connect(m_xdgSurface, &QWaylandXdgSurface::activatedChanged, this, &XdgShellIntegration::handleActivatedChanged); - connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellIntegration::handleSurfaceSizeChanged); -} - -bool XdgShellIntegration::mouseMoveEvent(QMouseEvent *event) -{ - if (grabberState == GrabberState::Resize) { - Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); - if (!resizeState.initialized) { - resizeState.initialMousePos = event->windowPos(); - resizeState.initialized = true; - return true; - } - QPointF delta = m_item->mapToSurface(event->windowPos() - resizeState.initialMousePos); - QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges); - m_xdgSurface->sendResizing(newSize); - } else if (grabberState == GrabberState::Move) { - Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); - QQuickItem *moveItem = m_item->moveItem(); - if (!moveState.initialized) { - moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); - moveState.initialized = true; - return true; - } - if (!moveItem->parentItem()) - return true; - QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->windowPos()); - moveItem->setPosition(parentPos - moveState.initialOffset); - } - return false; -} - -bool XdgShellIntegration::mouseReleaseEvent(QMouseEvent *event) -{ - Q_UNUSED(event); - - if (grabberState == GrabberState::Resize) { - m_xdgSurface->sendUnmaximized(); - grabberState = GrabberState::Default; - return true; - } else if (grabberState == GrabberState::Move) { - grabberState = GrabberState::Default; - return true; - } - return false; -} - -void XdgShellIntegration::handleStartMove(QWaylandSeat *seat) -{ - grabberState = GrabberState::Move; - moveState.seat = seat; - moveState.initialized = false; -} - -void XdgShellIntegration::handleStartResize(QWaylandSeat *seat, QWaylandXdgSurface::ResizeEdge edges) -{ - grabberState = GrabberState::Resize; - resizeState.seat = seat; - resizeState.resizeEdges = edges; - resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); - resizeState.initialPosition = m_item->moveItem()->position(); - resizeState.initialSurfaceSize = m_item->surface()->size(); - resizeState.initialized = false; -} - -void XdgShellIntegration::handleSetMaximized() -{ - maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); - maximizeState.initialPosition = m_item->moveItem()->position(); - - QWaylandOutput *output = m_item->view()->output(); - m_xdgSurface->sendMaximized(output->availableGeometry().size() / output->scaleFactor()); -} - -void XdgShellIntegration::handleUnsetMaximized() -{ - m_xdgSurface->sendUnmaximized(maximizeState.initialWindowSize); -} - -void XdgShellIntegration::handleMaximizedChanged() -{ - if (m_xdgSurface->maximized()) { - QWaylandOutput *output = m_item->view()->output(); - m_item->moveItem()->setPosition(output->position() + output->availableGeometry().topLeft()); - } else { - m_item->moveItem()->setPosition(maximizeState.initialPosition); - } -} - -void XdgShellIntegration::handleActivatedChanged() -{ - if (m_xdgSurface->activated()) - m_item->raise(); -} - -void XdgShellIntegration::handleSurfaceSizeChanged() -{ - if (grabberState == GrabberState::Resize) { - qreal x = resizeState.initialPosition.x(); - qreal y = resizeState.initialPosition.y(); - if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::TopEdge) - y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height(); - - if (resizeState.resizeEdges & QWaylandXdgSurface::ResizeEdge::LeftEdge) - x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); - m_item->moveItem()->setPosition(QPointF(x, y)); - } -} - -XdgPopupIntegration::XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item) - : QWaylandQuickShellIntegration (item) - , m_xdgPopup(qobject_cast(item->shellSurface())) - , m_xdgShell(QWaylandXdgPopupPrivate::get(m_xdgPopup)->m_xdgShell) -{ - item->setSurface(m_xdgPopup->surface()); - item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor())); - - QWaylandClient *client = m_xdgPopup->surface()->client(); - QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); }); - - connect(m_xdgPopup, &QWaylandXdgPopup::destroyed, this, &XdgPopupIntegration::handlePopupDestroyed); -} - -void XdgPopupIntegration::handlePopupDestroyed() -{ - QWaylandXdgShellPrivate *shellPrivate = QWaylandXdgShellPrivate::get(m_xdgShell); - auto popups = shellPrivate->m_xdgPopups; - if (popups.isEmpty()) - QWaylandQuickShellEventFilter::cancelFilter(); -} - -} - -QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellintegration_p.h b/src/compositor/extensions/qwaylandxdgshellintegration_p.h deleted file mode 100644 index 8a000ff6a..000000000 --- a/src/compositor/extensions/qwaylandxdgshellintegration_p.h +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtWaylandCompositor module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL3$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPLv3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or later as published by the Free -** Software Foundation and appearing in the file LICENSE.GPL included in -** the packaging of this file. Please review the following information to -** ensure the GNU General Public License version 2.0 requirements will be -** met: http://www.gnu.org/licenses/gpl-2.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QWAYLANDXDGSHELLINTEGRATION_H -#define QWAYLANDXDGSHELLINTEGRATION_H - -#include -#include - -QT_BEGIN_NAMESPACE - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -namespace QtWayland { - -class XdgShellIntegration : public QWaylandQuickShellIntegration -{ - Q_OBJECT -public: - XdgShellIntegration(QWaylandQuickShellSurfaceItem *item); - bool mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; - -private Q_SLOTS: - void handleStartMove(QWaylandSeat *seat); - void handleStartResize(QWaylandSeat *seat, QWaylandXdgSurface::ResizeEdge edges); - void handleSetMaximized(); - void handleUnsetMaximized(); - void handleMaximizedChanged(); - void handleActivatedChanged(); - void handleSurfaceSizeChanged(); - -private: - enum class GrabberState { - Default, - Resize, - Move - }; - QWaylandQuickShellSurfaceItem *m_item; - QWaylandXdgSurface *m_xdgSurface; - - GrabberState grabberState; - struct { - QWaylandSeat *seat; - QPointF initialOffset; - bool initialized; - } moveState; - - struct { - QWaylandSeat *seat; - QWaylandXdgSurface::ResizeEdge resizeEdges; - QSizeF initialWindowSize; - QPointF initialMousePos; - QPointF initialPosition; - QSize initialSurfaceSize; - bool initialized; - } resizeState; - - struct { - QSize initialWindowSize; - QPointF initialPosition; - } maximizeState; -}; - -class XdgPopupIntegration : public QWaylandQuickShellIntegration -{ - Q_OBJECT -public: - XdgPopupIntegration(QWaylandQuickShellSurfaceItem *item); - -private Q_SLOTS: - void handlePopupDestroyed(); - -private: - QWaylandXdgPopup *m_xdgPopup; - QWaylandXdgShell *m_xdgShell; -}; - -} - -QT_END_NAMESPACE - -#endif // QWAYLANDXDGSHELLINTEGRATION_H diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp new file mode 100644 index 000000000..284aa8b05 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp @@ -0,0 +1,1190 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandxdgshellv5.h" +#include "qwaylandxdgshellv5_p.h" + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK +#include "qwaylandxdgshellv5integration_p.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include + +QT_BEGIN_NAMESPACE + +QWaylandSurfaceRole QWaylandXdgSurfaceV5Private::s_role("xdg_surface"); +QWaylandSurfaceRole QWaylandXdgPopupV5Private::s_role("xdg_popup"); + +QWaylandXdgShellV5Private::QWaylandXdgShellV5Private() + : QWaylandCompositorExtensionPrivate() + , xdg_shell() +{ +} + +void QWaylandXdgShellV5Private::ping(Resource *resource, uint32_t serial) +{ + m_pings.insert(serial); + send_ping(resource->handle, serial); +} + +void QWaylandXdgShellV5Private::registerSurface(QWaylandXdgSurfaceV5 *xdgSurface) +{ + m_xdgSurfaces.insert(xdgSurface->surface()->client()->client(), xdgSurface); +} + +void QWaylandXdgShellV5Private::unregisterXdgSurface(QWaylandXdgSurfaceV5 *xdgSurface) +{ + auto xdgSurfacePrivate = QWaylandXdgSurfaceV5Private::get(xdgSurface); + if (!m_xdgSurfaces.remove(xdgSurfacePrivate->resource()->client(), xdgSurface)) + qWarning("%s Unexpected state. Can't find registered xdg surface\n", Q_FUNC_INFO); +} + +void QWaylandXdgShellV5Private::registerXdgPopup(QWaylandXdgPopupV5 *xdgPopup) +{ + m_xdgPopups.insert(xdgPopup->surface()->client()->client(), xdgPopup); +} + +void QWaylandXdgShellV5Private::unregisterXdgPopup(QWaylandXdgPopupV5 *xdgPopup) +{ + auto xdgPopupPrivate = QWaylandXdgPopupV5Private::get(xdgPopup); + if (!m_xdgPopups.remove(xdgPopupPrivate->resource()->client(), xdgPopup)) + qWarning("%s Unexpected state. Can't find registered xdg popup\n", Q_FUNC_INFO); +} + +bool QWaylandXdgShellV5Private::isValidPopupParent(QWaylandSurface *parentSurface) const +{ + QWaylandXdgPopupV5 *topmostPopup = topmostPopupForClient(parentSurface->client()->client()); + if (topmostPopup && topmostPopup->surface() != parentSurface) { + return false; + } + + QWaylandSurfaceRole *parentRole = parentSurface->role(); + if (parentRole != QWaylandXdgSurfaceV5::role() && parentRole != QWaylandXdgPopupV5::role()) { + return false; + } + + return true; +} + +QWaylandXdgPopupV5 *QWaylandXdgShellV5Private::topmostPopupForClient(wl_client *client) const +{ + QList clientPopups = m_xdgPopups.values(client); + return clientPopups.empty() ? nullptr : clientPopups.last(); +} + +QWaylandXdgSurfaceV5 *QWaylandXdgShellV5Private::xdgSurfaceFromSurface(QWaylandSurface *surface) +{ + Q_FOREACH (QWaylandXdgSurfaceV5 *xdgSurface, m_xdgSurfaces) { + if (surface == xdgSurface->surface()) + return xdgSurface; + } + return nullptr; +} + +void QWaylandXdgShellV5Private::xdg_shell_destroy(Resource *resource) +{ + if (!m_xdgSurfaces.values(resource->client()).empty()) + wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_DEFUNCT_SURFACES, + "xdg_shell was destroyed before children"); + + wl_resource_destroy(resource->handle); +} + +void QWaylandXdgShellV5Private::xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, + wl_resource *surface_res) +{ + Q_Q(QWaylandXdgShellV5); + QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); + + if (xdgSurfaceFromSurface(surface)) { + wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_ROLE, + "An active xdg_surface already exists for wl_surface@%d", + wl_resource_get_id(surface->resource())); + return; + } + + if (!surface->setRole(QWaylandXdgSurfaceV5::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) + return; + + QWaylandResource xdgSurfaceResource(wl_resource_create(resource->client(), &xdg_surface_interface, + wl_resource_get_version(resource->handle), id)); + + emit q->xdgSurfaceRequested(surface, xdgSurfaceResource); + + QWaylandXdgSurfaceV5 *xdgSurface = QWaylandXdgSurfaceV5::fromResource(xdgSurfaceResource.resource()); + if (!xdgSurface) { + // A QWaylandXdgSurfaceV5 was not created in response to the xdgSurfaceRequested signal, so we + // create one as fallback here instead. + xdgSurface = new QWaylandXdgSurfaceV5(q, surface, xdgSurfaceResource); + } + + registerSurface(xdgSurface); + emit q->xdgSurfaceCreated(xdgSurface); +} + +void QWaylandXdgShellV5Private::xdg_shell_use_unstable_version(Resource *resource, int32_t version) +{ + if (xdg_shell::version_current != version) { + wl_resource_post_error(resource->handle, WL_DISPLAY_ERROR_INVALID_OBJECT, + "incompatible version, server is %d, but client wants %d", + xdg_shell::version_current, version); + } +} + +void QWaylandXdgShellV5Private::xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, + wl_resource *surface_res, wl_resource *parent, + wl_resource *seatResource, uint32_t serial, + int32_t x, int32_t y) +{ + Q_UNUSED(serial); + Q_Q(QWaylandXdgShellV5); + QWaylandSurface *surface = QWaylandSurface::fromResource(surface_res); + QWaylandSurface *parentSurface = QWaylandSurface::fromResource(parent); + + if (!isValidPopupParent(parentSurface)) { + wl_resource_post_error(resource->handle, XDG_SHELL_ERROR_INVALID_POPUP_PARENT, + "the client specified an invalid popup parent surface"); + return; + } + + if (!surface->setRole(QWaylandXdgPopupV5::role(), resource->handle, XDG_SHELL_ERROR_ROLE)) { + return; + } + + QWaylandResource xdgPopupResource (wl_resource_create(resource->client(), &xdg_popup_interface, + wl_resource_get_version(resource->handle), id)); + QWaylandSeat *seat = QWaylandSeat::fromSeatResource(seatResource); + QPoint position(x, y); + emit q->xdgPopupRequested(surface, parentSurface, seat, position, xdgPopupResource); + + QWaylandXdgPopupV5 *xdgPopup = QWaylandXdgPopupV5::fromResource(xdgPopupResource.resource()); + if (!xdgPopup) { + // A QWaylandXdgPopupV5 was not created in response to the xdgPopupRequested signal, so we + // create one as fallback here instead. + xdgPopup = new QWaylandXdgPopupV5(q, surface, parentSurface, position, xdgPopupResource); + } + + registerXdgPopup(xdgPopup); + emit q->xdgPopupCreated(xdgPopup); +} + +void QWaylandXdgShellV5Private::xdg_shell_pong(Resource *resource, uint32_t serial) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgShellV5); + if (m_pings.remove(serial)) + emit q->pong(serial); + else + qWarning("Received an unexpected pong!"); +} + +QWaylandXdgSurfaceV5Private::QWaylandXdgSurfaceV5Private() + : QWaylandCompositorExtensionPrivate() + , xdg_surface() + , m_surface(nullptr) + , m_parentSurface(nullptr) + , m_windowType(UnknownWindowType) + , m_unsetWindowGeometry(true) + , m_lastAckedConfigure({{}, QSize(0, 0), 0}) +{ +} + +void QWaylandXdgSurfaceV5Private::handleFocusLost() +{ + Q_Q(QWaylandXdgSurfaceV5); + QWaylandXdgSurfaceV5Private::ConfigureEvent current = lastSentConfigure(); + current.states.removeOne(QWaylandXdgSurfaceV5::State::ActivatedState); + q->sendConfigure(current.size, current.states); +} + +void QWaylandXdgSurfaceV5Private::handleFocusReceived() +{ + Q_Q(QWaylandXdgSurfaceV5); + + QWaylandXdgSurfaceV5Private::ConfigureEvent current = lastSentConfigure(); + if (!current.states.contains(QWaylandXdgSurfaceV5::State::ActivatedState)) { + current.states.push_back(QWaylandXdgSurfaceV5::State::ActivatedState); + } + + q->sendConfigure(current.size, current.states); +} + +QRect QWaylandXdgSurfaceV5Private::calculateFallbackWindowGeometry() const +{ + // TODO: The unset window geometry should include subsurfaces as well, so this solution + // won't work too well on those kinds of clients. + return QRect(QPoint(0, 0), m_surface->size() / m_surface->bufferScale()); +} + +void QWaylandXdgSurfaceV5Private::updateFallbackWindowGeometry() +{ + Q_Q(QWaylandXdgSurfaceV5); + if (!m_unsetWindowGeometry) + return; + + const QRect unsetGeometry = calculateFallbackWindowGeometry(); + if (unsetGeometry == m_windowGeometry) + return; + + m_windowGeometry = unsetGeometry; + emit q->windowGeometryChanged(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + QWaylandXdgShellV5Private::get(m_xdgShell)->unregisterXdgSurface(q); + delete q; +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_destroy(Resource *resource) +{ + wl_resource_destroy(resource->handle); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_move(Resource *resource, wl_resource *seat, uint32_t serial) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + Q_Q(QWaylandXdgSurfaceV5); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); + emit q->startMove(input_device); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_resize(Resource *resource, wl_resource *seat, + uint32_t serial, uint32_t edges) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + + Q_Q(QWaylandXdgSurfaceV5); + QWaylandSeat *input_device = QWaylandSeat::fromSeatResource(seat); + emit q->startResize(input_device, QWaylandXdgSurfaceV5::ResizeEdge(edges)); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_maximized(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + emit q->setMaximized(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_unset_maximized(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + emit q->unsetMaximized(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_fullscreen(Resource *resource, wl_resource *output_res) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + QWaylandOutput *output = output_res ? QWaylandOutput::fromResource(output_res) : nullptr; + emit q->setFullscreen(output); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_unset_fullscreen(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + emit q->unsetFullscreen(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_minimized(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + emit q->setMinimized(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_parent(Resource *resource, wl_resource *parent) +{ + Q_UNUSED(resource); + QWaylandXdgSurfaceV5 *parentSurface = nullptr; + if (parent) { + parentSurface = static_cast( + QWaylandXdgSurfaceV5Private::Resource::fromResource(parent)->xdg_surface_object)->q_func(); + } + + Q_Q(QWaylandXdgSurfaceV5); + + if (m_parentSurface != parentSurface) { + m_parentSurface = parentSurface; + emit q->parentSurfaceChanged(); + } + + if (m_parentSurface && m_windowType != TransientWindowType) { + // There's a parent now, which means the surface is transient + m_windowType = TransientWindowType; + emit q->setTransient(); + } else if (!m_parentSurface && m_windowType != TopLevelWindowType) { + // When the surface has no parent it is toplevel + m_windowType = TopLevelWindowType; + emit q->setTopLevel(); + } +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_app_id(Resource *resource, const QString &app_id) +{ + Q_UNUSED(resource); + if (app_id == m_appId) + return; + Q_Q(QWaylandXdgSurfaceV5); + m_appId = app_id; + emit q->appIdChanged(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_show_window_menu(Resource *resource, wl_resource *seatResource, + uint32_t serial, int32_t x, int32_t y) +{ + Q_UNUSED(resource); + Q_UNUSED(serial); + QPoint position(x, y); + auto seat = QWaylandSeat::fromSeatResource(seatResource); + Q_Q(QWaylandXdgSurfaceV5); + emit q->showWindowMenu(seat, position); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_ack_configure(Resource *resource, uint32_t serial) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgSurfaceV5); + + ConfigureEvent config; + Q_FOREVER { + if (m_pendingConfigures.empty()) { + qWarning("Received an unexpected ack_configure!"); + return; + } + + config = m_pendingConfigures.takeFirst(); + + if (config.serial == serial) + break; + } + + QVector changedStates; + std::set_symmetric_difference( + m_lastAckedConfigure.states.begin(), m_lastAckedConfigure.states.end(), + config.states.begin(), config.states.end(), + std::back_inserter(changedStates)); + + m_lastAckedConfigure = config; + + if (!changedStates.empty()) { + Q_FOREACH (uint state, changedStates) { + switch (state) { + case QWaylandXdgSurfaceV5::State::MaximizedState: + emit q->maximizedChanged(); + break; + case QWaylandXdgSurfaceV5::State::FullscreenState: + emit q->fullscreenChanged(); + break; + case QWaylandXdgSurfaceV5::State::ResizingState: + emit q->resizingChanged(); + break; + case QWaylandXdgSurfaceV5::State::ActivatedState: + emit q->activatedChanged(); + break; + } + } + emit q->statesChanged(); + } + + emit q->ackConfigure(serial); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_title(Resource *resource, const QString &title) +{ + Q_UNUSED(resource); + if (title == m_title) + return; + Q_Q(QWaylandXdgSurfaceV5); + m_title = title; + emit q->titleChanged(); +} + +void QWaylandXdgSurfaceV5Private::xdg_surface_set_window_geometry(Resource *resource, + int32_t x, int32_t y, + int32_t width, int32_t height) +{ + Q_UNUSED(resource); + + if (width <= 0 || height <= 0) { + qWarning() << "Invalid (non-positive) dimensions received in set_window_geometry"; + return; + } + + m_unsetWindowGeometry = false; + + QRect geometry(x, y, width, height); + + Q_Q(QWaylandXdgSurfaceV5); + if ((q->maximized() || q->fullscreen()) && m_lastAckedConfigure.size != geometry.size()) + qWarning() << "Client window geometry did not obey last acked configure"; + + if (geometry == m_windowGeometry) + return; + + m_windowGeometry = geometry; + emit q->windowGeometryChanged(); +} + +QWaylandXdgPopupV5Private::QWaylandXdgPopupV5Private() + : QWaylandCompositorExtensionPrivate() + , xdg_popup() + , m_surface(nullptr) + , m_parentSurface(nullptr) + , m_xdgShell(nullptr) +{ +} + +void QWaylandXdgPopupV5Private::xdg_popup_destroy_resource(Resource *resource) +{ + Q_UNUSED(resource); + Q_Q(QWaylandXdgPopupV5); + QWaylandXdgShellV5Private::get(m_xdgShell)->unregisterXdgPopup(q); + delete q; +} + +void QWaylandXdgPopupV5Private::xdg_popup_destroy(Resource *resource) +{ + //TODO: post error if not topmost popup + wl_resource_destroy(resource->handle); +} + +/*! + * Constructs a QWaylandXdgShellV5 object. + */ +QWaylandXdgShellV5::QWaylandXdgShellV5() + : QWaylandCompositorExtensionTemplate(*new QWaylandXdgShellV5Private()) +{ } + +/*! + * Constructs a QWaylandXdgShellV5 object for the provided \a compositor. + */ +QWaylandXdgShellV5::QWaylandXdgShellV5(QWaylandCompositor *compositor) + : QWaylandCompositorExtensionTemplate(compositor, *new QWaylandXdgShellV5Private()) +{ } + +/*! + * Initializes the shell extension. + */ +void QWaylandXdgShellV5::initialize() +{ + Q_D(QWaylandXdgShellV5); + QWaylandCompositorExtensionTemplate::initialize(); + QWaylandCompositor *compositor = static_cast(extensionContainer()); + if (!compositor) { + qWarning() << "Failed to find QWaylandCompositor when initializing QWaylandXdgShellV5"; + return; + } + d->init(compositor->display(), 1); + + handleSeatChanged(compositor->defaultSeat(), nullptr); + + connect(compositor, &QWaylandCompositor::defaultSeatChanged, + this, &QWaylandXdgShellV5::handleSeatChanged); +} + +/*! + * Returns the Wayland interface for the QWaylandXdgShellV5. + */ +const struct wl_interface *QWaylandXdgShellV5::interface() +{ + return QWaylandXdgShellV5Private::interface(); +} + +QByteArray QWaylandXdgShellV5::interfaceName() +{ + return QWaylandXdgShellV5Private::interfaceName(); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgSurface::ping() + * + * Sends a ping event to the client. If the client replies to the event the + * \a pong signal will be emitted. + */ + +/*! + * Sends a ping event to the client. If the client replies to the event the + * \a pong signal will be emitted. + */ +uint QWaylandXdgShellV5::ping(QWaylandClient *client) +{ + Q_D(QWaylandXdgShellV5); + + QWaylandCompositor *compositor = static_cast(extensionContainer()); + Q_ASSERT(compositor); + + uint32_t serial = compositor->nextSerial(); + + QWaylandXdgShellV5Private::Resource *clientResource = d->resourceMap().value(client->client(), nullptr); + Q_ASSERT(clientResource); + + d->ping(clientResource, serial); + return serial; +} + +void QWaylandXdgShellV5::closeAllPopups() +{ + Q_D(QWaylandXdgShellV5); + Q_FOREACH (struct wl_client *client, d->m_xdgPopups.keys()) { + QList popups = d->m_xdgPopups.values(client); + std::reverse(popups.begin(), popups.end()); + Q_FOREACH (QWaylandXdgPopupV5 *currentTopmostPopup, popups) { + currentTopmostPopup->sendPopupDone(); + } + } +} + +void QWaylandXdgShellV5::handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat) +{ + if (oldSeat != nullptr) { + disconnect(oldSeat, &QWaylandSeat::keyboardFocusChanged, + this, &QWaylandXdgShellV5::handleFocusChanged); + } + + if (newSeat != nullptr) { + connect(newSeat, &QWaylandSeat::keyboardFocusChanged, + this, &QWaylandXdgShellV5::handleFocusChanged); + } +} + +void QWaylandXdgShellV5::handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface) +{ + Q_D(QWaylandXdgShellV5); + + QWaylandXdgSurfaceV5 *newXdgSurface = d->xdgSurfaceFromSurface(newSurface); + QWaylandXdgSurfaceV5 *oldXdgSurface = d->xdgSurfaceFromSurface(oldSurface); + + if (newXdgSurface) + QWaylandXdgSurfaceV5Private::get(newXdgSurface)->handleFocusReceived(); + + if (oldXdgSurface) + QWaylandXdgSurfaceV5Private::get(oldXdgSurface)->handleFocusLost(); +} + +/*! + * \class QWaylandXdgSurfaceV5 + * \inmodule QtWaylandCompositor + * \preliminary + * \brief The QWaylandXdgSurfaceV5 class provides desktop-style compositor-specific features to an xdg surface. + * + * This class is part of the QWaylandXdgShellV5 extension and provides a way to + * extend the functionality of an existing QWaylandSurface with features + * specific to desktop-style compositors, such as resizing and moving the + * surface. + * + * It corresponds to the Wayland interface xdg_surface. + */ + +/*! + * \qmlsignal QtWaylandCompositor::XdgSurface::setTopLevel() + * + * This signal is emitted when the parent surface is unset, effectively + * making the window top level. + */ + +/*! + * \qmlsignal QtWaylandCompositor::XdgSurface::setTransient() + * + * This signal is emitted when the parent surface is set, effectively + * making the window transient. + */ + +/*! + * Constructs a QWaylandXdgSurfaceV5. + */ +QWaylandXdgSurfaceV5::QWaylandXdgSurfaceV5() + : QWaylandShellSurfaceTemplate(*new QWaylandXdgSurfaceV5Private) +{ +} + +/*! + * Constructs a QWaylandXdgSurfaceV5 for \a surface and initializes it with the + * given \a xdgShell, \a surface, and resource \a res. + */ +QWaylandXdgSurfaceV5::QWaylandXdgSurfaceV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, const QWaylandResource &res) + : QWaylandShellSurfaceTemplate(*new QWaylandXdgSurfaceV5Private) +{ + initialize(xdgShell, surface, res); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgSurface::initialize(object surface, object client, int id) + * + * Initializes the XdgSurface, associating it with the given \a surface, + * \a client, and \a id. + */ + +/*! + * Initializes the QWaylandXdgSurfaceV5, associating it with the given \a xdgShell, \a surface + * and \a resource. + */ +void QWaylandXdgSurfaceV5::initialize(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, const QWaylandResource &resource) +{ + Q_D(QWaylandXdgSurfaceV5); + d->m_xdgShell = xdgShell; + d->m_surface = surface; + d->init(resource.resource()); + setExtensionContainer(surface); + d->m_windowGeometry = d->calculateFallbackWindowGeometry(); + connect(surface, &QWaylandSurface::sizeChanged, this, &QWaylandXdgSurfaceV5::handleSurfaceSizeChanged); + connect(surface, &QWaylandSurface::bufferScaleChanged, this, &QWaylandXdgSurfaceV5::handleBufferScaleChanged); + emit shellChanged(); + emit surfaceChanged(); + emit windowGeometryChanged(); + QWaylandCompositorExtension::initialize(); +} + +/*! + * \internal + */ +void QWaylandXdgSurfaceV5::initialize() +{ + QWaylandCompositorExtension::initialize(); +} + +QList QWaylandXdgSurfaceV5::statesAsInts() const +{ + QList list; + Q_FOREACH (uint state, states()) { + list << static_cast(state); + } + return list; +} + +void QWaylandXdgSurfaceV5::handleSurfaceSizeChanged() +{ + Q_D(QWaylandXdgSurfaceV5); + d->updateFallbackWindowGeometry(); +} + +void QWaylandXdgSurfaceV5::handleBufferScaleChanged() +{ + Q_D(QWaylandXdgSurfaceV5); + d->updateFallbackWindowGeometry(); +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::shell + * + * This property holds the shell associated with this XdgSurface. + */ + +/*! + * \property QWaylandXdgSurfaceV5::shell + * + * This property holds the shell associated with this QWaylandXdgSurfaceV5. + */ +QWaylandXdgShellV5 *QWaylandXdgSurfaceV5::shell() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_xdgShell; +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::surface + * + * This property holds the surface associated with this XdgSurface. + */ + +/*! + * \property QWaylandXdgSurfaceV5::surface + * + * This property holds the surface associated with this QWaylandXdgSurfaceV5. + */ +QWaylandSurface *QWaylandXdgSurfaceV5::surface() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_surface; +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgSurface::parentSurface + * + * This property holds the XdgSurface parent of this XdgSurface. + * When a parent surface is set, the parentSurfaceChanged() signal + * is guaranteed to be emitted before setTopLevel() and setTransient(). + * + * \sa QtWaylandCompositor::XdgSurface::setTopLevel() + * \sa QtWaylandCompositor::XdgSurface::setTransient() + */ + +/*! + * \property QWaylandXdgSurfaceV5::parentSurface + * + * This property holds the XdgSurface parent of this XdgSurface. + * When a parent surface is set, the parentSurfaceChanged() signal + * is guaranteed to be emitted before setTopLevel() and setTransient(). + * + * \sa QWaylandXdgSurfaceV5::setTopLevel() + * \sa QWaylandXdgSurfaceV5::setTransient() + */ +QWaylandXdgSurfaceV5 *QWaylandXdgSurfaceV5::parentSurface() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_parentSurface; +} + +/*! + * \qmlproperty string QtWaylandCompositor::XdgSurface::title + * + * This property holds the title of the XdgSurface. + */ + +/*! + * \property QWaylandXdgSurfaceV5::title + * + * This property holds the title of the QWaylandXdgSurfaceV5. + */ +QString QWaylandXdgSurfaceV5::title() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_title; +} + +/*! + * \property QWaylandXdgSurfaceV5::appId + * + * This property holds the app id of the QWaylandXdgSurfaceV5. + */ +QString QWaylandXdgSurfaceV5::appId() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_appId; +} + +/*! + * \property QWaylandXdgSurfaceV5::windowGeometry + * + * This property holds the window geometry of the QWaylandXdgSurfaceV5. The window + * geometry describes the window's visible bounds from the user's perspective. + * The geometry includes title bars and borders if drawn by the client, but + * excludes drop shadows. It is meant to be used for aligning and tiling + * windows. + */ +QRect QWaylandXdgSurfaceV5::windowGeometry() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_windowGeometry; +} + +/*! + * \property QWaylandXdgSurfaceV5::states + * + * This property holds the last states the client acknowledged for this QWaylandXdgSurfaceV5. + */ +QVector QWaylandXdgSurfaceV5::states() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_lastAckedConfigure.states; +} + +bool QWaylandXdgSurfaceV5::maximized() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::MaximizedState); +} + +bool QWaylandXdgSurfaceV5::fullscreen() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::FullscreenState); +} + +bool QWaylandXdgSurfaceV5::resizing() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::ResizingState); +} + +bool QWaylandXdgSurfaceV5::activated() const +{ + Q_D(const QWaylandXdgSurfaceV5); + return d->m_lastAckedConfigure.states.contains(QWaylandXdgSurfaceV5::State::ActivatedState); +} + +/*! + * Returns the Wayland interface for the QWaylandXdgSurfaceV5. + */ +const wl_interface *QWaylandXdgSurfaceV5::interface() +{ + return QWaylandXdgSurfaceV5Private::interface(); +} + +QByteArray QWaylandXdgSurfaceV5::interfaceName() +{ + return QWaylandXdgSurfaceV5Private::interfaceName(); +} + +/*! + * Returns the surface role for the QWaylandXdgSurfaceV5. + */ +QWaylandSurfaceRole *QWaylandXdgSurfaceV5::role() +{ + return &QWaylandXdgSurfaceV5Private::s_role; +} + +/*! + * Returns the QWaylandXdgSurfaceV5 corresponding to the \a resource. + */ +QWaylandXdgSurfaceV5 *QWaylandXdgSurfaceV5::fromResource(wl_resource *resource) +{ + auto xsResource = QWaylandXdgSurfaceV5Private::Resource::fromResource(resource); + if (!xsResource) + return nullptr; + return static_cast(xsResource->xdg_surface_object)->q_func(); +} + +QSize QWaylandXdgSurfaceV5::sizeForResize(const QSizeF &size, const QPointF &delta, + QWaylandXdgSurfaceV5::ResizeEdge edge) +{ + qreal width = size.width(); + qreal height = size.height(); + if (edge & LeftEdge) + width -= delta.x(); + else if (edge & RightEdge) + width += delta.x(); + + if (edge & TopEdge) + height -= delta.y(); + else if (edge & BottomEdge) + height += delta.y(); + + return QSizeF(width, height).toSize(); +} + +/*! + * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, List) + * + * Sends a configure event to the client. Known states are enumerated in XdgSurface::State + */ + +/*! + * Sends a configure event to the client. Known states are enumerated in QWaylandXdgSurfaceV5::State + */ +uint QWaylandXdgSurfaceV5::sendConfigure(const QSize &size, const QVector &states) +{ + Q_D(QWaylandXdgSurfaceV5); + auto statesBytes = QByteArray::fromRawData((char *)states.data(), states.size() * sizeof(State)); + QWaylandCompositor *compositor = static_cast(extensionContainer()); + Q_ASSERT(compositor); + uint32_t serial = compositor->nextSerial(); + d->m_pendingConfigures.append(QWaylandXdgSurfaceV5Private::ConfigureEvent{states, size, serial}); + d->send_configure(size.width(), size.height(), statesBytes, serial); + return serial; +} + +uint QWaylandXdgSurfaceV5::sendConfigure(const QSize &size, const QVector &states) +{ + QVector asUints; + Q_FOREACH (QWaylandXdgSurfaceV5::State state, states) { + asUints << state; + } + return sendConfigure(size, asUints); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgSurface::sendClose() + * + * Sends a close event to the client. + */ + +/*! + * Sends a close event to the client. + */ +void QWaylandXdgSurfaceV5::sendClose() +{ + Q_D(QWaylandXdgSurfaceV5); + d->send_close(); +} + +uint QWaylandXdgSurfaceV5::sendMaximized(const QSize &size) +{ + Q_D(QWaylandXdgSurfaceV5); + QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure(); + + if (!conf.states.contains(QWaylandXdgSurfaceV5::State::MaximizedState)) + conf.states.append(QWaylandXdgSurfaceV5::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::FullscreenState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::ResizingState); + + return sendConfigure(size, conf.states); +} + +uint QWaylandXdgSurfaceV5::sendUnmaximized(const QSize &size) +{ + Q_D(QWaylandXdgSurfaceV5); + QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure(); + + conf.states.removeOne(QWaylandXdgSurfaceV5::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::FullscreenState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::ResizingState); + + return sendConfigure(size, conf.states); +} + +uint QWaylandXdgSurfaceV5::sendFullscreen(const QSize &size) +{ + Q_D(QWaylandXdgSurfaceV5); + QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure(); + + if (!conf.states.contains(QWaylandXdgSurfaceV5::State::FullscreenState)) + conf.states.append(QWaylandXdgSurfaceV5::State::FullscreenState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::ResizingState); + + return sendConfigure(size, conf.states); +} + +uint QWaylandXdgSurfaceV5::sendResizing(const QSize &maxSize) +{ + Q_D(QWaylandXdgSurfaceV5); + QWaylandXdgSurfaceV5Private::ConfigureEvent conf = d->lastSentConfigure(); + + if (!conf.states.contains(QWaylandXdgSurfaceV5::State::ResizingState)) + conf.states.append(QWaylandXdgSurfaceV5::State::ResizingState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::MaximizedState); + conf.states.removeOne(QWaylandXdgSurfaceV5::State::FullscreenState); + + return sendConfigure(maxSize, conf.states); +} + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK +QWaylandQuickShellIntegration *QWaylandXdgSurfaceV5::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::XdgShellV5Integration(item); +} +#endif + +/*! + * \class QWaylandXdgPopupV5 + * \inmodule QtWaylandCompositor + * \preliminary + * \brief The QWaylandXdgPopupV5 class provides menus for an xdg surface + * + * This class is part of the QWaylandXdgShellV5 extension and provides a way to + * extend the functionality of an existing QWaylandSurface with features + * specific to desktop-style menus for an xdg surface. + * + * It corresponds to the Wayland interface xdg_popup. + */ + +/*! + * Constructs a QWaylandXdgPopupV5. + */ +QWaylandXdgPopupV5::QWaylandXdgPopupV5() + : QWaylandShellSurfaceTemplate(*new QWaylandXdgPopupV5Private) +{ +} + +/*! + * Constructs a QWaylandXdgPopupV5 for \a surface and initializes it with the + * given \a parentSurface and \a resource. + */ +QWaylandXdgPopupV5::QWaylandXdgPopupV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, + QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource) + : QWaylandShellSurfaceTemplate(*new QWaylandXdgPopupV5Private) +{ + initialize(xdgShell, surface, parentSurface, position, resource); +} + +/*! + * \qmlmethod void QtWaylandCompositor::XdgPopup::initialize(object surface, object parentSurface, object resource) + * + * Initializes the xdg popup, associating it with the given \a shell, \a surface, + * \a parentSurface and \a resource. + */ + +/*! + * Initializes the QWaylandXdgPopupV5, associating it with the given \a shell \a surface, + * \a parentSurface and \a resource. + */ +void QWaylandXdgPopupV5::initialize(QWaylandXdgShellV5 *shell, QWaylandSurface *surface, QWaylandSurface *parentSurface, + const QPoint& position, const QWaylandResource &resource) +{ + Q_D(QWaylandXdgPopupV5); + d->m_surface = surface; + d->m_parentSurface = parentSurface; + d->m_xdgShell = shell; + d->m_position = position; + d->init(resource.resource()); + setExtensionContainer(surface); + emit shellChanged(); + emit surfaceChanged(); + emit parentSurfaceChanged(); + QWaylandCompositorExtension::initialize(); +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::shell + * + * This property holds the shell associated with this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopupV5::shell + * + * This property holds the shell associated with this QWaylandXdgPopupV5. + */ +QWaylandXdgShellV5 *QWaylandXdgPopupV5::shell() const +{ + Q_D(const QWaylandXdgPopupV5); + return d->m_xdgShell; +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::surface + * + * This property holds the surface associated with this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopupV5::surface + * + * This property holds the surface associated with this QWaylandXdgPopupV5. + */ +QWaylandSurface *QWaylandXdgPopupV5::surface() const +{ + Q_D(const QWaylandXdgPopupV5); + return d->m_surface; +} + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::parentSurface + * + * This property holds the surface associated with the parent of this XdgPopup. + */ + +/*! + * \property QWaylandXdgPopupV5::parentSurface + * + * This property holds the surface associated with the parent of this + * QWaylandXdgPopupV5. + */ +QWaylandSurface *QWaylandXdgPopupV5::parentSurface() const +{ + Q_D(const QWaylandXdgPopupV5); + return d->m_parentSurface; +} + + +/*! + * \qmlproperty object QtWaylandCompositor::XdgPopup::position + * + * This property holds the location of the upper left corner of the surface + * relative to the upper left corner of the parent surface, in surface local + * coordinates. + */ + +/*! + * \property QWaylandXdgPopupV5::position + * + * This property holds the location of the upper left corner of the surface + * relative to the upper left corner of the parent surface, in surface local + * coordinates. + */ +QPoint QWaylandXdgPopupV5::position() const +{ + Q_D(const QWaylandXdgPopupV5); + return d->m_position; +} + +/*! + * \internal + */ +void QWaylandXdgPopupV5::initialize() +{ + QWaylandCompositorExtension::initialize(); +} + +/*! + * Returns the Wayland interface for the QWaylandXdgPopupV5. + */ +const wl_interface *QWaylandXdgPopupV5::interface() +{ + return QWaylandXdgPopupV5Private::interface(); +} + +QByteArray QWaylandXdgPopupV5::interfaceName() +{ + return QWaylandXdgPopupV5Private::interfaceName(); +} + +/*! + * Returns the surface role for the QWaylandXdgPopupV5. + */ +QWaylandSurfaceRole *QWaylandXdgPopupV5::role() +{ + return &QWaylandXdgPopupV5Private::s_role; +} + +QWaylandXdgPopupV5 *QWaylandXdgPopupV5::fromResource(wl_resource *resource) +{ + auto popupResource = QWaylandXdgPopupV5Private::Resource::fromResource(resource); + if (!popupResource) + return nullptr; + return static_cast(popupResource->xdg_popup_object)->q_func(); +} + +void QWaylandXdgPopupV5::sendPopupDone() +{ + Q_D(QWaylandXdgPopupV5); + d->send_popup_done(); +} + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK +QWaylandQuickShellIntegration *QWaylandXdgPopupV5::createIntegration(QWaylandQuickShellSurfaceItem *item) +{ + return new QtWayland::XdgPopupV5Integration(item); +} +#endif + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellv5.h b/src/compositor/extensions/qwaylandxdgshellv5.h new file mode 100644 index 000000000..c99f36282 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellv5.h @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGSHELLV5_H +#define QWAYLANDXDGSHELLV5_H + +#include +#include +#include + +#include + +struct wl_resource; + +QT_BEGIN_NAMESPACE + +class QWaylandXdgShellV5Private; +class QWaylandXdgSurfaceV5; +class QWaylandXdgSurfaceV5Private; +class QWaylandXdgPopupV5; +class QWaylandXdgPopupV5Private; + +class QWaylandSurface; +class QWaylandSurfaceRole; +class QWaylandSeat; +class QWaylandOutput; +class QWaylandClient; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellV5 : public QWaylandCompositorExtensionTemplate +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgShellV5) +public: + QWaylandXdgShellV5(); + QWaylandXdgShellV5(QWaylandCompositor *compositor); + + void initialize() Q_DECL_OVERRIDE; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + +public Q_SLOTS: + uint ping(QWaylandClient *client); + void closeAllPopups(); + +Q_SIGNALS: + void xdgSurfaceRequested(QWaylandSurface *surface, const QWaylandResource &resource); + void xdgSurfaceCreated(QWaylandXdgSurfaceV5 *xdgSurface); + void xdgPopupCreated(QWaylandXdgPopupV5 *xdgPopup); + void xdgPopupRequested(QWaylandSurface *surface, QWaylandSurface *parent, QWaylandSeat *seat, const QPoint &position, const QWaylandResource &resource); + void pong(uint serial); + +private Q_SLOTS: + void handleSeatChanged(QWaylandSeat *newSeat, QWaylandSeat *oldSeat); + void handleFocusChanged(QWaylandSurface *newSurface, QWaylandSurface *oldSurface); + +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfaceV5 : public QWaylandShellSurfaceTemplate +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgSurfaceV5) + Q_PROPERTY(QWaylandXdgShellV5 *shell READ shell NOTIFY shellChanged) + Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandXdgSurfaceV5 *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) + Q_PROPERTY(QString title READ title NOTIFY titleChanged) + Q_PROPERTY(QString appId READ appId NOTIFY appIdChanged) + Q_PROPERTY(QRect windowGeometry READ windowGeometry NOTIFY windowGeometryChanged) + + Q_PROPERTY(QList states READ statesAsInts NOTIFY statesChanged) + Q_PROPERTY(bool maximized READ maximized NOTIFY maximizedChanged) + Q_PROPERTY(bool fullscreen READ fullscreen NOTIFY fullscreenChanged) + Q_PROPERTY(bool resizing READ resizing NOTIFY resizingChanged) + Q_PROPERTY(bool activated READ activated NOTIFY activatedChanged) + +public: + enum State : uint { + MaximizedState = 1, + FullscreenState = 2, + ResizingState = 3, + ActivatedState = 4 + }; + Q_ENUM(State) + + enum ResizeEdge : uint { + NoneEdge = 0, + TopEdge = 1, + BottomEdge = 2, + LeftEdge = 4, + TopLeftEdge = 5, + BottomLeftEdge = 6, + RightEdge = 8, + TopRightEdge = 9, + BottomRightEdge = 10 + }; + Q_ENUM(ResizeEdge) + + QWaylandXdgSurfaceV5(); + QWaylandXdgSurfaceV5(QWaylandXdgShellV5* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource); + + Q_INVOKABLE void initialize(QWaylandXdgShellV5* xdgShell, QWaylandSurface *surface, const QWaylandResource &resource); + + QString title() const; + QString appId() const; + QRect windowGeometry() const; + QVector states() const; + bool maximized() const; + bool fullscreen() const; + bool resizing() const; + bool activated() const; + + QWaylandXdgShellV5 *shell() const; + + QWaylandSurface *surface() const; + QWaylandXdgSurfaceV5 *parentSurface() const; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); + static QWaylandXdgSurfaceV5 *fromResource(::wl_resource *resource); + + Q_INVOKABLE QSize sizeForResize(const QSizeF &size, const QPointF &delta, ResizeEdge edge); + Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector &states); + Q_INVOKABLE uint sendConfigure(const QSize &size, const QVector &states); + Q_INVOKABLE void sendClose(); + + Q_INVOKABLE uint sendMaximized(const QSize &size); + Q_INVOKABLE uint sendUnmaximized(const QSize &size = QSize(0, 0)); + Q_INVOKABLE uint sendFullscreen(const QSize &size); + Q_INVOKABLE uint sendResizing(const QSize &maxSize); + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif + +Q_SIGNALS: + void shellChanged(); + void surfaceChanged(); + void titleChanged(); + void windowGeometryChanged(); + void appIdChanged(); + void parentSurfaceChanged(); + + void statesChanged(); + void maximizedChanged(); + void fullscreenChanged(); + void resizingChanged(); + void activatedChanged(); + + void showWindowMenu(QWaylandSeat *seat, const QPoint &localSurfacePosition); + void startMove(QWaylandSeat *seat); + void startResize(QWaylandSeat *seat, ResizeEdge edges); + void setTopLevel(); + void setTransient(); + void setMaximized(); + void unsetMaximized(); + void setFullscreen(QWaylandOutput *output); + void unsetFullscreen(); + void setMinimized(); + void ackConfigure(uint serial); + +private: + void initialize() override; + QList statesAsInts() const; + +private Q_SLOTS: + void handleSurfaceSizeChanged(); + void handleBufferScaleChanged(); +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupV5 : public QWaylandShellSurfaceTemplate +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QWaylandXdgPopupV5) + Q_PROPERTY(QWaylandXdgShellV5 *shell READ shell NOTIFY shellChanged) + Q_PROPERTY(QWaylandSurface *surface READ surface NOTIFY surfaceChanged) + Q_PROPERTY(QWaylandSurface *parentSurface READ parentSurface NOTIFY parentSurfaceChanged) + Q_PROPERTY(QPoint position READ position) + +public: + QWaylandXdgPopupV5(); + QWaylandXdgPopupV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface, QWaylandSurface *parentSurface, + const QPoint &position, const QWaylandResource &resource); + + Qt::WindowType windowType() const override { return Qt::WindowType::Popup; } + + Q_INVOKABLE void initialize(QWaylandXdgShellV5 *shell, QWaylandSurface *surface, + QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource); + + QWaylandXdgShellV5 *shell() const; + + QWaylandSurface *surface() const; + QWaylandSurface *parentSurface() const; + QPoint position() const; + + static const struct wl_interface *interface(); + static QByteArray interfaceName(); + static QWaylandSurfaceRole *role(); + static QWaylandXdgPopupV5 *fromResource(::wl_resource *resource); + + Q_INVOKABLE void sendPopupDone(); + +#ifdef QT_WAYLAND_COMPOSITOR_QUICK + QWaylandQuickShellIntegration *createIntegration(QWaylandQuickShellSurfaceItem *item) Q_DECL_OVERRIDE; +#endif + +Q_SIGNALS: + void shellChanged(); + void surfaceChanged(); + void parentSurfaceChanged(); + +private: + void initialize() override; +}; + +QT_END_NAMESPACE + +#endif /*QWAYLANDXDGSHELL_H*/ diff --git a/src/compositor/extensions/qwaylandxdgshellv5_p.h b/src/compositor/extensions/qwaylandxdgshellv5_p.h new file mode 100644 index 000000000..31aa2112c --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellv5_p.h @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGSHELLV5_P_H +#define QWAYLANDXDGSHELLV5_P_H + +#include +#include + +#include + +#include + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgShellV5Private + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::xdg_shell +{ + Q_DECLARE_PUBLIC(QWaylandXdgShellV5) +public: + QWaylandXdgShellV5Private(); + void ping(Resource *resource, uint32_t serial); + void registerSurface(QWaylandXdgSurfaceV5 *xdgSurface); + void unregisterXdgSurface(QWaylandXdgSurfaceV5 *xdgSurface); + void registerXdgPopup(QWaylandXdgPopupV5 *xdgPopup); + void unregisterXdgPopup(QWaylandXdgPopupV5 *xdgPopup); + static QWaylandXdgShellV5Private *get(QWaylandXdgShellV5 *xdgShell) { return xdgShell->d_func(); } + bool isValidPopupParent(QWaylandSurface *parentSurface) const; + QWaylandXdgPopupV5 *topmostPopupForClient(struct wl_client* client) const; + + QSet m_pings; + QMultiMap m_xdgSurfaces; + QMultiMap m_xdgPopups; + + QWaylandXdgSurfaceV5 *xdgSurfaceFromSurface(QWaylandSurface *surface); + +protected: + void xdg_shell_destroy(Resource *resource) Q_DECL_OVERRIDE; + void xdg_shell_get_xdg_surface(Resource *resource, uint32_t id, + struct ::wl_resource *surface) Q_DECL_OVERRIDE; + void xdg_shell_use_unstable_version(Resource *resource, int32_t version) Q_DECL_OVERRIDE; + void xdg_shell_get_xdg_popup(Resource *resource, uint32_t id, struct ::wl_resource *surface, + struct ::wl_resource *parent, struct ::wl_resource *seatResource, + uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; + void xdg_shell_pong(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgSurfaceV5Private + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::xdg_surface +{ + Q_DECLARE_PUBLIC(QWaylandXdgSurfaceV5) +public: + QWaylandXdgSurfaceV5Private(); + static QWaylandXdgSurfaceV5Private *get(QWaylandXdgSurfaceV5 *xdgSurface) { return xdgSurface->d_func(); } + + enum WindowType { + UnknownWindowType, + TopLevelWindowType, + TransientWindowType + }; + + struct ConfigureEvent { + QVector states; + QSize size; + uint serial; + }; + + void handleFocusLost(); + void handleFocusReceived(); + QRect calculateFallbackWindowGeometry() const; + void updateFallbackWindowGeometry(); + +private: + QWaylandXdgShellV5 *m_xdgShell; + QWaylandSurface *m_surface; + QWaylandXdgSurfaceV5 *m_parentSurface; + + WindowType m_windowType; + + QString m_title; + QString m_appId; + QRect m_windowGeometry; + bool m_unsetWindowGeometry; + + QList m_pendingConfigures; + ConfigureEvent m_lastAckedConfigure; + ConfigureEvent lastSentConfigure() const { return m_pendingConfigures.empty() ? m_lastAckedConfigure : m_pendingConfigures.first(); } + + void xdg_surface_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + + void xdg_surface_destroy(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_move(Resource *resource, struct ::wl_resource *seat, + uint32_t serial) Q_DECL_OVERRIDE; + void xdg_surface_resize(Resource *resource, struct ::wl_resource *seat, uint32_t serial, + uint32_t edges) Q_DECL_OVERRIDE; + void xdg_surface_set_maximized(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_unset_maximized(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_set_fullscreen(Resource *resource, + struct ::wl_resource *output) Q_DECL_OVERRIDE; + void xdg_surface_unset_fullscreen(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_set_minimized(Resource *resource) Q_DECL_OVERRIDE; + void xdg_surface_set_parent(Resource *resource, struct ::wl_resource *parent) Q_DECL_OVERRIDE; + void xdg_surface_set_app_id(Resource *resource, const QString &app_id) Q_DECL_OVERRIDE; + void xdg_surface_show_window_menu(Resource *resource, struct ::wl_resource *seatResource, + uint32_t serial, int32_t x, int32_t y) Q_DECL_OVERRIDE; + void xdg_surface_ack_configure(Resource *resource, uint32_t serial) Q_DECL_OVERRIDE; + void xdg_surface_set_title(Resource *resource, const QString &title) Q_DECL_OVERRIDE; + void xdg_surface_set_window_geometry(Resource *resource, int32_t x, int32_t y, + int32_t width, int32_t height) Q_DECL_OVERRIDE; + + static QWaylandSurfaceRole s_role; +}; + +class Q_WAYLAND_COMPOSITOR_EXPORT QWaylandXdgPopupV5Private + : public QWaylandCompositorExtensionPrivate + , public QtWaylandServer::xdg_popup +{ + Q_DECLARE_PUBLIC(QWaylandXdgPopupV5) + +public: + QWaylandXdgPopupV5Private(); + static QWaylandXdgPopupV5Private *get(QWaylandXdgPopupV5 *xdgPopup) { return xdgPopup->d_func(); } + + QWaylandSurface *m_surface; + QWaylandSurface *m_parentSurface; + QWaylandXdgShellV5 *m_xdgShell; + QPoint m_position; + + void xdg_popup_destroy_resource(Resource *resource) Q_DECL_OVERRIDE; + void xdg_popup_destroy(xdg_popup::Resource *resource) Q_DECL_OVERRIDE; + + static QWaylandSurfaceRole s_role; +}; + +QT_END_NAMESPACE + +#endif // QWAYLANDXDGSHELL_P_H diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp new file mode 100644 index 000000000..768747e44 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp @@ -0,0 +1,195 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandxdgshellv5integration_p.h" + +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +namespace QtWayland { + +XdgShellV5Integration::XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration(item) + , m_item(item) + , m_xdgSurface(qobject_cast(item->shellSurface())) + , grabberState(GrabberState::Default) +{ + m_item->setSurface(m_xdgSurface->surface()); + connect(m_xdgSurface, &QWaylandXdgSurfaceV5::startMove, this, &XdgShellV5Integration::handleStartMove); + connect(m_xdgSurface, &QWaylandXdgSurfaceV5::startResize, this, &XdgShellV5Integration::handleStartResize); + connect(m_xdgSurface, &QWaylandXdgSurfaceV5::setMaximized, this, &XdgShellV5Integration::handleSetMaximized); + connect(m_xdgSurface, &QWaylandXdgSurfaceV5::unsetMaximized, this, &XdgShellV5Integration::handleUnsetMaximized); + connect(m_xdgSurface, &QWaylandXdgSurfaceV5::maximizedChanged, this, &XdgShellV5Integration::handleMaximizedChanged); + connect(m_xdgSurface, &QWaylandXdgSurfaceV5::activatedChanged, this, &XdgShellV5Integration::handleActivatedChanged); + connect(m_xdgSurface->surface(), &QWaylandSurface::sizeChanged, this, &XdgShellV5Integration::handleSurfaceSizeChanged); +} + +bool XdgShellV5Integration::mouseMoveEvent(QMouseEvent *event) +{ + if (grabberState == GrabberState::Resize) { + Q_ASSERT(resizeState.seat == m_item->compositor()->seatFor(event)); + if (!resizeState.initialized) { + resizeState.initialMousePos = event->windowPos(); + resizeState.initialized = true; + return true; + } + QPointF delta = m_item->mapToSurface(event->windowPos() - resizeState.initialMousePos); + QSize newSize = m_xdgSurface->sizeForResize(resizeState.initialWindowSize, delta, resizeState.resizeEdges); + m_xdgSurface->sendResizing(newSize); + } else if (grabberState == GrabberState::Move) { + Q_ASSERT(moveState.seat == m_item->compositor()->seatFor(event)); + QQuickItem *moveItem = m_item->moveItem(); + if (!moveState.initialized) { + moveState.initialOffset = moveItem->mapFromItem(nullptr, event->windowPos()); + moveState.initialized = true; + return true; + } + if (!moveItem->parentItem()) + return true; + QPointF parentPos = moveItem->parentItem()->mapFromItem(nullptr, event->windowPos()); + moveItem->setPosition(parentPos - moveState.initialOffset); + } + return false; +} + +bool XdgShellV5Integration::mouseReleaseEvent(QMouseEvent *event) +{ + Q_UNUSED(event); + + if (grabberState == GrabberState::Resize) { + m_xdgSurface->sendUnmaximized(); + grabberState = GrabberState::Default; + return true; + } else if (grabberState == GrabberState::Move) { + grabberState = GrabberState::Default; + return true; + } + return false; +} + +void XdgShellV5Integration::handleStartMove(QWaylandSeat *seat) +{ + grabberState = GrabberState::Move; + moveState.seat = seat; + moveState.initialized = false; +} + +void XdgShellV5Integration::handleStartResize(QWaylandSeat *seat, QWaylandXdgSurfaceV5::ResizeEdge edges) +{ + grabberState = GrabberState::Resize; + resizeState.seat = seat; + resizeState.resizeEdges = edges; + resizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); + resizeState.initialPosition = m_item->moveItem()->position(); + resizeState.initialSurfaceSize = m_item->surface()->size(); + resizeState.initialized = false; +} + +void XdgShellV5Integration::handleSetMaximized() +{ + maximizeState.initialWindowSize = m_xdgSurface->windowGeometry().size(); + maximizeState.initialPosition = m_item->moveItem()->position(); + + QWaylandOutput *output = m_item->view()->output(); + m_xdgSurface->sendMaximized(output->availableGeometry().size() / output->scaleFactor()); +} + +void XdgShellV5Integration::handleUnsetMaximized() +{ + m_xdgSurface->sendUnmaximized(maximizeState.initialWindowSize); +} + +void XdgShellV5Integration::handleMaximizedChanged() +{ + if (m_xdgSurface->maximized()) { + QWaylandOutput *output = m_item->view()->output(); + m_item->moveItem()->setPosition(output->position() + output->availableGeometry().topLeft()); + } else { + m_item->moveItem()->setPosition(maximizeState.initialPosition); + } +} + +void XdgShellV5Integration::handleActivatedChanged() +{ + if (m_xdgSurface->activated()) + m_item->raise(); +} + +void XdgShellV5Integration::handleSurfaceSizeChanged() +{ + if (grabberState == GrabberState::Resize) { + qreal x = resizeState.initialPosition.x(); + qreal y = resizeState.initialPosition.y(); + if (resizeState.resizeEdges & QWaylandXdgSurfaceV5::ResizeEdge::TopEdge) + y += resizeState.initialSurfaceSize.height() - m_item->surface()->size().height(); + + if (resizeState.resizeEdges & QWaylandXdgSurfaceV5::ResizeEdge::LeftEdge) + x += resizeState.initialSurfaceSize.width() - m_item->surface()->size().width(); + m_item->moveItem()->setPosition(QPointF(x, y)); + } +} + +XdgPopupV5Integration::XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item) + : QWaylandQuickShellIntegration (item) + , m_xdgPopup(qobject_cast(item->shellSurface())) + , m_xdgShell(QWaylandXdgPopupV5Private::get(m_xdgPopup)->m_xdgShell) +{ + item->setSurface(m_xdgPopup->surface()); + item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor())); + + QWaylandClient *client = m_xdgPopup->surface()->client(); + QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); }); + + connect(m_xdgPopup, &QWaylandXdgPopupV5::destroyed, this, &XdgPopupV5Integration::handlePopupDestroyed); +} + +void XdgPopupV5Integration::handlePopupDestroyed() +{ + QWaylandXdgShellV5Private *shellPrivate = QWaylandXdgShellV5Private::get(m_xdgShell); + auto popups = shellPrivate->m_xdgPopups; + if (popups.isEmpty()) + QWaylandQuickShellEventFilter::cancelFilter(); +} + +} + +QT_END_NAMESPACE diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration_p.h b/src/compositor/extensions/qwaylandxdgshellv5integration_p.h new file mode 100644 index 000000000..61db435e5 --- /dev/null +++ b/src/compositor/extensions/qwaylandxdgshellv5integration_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWaylandCompositor module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGSHELLV5INTEGRATION_H +#define QWAYLANDXDGSHELLV5INTEGRATION_H + +#include +#include + +QT_BEGIN_NAMESPACE + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +namespace QtWayland { + +class XdgShellV5Integration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + XdgShellV5Integration(QWaylandQuickShellSurfaceItem *item); + bool mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + bool mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + +private Q_SLOTS: + void handleStartMove(QWaylandSeat *seat); + void handleStartResize(QWaylandSeat *seat, QWaylandXdgSurfaceV5::ResizeEdge edges); + void handleSetMaximized(); + void handleUnsetMaximized(); + void handleMaximizedChanged(); + void handleActivatedChanged(); + void handleSurfaceSizeChanged(); + +private: + enum class GrabberState { + Default, + Resize, + Move + }; + QWaylandQuickShellSurfaceItem *m_item; + QWaylandXdgSurfaceV5 *m_xdgSurface; + + GrabberState grabberState; + struct { + QWaylandSeat *seat; + QPointF initialOffset; + bool initialized; + } moveState; + + struct { + QWaylandSeat *seat; + QWaylandXdgSurfaceV5::ResizeEdge resizeEdges; + QSizeF initialWindowSize; + QPointF initialMousePos; + QPointF initialPosition; + QSize initialSurfaceSize; + bool initialized; + } resizeState; + + struct { + QSize initialWindowSize; + QPointF initialPosition; + } maximizeState; +}; + +class XdgPopupV5Integration : public QWaylandQuickShellIntegration +{ + Q_OBJECT +public: + XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item); + +private Q_SLOTS: + void handlePopupDestroyed(); + +private: + QWaylandXdgPopupV5 *m_xdgPopup; + QWaylandXdgShellV5 *m_xdgShell; +}; + +} + +QT_END_NAMESPACE + +#endif // QWAYLANDXDGSHELLINTEGRATION_H diff --git a/src/imports/compositor/plugins.qmltypes b/src/imports/compositor/plugins.qmltypes index 4c7cd7aa5..efeca304c 100644 --- a/src/imports/compositor/plugins.qmltypes +++ b/src/imports/compositor/plugins.qmltypes @@ -519,7 +519,7 @@ Module { Method { name: "sendPopupDone" } } Component { - name: "QWaylandXdgShell" + name: "QWaylandXdgShellV5" prototype: "QWaylandCompositorExtension" Signal { name: "xdgSurfaceRequested" @@ -528,11 +528,11 @@ Module { } Signal { name: "xdgSurfaceCreated" - Parameter { name: "xdgSurface"; type: "QWaylandXdgSurface"; isPointer: true } + Parameter { name: "xdgSurface"; type: "QWaylandXdgSurfaceV5"; isPointer: true } } Signal { name: "xdgPopupCreated" - Parameter { name: "xdgPopup"; type: "QWaylandXdgPopup"; isPointer: true } + Parameter { name: "xdgPopup"; type: "QWaylandXdgPopupV5"; isPointer: true } } Signal { name: "xdgPopupRequested" @@ -554,15 +554,15 @@ Module { Method { name: "closeAllPopups" } } Component { - name: "QWaylandXdgShellQuickExtension" + name: "QWaylandXdgShellV5QuickExtension" defaultProperty: "data" - prototype: "QWaylandXdgShell" + prototype: "QWaylandXdgShellV5" exports: ["QtWayland.Compositor/XdgShell 1.0"] exportMetaObjectRevisions: [0] Property { name: "data"; type: "QObject"; isList: true; isReadonly: true } } Component { - name: "QWaylandXdgSurface" + name: "QWaylandXdgSurfaceV5" prototype: "QWaylandShellSurface" exports: ["QtWayland.Compositor/XdgSurface 1.0"] exportMetaObjectRevisions: [0] @@ -590,7 +590,7 @@ Module { } } Property { name: "surface"; type: "QWaylandSurface"; isReadonly: true; isPointer: true } - Property { name: "parentSurface"; type: "QWaylandXdgSurface"; isReadonly: true; isPointer: true } + Property { name: "parentSurface"; type: "QWaylandXdgSurfaceV5"; isReadonly: true; isPointer: true } Property { name: "title"; type: "string"; isReadonly: true } Property { name: "appId"; type: "string"; isReadonly: true } Property { name: "windowGeometry"; type: "QRect"; isReadonly: true } @@ -629,7 +629,7 @@ Module { } Method { name: "initialize" - Parameter { name: "xdgShell"; type: "QWaylandXdgShell"; isPointer: true } + Parameter { name: "xdgShell"; type: "QWaylandXdgShellV5"; isPointer: true } Parameter { name: "surface"; type: "QWaylandSurface"; isPointer: true } Parameter { name: "resource"; type: "QWaylandResource" } } diff --git a/src/imports/compositor/qwaylandquickcompositorplugin.cpp b/src/imports/compositor/qwaylandquickcompositorplugin.cpp index 894a3e28f..45b46a811 100644 --- a/src/imports/compositor/qwaylandquickcompositorplugin.cpp +++ b/src/imports/compositor/qwaylandquickcompositorplugin.cpp @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include "qwaylandmousetracker_p.h" @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CONTAINER_CLASS(QWaylandQuickCompositor) Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandQtWindowManager) Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandWlShell) -Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShell) +Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandXdgShellV5) Q_COMPOSITOR_DECLARE_QUICK_EXTENSION_CLASS(QWaylandTextInputManager) class QmlUrlResolver @@ -133,8 +133,8 @@ public: qmlRegisterType(uri, 1, 0, "WlShell"); qmlRegisterType(uri, 1, 0, "WlShellSurface"); qmlRegisterType(uri, 1, 0, "ShellSurfaceItem"); - qmlRegisterType(uri, 1, 0, "XdgShell"); - qmlRegisterType(uri, 1, 0, "XdgSurface"); + qmlRegisterType(uri, 1, 0, "XdgShellV5"); + qmlRegisterType(uri, 1, 0, "XdgSurfaceV5"); qmlRegisterType(uri, 1, 0, "TextInputManager"); } }; -- cgit v1.2.3