From 1bc3b0fdc8d934c1ab69a902054681896b56d672 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing <johan.helsing@qt.io> Date: Fri, 5 Aug 2016 10:27:06 +0200 Subject: [PATCH] Client: Fix popup position for xdg shell Popups used xdg_surface instead of xdg_popup. It's not possible to set a position for an xdg_surface, because it's supposed to be a top level window (in xdg shell v5). Consequently, popups were treated as top level windows and positioned randomly on Weston. Using xdg_popup instead solves the problem. Task-number: QTBUG-55063 Change-Id: I223348677ef8a1ef1eee6a4c389276a6c802bcb5 Reviewed-by: Giulio Camuffo <giulio.camuffo@kdab.com> --- src/client/client.pro | 2 + src/client/qwaylandxdgpopup_p.cpp | 61 +++++++++++++++++ src/client/qwaylandxdgpopup_p.h | 79 ++++++++++++++++++++++ src/client/qwaylandxdgshell.cpp | 14 ++++ src/client/qwaylandxdgshell_p.h | 2 + src/client/qwaylandxdgshellintegration.cpp | 6 +- 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 src/client/qwaylandxdgpopup_p.cpp create mode 100644 src/client/qwaylandxdgpopup_p.h diff --git a/src/client/client.pro b/src/client/client.pro index d2d12d9f..88b9ea12 100644 --- a/src/client/client.pro +++ b/src/client/client.pro @@ -62,6 +62,7 @@ SOURCES += qwaylandintegration.cpp \ qwaylandwlshellintegration.cpp \ qwaylandxdgshell.cpp \ qwaylandxdgsurface.cpp \ + qwaylandxdgpopup_p.cpp \ qwaylandxdgshellintegration.cpp \ qwaylandextendedsurface.cpp \ qwaylandsubsurface.cpp \ @@ -97,6 +98,7 @@ HEADERS += qwaylandintegration_p.h \ qwaylandwlshellintegration_p.h \ qwaylandxdgshell_p.h \ qwaylandxdgsurface_p.h \ + qwaylandxdgpopup_p.h \ qwaylandxdgshellintegration_p.h \ qwaylandextendedsurface_p.h \ qwaylandsubsurface_p.h \ diff --git a/src/client/qwaylandxdgpopup_p.cpp b/src/client/qwaylandxdgpopup_p.cpp new file mode 100644 index 00000000..abc25278 --- /dev/null +++ b/src/client/qwaylandxdgpopup_p.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwaylandxdgpopup_p.h" + +#include "qwaylandwindow_p.h" +#include "qwaylanddisplay_p.h" +#include "qwaylandextendedsurface_p.h" + +QT_BEGIN_NAMESPACE + +namespace QtWaylandClient { + +QWaylandXdgPopup::QWaylandXdgPopup(struct ::xdg_popup *popup, QWaylandWindow *window) + : QWaylandShellSurface(window) + , QtWayland::xdg_popup(popup) + , m_extendedWindow(nullptr) +{ + if (window->display()->windowExtension()) + m_extendedWindow = new QWaylandExtendedSurface(window); +} + +QWaylandXdgPopup::~QWaylandXdgPopup() +{ + xdg_popup_destroy(object()); + delete m_extendedWindow; +} + +} + +QT_END_NAMESPACE diff --git a/src/client/qwaylandxdgpopup_p.h b/src/client/qwaylandxdgpopup_p.h new file mode 100644 index 00000000..b7574dd1 --- /dev/null +++ b/src/client/qwaylandxdgpopup_p.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWAYLANDXDGPOPUP_P_H +#define QWAYLANDXDGPOPUP_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <wayland-client.h> + +#include <QtWaylandClient/private/qwayland-xdg-shell.h> +#include <QtWaylandClient/private/qwaylandclientexport_p.h> +#include "qwaylandshellsurface_p.h" + +QT_BEGIN_NAMESPACE + +class QWindow; + +namespace QtWaylandClient { + +class QWaylandWindow; +class QWaylandExtendedSurface; + +class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgPopup : public QWaylandShellSurface + , public QtWayland::xdg_popup +{ + Q_OBJECT +public: + QWaylandXdgPopup(struct ::xdg_popup *popup, QWaylandWindow *window); + virtual ~QWaylandXdgPopup(); + +private: + QWaylandExtendedSurface *m_extendedWindow; +}; + +QT_END_NAMESPACE + +} + +#endif // QWAYLANDXDGPOPUP_P_H diff --git a/src/client/qwaylandxdgshell.cpp b/src/client/qwaylandxdgshell.cpp index 9b351da6..56bb3fae 100644 --- a/src/client/qwaylandxdgshell.cpp +++ b/src/client/qwaylandxdgshell.cpp @@ -37,6 +37,7 @@ #include "qwaylandwindow_p.h" #include "qwaylandinputdevice_p.h" #include "qwaylandscreen_p.h" +#include "qwaylandxdgpopup_p.h" #include "qwaylandxdgsurface_p.h" #include <QtCore/QDebug> @@ -66,6 +67,19 @@ QWaylandXdgSurface *QWaylandXdgShell::createXdgSurface(QWaylandWindow *window) return new QWaylandXdgSurface(this, window); } +QWaylandXdgPopup *QWaylandXdgShell::createXdgPopup(QWaylandWindow *window) +{ + QWaylandWindow *parentWindow = window->transientParent(); + ::wl_surface *parentSurface = parentWindow->object(); + QWaylandInputDevice *inputDevice = window->display()->lastInputDevice(); + ::wl_seat *seat = inputDevice->wl_seat(); + uint serial = inputDevice->serial(); + QPoint position = window->geometry().topLeft(); + int x = position.x() + parentWindow->frameMargins().left(); + int y = position.y() + parentWindow->frameMargins().top(); + return new QWaylandXdgPopup(get_xdg_popup(window->object(), parentSurface, seat, serial, x, y), window); +} + void QWaylandXdgShell::xdg_shell_ping(uint32_t serial) { pong(serial); diff --git a/src/client/qwaylandxdgshell_p.h b/src/client/qwaylandxdgshell_p.h index cd165641..fc5adb48 100644 --- a/src/client/qwaylandxdgshell_p.h +++ b/src/client/qwaylandxdgshell_p.h @@ -62,6 +62,7 @@ namespace QtWaylandClient { class QWaylandWindow; class QWaylandInputDevice; class QWaylandXdgSurface; +class QWaylandXdgPopup; class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShell : public QtWayland::xdg_shell { @@ -71,6 +72,7 @@ public: virtual ~QWaylandXdgShell(); QWaylandXdgSurface *createXdgSurface(QWaylandWindow *window); + QWaylandXdgPopup *createXdgPopup(QWaylandWindow *window); private: void xdg_shell_ping(uint32_t serial) Q_DECL_OVERRIDE; diff --git a/src/client/qwaylandxdgshellintegration.cpp b/src/client/qwaylandxdgshellintegration.cpp index 5a569129..b6b1d9d3 100644 --- a/src/client/qwaylandxdgshellintegration.cpp +++ b/src/client/qwaylandxdgshellintegration.cpp @@ -36,6 +36,7 @@ #include <QtWaylandClient/private/qwaylandwindow_p.h> #include <QtWaylandClient/private/qwaylanddisplay_p.h> #include <QtWaylandClient/private/qwaylandxdgsurface_p.h> +#include <QtWaylandClient/private/qwaylandxdgpopup_p.h> #include <QtWaylandClient/private/qwaylandxdgshell_p.h> QT_BEGIN_NAMESPACE @@ -55,7 +56,10 @@ QWaylandXdgShellIntegration::QWaylandXdgShellIntegration(QWaylandDisplay *displa QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window) { - return m_xdgShell->createXdgSurface(window); + if (window->window()->type() == Qt::WindowType::Popup) + return m_xdgShell->createXdgPopup(window); + else + return m_xdgShell->createXdgSurface(window); } } -- GitLab