fe1bb50e8413d9edafb6438ccc0ebd9124417d70
[AGL/meta-agl-demo.git] / recipes-qt / qt5 / qtwayland / 0017-xdg-shell-Add-minimize-feature-to-QWindow-using-wayl.patch
1 From 0edba039247ce888dbb7ff0a93c7b9ec01bac46e Mon Sep 17 00:00:00 2001
2 From: Philippe Coval <philippe.coval@open.eurogiciel.org>
3 Date: Wed, 26 Mar 2014 10:16:01 +0100
4 Subject: [PATCH 17/21] xdg-shell: Add minimize feature to QWindow using
5  wayland's xdg-shell
6
7 The feature is disabled by default,
8 and can be enabled at runtime
9 by exporting QT_WAYLAND_USE_XDG_SHELL env variable.
10
11 This patch relies on presence of protocol file
12 which has been imported from weston-1.4.0 sources,
13 until the xdg-shell is merge into wayland itself.
14
15 Because xdg-shell is experimental,
16 code fallback to WaylandShell if no XdgShell
17 but keep in mind those shells are exclusive.
18
19 Since xdg-shell and wayland-shell share most of the API,
20 some factorization is done by an (empty) abstraction class
21 to keep the code more readable.
22
23 Despite xdg-shell introduces new popups concept,
24 they're not used on this change for maitainance purpose.
25
26 Notes:
27
28 * This change depends on presence of xdg-shell protocol file.
29
30 * You can check a demo video
31   (qt-tizen-cinematic-experience-20140430-rzr)
32   of the test case at :
33   https://www.youtube.com/watch?v=pY_XXvKc_0E#
34
35 * Use Super+Tab to show window again if hidden
36
37 Task-number: QTBUG-38633/part/2of2
38 Change-Id: I2d7ed85bea1847d82439fdfc893a3dbb2581ffff
39 Reviewed-by: Giulio Camuffo <giulio.camuffo@jollamobile.com>
40 Origin: https://www.qt.gitorious.org/qt/qtwayland/commit/768484daaa64bea965bef981a16f59be8db0c190
41 Bug-Tizen: TIVI-3113/part
42 Signed-off-by: Philippe Coval <philippe.coval@open.eurogiciel.org>
43 ---
44  src/client/client.pro                 |   5 +
45  src/client/qwaylanddisplay.cpp        |   5 +
46  src/client/qwaylanddisplay_p.h        |   4 +
47  src/client/qwaylandshellsurface.cpp   | 134 ------------------------
48  src/client/qwaylandshellsurface_p.h   |  40 +++-----
49  src/client/qwaylandwindow.cpp         |  40 ++++++--
50  src/client/qwaylandwlshellsurface.cpp | 186 ++++++++++++++++++++++++++++++++++
51  src/client/qwaylandwlshellsurface_p.h | 101 ++++++++++++++++++
52  src/client/qwaylandxdgsurface.cpp     | 173 +++++++++++++++++++++++++++++++
53  src/client/qwaylandxdgsurface_p.h     | 105 +++++++++++++++++++
54  10 files changed, 625 insertions(+), 168 deletions(-)
55  create mode 100644 src/client/qwaylandwlshellsurface.cpp
56  create mode 100644 src/client/qwaylandwlshellsurface_p.h
57  create mode 100644 src/client/qwaylandxdgsurface.cpp
58  create mode 100644 src/client/qwaylandxdgsurface_p.h
59
60 diff --git a/src/client/client.pro b/src/client/client.pro
61 index 10cbd31..9ecf82f 100644
62 --- a/src/client/client.pro
63 +++ b/src/client/client.pro
64 @@ -41,6 +41,7 @@ WAYLANDCLIENTSOURCES += \
65              ../extensions/qtkey-extension.xml \
66              ../extensions/windowmanager.xml \
67              ../3rdparty/protocol/text.xml \
68 +            ../3rdparty/protocol/xdg-shell.xml \
69  
70  SOURCES +=  qwaylandintegration.cpp \
71              qwaylandnativeinterface.cpp \
72 @@ -57,6 +58,8 @@ SOURCES +=  qwaylandintegration.cpp \
73              qwaylanddatadevicemanager.cpp \
74              qwaylanddatasource.cpp \
75              qwaylandshellsurface.cpp \
76 +            qwaylandwlshellsurface.cpp \
77 +            qwaylandxdgsurface.cpp \
78              qwaylandextendedoutput.cpp \
79              qwaylandextendedsurface.cpp \
80              qwaylandsubsurface.cpp \
81 @@ -85,6 +88,8 @@ HEADERS +=  qwaylandintegration_p.h \
82              qwaylanddatadevicemanager_p.h \
83              qwaylanddatasource_p.h \
84              qwaylandshellsurface_p.h \
85 +            qwaylandwlshellsurface_p.h \
86 +            qwaylandxdgsurface_p.h \
87              qwaylandextendedoutput_p.h \
88              qwaylandextendedsurface_p.h \
89              qwaylandsubsurface_p.h \
90 diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
91 index 0b715c0..7f953ad 100644
92 --- a/src/client/qwaylanddisplay.cpp
93 +++ b/src/client/qwaylanddisplay.cpp
94 @@ -61,6 +61,7 @@
95  #include "qwaylandqtkey_p.h"
96  
97  #include <QtWaylandClient/private/qwayland-text.h>
98 +#include <QtWaylandClient/private/qwayland-xdg-shell.h>
99  
100  #include <QtCore/QAbstractEventDispatcher>
101  #include <QtGui/private/qguiapplication_p.h>
102 @@ -206,6 +207,10 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
103          mCompositor.init(registry, id);
104      } else if (interface == QStringLiteral("wl_shm")) {
105          mShm = static_cast<struct wl_shm *>(wl_registry_bind(registry, id, &wl_shm_interface,1));
106 +    } else if (interface == QStringLiteral("xdg_shell")
107 +               && qEnvironmentVariableIsSet("QT_WAYLAND_USE_XDG_SHELL")) {
108 +        mShellXdg.reset(new QtWayland::xdg_shell(registry, id));
109 +        mShellXdg->use_unstable_version(QtWayland::xdg_shell::version_current);
110      } else if (interface == QStringLiteral("wl_shell")){
111          mShell.reset(new QtWayland::wl_shell(registry, id));
112      } else if (interface == QStringLiteral("wl_seat")) {
113 diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
114 index 40cb2b2..cf5dfc2 100644
115 --- a/src/client/qwaylanddisplay_p.h
116 +++ b/src/client/qwaylanddisplay_p.h
117 @@ -51,6 +51,7 @@
118  
119  #include <QtWaylandClient/private/qwayland-wayland.h>
120  #include <QtWaylandClient/private/qwaylandclientexport_p.h>
121 +#include <QtWaylandClient/private/qwayland-xdg-shell.h>
122  
123  struct wl_cursor_image;
124  
125 @@ -78,6 +79,7 @@ namespace QtWayland {
126      class qt_sub_surface_extension;
127      class qt_surface_extension;
128      class wl_text_input_manager;
129 +    class xdg_shell;
130  }
131  
132  typedef void (*RegistryListener)(void *data,
133 @@ -113,6 +115,7 @@ public:
134      QtWayland::wl_compositor *compositor() { return &mCompositor; }
135  
136      QtWayland::wl_shell *shell() { return mShell.data(); }
137 +    QtWayland::xdg_shell *shellXdg() { return mShellXdg.data(); }
138  
139      QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
140      QWaylandInputDevice *defaultInputDevice() const;
141 @@ -168,6 +171,7 @@ private:
142      QThread *mEventThread;
143      QWaylandEventThread *mEventThreadObject;
144      QScopedPointer<QtWayland::wl_shell> mShell;
145 +    QScopedPointer<QtWayland::xdg_shell> mShellXdg;
146      QList<QPlatformScreen *> mScreens;
147      QList<QWaylandInputDevice *> mInputDevices;
148      QList<Listener> mRegistryListeners;
149 diff --git a/src/client/qwaylandshellsurface.cpp b/src/client/qwaylandshellsurface.cpp
150 index b7a819f..80e509b 100644
151 --- a/src/client/qwaylandshellsurface.cpp
152 +++ b/src/client/qwaylandshellsurface.cpp
153 @@ -40,137 +40,3 @@
154  ****************************************************************************/
155  
156  #include "qwaylandshellsurface_p.h"
157 -
158 -#include "qwaylanddisplay_p.h"
159 -#include "qwaylandwindow_p.h"
160 -#include "qwaylandinputdevice_p.h"
161 -#include "qwaylanddecoration_p.h"
162 -#include "qwaylandscreen_p.h"
163 -
164 -#include <QtCore/QDebug>
165 -
166 -QT_BEGIN_NAMESPACE
167 -
168 -QWaylandShellSurface::QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window)
169 -    : QtWayland::wl_shell_surface(shell_surface)
170 -    , m_window(window)
171 -    , m_maximized(false)
172 -    , m_fullscreen(false)
173 -{
174 -}
175 -
176 -QWaylandShellSurface::~QWaylandShellSurface()
177 -{
178 -    wl_shell_surface_destroy(object());
179 -}
180 -
181 -void QWaylandShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges)
182 -{
183 -    resize(inputDevice->wl_seat(),
184 -           inputDevice->serial(),
185 -           edges);
186 -}
187 -
188 -void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice)
189 -{
190 -    move(inputDevice->wl_seat(),
191 -         inputDevice->serial());
192 -}
193 -
194 -void QWaylandShellSurface::setMaximized()
195 -{
196 -    m_maximized = true;
197 -    m_size = m_window->window()->geometry().size();
198 -    set_maximized(0);
199 -}
200 -
201 -void QWaylandShellSurface::setFullscreen()
202 -{
203 -    m_fullscreen = true;
204 -    m_size = m_window->window()->geometry().size();
205 -    set_fullscreen(WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, 0);
206 -}
207 -
208 -void QWaylandShellSurface::setNormal()
209 -{
210 -    if (m_fullscreen || m_maximized) {
211 -        m_fullscreen = m_maximized = false;
212 -        setTopLevel();
213 -        QMargins m = m_window->frameMargins();
214 -        m_window->configure(0, m_size.width() + m.left() + m.right(), m_size.height() + m.top() + m.bottom());
215 -    }
216 -}
217 -
218 -void QWaylandShellSurface::setMinimized()
219 -{
220 -    // TODO: There's no wl_shell_surface API for this
221 -}
222 -
223 -void QWaylandShellSurface::setTopLevel()
224 -{
225 -    set_toplevel();
226 -}
227 -
228 -void QWaylandShellSurface::updateTransientParent(QWindow *parent)
229 -{
230 -    QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
231 -    if (!parent_wayland_window)
232 -        return;
233 -
234 -    // set_transient expects a position relative to the parent
235 -    QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
236 -    QWindow *parentWin = m_window->window()->transientParent();
237 -    transientPos -= parentWin->geometry().topLeft();
238 -    if (parent_wayland_window->decoration()) {
239 -        transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
240 -        transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
241 -    }
242 -
243 -    uint32_t flags = 0;
244 -    Qt::WindowFlags wf = m_window->window()->flags();
245 -    if (wf.testFlag(Qt::ToolTip)
246 -            || wf.testFlag(Qt::WindowTransparentForInput))
247 -        flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
248 -
249 -    set_transient(parent_wayland_window->object(),
250 -                  transientPos.x(),
251 -                  transientPos.y(),
252 -                  flags);
253 -}
254 -
255 -void QWaylandShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial)
256 -{
257 -    QWaylandWindow *parent_wayland_window = parent;
258 -    if (!parent_wayland_window)
259 -        return;
260 -
261 -    // set_popup expects a position relative to the parent
262 -    QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
263 -    transientPos -= parent_wayland_window->geometry().topLeft();
264 -    if (parent_wayland_window->decoration()) {
265 -        transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
266 -        transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
267 -    }
268 -
269 -    set_popup(device->wl_seat(), serial, parent_wayland_window->object(),
270 -              transientPos.x(), transientPos.y(), 0);
271 -}
272 -
273 -void QWaylandShellSurface::shell_surface_ping(uint32_t serial)
274 -{
275 -    pong(serial);
276 -}
277 -
278 -void QWaylandShellSurface::shell_surface_configure(uint32_t edges,
279 -                                                   int32_t width,
280 -                                                   int32_t height)
281 -{
282 -    m_window->configure(edges, width, height);
283 -}
284 -
285 -void QWaylandShellSurface::shell_surface_popup_done()
286 -{
287 -    QCoreApplication::postEvent(m_window->window(), new QCloseEvent());
288 -}
289 -
290 -QT_END_NAMESPACE
291 diff --git a/src/client/qwaylandshellsurface_p.h b/src/client/qwaylandshellsurface_p.h
292 index 2477c3f..2f59f60 100644
293 --- a/src/client/qwaylandshellsurface_p.h
294 +++ b/src/client/qwaylandshellsurface_p.h
295 @@ -55,39 +55,25 @@ class QWaylandWindow;
296  class QWaylandInputDevice;
297  class QWindow;
298  
299 -class Q_WAYLAND_CLIENT_EXPORT QWaylandShellSurface : public QtWayland::wl_shell_surface
300 +class Q_WAYLAND_CLIENT_EXPORT QWaylandShellSurface
301  {
302  public:
303 -    QWaylandShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window);
304 -    ~QWaylandShellSurface();
305 +    virtual ~QWaylandShellSurface() {}
306 +    virtual void resize(QWaylandInputDevice * /*inputDevice*/, enum wl_shell_surface_resize /*edges*/)
307 +    {}
308  
309 -    using QtWayland::wl_shell_surface::resize;
310 -    void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges);
311 -
312 -    using QtWayland::wl_shell_surface::move;
313 -    void move(QWaylandInputDevice *inputDevice);
314 +    virtual void move(QWaylandInputDevice * /*inputDevice*/) {}
315 +    virtual void setTitle(const QString & /*title*/) {}
316 +    virtual void setAppId(const QString & /*appId*/) {}
317  
318  private:
319 -    void setMaximized();
320 -    void setFullscreen();
321 -    void setNormal();
322 -    void setMinimized();
323 -
324 -    void setTopLevel();
325 -    void updateTransientParent(QWindow *parent);
326 -    void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial);
327 -
328 -    QWaylandWindow *m_window;
329 -    bool m_maximized;
330 -    bool m_fullscreen;
331 -    QSize m_size;
332 -
333 -    void shell_surface_ping(uint32_t serial) Q_DECL_OVERRIDE;
334 -    void shell_surface_configure(uint32_t edges,
335 -                                 int32_t width,
336 -                                 int32_t height) Q_DECL_OVERRIDE;
337 -    void shell_surface_popup_done() Q_DECL_OVERRIDE;
338 +    virtual void setMaximized() {}
339 +    virtual void setFullscreen() {}
340 +    virtual void setNormal() {}
341 +    virtual void setMinimized() {}
342  
343 +    virtual void setTopLevel() {}
344 +    virtual void updateTransientParent(QWindow * /*parent*/) {}
345      friend class QWaylandWindow;
346  };
347  
348 diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
349 index 920c977..3fb3a49 100644
350 --- a/src/client/qwaylandwindow.cpp
351 +++ b/src/client/qwaylandwindow.cpp
352 @@ -46,6 +46,8 @@
353  #include "qwaylandinputdevice_p.h"
354  #include "qwaylandscreen_p.h"
355  #include "qwaylandshellsurface_p.h"
356 +#include "qwaylandwlshellsurface_p.h"
357 +#include "qwaylandxdgsurface_p.h"
358  #include "qwaylandextendedsurface_p.h"
359  #include "qwaylandsubsurface_p.h"
360  #include "qwaylanddecoration_p.h"
361 @@ -92,8 +94,16 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
362      static WId id = 1;
363      mWindowId = id++;
364  
365 -    if (mDisplay->shell() && window->type() & Qt::Window && !(window->flags() & Qt::BypassWindowManagerHint))
366 -        mShellSurface = new QWaylandShellSurface(mDisplay->shell()->get_shell_surface(object()), this);
367 +    if (!(window->flags() & Qt::BypassWindowManagerHint)) {
368 +        if (mDisplay->shellXdg()) {
369 +           if (window->type() & Qt::Window) {
370 +                mShellSurface = new QWaylandXdgSurface(mDisplay->shellXdg()->get_xdg_surface(object()), this);
371 +            }
372 +        } else if (mDisplay->shell() && window->type() & Qt::Window) {
373 +            mShellSurface = new QWaylandWlShellSurface(mDisplay->shell()->get_shell_surface(object()), this);
374 +        }
375 +    }
376 +
377      if (mDisplay->windowExtension())
378          mExtendedWindow = new QWaylandExtendedSurface(this, mDisplay->windowExtension()->get_extended_surface(object()));
379      if (mDisplay->subSurfaceExtension())
380 @@ -101,12 +111,12 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
381  
382      if (mShellSurface) {
383          // Set initial surface title
384 -        mShellSurface->set_title(window->title());
385 +        mShellSurface->setTitle(window->title());
386  
387          // Set surface class to the .desktop file name (obtained from executable name)
388          QFileInfo exeFileInfo(qApp->applicationFilePath());
389          QString className = exeFileInfo.baseName() + QLatin1String(".desktop");
390 -        mShellSurface->set_class(className);
391 +        mShellSurface->setAppId(className);
392      }
393  
394      if (QPlatformWindow::parent() && mSubSurfaceWindow) {
395 @@ -170,7 +180,7 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent)
396  void QWaylandWindow::setWindowTitle(const QString &title)
397  {
398      if (mShellSurface) {
399 -        mShellSurface->set_title(title);
400 +        mShellSurface->setTitle(title);
401      }
402  
403      if (mWindowDecoration && window()->isVisible())
404 @@ -212,8 +222,10 @@ void QWaylandWindow::setVisible(bool visible)
405              mMouseDevice = parent->mMouseDevice;
406              mMouseSerial = parent->mMouseSerial;
407  
408 -            if (mMouseDevice)
409 -                mShellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial);
410 +            QWaylandWlShellSurface *wlshellSurface = dynamic_cast<QWaylandWlShellSurface*>(mShellSurface);
411 +            if (mMouseDevice && wlshellSurface) {
412 +                wlshellSurface->setPopup(transientParent(), mMouseDevice, mMouseSerial);
413 +            }
414          }
415  
416          if (!mSentInitialResize) {
417 @@ -428,6 +440,20 @@ void QWaylandWindow::setWindowFlags(Qt::WindowFlags flags)
418  
419  bool QWaylandWindow::createDecoration()
420  {
421 +    // so far only xdg-shell support this "unminimize" trick, may be moved elsewhere
422 +    if (mState == Qt::WindowMinimized) {
423 +        QWaylandXdgSurface *xdgSurface = dynamic_cast<QWaylandXdgSurface *>(mShellSurface);
424 +        if ( xdgSurface ) {
425 +            if (xdgSurface->isFullscreen()) {
426 +                setWindowStateInternal(Qt::WindowFullScreen);
427 +            } else if (xdgSurface->isMaximized()) {
428 +                setWindowStateInternal(Qt::WindowMaximized);
429 +            } else {
430 +                setWindowStateInternal(Qt::WindowNoState);
431 +            }
432 +        }
433 +    }
434 +
435      static bool disableWaylandDecorations = !qgetenv("QT_WAYLAND_DISABLE_WINDOWDECORATION").isEmpty();
436      if (disableWaylandDecorations)
437          return false;
438 diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp
439 new file mode 100644
440 index 0000000..4b73ec2
441 --- /dev/null
442 +++ b/src/client/qwaylandwlshellsurface.cpp
443 @@ -0,0 +1,186 @@
444 +/****************************************************************************
445 +**
446 +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
447 +** Contact: http://www.qt-project.org/legal
448 +**
449 +** This file is part of the config.tests of the Qt Toolkit.
450 +**
451 +** $QT_BEGIN_LICENSE:LGPL$
452 +** Commercial License Usage
453 +** Licensees holding valid commercial Qt licenses may use this file in
454 +** accordance with the commercial license agreement provided with the
455 +** Software or, alternatively, in accordance with the terms contained in
456 +** a written agreement between you and Digia.  For licensing terms and
457 +** conditions see http://qt.digia.com/licensing.  For further information
458 +** use the contact form at http://qt.digia.com/contact-us.
459 +**
460 +** GNU Lesser General Public License Usage
461 +** Alternatively, this file may be used under the terms of the GNU Lesser
462 +** General Public License version 2.1 as published by the Free Software
463 +** Foundation and appearing in the file LICENSE.LGPL included in the
464 +** packaging of this file.  Please review the following information to
465 +** ensure the GNU Lesser General Public License version 2.1 requirements
466 +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
467 +**
468 +** In addition, as a special exception, Digia gives you certain additional
469 +** rights.  These rights are described in the Digia Qt LGPL Exception
470 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
471 +**
472 +** GNU General Public License Usage
473 +** Alternatively, this file may be used under the terms of the GNU
474 +** General Public License version 3.0 as published by the Free Software
475 +** Foundation and appearing in the file LICENSE.GPL included in the
476 +** packaging of this file.  Please review the following information to
477 +** ensure the GNU General Public License version 3.0 requirements will be
478 +** met: http://www.gnu.org/copyleft/gpl.html.
479 +**
480 +**
481 +** $QT_END_LICENSE$
482 +**
483 +****************************************************************************/
484 +
485 +#include "qwaylandwlshellsurface_p.h"
486 +
487 +#include "qwaylanddisplay_p.h"
488 +#include "qwaylandwindow_p.h"
489 +#include "qwaylandinputdevice_p.h"
490 +#include "qwaylanddecoration_p.h"
491 +#include "qwaylandscreen_p.h"
492 +
493 +#include <QtCore/QDebug>
494 +
495 +QT_BEGIN_NAMESPACE
496 +
497 +QWaylandWlShellSurface::QWaylandWlShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window)
498 +    : QtWayland::wl_shell_surface(shell_surface)
499 +    , m_window(window)
500 +    , m_maximized(false)
501 +    , m_fullscreen(false)
502 +{
503 +}
504 +
505 +QWaylandWlShellSurface::~QWaylandWlShellSurface()
506 +{
507 +    wl_shell_surface_destroy(object());
508 +}
509 +
510 +void QWaylandWlShellSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges)
511 +{
512 +    resize(inputDevice->wl_seat(),
513 +           inputDevice->serial(),
514 +           edges);
515 +}
516 +
517 +void QWaylandWlShellSurface::move(QWaylandInputDevice *inputDevice)
518 +{
519 +    move(inputDevice->wl_seat(),
520 +         inputDevice->serial());
521 +}
522 +
523 +void QWaylandWlShellSurface::setTitle(const QString & title)
524 +{
525 +    return QtWayland::wl_shell_surface::set_title(title);
526 +}
527 +
528 +void QWaylandWlShellSurface::setAppId(const QString & appId)
529 +{
530 +    return QtWayland::wl_shell_surface::set_class(appId);
531 +}
532 +
533 +void QWaylandWlShellSurface::setMaximized()
534 +{
535 +    m_maximized = true;
536 +    m_size = m_window->window()->geometry().size();
537 +    set_maximized(0);
538 +}
539 +
540 +void QWaylandWlShellSurface::setFullscreen()
541 +{
542 +    m_fullscreen = true;
543 +    m_size = m_window->window()->geometry().size();
544 +    set_fullscreen(WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, 0);
545 +}
546 +
547 +void QWaylandWlShellSurface::setNormal()
548 +{
549 +    if (m_fullscreen || m_maximized) {
550 +        m_fullscreen = m_maximized = false;
551 +        setTopLevel();
552 +        QMargins m = m_window->frameMargins();
553 +        m_window->configure(0, m_size.width() + m.left() + m.right(), m_size.height() + m.top() + m.bottom());
554 +    }
555 +}
556 +
557 +void QWaylandWlShellSurface::setMinimized()
558 +{
559 +    // TODO: There's no wl_shell_surface API for this
560 +}
561 +
562 +void QWaylandWlShellSurface::setTopLevel()
563 +{
564 +    set_toplevel();
565 +}
566 +
567 +void QWaylandWlShellSurface::updateTransientParent(QWindow *parent)
568 +{
569 +    QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
570 +    if (!parent_wayland_window)
571 +        return;
572 +
573 +    // set_transient expects a position relative to the parent
574 +    QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
575 +    QWindow *parentWin = m_window->window()->transientParent();
576 +    transientPos -= parentWin->geometry().topLeft();
577 +    if (parent_wayland_window->decoration()) {
578 +        transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
579 +        transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
580 +    }
581 +
582 +    uint32_t flags = 0;
583 +    Qt::WindowFlags wf = m_window->window()->flags();
584 +    if (wf.testFlag(Qt::ToolTip)
585 +            || wf.testFlag(Qt::WindowTransparentForInput))
586 +        flags |= WL_SHELL_SURFACE_TRANSIENT_INACTIVE;
587 +
588 +    set_transient(parent_wayland_window->object(),
589 +                  transientPos.x(),
590 +                  transientPos.y(),
591 +                  flags);
592 +}
593 +
594 +void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial)
595 +{
596 +    QWaylandWindow *parent_wayland_window = parent;
597 +    if (!parent_wayland_window)
598 +        return;
599 +
600 +    // set_popup expects a position relative to the parent
601 +    QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
602 +    transientPos -= parent_wayland_window->geometry().topLeft();
603 +    if (parent_wayland_window->decoration()) {
604 +        transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
605 +        transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
606 +    }
607 +
608 +    set_popup(device->wl_seat(), serial, parent_wayland_window->object(),
609 +              transientPos.x(), transientPos.y(), 0);
610 +}
611 +
612 +void QWaylandWlShellSurface::shell_surface_ping(uint32_t serial)
613 +{
614 +    pong(serial);
615 +}
616 +
617 +void QWaylandWlShellSurface::shell_surface_configure(uint32_t edges,
618 +                                                     int32_t width,
619 +                                                     int32_t height)
620 +{
621 +    m_window->configure(edges, width, height);
622 +}
623 +
624 +void QWaylandWlShellSurface::shell_surface_popup_done()
625 +{
626 +    QCoreApplication::postEvent(m_window->window(), new QCloseEvent());
627 +}
628 +
629 +QT_END_NAMESPACE
630 diff --git a/src/client/qwaylandwlshellsurface_p.h b/src/client/qwaylandwlshellsurface_p.h
631 new file mode 100644
632 index 0000000..d02bb7b
633 --- /dev/null
634 +++ b/src/client/qwaylandwlshellsurface_p.h
635 @@ -0,0 +1,101 @@
636 +/****************************************************************************
637 +**
638 +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
639 +** Contact: http://www.qt-project.org/legal
640 +**
641 +** This file is part of the config.tests of the Qt Toolkit.
642 +**
643 +** $QT_BEGIN_LICENSE:LGPL$
644 +** Commercial License Usage
645 +** Licensees holding valid commercial Qt licenses may use this file in
646 +** accordance with the commercial license agreement provided with the
647 +** Software or, alternatively, in accordance with the terms contained in
648 +** a written agreement between you and Digia.  For licensing terms and
649 +** conditions see http://qt.digia.com/licensing.  For further information
650 +** use the contact form at http://qt.digia.com/contact-us.
651 +**
652 +** GNU Lesser General Public License Usage
653 +** Alternatively, this file may be used under the terms of the GNU Lesser
654 +** General Public License version 2.1 as published by the Free Software
655 +** Foundation and appearing in the file LICENSE.LGPL included in the
656 +** packaging of this file.  Please review the following information to
657 +** ensure the GNU Lesser General Public License version 2.1 requirements
658 +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
659 +**
660 +** In addition, as a special exception, Digia gives you certain additional
661 +** rights.  These rights are described in the Digia Qt LGPL Exception
662 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
663 +**
664 +** GNU General Public License Usage
665 +** Alternatively, this file may be used under the terms of the GNU
666 +** General Public License version 3.0 as published by the Free Software
667 +** Foundation and appearing in the file LICENSE.GPL included in the
668 +** packaging of this file.  Please review the following information to
669 +** ensure the GNU General Public License version 3.0 requirements will be
670 +** met: http://www.gnu.org/copyleft/gpl.html.
671 +**
672 +**
673 +** $QT_END_LICENSE$
674 +**
675 +****************************************************************************/
676 +
677 +#ifndef QWAYLANDWLSHELLSURFACE_H
678 +#define QWAYLANDWLSHELLSURFACE_H
679 +
680 +#include <QtCore/QSize>
681 +
682 +#include <wayland-client.h>
683 +
684 +#include <QtWaylandClient/private/qwayland-wayland.h>
685 +#include <QtWaylandClient/private/qwaylandclientexport_p.h>
686 +#include "qwaylandshellsurface_p.h"
687 +
688 +QT_BEGIN_NAMESPACE
689 +
690 +class QWaylandWindow;
691 +class QWaylandInputDevice;
692 +class QWindow;
693 +
694 +class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellSurface : public QtWayland::wl_shell_surface
695 +        , public QWaylandShellSurface
696 +{
697 +public:
698 +    QWaylandWlShellSurface(struct ::wl_shell_surface *shell_surface, QWaylandWindow *window);
699 +    virtual ~QWaylandWlShellSurface();
700 +
701 +    using QtWayland::wl_shell_surface::resize;
702 +    void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) Q_DECL_OVERRIDE;
703 +
704 +    using QtWayland::wl_shell_surface::move;
705 +    void move(QWaylandInputDevice *inputDevice) Q_DECL_OVERRIDE;
706 +
707 +    void setTitle(const QString & title) Q_DECL_OVERRIDE;
708 +    void setAppId(const QString &appId) Q_DECL_OVERRIDE;
709 +
710 +private:
711 +    void setMaximized() Q_DECL_OVERRIDE;
712 +    void setFullscreen() Q_DECL_OVERRIDE;
713 +    void setNormal() Q_DECL_OVERRIDE;
714 +    void setMinimized() Q_DECL_OVERRIDE;
715 +
716 +    void setTopLevel() Q_DECL_OVERRIDE;
717 +    void updateTransientParent(QWindow *parent) Q_DECL_OVERRIDE;
718 +    void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial);
719 +
720 +    QWaylandWindow *m_window;
721 +    bool m_maximized;
722 +    bool m_fullscreen;
723 +    QSize m_size;
724 +
725 +    void shell_surface_ping(uint32_t serial) Q_DECL_OVERRIDE;
726 +    void shell_surface_configure(uint32_t edges,
727 +                                 int32_t width,
728 +                                 int32_t height) Q_DECL_OVERRIDE;
729 +    void shell_surface_popup_done() Q_DECL_OVERRIDE;
730 +
731 +    friend class QWaylandWindow;
732 +};
733 +
734 +QT_END_NAMESPACE
735 +
736 +#endif // QWAYLANDSHELLSURFACE_H
737 diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp
738 new file mode 100644
739 index 0000000..1b8affa
740 --- /dev/null
741 +++ b/src/client/qwaylandxdgsurface.cpp
742 @@ -0,0 +1,173 @@
743 +/****************************************************************************
744 +**
745 +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
746 +** Contact: http://www.qt-project.org/legal
747 +**
748 +** This file is part of the config.tests of the Qt Toolkit.
749 +**
750 +** $QT_BEGIN_LICENSE:LGPL$
751 +** Commercial License Usage
752 +** Licensees holding valid commercial Qt licenses may use this file in
753 +** accordance with the commercial license agreement provided with the
754 +** Software or, alternatively, in accordance with the terms contained in
755 +** a written agreement between you and Digia.  For licensing terms and
756 +** conditions see http://qt.digia.com/licensing.  For further information
757 +** use the contact form at http://qt.digia.com/contact-us.
758 +**
759 +** GNU Lesser General Public License Usage
760 +** Alternatively, this file may be used under the terms of the GNU Lesser
761 +** General Public License version 2.1 as published by the Free Software
762 +** Foundation and appearing in the file LICENSE.LGPL included in the
763 +** packaging of this file.  Please review the following information to
764 +** ensure the GNU Lesser General Public License version 2.1 requirements
765 +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
766 +**
767 +** In addition, as a special exception, Digia gives you certain additional
768 +** rights.  These rights are described in the Digia Qt LGPL Exception
769 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
770 +**
771 +** GNU General Public License Usage
772 +** Alternatively, this file may be used under the terms of the GNU
773 +** General Public License version 3.0 as published by the Free Software
774 +** Foundation and appearing in the file LICENSE.GPL included in the
775 +** packaging of this file.  Please review the following information to
776 +** ensure the GNU General Public License version 3.0 requirements will be
777 +** met: http://www.gnu.org/copyleft/gpl.html.
778 +**
779 +**
780 +** $QT_END_LICENSE$
781 +**
782 +****************************************************************************/
783 +
784 +#include "qwaylandxdgsurface_p.h"
785 +
786 +#include "qwaylanddisplay_p.h"
787 +#include "qwaylandwindow_p.h"
788 +#include "qwaylandinputdevice_p.h"
789 +#include "qwaylanddecoration_p.h"
790 +#include "qwaylandscreen_p.h"
791 +
792 +#include <QtCore/QDebug>
793 +
794 +QT_BEGIN_NAMESPACE
795 +
796 +QWaylandXdgSurface::QWaylandXdgSurface(struct ::xdg_surface *xdg_surface, QWaylandWindow *window)
797 +    : QtWayland::xdg_surface(xdg_surface)
798 +    , m_window(window)
799 +    , m_maximized(false)
800 +    , m_minimized(false)
801 +    , m_fullscreen(false)
802 +{
803 +}
804 +
805 +QWaylandXdgSurface::~QWaylandXdgSurface()
806 +{
807 +    xdg_surface_destroy(object());
808 +}
809 +
810 +void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges)
811 +{
812 +    // May need some conversion if types get incompatibles, ATM they're identical
813 +    enum resize_edge const * const arg = reinterpret_cast<enum resize_edge const * const>(&edges);
814 +    resize(inputDevice, *arg);
815 +}
816 +
817 +void QWaylandXdgSurface::resize(QWaylandInputDevice *inputDevice, enum resize_edge edges)
818 +{
819 +    resize(inputDevice->wl_seat(),
820 +           inputDevice->serial(),
821 +           edges);
822 +}
823 +
824 +void QWaylandXdgSurface::move(QWaylandInputDevice *inputDevice)
825 +{
826 +    move(inputDevice->wl_seat(),
827 +         inputDevice->serial());
828 +}
829 +
830 +void QWaylandXdgSurface::setMaximized()
831 +{
832 +    m_maximized = true;
833 +    m_size = m_window->window()->geometry().size();
834 +    set_maximized();
835 +}
836 +
837 +void QWaylandXdgSurface::setFullscreen()
838 +{
839 +    m_fullscreen = true;
840 +    m_size = m_window->window()->geometry().size();
841 +    set_fullscreen();
842 +}
843 +
844 +void QWaylandXdgSurface::setNormal()
845 +{
846 +    if (m_fullscreen || m_maximized  || m_minimized) {
847 +        if (m_maximized) { unset_maximized(); }
848 +        if (m_fullscreen) { unset_fullscreen(); }
849 +
850 +        m_fullscreen = m_maximized = m_minimized = false;
851 +        setTopLevel();
852 +        QMargins m = m_window->frameMargins();
853 +        m_window->configure(0, m_size.width() + m.left() + m.right(), m_size.height() + m.top() + m.bottom());
854 +    }
855 +}
856 +
857 +void QWaylandXdgSurface::setMinimized()
858 +{
859 +    m_minimized = true;
860 +    m_size = m_window->window()->geometry().size();
861 +    set_minimized();
862 +}
863 +
864 +void QWaylandXdgSurface::setTopLevel()
865 +{
866 +    // There's no xdg_shell_surface API for this, ignoring
867 +}
868 +
869 +void QWaylandXdgSurface::updateTransientParent(QWindow *parent)
870 +{
871 +    QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
872 +    if (!parent_wayland_window)
873 +        return;
874 +
875 +    // set_transient expects a position relative to the parent
876 +    QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
877 +    QWindow *parentWin = m_window->window()->transientParent();
878 +    transientPos -= parentWin->geometry().topLeft();
879 +    if (parent_wayland_window->decoration()) {
880 +        transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
881 +        transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
882 +    }
883 +
884 +    uint32_t flags = 0;
885 +    Qt::WindowFlags wf = m_window->window()->flags();
886 +    if (wf.testFlag(Qt::ToolTip)
887 +            || wf.testFlag(Qt::WindowTransparentForInput))
888 +        flags |= XDG_SURFACE_SET_TRANSIENT_FOR;
889 +
890 +    set_transient_for(parent_wayland_window->object());
891 +}
892 +
893 +void QWaylandXdgSurface::setTitle(const QString & title)
894 +{
895 +    return QtWayland::xdg_surface::set_title(title);
896 +}
897 +
898 +void QWaylandXdgSurface::setAppId(const QString & appId)
899 +{
900 +    return QtWayland::xdg_surface::set_app_id(appId);
901 +}
902 +
903 +void QWaylandXdgSurface::xdg_surface_ping(uint32_t serial)
904 +{
905 +    pong(serial);
906 +}
907 +
908 +void QWaylandXdgSurface::xdg_surface_configure(uint32_t edges, int32_t width,
909 +                                               int32_t height)
910 +{
911 +    m_window->configure(edges, width, height);
912 +}
913 +
914 +
915 +QT_END_NAMESPACE
916 diff --git a/src/client/qwaylandxdgsurface_p.h b/src/client/qwaylandxdgsurface_p.h
917 new file mode 100644
918 index 0000000..744d3f3
919 --- /dev/null
920 +++ b/src/client/qwaylandxdgsurface_p.h
921 @@ -0,0 +1,105 @@
922 +/****************************************************************************
923 +**
924 +** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
925 +** Contact: http://www.qt-project.org/legal
926 +**
927 +** This file is part of the config.tests of the Qt Toolkit.
928 +**
929 +** $QT_BEGIN_LICENSE:LGPL$
930 +** Commercial License Usage
931 +** Licensees holding valid commercial Qt licenses may use this file in
932 +** accordance with the commercial license agreement provided with the
933 +** Software or, alternatively, in accordance with the terms contained in
934 +** a written agreement between you and Digia.  For licensing terms and
935 +** conditions see http://qt.digia.com/licensing.  For further information
936 +** use the contact form at http://qt.digia.com/contact-us.
937 +**
938 +** GNU Lesser General Public License Usage
939 +** Alternatively, this file may be used under the terms of the GNU Lesser
940 +** General Public License version 2.1 as published by the Free Software
941 +** Foundation and appearing in the file LICENSE.LGPL included in the
942 +** packaging of this file.  Please review the following information to
943 +** ensure the GNU Lesser General Public License version 2.1 requirements
944 +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
945 +**
946 +** In addition, as a special exception, Digia gives you certain additional
947 +** rights.  These rights are described in the Digia Qt LGPL Exception
948 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
949 +**
950 +** GNU General Public License Usage
951 +** Alternatively, this file may be used under the terms of the GNU
952 +** General Public License version 3.0 as published by the Free Software
953 +** Foundation and appearing in the file LICENSE.GPL included in the
954 +** packaging of this file.  Please review the following information to
955 +** ensure the GNU General Public License version 3.0 requirements will be
956 +** met: http://www.gnu.org/copyleft/gpl.html.
957 +**
958 +**
959 +** $QT_END_LICENSE$
960 +**
961 +****************************************************************************/
962 +
963 +#ifndef QWAYLANDXDGSURFACE_H
964 +#define QWAYLANDXDGSURFACE_H
965 +
966 +#include <QtCore/QSize>
967 +
968 +#include <wayland-client.h>
969 +
970 +#include <QtWaylandClient/private/qwayland-xdg-shell.h>
971 +#include <QtWaylandClient/private/qwaylandclientexport_p.h>
972 +#include "qwaylandshellsurface_p.h"
973 +
974 +QT_BEGIN_NAMESPACE
975 +
976 +class QWaylandWindow;
977 +class QWaylandInputDevice;
978 +class QWindow;
979 +
980 +class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgSurface : public QtWayland::xdg_surface
981 +        , public QWaylandShellSurface
982 +{
983 +public:
984 +    QWaylandXdgSurface(struct ::xdg_surface *shell_surface, QWaylandWindow *window);
985 +    virtual ~QWaylandXdgSurface();
986 +
987 +    using QtWayland::xdg_surface::resize;
988 +    void resize(QWaylandInputDevice *inputDevice, enum resize_edge edges);
989 +
990 +    void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges) Q_DECL_OVERRIDE;
991 +
992 +    using QtWayland::xdg_surface::move;
993 +    void move(QWaylandInputDevice *inputDevice) Q_DECL_OVERRIDE;
994 +
995 +    void setTitle(const QString &title) Q_DECL_OVERRIDE;
996 +    void setAppId(const QString &appId) Q_DECL_OVERRIDE;
997 +
998 +    bool isFullscreen() const { return m_fullscreen; }
999 +    bool isMaximized() const { return m_maximized; }
1000 +
1001 +private:
1002 +    void setMaximized() Q_DECL_OVERRIDE;
1003 +    void setFullscreen() Q_DECL_OVERRIDE;
1004 +    void setNormal() Q_DECL_OVERRIDE;
1005 +    void setMinimized() Q_DECL_OVERRIDE;
1006 +
1007 +    void setTopLevel() Q_DECL_OVERRIDE;
1008 +    void updateTransientParent(QWindow *parent) Q_DECL_OVERRIDE;
1009 +
1010 +private:
1011 +    QWaylandWindow *m_window;
1012 +    bool m_maximized;
1013 +    bool m_minimized;
1014 +    bool m_fullscreen;
1015 +    QSize m_size;
1016 +
1017 +    void xdg_surface_ping(uint32_t serial) Q_DECL_OVERRIDE;
1018 +    void xdg_surface_configure(uint32_t edges,
1019 +                               int32_t width,
1020 +                               int32_t height) Q_DECL_OVERRIDE;
1021 +    friend class QWaylandWindow;
1022 +};
1023 +
1024 +QT_END_NAMESPACE
1025 +
1026 +#endif // QWAYLANDXDGSURFACE_H
1027 -- 
1028 1.9.1
1029