diff --git a/src/3rdparty/wayland/protocols/xdg-shell.xml b/src/3rdparty/wayland/protocols/xdg-shell.xml
index 79a283173ff..275837f3dc0 100644
--- a/src/3rdparty/wayland/protocols/xdg-shell.xml
+++ b/src/3rdparty/wayland/protocols/xdg-shell.xml
@@ -45,7 +45,7 @@
they implement using static_assert to ensure the protocol and
implementation versions match.
-
+
@@ -137,11 +137,8 @@
-
+
- Setting a surface as transient of another means that it is child
- of another surface.
-
Child surfaces are stacked above their parents, and will be
unmapped if the parent is unmapped too. They should not appear
on task bars and alt+tab.
@@ -149,32 +146,6 @@
-
-
- This tells the compositor what the visible size of the window
- should be, so it can use it to determine what borders to use for
- constrainment and alignment.
-
- CSD often has invisible areas for decoration purposes, like drop
- shadows. These "shadow" drawings need to be subtracted out of the
- normal boundaries of the window when computing where to place
- windows (e.g. to set this window so it's centered on top of another,
- or to put it to the left or right of the screen.)
-
- This value should change as little as possible at runtime, to
- prevent flicker.
-
- This value is also ignored when the window is maximized or
- fullscreen, and assumed to be 0.
-
- If never called, this value is assumed to be 0.
-
-
-
-
-
-
-
Set a short title for the surface.
@@ -201,6 +172,26 @@
+
+
+ Clients implementing client-side decorations might want to show
+ a context menu when right-clicking on the decorations, giving the
+ user a menu that they can use to maximize or minimize the window.
+
+ This request asks the compositor to pop up such a window menu at
+ the given position, relative to the parent surface. There are
+ no guarantees as to what the window menu contains.
+
+ Your surface must have focus on the seat passed in to pop up the
+ window menu.
+
+
+
+
+
+
+
+
Start a pointer-driven move of the surface.
@@ -244,46 +235,12 @@
-
-
- The configure event asks the client to resize its surface.
-
- The size is a hint, in the sense that the client is free to
- ignore it if it doesn't resize, pick a smaller size (to
- satisfy aspect ratio or resize in steps of NxM pixels).
-
- The client is free to dismiss all but the last configure
- event it received.
-
- The width and height arguments specify the size of the window
- in surface local coordinates.
-
-
-
-
-
-
-
-
- Set the default output used by this surface when it is first mapped.
-
- If this value is NULL (default), it's up to the compositor to choose
- which display will be used to map this surface.
-
- When fullscreen or maximized state are set on this surface, and it
- wasn't mapped yet, the output set with this method will be used.
- Otherwise, the output where the surface is currently mapped will be
- used.
-
-
-
-
The different state values used on the surface. This is designed for
state values like maximized, fullscreen. It is paired with the
- request_change_state event to ensure that both the client and the
- compositor setting the state can be synchronized.
+ configure event to ensure that both the client and the compositor
+ setting the state can be synchronized.
States set in this way are double-buffered. They will get applied on
the next commit.
@@ -300,89 +257,101 @@
0x1000 - 0x1FFF: GNOME
- A non-zero value indicates the surface is maximized. Otherwise,
- the surface is unmaximized.
+ The surface is maximized. The window geometry specified in the configure
+ event must be obeyed by the client.
- A non-zero value indicates the surface is fullscreen. Otherwise,
- the surface is not fullscreen.
+ The surface is fullscreen. The window geometry specified in the configure
+ event must be obeyed by the client.
+
+
+ The surface is being resized. The window geometry specified in the
+ configure event is a maximum; the client cannot resize beyond it.
+ Clients that have aspect ratio or cell sizing configuration can use
+ a smaller size, however.
+
+
+ Client window decorations should be painted as if the window is
+ active. Do not assume this means that the window actually has
+ keyboard or pointer focus.
-
-
- This asks the compositor to change the state. If the compositor wants
- to change the state, it will send a change_state event with the same
- state_type, value, and serial, and the event flow continues as if it
- it was initiated by the compositor.
+
+
+ The configure event asks the client to resize its surface.
- If the compositor does not want to change the state, it will send a
- change_state to the client with the old value of the state.
-
-
-
-
- This serial is so the client can know which change_state event corresponds
- to which request_change_state request it sent out.
-
-
+ The width and height arguments specify a hint to the window
+ about how its surface should be resized in window geometry
+ coordinates. The states listed in the event specify how the
+ width/height arguments should be interpreted.
-
-
- This event tells the client to change a surface's state. The client
- should respond with an ack_change_state request to the compositor to
- guarantee that the compositor knows that the client has seen it.
+ A client should arrange a new surface, and then send a
+ ack_configure request with the serial sent in this configure
+ event before attaching a new surface.
+
+ If the client receives multiple configure events before it
+ can respond to one, it is free to discard all but the last
+ event it received.
-
-
-
+
+
+
+
-
-
- When a change_state event is received, a client should then ack it
- using the ack_change_state request to ensure that the compositor
+
+
+ When a configure event is received, a client should then ack it
+ using the ack_configure request to ensure that the compositor
knows the client has seen the event.
By this point, the state is confirmed, and the next attach should
- contain the buffer drawn for the new state value.
-
- The values here need to be the same as the values in the cooresponding
- change_state event.
+ contain the buffer drawn for the configure event you are acking.
-
-
-
+
-
-
- Minimize the surface.
+
+
+ The window geometry of a window is its "visible bounds" from the
+ user's perspective. Client-side decorations often have invisible
+ portions like drop-shadows which should be ignored for the
+ purposes of aligning, placing and constraining windows.
+
+ The default value is the full bounds of the surface, including any
+ subsurfaces. Once the window geometry of the surface is set once,
+ it is not possible to unset it, and it will remain the same until
+ set_window_geometry is called again, even if a new subsurface or
+ buffer is attached.
+
+ If responding to a configure event, the window geometry in here
+ must respect the sizing negotiations specified by the states in
+ the configure event.
+
+
+
+
-
-
- The activated_set event is sent when this surface has been
- activated, which means that the surface has user attention.
- Window decorations should be updated accordingly. You should
- not use this event for anything but the style of decorations
- you display, use wl_keyboard.enter and wl_keyboard.leave for
- determining keyboard focus.
-
-
+
+
-
-
- The deactivate event is sent when this surface has been
- deactivated, which means that the surface lost user attention.
- Window decorations should be updated accordingly. You should
- not use this event for anything but the style of decorations
- you display, use wl_keyboard.enter and wl_keyboard.leave for
- determining keyboard focus.
+
+
+ Make the surface fullscreen.
+
+ You can specify an output that you would prefer to be fullscreen.
+ If this value is NULL, it's up to the compositor to choose which
+ display will be used to map this surface.
-
+
+
+
+
+
diff --git a/src/plugins/platforms/wayland/qwaylandxdgsurface.cpp b/src/plugins/platforms/wayland/qwaylandxdgsurface.cpp
index 318ff86d944..7f0c7f418f6 100644
--- a/src/plugins/platforms/wayland/qwaylandxdgsurface.cpp
+++ b/src/plugins/platforms/wayland/qwaylandxdgsurface.cpp
@@ -48,7 +48,6 @@
#include "qwaylandscreen_p.h"
#include "qwaylandextendedsurface_p.h"
-#include
QT_BEGIN_NAMESPACE
@@ -94,36 +93,32 @@ void QWaylandXdgSurface::move(QWaylandInputDevice *inputDevice)
void QWaylandXdgSurface::setMaximized()
{
if (!m_maximized)
- request_change_state(XDG_SURFACE_STATE_MAXIMIZED, true, 0);
+ set_maximized();
}
void QWaylandXdgSurface::setFullscreen()
{
if (!m_fullscreen)
- request_change_state(XDG_SURFACE_STATE_FULLSCREEN, true, 0);
+ set_fullscreen(Q_NULLPTR);
}
void QWaylandXdgSurface::setNormal()
{
if (m_fullscreen || m_maximized || m_minimized) {
if (m_maximized) {
- request_change_state(XDG_SURFACE_STATE_MAXIMIZED, false, 0);
+ unset_maximized();
}
if (m_fullscreen) {
- request_change_state(XDG_SURFACE_STATE_FULLSCREEN, false, 0);
+ unset_fullscreen();
}
m_fullscreen = m_maximized = m_minimized = false;
- setTopLevel();
- QMargins m = m_window->frameMargins();
- m_window->configure(0, m_size.width() + m.left() + m.right(), m_size.height() + m.top() + m.bottom());
}
}
void QWaylandXdgSurface::setMinimized()
{
m_minimized = true;
- m_size = m_window->window()->geometry().size();
set_minimized();
}
@@ -138,22 +133,7 @@ void QWaylandXdgSurface::updateTransientParent(QWindow *parent)
if (!parent_wayland_window)
return;
- // set_transient expects a position relative to the parent
- QPoint transientPos = m_window->geometry().topLeft(); // this is absolute
- QWindow *parentWin = m_window->window()->transientParent();
- transientPos -= parentWin->geometry().topLeft();
- if (parent_wayland_window->decoration()) {
- transientPos.setX(transientPos.x() + parent_wayland_window->decoration()->margins().left());
- transientPos.setY(transientPos.y() + parent_wayland_window->decoration()->margins().top());
- }
-
- uint32_t flags = 0;
- Qt::WindowFlags wf = m_window->window()->flags();
- if (wf.testFlag(Qt::ToolTip)
- || wf.testFlag(Qt::WindowTransparentForInput))
- flags |= XDG_SURFACE_SET_TRANSIENT_FOR;
-
- set_transient_for(parent_wayland_window->object());
+ set_parent(parent_wayland_window->object());
}
void QWaylandXdgSurface::setTitle(const QString & title)
@@ -196,44 +176,64 @@ void QWaylandXdgSurface::sendProperty(const QString &name, const QVariant &value
m_extendedWindow->updateGenericProperty(name, value);
}
-void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height)
+void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height, struct wl_array *states,uint32_t serial)
{
- m_window->configure(0 , width, height);
-}
+ uint32_t *state = 0;
+ bool aboutToMaximize = false;
+ bool aboutToFullScreen = false;
-void QWaylandXdgSurface::xdg_surface_change_state(uint32_t state,
- uint32_t value,
- uint32_t serial)
-{
+ state = (uint32_t*) states->data;
- if (state == XDG_SURFACE_STATE_MAXIMIZED
- || state == XDG_SURFACE_STATE_FULLSCREEN) {
- if (value) {
- m_size = m_window->window()->geometry().size();
- } else {
- QMargins m = m_window->frameMargins();
- m_window->configure(0, m_size.width() + m.left() + m.right(), m_size.height() + m.top() + m.bottom());
+ for (uint32_t i=0; i < states->size; i++)
+ {
+ switch (*(state+i)) {
+ case XDG_SURFACE_STATE_MAXIMIZED:
+ aboutToMaximize = true;
+ break;
+ case XDG_SURFACE_STATE_FULLSCREEN:
+ aboutToFullScreen = true;
+ break;
+ case XDG_SURFACE_STATE_RESIZING:
+ m_margins = m_window->frameMargins();
+ width -= m_margins.left() + m_margins.right();
+ height -= m_margins.top() + m_margins.bottom();
+ m_size = QSize(width,height);
+ break;
+ case XDG_SURFACE_STATE_ACTIVATED:
+ // TODO: here about the missing window activation
+ break;
+ default:
+ break;
}
}
- switch (state) {
- case XDG_SURFACE_STATE_MAXIMIZED:
- m_maximized = value;
- break;
- case XDG_SURFACE_STATE_FULLSCREEN:
- m_fullscreen = value;
- break;
+ if (!m_fullscreen && aboutToFullScreen) {
+ m_fullscreen = true;
+ m_size = m_window->window()->geometry().size();
+ m_window->window()->showFullScreen();
+ } else if (m_fullscreen && !aboutToFullScreen) {
+ m_fullscreen = false;
+ m_window->window()->showNormal();
+ } else if (!m_maximized && aboutToMaximize) {
+ m_maximized = true;
+ m_size = m_window->window()->geometry().size();
+ m_window->window()->showMaximized();
+ } else if (m_maximized && !aboutToMaximize) {
+ m_maximized = false;
+ m_window->window()->showNormal();
}
- xdg_surface_ack_change_state(object(), state, value, serial);
-}
+ if (width == 0 && height == 0) {
+ width = m_size.width();
+ height = m_size.height();
+ }
-void QWaylandXdgSurface::xdg_surface_activated()
-{
-}
+ if (width > 0 && height > 0) {
+ m_margins = m_window->frameMargins();
+ m_window->configure(0, width + m_margins.left() + m_margins.right(), height + m_margins.top() + m_margins.bottom());
+ }
-void QWaylandXdgSurface::xdg_surface_deactivated()
-{
+ xdg_surface_ack_configure(object(), serial);
}
void QWaylandXdgSurface::xdg_surface_close()
diff --git a/src/plugins/platforms/wayland/qwaylandxdgsurface_p.h b/src/plugins/platforms/wayland/qwaylandxdgsurface_p.h
index 635c9496a7e..c5ae9c792c5 100644
--- a/src/plugins/platforms/wayland/qwaylandxdgsurface_p.h
+++ b/src/plugins/platforms/wayland/qwaylandxdgsurface_p.h
@@ -43,6 +43,7 @@
#define QWAYLANDXDGSURFACE_H
#include
+#include
#include
@@ -99,15 +100,13 @@ private:
bool m_minimized;
bool m_fullscreen;
QSize m_size;
+ QMargins m_margins;
QWaylandExtendedSurface *m_extendedWindow;
void xdg_surface_configure(int32_t width,
- int32_t height) Q_DECL_OVERRIDE;
- void xdg_surface_change_state(uint32_t state,
- uint32_t value,
- uint32_t serial) Q_DECL_OVERRIDE;
- void xdg_surface_activated() Q_DECL_OVERRIDE;
- void xdg_surface_deactivated() Q_DECL_OVERRIDE;
+ int32_t height,
+ struct wl_array *states,
+ uint32_t serial) Q_DECL_OVERRIDE;
void xdg_surface_close() Q_DECL_OVERRIDE;
friend class QWaylandWindow;