diff options
author | Pier Luigi Fiorini <pierluigi.fiorini@gmail.com> | 2013-01-09 22:00:01 +0100 |
---|---|---|
committer | Jørgen Lind <jorgen.lind@gmail.com> | 2013-01-10 08:59:51 +0100 |
commit | b483b70cc6d30828b9c7cf3fa176dc593b76037a (patch) | |
tree | 8e3cca6314f6752315b7e86fa7bbaba63d5ab8e6 /src | |
parent | d9e1acd6f6f037af766e1c043353f055af8ec635 (diff) |
Client-side decoration actions.
Add close, maximize and minimize buttons to the title bar.
However the minimize button is not yet implement, it seems missing from
the wl_shell_surface API.
Task-number: QTBUG-27465
Change-Id: Id683f069cf5b329f827af87f457cfd81a5c6e6a1
Reviewed-by: Jørgen Lind <jorgen.lind@gmail.com>
Diffstat (limited to 'src')
4 files changed, 114 insertions, 4 deletions
diff --git a/src/plugins/platforms/wayland/qwaylanddecoration.cpp b/src/plugins/platforms/wayland/qwaylanddecoration.cpp index 5d7df416c..b27c7b36f 100644 --- a/src/plugins/platforms/wayland/qwaylanddecoration.cpp +++ b/src/plugins/platforms/wayland/qwaylanddecoration.cpp @@ -50,6 +50,9 @@ #include <QtGui/QPainter> #include <QtGui/QRadialGradient> +#define BUTTON_WIDTH 25 +#define BUTTON_SPACING 5 + QWaylandDecoration::QWaylandDecoration(QWaylandWindow *window) : m_window(window->window()) , m_wayland_window(window) @@ -79,10 +82,14 @@ void QWaylandDecoration::paint(QPaintDevice *device) QRect(0, margins().top(), margins().left(), surfaceRect.height() - margins().top() - margins().bottom()), QRect(surfaceRect.width() - margins().right(), margins().top(), margins().left(), surfaceRect.height() - margins().top() - margins().bottom()) }; + QRect top = clips[0]; + QPainter p(device); p.setRenderHint(QPainter::Antialiasing); - QPoint gradCenter(top.center()+ QPoint(30,60)); + + // Title bar + QPoint gradCenter(top.center()+ QPoint(30, 60)); QRadialGradient grad(gradCenter, top.width() / 2, gradCenter); QColor base(backgroundColor()); grad.setColorAt(1, base); @@ -96,7 +103,7 @@ void QWaylandDecoration::paint(QPaintDevice *device) p.restore(); } - + // Window title QString windowTitleText = window()->title(); if (!windowTitleText.isEmpty()) { if (m_windowTitle.text() != windowTitleText) { @@ -122,14 +129,69 @@ void QWaylandDecoration::paint(QPaintDevice *device) p.drawStaticText(windowTitlePoint,m_windowTitle); p.restore(); } + + // We don't need antialiasing from now on + p.setRenderHint(QPainter::Antialiasing, false); + + QRectF rect; + + // Default pen + QPen pen(QColor(0xee, 0xee, 0xee)); + p.setPen(pen); + + // Close button + p.save(); + rect = closeButtonRect(); + p.drawRect(rect); + qreal crossSize = rect.height() / 2; + QPointF crossCenter(rect.center()); + QRectF crossRect(crossCenter.x() - crossSize / 2, crossCenter.y() - crossSize / 2, crossSize, crossSize); + pen.setWidth(2); + p.setPen(pen); + p.drawLine(crossRect.topLeft(), crossRect.bottomRight()); + p.drawLine(crossRect.bottomLeft(), crossRect.topRight()); + p.restore(); + + // Maximize button + p.save(); + p.drawRect(maximizeButtonRect()); + rect = maximizeButtonRect().adjusted(5, 5, -5, -5); + if (m_wayland_window->shellSurface()->isMaximized()) { + QRectF rect1 = rect.adjusted(rect.width() / 3, 0, 0, -rect.height() / 3); + QRectF rect2 = rect.adjusted(0, rect.height() / 4, -rect.width() / 4, 0); + p.drawRect(rect1); + p.drawRect(rect2); + } else { + p.setPen(QColor(0xee, 0xee, 0xee)); + p.drawRect(rect); + p.drawLine(rect.left(), rect.top() + 1, rect.right(), rect.top() + 1); + } + p.restore(); + + // Minimize button + p.save(); + p.drawRect(minimizeButtonRect()); + rect = minimizeButtonRect().adjusted(5, 5, -5, -5); + pen.setWidth(2); + p.setPen(pen); + p.drawLine(rect.bottomLeft(), rect.bottomRight()); + p.restore(); } void QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::MouseButtons b, Qt::KeyboardModifiers mods) { Q_UNUSED(global); - //figure out what area mouse is in - if (local.y() <= m_margins.top()) { + + // Figure out what area mouse is in + if (closeButtonRect().contains(local) && isLeftClicked(b)) { + if (m_wayland_window->window()) + QCoreApplication::postEvent(m_wayland_window->window(), new QCloseEvent()); + } else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) { + m_wayland_window->shellSurface()->toggleMaximize(); + } else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) { + m_wayland_window->shellSurface()->minimize(); + } else if (local.y() <= m_margins.top()) { processMouseTop(inputDevice,local,b,mods); } else if (local.y() > m_window->height() - m_margins.bottom()) { processMouseBottom(inputDevice,local,b,mods); @@ -140,6 +202,7 @@ void QWaylandDecoration::handleMouse(QWaylandInputDevice *inputDevice, const QPo } else { restoreMouseCursor(); } + m_mouseButtons = b; } @@ -240,6 +303,24 @@ bool QWaylandDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState) return false; } +QRectF QWaylandDecoration::closeButtonRect() const +{ + return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 2, + BUTTON_SPACING, BUTTON_WIDTH, margins().top() - BUTTON_SPACING * 2); +} + +QRectF QWaylandDecoration::maximizeButtonRect() const +{ + return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 3, + BUTTON_SPACING, BUTTON_WIDTH, margins().top() - BUTTON_SPACING * 2); +} + +QRectF QWaylandDecoration::minimizeButtonRect() const +{ + return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 4, + BUTTON_SPACING, BUTTON_WIDTH, margins().top() - BUTTON_SPACING * 2); +} + void QWaylandDecoration::setBackgroundColor(const QColor &c) { m_backgroundColor = c; diff --git a/src/plugins/platforms/wayland/qwaylanddecoration.h b/src/plugins/platforms/wayland/qwaylanddecoration.h index 92c9457db..b1f31ed11 100644 --- a/src/plugins/platforms/wayland/qwaylanddecoration.h +++ b/src/plugins/platforms/wayland/qwaylanddecoration.h @@ -95,6 +95,10 @@ private: bool isLeftClicked(Qt::MouseButtons newMouseButtonState); bool isLeftReleased(Qt::MouseButtons newMouseButtonState); + QRectF closeButtonRect() const; + QRectF maximizeButtonRect() const; + QRectF minimizeButtonRect() const; + QWindow *m_window; QWaylandWindow *m_wayland_window; diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp index de0101f9b..8403341e3 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.cpp +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.cpp @@ -51,6 +51,7 @@ QWaylandShellSurface::QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window) : m_shell_surface(shell_surface) , m_window(window) + , m_maximized(false) { wl_shell_surface_add_listener(m_shell_surface,&m_shell_surface_listener,this); } @@ -74,6 +75,24 @@ void QWaylandShellSurface::move(QWaylandInputDevice *inputDevice) QWaylandDisplay::currentTimeMillisec()); } +void QWaylandShellSurface::toggleMaximize() +{ + if (m_maximized) { + setTopLevel(); + m_window->configure(0, m_size.width(), m_size.height()); + } else { + m_size = m_window->window()->frameGeometry().size(); + wl_shell_surface_set_maximized(m_shell_surface, 0); + } + + m_maximized = !m_maximized; +} + +void QWaylandShellSurface::minimize() +{ + // TODO: There's no wl_shell_surface API for this +} + void QWaylandShellSurface::setTopLevel() { wl_shell_surface_set_toplevel(m_shell_surface); diff --git a/src/plugins/platforms/wayland/qwaylandshellsurface.h b/src/plugins/platforms/wayland/qwaylandshellsurface.h index d18bda36d..8357ec246 100644 --- a/src/plugins/platforms/wayland/qwaylandshellsurface.h +++ b/src/plugins/platforms/wayland/qwaylandshellsurface.h @@ -56,8 +56,12 @@ public: QWaylandShellSurface(struct wl_shell_surface *shell_surface, QWaylandWindow *window); ~QWaylandShellSurface(); + bool isMaximized() const { return m_maximized; } + void resize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize edges); void move(QWaylandInputDevice *inputDevice); + void toggleMaximize(); + void minimize(); void setTopLevel(); void updateTransientParent(QWindow *parent); @@ -71,6 +75,8 @@ public: private: struct wl_shell_surface *m_shell_surface; QWaylandWindow *m_window; + bool m_maximized; + QSize m_size; static void ping(void *data, struct wl_shell_surface *wl_shell_surface, |