QtWaylandClient: Pluginize window decorations.
Convert to a D-pointer, split between abstract base class and an implementation. Also move implementation of the current built-in decoration to the "bradient" plugin, named in glorious memory of the programmer-designed blue gradient that will forever sear our eyeballs. The decoration plugin may be specified using the environment variable QT_WAYLAND_DECORATION. Change-Id: Idc99ab06ae138ad299bad2b62b9595379bd007ab Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
This commit is contained in:
parent
abd71e1305
commit
9dca9722f0
@ -3,7 +3,7 @@ QT += core-private gui-private
|
|||||||
QT_FOR_PRIVATE += platformsupport-private
|
QT_FOR_PRIVATE += platformsupport-private
|
||||||
|
|
||||||
MODULE=waylandclient
|
MODULE=waylandclient
|
||||||
MODULE_PLUGIN_TYPES = wayland-graphics-integration-client
|
MODULE_PLUGIN_TYPES = wayland-graphics-integration-client wayland-decoration-client
|
||||||
|
|
||||||
load(qt_module)
|
load(qt_module)
|
||||||
|
|
||||||
@ -70,6 +70,8 @@ SOURCES += qwaylandintegration.cpp \
|
|||||||
qwaylandqtkey.cpp \
|
qwaylandqtkey.cpp \
|
||||||
../shared/qwaylandmimehelper.cpp \
|
../shared/qwaylandmimehelper.cpp \
|
||||||
qwaylandabstractdecoration.cpp \
|
qwaylandabstractdecoration.cpp \
|
||||||
|
qwaylanddecorationfactory.cpp \
|
||||||
|
qwaylanddecorationplugin.cpp \
|
||||||
qwaylandeventthread.cpp\
|
qwaylandeventthread.cpp\
|
||||||
qwaylandwindowmanagerintegration.cpp \
|
qwaylandwindowmanagerintegration.cpp \
|
||||||
qwaylandinputcontext.cpp \
|
qwaylandinputcontext.cpp \
|
||||||
@ -101,6 +103,8 @@ HEADERS += qwaylandintegration_p.h \
|
|||||||
qwaylandqtkey_p.h \
|
qwaylandqtkey_p.h \
|
||||||
../shared/qwaylandmimehelper.h \
|
../shared/qwaylandmimehelper.h \
|
||||||
qwaylandabstractdecoration_p.h \
|
qwaylandabstractdecoration_p.h \
|
||||||
|
qwaylanddecorationfactory_p.h \
|
||||||
|
qwaylanddecorationplugin_p.h \
|
||||||
qwaylandeventthread_p.h \
|
qwaylandeventthread_p.h \
|
||||||
qwaylandwindowmanagerintegration_p.h \
|
qwaylandwindowmanagerintegration_p.h \
|
||||||
qwaylandinputcontext_p.h \
|
qwaylandinputcontext_p.h \
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"Keys": [ "bradient" ]
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
PLUGIN_TYPE = wayland-decoration-client
|
||||||
|
load(qt_plugin)
|
||||||
|
|
||||||
|
QT += waylandclient-private
|
||||||
|
|
||||||
|
OTHER_FILES += \
|
||||||
|
bradient.json
|
||||||
|
|
||||||
|
SOURCES += main.cpp
|
||||||
|
|
||||||
|
contains(QT_CONFIG, no-pkg-config) {
|
||||||
|
LIBS += -lwayland-client
|
||||||
|
} else {
|
||||||
|
CONFIG += link_pkgconfig
|
||||||
|
PKGCONFIG += wayland-client
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,452 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
|
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/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 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 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 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <QtGui/QCursor>
|
||||||
|
#include <QtGui/QPainter>
|
||||||
|
#include <QtGui/QPalette>
|
||||||
|
#include <QtGui/QLinearGradient>
|
||||||
|
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
|
#include <QtWaylandClient/private/qwaylanddecorationplugin_p.h>
|
||||||
|
#include <QtWaylandClient/private/qwaylandabstractdecoration_p.h>
|
||||||
|
#include <QtWaylandClient/private/qwaylandwindow_p.h>
|
||||||
|
#include <QtWaylandClient/private/qwaylandshellsurface_p.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
#define BUTTON_SPACING 5
|
||||||
|
|
||||||
|
#ifndef QT_NO_IMAGEFORMAT_XPM
|
||||||
|
# define BUTTON_WIDTH 10
|
||||||
|
|
||||||
|
static const char * const qt_close_xpm[] = {
|
||||||
|
"10 10 2 1",
|
||||||
|
"# c #000000",
|
||||||
|
". c None",
|
||||||
|
"..........",
|
||||||
|
".##....##.",
|
||||||
|
"..##..##..",
|
||||||
|
"...####...",
|
||||||
|
"....##....",
|
||||||
|
"...####...",
|
||||||
|
"..##..##..",
|
||||||
|
".##....##.",
|
||||||
|
"..........",
|
||||||
|
".........."};
|
||||||
|
|
||||||
|
static const char * const qt_maximize_xpm[]={
|
||||||
|
"10 10 2 1",
|
||||||
|
"# c #000000",
|
||||||
|
". c None",
|
||||||
|
"#########.",
|
||||||
|
"#########.",
|
||||||
|
"#.......#.",
|
||||||
|
"#.......#.",
|
||||||
|
"#.......#.",
|
||||||
|
"#.......#.",
|
||||||
|
"#.......#.",
|
||||||
|
"#.......#.",
|
||||||
|
"#########.",
|
||||||
|
".........."};
|
||||||
|
|
||||||
|
static const char * const qt_minimize_xpm[] = {
|
||||||
|
"10 10 2 1",
|
||||||
|
"# c #000000",
|
||||||
|
". c None",
|
||||||
|
"..........",
|
||||||
|
"..........",
|
||||||
|
"..........",
|
||||||
|
"..........",
|
||||||
|
"..........",
|
||||||
|
"..........",
|
||||||
|
"..........",
|
||||||
|
".#######..",
|
||||||
|
".#######..",
|
||||||
|
".........."};
|
||||||
|
|
||||||
|
static const char * const qt_normalizeup_xpm[] = {
|
||||||
|
"10 10 2 1",
|
||||||
|
"# c #000000",
|
||||||
|
". c None",
|
||||||
|
"...######.",
|
||||||
|
"...######.",
|
||||||
|
"...#....#.",
|
||||||
|
".######.#.",
|
||||||
|
".######.#.",
|
||||||
|
".#....###.",
|
||||||
|
".#....#...",
|
||||||
|
".#....#...",
|
||||||
|
".######...",
|
||||||
|
".........."};
|
||||||
|
#else
|
||||||
|
# define BUTTON_WIDTH 22
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandBradientDecoration : public QWaylandAbstractDecoration
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QWaylandBradientDecoration();
|
||||||
|
protected:
|
||||||
|
QMargins margins() const Q_DECL_OVERRIDE;
|
||||||
|
void paint(QPaintDevice *device) Q_DECL_OVERRIDE;
|
||||||
|
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods) Q_DECL_OVERRIDE;
|
||||||
|
bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods) Q_DECL_OVERRIDE;
|
||||||
|
private:
|
||||||
|
void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
||||||
|
void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
||||||
|
void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
||||||
|
void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
||||||
|
|
||||||
|
QRectF closeButtonRect() const;
|
||||||
|
QRectF maximizeButtonRect() const;
|
||||||
|
QRectF minimizeButtonRect() const;
|
||||||
|
|
||||||
|
QColor m_foregroundColor;
|
||||||
|
QColor m_backgroundColor;
|
||||||
|
QStaticText m_windowTitle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QWaylandBradientDecoration::QWaylandBradientDecoration()
|
||||||
|
: QWaylandAbstractDecoration()
|
||||||
|
{
|
||||||
|
QPalette palette;
|
||||||
|
m_foregroundColor = palette.color(QPalette::Active, QPalette::HighlightedText);
|
||||||
|
m_backgroundColor = palette.color(QPalette::Active, QPalette::Highlight);
|
||||||
|
|
||||||
|
QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||||
|
option.setWrapMode(QTextOption::NoWrap);
|
||||||
|
m_windowTitle.setTextOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QWaylandBradientDecoration::closeButtonRect() const
|
||||||
|
{
|
||||||
|
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 2,
|
||||||
|
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QWaylandBradientDecoration::maximizeButtonRect() const
|
||||||
|
{
|
||||||
|
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 3,
|
||||||
|
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF QWaylandBradientDecoration::minimizeButtonRect() const
|
||||||
|
{
|
||||||
|
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 4,
|
||||||
|
(margins().top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMargins QWaylandBradientDecoration::margins() const
|
||||||
|
{
|
||||||
|
return QMargins(3, 30, 3, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandBradientDecoration::paint(QPaintDevice *device)
|
||||||
|
{
|
||||||
|
QRect surfaceRect(QPoint(), window()->frameGeometry().size());
|
||||||
|
QRect clips[] =
|
||||||
|
{
|
||||||
|
QRect(0, 0, surfaceRect.width(), margins().top()),
|
||||||
|
QRect(0, surfaceRect.height() - margins().bottom(), surfaceRect.width(), margins().bottom()),
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Title bar
|
||||||
|
QPoint gradCenter(top.center()+ QPoint(30, 60));
|
||||||
|
QLinearGradient grad(top.topLeft(), top.bottomLeft());
|
||||||
|
QColor base(m_backgroundColor);
|
||||||
|
grad.setColorAt(0, base.lighter(100));
|
||||||
|
grad.setColorAt(1, base.darker(180));
|
||||||
|
QPainterPath roundedRect;
|
||||||
|
roundedRect.addRoundedRect(surfaceRect, 6, 6);
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
p.save();
|
||||||
|
p.setClipRect(clips[i]);
|
||||||
|
p.fillPath(roundedRect, grad);
|
||||||
|
p.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window icon
|
||||||
|
QIcon icon = waylandWindow()->windowIcon();
|
||||||
|
if (!icon.isNull()) {
|
||||||
|
QPixmap pixmap = icon.pixmap(QSize(128, 128));
|
||||||
|
QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
|
||||||
|
QRectF iconRect(0, 0, 22, 22);
|
||||||
|
p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
|
||||||
|
margins().left() + BUTTON_SPACING, 4),
|
||||||
|
scaled, iconRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Window title
|
||||||
|
QString windowTitleText = window()->title();
|
||||||
|
if (!windowTitleText.isEmpty()) {
|
||||||
|
if (m_windowTitle.text() != windowTitleText) {
|
||||||
|
m_windowTitle.setText(windowTitleText);
|
||||||
|
m_windowTitle.prepare();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect titleBar = top;
|
||||||
|
titleBar.setLeft(margins().left() + BUTTON_SPACING +
|
||||||
|
(icon.isNull() ? 0 : 22 + BUTTON_SPACING));
|
||||||
|
titleBar.setRight(minimizeButtonRect().left() - BUTTON_SPACING);
|
||||||
|
|
||||||
|
p.save();
|
||||||
|
p.setClipRect(titleBar);
|
||||||
|
p.setPen(m_foregroundColor);
|
||||||
|
QSizeF size = m_windowTitle.size();
|
||||||
|
int dx = (top.width() - size.width()) /2;
|
||||||
|
int dy = (top.height()- size.height()) /2;
|
||||||
|
QFont font = p.font();
|
||||||
|
font.setBold(true);
|
||||||
|
p.setFont(font);
|
||||||
|
QPoint windowTitlePoint(top.topLeft().x() + dx,
|
||||||
|
top.topLeft().y() + dy);
|
||||||
|
p.drawStaticText(windowTitlePoint, m_windowTitle);
|
||||||
|
p.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_IMAGEFORMAT_XPM
|
||||||
|
p.save();
|
||||||
|
|
||||||
|
// Close button
|
||||||
|
QPixmap closePixmap(qt_close_xpm);
|
||||||
|
p.drawPixmap(closeButtonRect(), closePixmap, closePixmap.rect());
|
||||||
|
|
||||||
|
// Maximize button
|
||||||
|
QPixmap maximizePixmap(waylandWindow()->isMaximized()
|
||||||
|
? qt_normalizeup_xpm : qt_maximize_xpm);
|
||||||
|
p.drawPixmap(maximizeButtonRect(), maximizePixmap, maximizePixmap.rect());
|
||||||
|
|
||||||
|
// Minimize button
|
||||||
|
QPixmap minimizePixmap(qt_minimize_xpm);
|
||||||
|
p.drawPixmap(minimizeButtonRect(), minimizePixmap, minimizePixmap.rect());
|
||||||
|
|
||||||
|
p.restore();
|
||||||
|
#else
|
||||||
|
// We don't need antialiasing from now on
|
||||||
|
p.setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
|
||||||
|
QRectF rect;
|
||||||
|
|
||||||
|
// Default pen
|
||||||
|
QPen pen(m_foregroundColor);
|
||||||
|
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 (waylandWindow()->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(m_foregroundColor);
|
||||||
|
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();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QWaylandBradientDecoration::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 (closeButtonRect().contains(local) && isLeftClicked(b)) {
|
||||||
|
QWindowSystemInterface::handleCloseEvent(window());
|
||||||
|
} else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) {
|
||||||
|
window()->setWindowState(waylandWindow()->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
|
||||||
|
} else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) {
|
||||||
|
window()->setWindowState(Qt::WindowMinimized);
|
||||||
|
} else if (local.y() <= margins().top()) {
|
||||||
|
processMouseTop(inputDevice,local,b,mods);
|
||||||
|
} else if (local.y() > window()->height() - margins().bottom() + margins().top()) {
|
||||||
|
processMouseBottom(inputDevice,local,b,mods);
|
||||||
|
} else if (local.x() <= margins().left()) {
|
||||||
|
processMouseLeft(inputDevice,local,b,mods);
|
||||||
|
} else if (local.x() > window()->width() - margins().right() + margins().left()) {
|
||||||
|
processMouseRight(inputDevice,local,b,mods);
|
||||||
|
} else {
|
||||||
|
waylandWindow()->restoreMouseCursor(inputDevice);
|
||||||
|
setMouseButtons(b);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMouseButtons(b);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QWaylandBradientDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
|
||||||
|
{
|
||||||
|
Q_UNUSED(inputDevice);
|
||||||
|
Q_UNUSED(global);
|
||||||
|
Q_UNUSED(mods);
|
||||||
|
bool handled = state == Qt::TouchPointPressed;
|
||||||
|
if (handled) {
|
||||||
|
if (closeButtonRect().contains(local))
|
||||||
|
QWindowSystemInterface::handleCloseEvent(window());
|
||||||
|
else if (maximizeButtonRect().contains(local))
|
||||||
|
window()->setWindowState(waylandWindow()->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
|
||||||
|
else if (minimizeButtonRect().contains(local))
|
||||||
|
window()->setWindowState(Qt::WindowMinimized);
|
||||||
|
else if (local.y() <= margins().top())
|
||||||
|
waylandWindow()->shellSurface()->move(inputDevice);
|
||||||
|
else
|
||||||
|
handled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandBradientDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mods);
|
||||||
|
if (local.y() <= margins().bottom()) {
|
||||||
|
if (local.x() <= margins().left()) {
|
||||||
|
//top left bit
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
|
||||||
|
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b);
|
||||||
|
} else if (local.x() > window()->width() - margins().right()) {
|
||||||
|
//top right bit
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
|
||||||
|
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b);
|
||||||
|
} else {
|
||||||
|
//top reszie bit
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor);
|
||||||
|
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
waylandWindow()->restoreMouseCursor(inputDevice);
|
||||||
|
startMove(inputDevice,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandBradientDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mods);
|
||||||
|
if (local.x() <= margins().left()) {
|
||||||
|
//bottom left bit
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
|
||||||
|
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b);
|
||||||
|
} else if (local.x() > window()->width() - margins().right()) {
|
||||||
|
//bottom right bit
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
|
||||||
|
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b);
|
||||||
|
} else {
|
||||||
|
//bottom bit
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SplitVCursor);
|
||||||
|
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandBradientDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||||
|
{
|
||||||
|
Q_UNUSED(local);
|
||||||
|
Q_UNUSED(mods);
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SplitHCursor);
|
||||||
|
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QWaylandBradientDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
||||||
|
{
|
||||||
|
Q_UNUSED(local);
|
||||||
|
Q_UNUSED(mods);
|
||||||
|
waylandWindow()->setMouseCursor(inputDevice, Qt::SplitHCursor);
|
||||||
|
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b);
|
||||||
|
}
|
||||||
|
|
||||||
|
class QWaylandBradientDecorationPlugin : public QWaylandDecorationPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID QWaylandDecorationFactoryInterface_iid FILE "bradient.json")
|
||||||
|
public:
|
||||||
|
QWaylandAbstractDecoration *create(const QString&, const QStringList&) Q_DECL_OVERRIDE;
|
||||||
|
};
|
||||||
|
|
||||||
|
QWaylandAbstractDecoration *QWaylandBradientDecorationPlugin::create(const QString& system, const QStringList& paramList)
|
||||||
|
{
|
||||||
|
Q_UNUSED(paramList);
|
||||||
|
Q_UNUSED(system);
|
||||||
|
return new QWaylandBradientDecoration();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#include "main.moc"
|
@ -0,0 +1,3 @@
|
|||||||
|
TEMPLATE = subdirs
|
||||||
|
SUBDIRS += \
|
||||||
|
bradient
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
@ -41,431 +42,148 @@
|
|||||||
|
|
||||||
#include "qwaylandabstractdecoration_p.h"
|
#include "qwaylandabstractdecoration_p.h"
|
||||||
|
|
||||||
|
#include <private/qobject_p.h>
|
||||||
#include "qwaylandwindow_p.h"
|
#include "qwaylandwindow_p.h"
|
||||||
#include "qwaylandshellsurface_p.h"
|
#include "qwaylandshellsurface_p.h"
|
||||||
#include "qwaylandinputdevice_p.h"
|
#include "qwaylandinputdevice_p.h"
|
||||||
#include "qwaylandscreen_p.h"
|
#include "qwaylandscreen_p.h"
|
||||||
|
|
||||||
#include <QtGui/QGuiApplication>
|
|
||||||
#include <QtGui/QImage>
|
#include <QtGui/QImage>
|
||||||
#include <QtGui/QCursor>
|
|
||||||
#include <QtGui/QPainter>
|
|
||||||
#include <QtGui/QPalette>
|
|
||||||
#include <QtGui/QLinearGradient>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#define BUTTON_SPACING 5
|
class QWaylandAbstractDecorationPrivate : public QObjectPrivate
|
||||||
|
{
|
||||||
|
Q_DECLARE_PUBLIC(QWaylandAbstractDecoration)
|
||||||
|
|
||||||
#ifndef QT_NO_IMAGEFORMAT_XPM
|
public:
|
||||||
# define BUTTON_WIDTH 10
|
QWaylandAbstractDecorationPrivate();
|
||||||
|
~QWaylandAbstractDecorationPrivate();
|
||||||
|
|
||||||
static const char * const qt_close_xpm[] = {
|
QWindow *m_window;
|
||||||
"10 10 2 1",
|
QWaylandWindow *m_wayland_window;
|
||||||
"# c #000000",
|
|
||||||
". c None",
|
|
||||||
"..........",
|
|
||||||
".##....##.",
|
|
||||||
"..##..##..",
|
|
||||||
"...####...",
|
|
||||||
"....##....",
|
|
||||||
"...####...",
|
|
||||||
"..##..##..",
|
|
||||||
".##....##.",
|
|
||||||
"..........",
|
|
||||||
".........."};
|
|
||||||
|
|
||||||
static const char * const qt_maximize_xpm[]={
|
bool m_isDirty;
|
||||||
"10 10 2 1",
|
QImage m_decorationContentImage;
|
||||||
"# c #000000",
|
|
||||||
". c None",
|
|
||||||
"#########.",
|
|
||||||
"#########.",
|
|
||||||
"#.......#.",
|
|
||||||
"#.......#.",
|
|
||||||
"#.......#.",
|
|
||||||
"#.......#.",
|
|
||||||
"#.......#.",
|
|
||||||
"#.......#.",
|
|
||||||
"#########.",
|
|
||||||
".........."};
|
|
||||||
|
|
||||||
static const char * const qt_minimize_xpm[] = {
|
Qt::MouseButtons m_mouseButtons;
|
||||||
"10 10 2 1",
|
};
|
||||||
"# c #000000",
|
|
||||||
". c None",
|
|
||||||
"..........",
|
|
||||||
"..........",
|
|
||||||
"..........",
|
|
||||||
"..........",
|
|
||||||
"..........",
|
|
||||||
"..........",
|
|
||||||
"..........",
|
|
||||||
".#######..",
|
|
||||||
".#######..",
|
|
||||||
".........."};
|
|
||||||
|
|
||||||
static const char * const qt_normalizeup_xpm[] = {
|
QWaylandAbstractDecorationPrivate::QWaylandAbstractDecorationPrivate()
|
||||||
"10 10 2 1",
|
: m_window(0)
|
||||||
"# c #000000",
|
, m_wayland_window(0)
|
||||||
". c None",
|
|
||||||
"...######.",
|
|
||||||
"...######.",
|
|
||||||
"...#....#.",
|
|
||||||
".######.#.",
|
|
||||||
".######.#.",
|
|
||||||
".#....###.",
|
|
||||||
".#....#...",
|
|
||||||
".#....#...",
|
|
||||||
".######...",
|
|
||||||
".........."};
|
|
||||||
#else
|
|
||||||
# define BUTTON_WIDTH 22
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QWaylandAbstractDecoration::QWaylandAbstractDecoration(QWaylandWindow *window)
|
|
||||||
: m_window(window->window())
|
|
||||||
, m_wayland_window(window)
|
|
||||||
, m_isDirty(true)
|
, m_isDirty(true)
|
||||||
, m_decorationContentImage(0)
|
, m_decorationContentImage(0)
|
||||||
, m_margins(3,30,3,3)
|
|
||||||
, m_mouseButtons(Qt::NoButton)
|
, m_mouseButtons(Qt::NoButton)
|
||||||
{
|
{
|
||||||
m_wayland_window->setDecoration(this);
|
|
||||||
|
|
||||||
QPalette palette;
|
|
||||||
m_foregroundColor = palette.color(QPalette::Active, QPalette::HighlightedText);
|
|
||||||
m_backgroundColor = palette.color(QPalette::Active, QPalette::Highlight);
|
|
||||||
|
|
||||||
QTextOption option(Qt::AlignHCenter | Qt::AlignVCenter);
|
|
||||||
option.setWrapMode(QTextOption::NoWrap);
|
|
||||||
m_windowTitle.setTextOption(option);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWaylandAbstractDecoration::~QWaylandAbstractDecoration()
|
QWaylandAbstractDecorationPrivate::~QWaylandAbstractDecorationPrivate()
|
||||||
{
|
{
|
||||||
m_wayland_window->setDecoration(0);
|
m_wayland_window->setDecoration(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWaylandAbstractDecoration::QWaylandAbstractDecoration()
|
||||||
|
: QObject(*new QWaylandAbstractDecorationPrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandAbstractDecoration::~QWaylandAbstractDecoration()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// we do this as a setter to get around plugin factory creates not really
|
||||||
|
// being a great way to pass arguments
|
||||||
|
void QWaylandAbstractDecoration::setWaylandWindow(QWaylandWindow *window)
|
||||||
|
{
|
||||||
|
Q_D(QWaylandAbstractDecoration);
|
||||||
|
|
||||||
|
// double initialization is probably not great
|
||||||
|
Q_ASSERT(!d->m_window && !d->m_wayland_window);
|
||||||
|
|
||||||
|
d->m_window = window->window();
|
||||||
|
d->m_wayland_window = window;
|
||||||
|
d->m_wayland_window->setDecoration(this);
|
||||||
|
}
|
||||||
|
|
||||||
const QImage &QWaylandAbstractDecoration::contentImage()
|
const QImage &QWaylandAbstractDecoration::contentImage()
|
||||||
{
|
{
|
||||||
if (m_isDirty) {
|
Q_D(QWaylandAbstractDecoration);
|
||||||
|
if (d->m_isDirty) {
|
||||||
//Update the decoration backingstore
|
//Update the decoration backingstore
|
||||||
|
|
||||||
m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied);
|
d->m_decorationContentImage = QImage(window()->frameGeometry().size(), QImage::Format_ARGB32_Premultiplied);
|
||||||
m_decorationContentImage.fill(Qt::transparent);
|
d->m_decorationContentImage.fill(Qt::transparent);
|
||||||
this->paint(&m_decorationContentImage);
|
this->paint(&d->m_decorationContentImage);
|
||||||
|
|
||||||
m_isDirty = false;
|
d->m_isDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_decorationContentImage;
|
return d->m_decorationContentImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::update()
|
void QWaylandAbstractDecoration::update()
|
||||||
{
|
{
|
||||||
m_isDirty = true;
|
Q_D(QWaylandAbstractDecoration);
|
||||||
|
d->m_isDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::paint(QPaintDevice *device)
|
void QWaylandAbstractDecoration::setMouseButtons(Qt::MouseButtons mb)
|
||||||
{
|
{
|
||||||
QRect surfaceRect(QPoint(), window()->frameGeometry().size());
|
Q_D(QWaylandAbstractDecoration);
|
||||||
QRect clips[] =
|
d->m_mouseButtons = mb;
|
||||||
{
|
|
||||||
QRect(0, 0, surfaceRect.width(), margins().top()),
|
|
||||||
QRect(0, surfaceRect.height() - margins().bottom(), surfaceRect.width(), margins().bottom()),
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Title bar
|
|
||||||
QPoint gradCenter(top.center()+ QPoint(30, 60));
|
|
||||||
QLinearGradient grad(top.topLeft(), top.bottomLeft());
|
|
||||||
QColor base(m_backgroundColor);
|
|
||||||
grad.setColorAt(0, base.lighter(100));
|
|
||||||
grad.setColorAt(1, base.darker(180));
|
|
||||||
QPainterPath roundedRect;
|
|
||||||
roundedRect.addRoundedRect(surfaceRect, 6, 6);
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
p.save();
|
|
||||||
p.setClipRect(clips[i]);
|
|
||||||
p.fillPath(roundedRect, grad);
|
|
||||||
p.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Window icon
|
|
||||||
QIcon icon = m_wayland_window->windowIcon();
|
|
||||||
if (!icon.isNull()) {
|
|
||||||
QPixmap pixmap = icon.pixmap(QSize(128, 128));
|
|
||||||
QPixmap scaled = pixmap.scaled(22, 22, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
|
|
||||||
QRectF iconRect(0, 0, 22, 22);
|
|
||||||
p.drawPixmap(iconRect.adjusted(margins().left() + BUTTON_SPACING, 4,
|
|
||||||
margins().left() + BUTTON_SPACING, 4),
|
|
||||||
scaled, iconRect);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Window title
|
|
||||||
QString windowTitleText = window()->title();
|
|
||||||
if (!windowTitleText.isEmpty()) {
|
|
||||||
if (m_windowTitle.text() != windowTitleText) {
|
|
||||||
m_windowTitle.setText(windowTitleText);
|
|
||||||
m_windowTitle.prepare();
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect titleBar = top;
|
|
||||||
titleBar.setLeft(m_margins.left() + BUTTON_SPACING +
|
|
||||||
(icon.isNull() ? 0 : 22 + BUTTON_SPACING));
|
|
||||||
titleBar.setRight(minimizeButtonRect().left() - BUTTON_SPACING);
|
|
||||||
|
|
||||||
p.save();
|
|
||||||
p.setClipRect(titleBar);
|
|
||||||
p.setPen(m_foregroundColor);
|
|
||||||
QSizeF size = m_windowTitle.size();
|
|
||||||
int dx = (top.width() - size.width()) /2;
|
|
||||||
int dy = (top.height()- size.height()) /2;
|
|
||||||
QFont font = p.font();
|
|
||||||
font.setBold(true);
|
|
||||||
p.setFont(font);
|
|
||||||
QPoint windowTitlePoint(top.topLeft().x() + dx,
|
|
||||||
top.topLeft().y() + dy);
|
|
||||||
p.drawStaticText(windowTitlePoint,m_windowTitle);
|
|
||||||
p.restore();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef QT_NO_IMAGEFORMAT_XPM
|
|
||||||
p.save();
|
|
||||||
|
|
||||||
// Close button
|
|
||||||
QPixmap closePixmap(qt_close_xpm);
|
|
||||||
p.drawPixmap(closeButtonRect(), closePixmap, closePixmap.rect());
|
|
||||||
|
|
||||||
// Maximize button
|
|
||||||
QPixmap maximizePixmap(m_wayland_window->isMaximized()
|
|
||||||
? qt_normalizeup_xpm : qt_maximize_xpm);
|
|
||||||
p.drawPixmap(maximizeButtonRect(), maximizePixmap, maximizePixmap.rect());
|
|
||||||
|
|
||||||
// Minimize button
|
|
||||||
QPixmap minimizePixmap(qt_minimize_xpm);
|
|
||||||
p.drawPixmap(minimizeButtonRect(), minimizePixmap, minimizePixmap.rect());
|
|
||||||
|
|
||||||
p.restore();
|
|
||||||
#else
|
|
||||||
// We don't need antialiasing from now on
|
|
||||||
p.setRenderHint(QPainter::Antialiasing, false);
|
|
||||||
|
|
||||||
QRectF rect;
|
|
||||||
|
|
||||||
// Default pen
|
|
||||||
QPen pen(m_foregroundColor);
|
|
||||||
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->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(m_foregroundColor);
|
|
||||||
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();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QWaylandAbstractDecoration::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 (closeButtonRect().contains(local) && isLeftClicked(b)) {
|
|
||||||
QWindowSystemInterface::handleCloseEvent(m_window);
|
|
||||||
} else if (maximizeButtonRect().contains(local) && isLeftClicked(b)) {
|
|
||||||
m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
|
|
||||||
} else if (minimizeButtonRect().contains(local) && isLeftClicked(b)) {
|
|
||||||
m_window->setWindowState(Qt::WindowMinimized);
|
|
||||||
} else if (local.y() <= m_margins.top()) {
|
|
||||||
processMouseTop(inputDevice,local,b,mods);
|
|
||||||
} else if (local.y() > m_window->height() - m_margins.bottom() + m_margins.top()) {
|
|
||||||
processMouseBottom(inputDevice,local,b,mods);
|
|
||||||
} else if (local.x() <= m_margins.left()) {
|
|
||||||
processMouseLeft(inputDevice,local,b,mods);
|
|
||||||
} else if (local.x() > m_window->width() - m_margins.right() + m_margins.left()) {
|
|
||||||
processMouseRight(inputDevice,local,b,mods);
|
|
||||||
} else {
|
|
||||||
m_wayland_window->restoreMouseCursor(inputDevice);
|
|
||||||
m_mouseButtons = b;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_mouseButtons = b;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QWaylandAbstractDecoration::handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods)
|
|
||||||
{
|
|
||||||
Q_UNUSED(inputDevice);
|
|
||||||
Q_UNUSED(global);
|
|
||||||
Q_UNUSED(mods);
|
|
||||||
bool handled = state == Qt::TouchPointPressed;
|
|
||||||
if (handled) {
|
|
||||||
if (closeButtonRect().contains(local))
|
|
||||||
QWindowSystemInterface::handleCloseEvent(m_window);
|
|
||||||
else if (maximizeButtonRect().contains(local))
|
|
||||||
m_window->setWindowState(m_wayland_window->isMaximized() ? Qt::WindowNoState : Qt::WindowMaximized);
|
|
||||||
else if (minimizeButtonRect().contains(local))
|
|
||||||
m_window->setWindowState(Qt::WindowMinimized);
|
|
||||||
else if (local.y() <= m_margins.top())
|
|
||||||
m_wayland_window->shellSurface()->move(inputDevice);
|
|
||||||
else
|
|
||||||
handled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QWaylandAbstractDecoration::inMouseButtonPressedState() const
|
|
||||||
{
|
|
||||||
return m_mouseButtons & Qt::NoButton;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons)
|
void QWaylandAbstractDecoration::startResize(QWaylandInputDevice *inputDevice, enum wl_shell_surface_resize resize, Qt::MouseButtons buttons)
|
||||||
{
|
{
|
||||||
|
Q_D(QWaylandAbstractDecoration);
|
||||||
if (isLeftClicked(buttons)) {
|
if (isLeftClicked(buttons)) {
|
||||||
m_wayland_window->shellSurface()->resize(inputDevice, resize);
|
d->m_wayland_window->shellSurface()->resize(inputDevice, resize);
|
||||||
inputDevice->removeMouseButtonFromState(Qt::LeftButton);
|
inputDevice->removeMouseButtonFromState(Qt::LeftButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons)
|
void QWaylandAbstractDecoration::startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons)
|
||||||
{
|
{
|
||||||
|
Q_D(QWaylandAbstractDecoration);
|
||||||
if (isLeftClicked(buttons)) {
|
if (isLeftClicked(buttons)) {
|
||||||
m_wayland_window->shellSurface()->move(inputDevice);
|
d->m_wayland_window->shellSurface()->move(inputDevice);
|
||||||
inputDevice->removeMouseButtonFromState(Qt::LeftButton);
|
inputDevice->removeMouseButtonFromState(Qt::LeftButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
|
||||||
{
|
|
||||||
Q_UNUSED(mods);
|
|
||||||
if (local.y() <= m_margins.bottom()) {
|
|
||||||
if (local.x() <= margins().left()) {
|
|
||||||
//top left bit
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
|
|
||||||
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_LEFT,b);
|
|
||||||
} else if (local.x() > m_window->width() - margins().right()) {
|
|
||||||
//top right bit
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
|
|
||||||
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP_RIGHT,b);
|
|
||||||
} else {
|
|
||||||
//top reszie bit
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor);
|
|
||||||
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_TOP,b);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_wayland_window->restoreMouseCursor(inputDevice);
|
|
||||||
startMove(inputDevice,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
|
||||||
{
|
|
||||||
Q_UNUSED(mods);
|
|
||||||
if (local.x() <= margins().left()) {
|
|
||||||
//bottom left bit
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeBDiagCursor);
|
|
||||||
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT,b);
|
|
||||||
} else if (local.x() > m_window->width() - margins().right()) {
|
|
||||||
//bottom right bit
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SizeFDiagCursor);
|
|
||||||
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT,b);
|
|
||||||
} else {
|
|
||||||
//bottom bit
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitVCursor);
|
|
||||||
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_BOTTOM,b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
|
||||||
{
|
|
||||||
Q_UNUSED(local);
|
|
||||||
Q_UNUSED(mods);
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor);
|
|
||||||
startResize(inputDevice,WL_SHELL_SURFACE_RESIZE_LEFT,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QWaylandAbstractDecoration::processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b, Qt::KeyboardModifiers mods)
|
|
||||||
{
|
|
||||||
Q_UNUSED(local);
|
|
||||||
Q_UNUSED(mods);
|
|
||||||
m_wayland_window->setMouseCursor(inputDevice, Qt::SplitHCursor);
|
|
||||||
startResize(inputDevice, WL_SHELL_SURFACE_RESIZE_RIGHT,b);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QWaylandAbstractDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState)
|
bool QWaylandAbstractDecoration::isLeftClicked(Qt::MouseButtons newMouseButtonState)
|
||||||
{
|
{
|
||||||
if ((!m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton))
|
Q_D(QWaylandAbstractDecoration);
|
||||||
|
if ((!d->m_mouseButtons & Qt::LeftButton) && (newMouseButtonState & Qt::LeftButton))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QWaylandAbstractDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState)
|
bool QWaylandAbstractDecoration::isLeftReleased(Qt::MouseButtons newMouseButtonState)
|
||||||
{
|
{
|
||||||
if ((m_mouseButtons & Qt::LeftButton) && !(newMouseButtonState & Qt::LeftButton))
|
Q_D(QWaylandAbstractDecoration);
|
||||||
|
if ((d->m_mouseButtons & Qt::LeftButton) && !(newMouseButtonState & Qt::LeftButton))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QWaylandAbstractDecoration::closeButtonRect() const
|
bool QWaylandAbstractDecoration::isDirty() const
|
||||||
{
|
{
|
||||||
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH - BUTTON_SPACING * 2,
|
Q_D(const QWaylandAbstractDecoration);
|
||||||
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
return d->m_isDirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QWaylandAbstractDecoration::maximizeButtonRect() const
|
QWindow *QWaylandAbstractDecoration::window() const
|
||||||
{
|
{
|
||||||
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 2 - BUTTON_SPACING * 3,
|
Q_D(const QWaylandAbstractDecoration);
|
||||||
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
return d->m_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF QWaylandAbstractDecoration::minimizeButtonRect() const
|
QWaylandWindow *QWaylandAbstractDecoration::waylandWindow() const
|
||||||
{
|
{
|
||||||
return QRectF(window()->frameGeometry().width() - BUTTON_WIDTH * 3 - BUTTON_SPACING * 4,
|
Q_D(const QWaylandAbstractDecoration);
|
||||||
(m_margins.top() - BUTTON_WIDTH) / 2, BUTTON_WIDTH, BUTTON_WIDTH);
|
return d->m_wayland_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
|
||||||
** Contact: http://www.qt-project.org/legal
|
** Contact: http://www.qt-project.org/legal
|
||||||
**
|
**
|
||||||
@ -64,77 +65,41 @@ class QEvent;
|
|||||||
class QWaylandScreen;
|
class QWaylandScreen;
|
||||||
class QWaylandWindow;
|
class QWaylandWindow;
|
||||||
class QWaylandInputDevice;
|
class QWaylandInputDevice;
|
||||||
|
class QWaylandAbstractDecorationPrivate;
|
||||||
|
|
||||||
class Q_WAYLAND_CLIENT_EXPORT QWaylandAbstractDecoration
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandAbstractDecoration : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DECLARE_PRIVATE(QWaylandAbstractDecoration)
|
||||||
public:
|
public:
|
||||||
QWaylandAbstractDecoration(QWaylandWindow *window);
|
QWaylandAbstractDecoration();
|
||||||
virtual ~QWaylandAbstractDecoration();
|
virtual ~QWaylandAbstractDecoration();
|
||||||
|
|
||||||
|
void setWaylandWindow(QWaylandWindow *window);
|
||||||
|
QWaylandWindow *waylandWindow() const;
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
bool isDirty() const;
|
bool isDirty() const;
|
||||||
|
|
||||||
bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
virtual QMargins margins() const = 0;
|
||||||
bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods);
|
QWindow *window() const;
|
||||||
bool inMouseButtonPressedState() const;
|
const QImage &contentImage();
|
||||||
|
|
||||||
|
virtual bool handleMouse(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global,Qt::MouseButtons b,Qt::KeyboardModifiers mods) = 0;
|
||||||
|
virtual bool handleTouch(QWaylandInputDevice *inputDevice, const QPointF &local, const QPointF &global, Qt::TouchPointState state, Qt::KeyboardModifiers mods) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paint(QPaintDevice *device) = 0;
|
||||||
|
|
||||||
|
void setMouseButtons(Qt::MouseButtons mb);
|
||||||
|
|
||||||
void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons);
|
void startResize(QWaylandInputDevice *inputDevice,enum wl_shell_surface_resize resize, Qt::MouseButtons buttons);
|
||||||
void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons);
|
void startMove(QWaylandInputDevice *inputDevice, Qt::MouseButtons buttons);
|
||||||
QMargins margins() const;
|
|
||||||
QWindow *window() const;
|
|
||||||
QWaylandWindow *waylandWindow() const;
|
|
||||||
const QImage &contentImage();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void paint(QPaintDevice *device);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void processMouseTop(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
|
||||||
void processMouseBottom(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
|
||||||
void processMouseLeft(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
|
||||||
void processMouseRight(QWaylandInputDevice *inputDevice, const QPointF &local, Qt::MouseButtons b,Qt::KeyboardModifiers mods);
|
|
||||||
|
|
||||||
bool isLeftClicked(Qt::MouseButtons newMouseButtonState);
|
bool isLeftClicked(Qt::MouseButtons newMouseButtonState);
|
||||||
bool isLeftReleased(Qt::MouseButtons newMouseButtonState);
|
bool isLeftReleased(Qt::MouseButtons newMouseButtonState);
|
||||||
|
|
||||||
QRectF closeButtonRect() const;
|
|
||||||
QRectF maximizeButtonRect() const;
|
|
||||||
QRectF minimizeButtonRect() const;
|
|
||||||
|
|
||||||
QWindow *m_window;
|
|
||||||
QWaylandWindow *m_wayland_window;
|
|
||||||
|
|
||||||
bool m_isDirty;
|
|
||||||
QImage m_decorationContentImage;
|
|
||||||
|
|
||||||
QMargins m_margins;
|
|
||||||
Qt::MouseButtons m_mouseButtons;
|
|
||||||
|
|
||||||
QColor m_foregroundColor;
|
|
||||||
QColor m_backgroundColor;
|
|
||||||
QStaticText m_windowTitle;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool QWaylandAbstractDecoration::isDirty() const
|
|
||||||
{
|
|
||||||
return m_isDirty;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QMargins QWaylandAbstractDecoration::margins() const
|
|
||||||
{
|
|
||||||
return m_margins;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QWindow *QWaylandAbstractDecoration::window() const
|
|
||||||
{
|
|
||||||
return m_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QWaylandWindow *QWaylandAbstractDecoration::waylandWindow() const
|
|
||||||
{
|
|
||||||
return m_wayland_window;
|
|
||||||
}
|
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QWAYLANDABSTRACTDECORATION_H
|
#endif // QWAYLANDABSTRACTDECORATION_H
|
||||||
|
97
src/plugins/platforms/wayland/qwaylanddecorationfactory.cpp
Normal file
97
src/plugins/platforms/wayland/qwaylanddecorationfactory.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/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 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 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 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qwaylanddecorationfactory_p.h"
|
||||||
|
#include "qwaylanddecorationplugin_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/private/qfactoryloader_p.h>
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
#ifndef QT_NO_LIBRARY
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
|
||||||
|
(QWaylandDecorationFactoryInterface_iid, QLatin1String("/wayland-decoration-client"), Qt::CaseInsensitive))
|
||||||
|
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, directLoader,
|
||||||
|
(QWaylandDecorationFactoryInterface_iid, QLatin1String(""), Qt::CaseInsensitive))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QStringList QWaylandDecorationFactory::keys(const QString &pluginPath)
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_LIBRARY
|
||||||
|
QStringList list;
|
||||||
|
if (!pluginPath.isEmpty()) {
|
||||||
|
QCoreApplication::addLibraryPath(pluginPath);
|
||||||
|
list = directLoader()->keyMap().values();
|
||||||
|
if (!list.isEmpty()) {
|
||||||
|
const QString postFix = QStringLiteral(" (from ")
|
||||||
|
+ QDir::toNativeSeparators(pluginPath)
|
||||||
|
+ QLatin1Char(')');
|
||||||
|
const QStringList::iterator end = list.end();
|
||||||
|
for (QStringList::iterator it = list.begin(); it != end; ++it)
|
||||||
|
(*it).append(postFix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
list.append(loader()->keyMap().values());
|
||||||
|
return list;
|
||||||
|
#else
|
||||||
|
return QStringList();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QWaylandAbstractDecoration *QWaylandDecorationFactory::create(const QString &name, const QStringList &args, const QString &pluginPath)
|
||||||
|
{
|
||||||
|
#ifndef QT_NO_LIBRARY
|
||||||
|
// Try loading the plugin from platformPluginPath first:
|
||||||
|
if (!pluginPath.isEmpty()) {
|
||||||
|
QCoreApplication::addLibraryPath(pluginPath);
|
||||||
|
if (QWaylandAbstractDecoration *ret = qLoadPlugin1<QWaylandAbstractDecoration, QWaylandDecorationPlugin>(directLoader(), name, args))
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (QWaylandAbstractDecoration *ret = qLoadPlugin1<QWaylandAbstractDecoration, QWaylandDecorationPlugin>(loader(), name, args))
|
||||||
|
return ret;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
61
src/plugins/platforms/wayland/qwaylanddecorationfactory_p.h
Normal file
61
src/plugins/platforms/wayland/qwaylanddecorationfactory_p.h
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/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 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 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 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QWAYLANDDECORATIONFACTORY_H
|
||||||
|
#define QWAYLANDDECORATIONFACTORY_H
|
||||||
|
|
||||||
|
#include <QtWaylandClient/private/qwaylandclientexport_p.h>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QWaylandAbstractDecoration;
|
||||||
|
|
||||||
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandDecorationFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static QStringList keys(const QString &pluginPath = QString());
|
||||||
|
static QWaylandAbstractDecoration *create(const QString &name, const QStringList &args, const QString &pluginPath = QString());
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QWAYLANDDECORATIONFACTORY_H
|
54
src/plugins/platforms/wayland/qwaylanddecorationplugin.cpp
Normal file
54
src/plugins/platforms/wayland/qwaylanddecorationplugin.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the QtGui module of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/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 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 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 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "qwaylanddecorationplugin_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QWaylandDecorationPlugin::QWaylandDecorationPlugin(QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
QWaylandDecorationPlugin::~QWaylandDecorationPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
69
src/plugins/platforms/wayland/qwaylanddecorationplugin_p.h
Normal file
69
src/plugins/platforms/wayland/qwaylanddecorationplugin_p.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2014 Robin Burchell <robin.burchell@viroteck.net>
|
||||||
|
** Contact: http://www.qt-project.org/legal
|
||||||
|
**
|
||||||
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
|
**
|
||||||
|
** $QT_BEGIN_LICENSE:LGPL$
|
||||||
|
** 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 Digia. For licensing terms and
|
||||||
|
** conditions see http://qt.digia.com/licensing. For further information
|
||||||
|
** use the contact form at http://qt.digia.com/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 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||||
|
** packaging of this file. Please review the following information to
|
||||||
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||||
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Digia gives you certain additional
|
||||||
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3.0 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 3.0 requirements will be
|
||||||
|
** met: http://www.gnu.org/copyleft/gpl.html.
|
||||||
|
**
|
||||||
|
**
|
||||||
|
** $QT_END_LICENSE$
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QWAYLANDDECORATIONPLUGIN_H
|
||||||
|
#define QWAYLANDDECORATIONPLUGIN_H
|
||||||
|
|
||||||
|
#include <QtWaylandClient/private/qwaylandclientexport_p.h>
|
||||||
|
|
||||||
|
#include <QtCore/qplugin.h>
|
||||||
|
#include <QtCore/qfactoryinterface.h>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QWaylandAbstractDecoration;
|
||||||
|
|
||||||
|
#define QWaylandDecorationFactoryInterface_iid "org.qt-project.Qt.WaylandClient.QWaylandDecorationFactoryInterface.5.4"
|
||||||
|
|
||||||
|
class Q_WAYLAND_CLIENT_EXPORT QWaylandDecorationPlugin : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit QWaylandDecorationPlugin(QObject *parent = 0);
|
||||||
|
~QWaylandDecorationPlugin();
|
||||||
|
|
||||||
|
virtual QWaylandAbstractDecoration *create(const QString &key, const QStringList ¶mList) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QWAYLANDDECORATIONPLUGIN_H
|
@ -53,6 +53,7 @@
|
|||||||
#include "qwaylandabstractdecoration_p.h"
|
#include "qwaylandabstractdecoration_p.h"
|
||||||
#include "qwaylandwindowmanagerintegration_p.h"
|
#include "qwaylandwindowmanagerintegration_p.h"
|
||||||
#include "qwaylandnativeinterface_p.h"
|
#include "qwaylandnativeinterface_p.h"
|
||||||
|
#include "qwaylanddecorationfactory_p.h"
|
||||||
|
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
#include <QtCore/QPointer>
|
#include <QtCore/QPointer>
|
||||||
@ -486,6 +487,7 @@ bool QWaylandWindow::createDecoration()
|
|||||||
if (!mDisplay->supportsWindowDecoration())
|
if (!mDisplay->supportsWindowDecoration())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
static bool decorationPluginFailed = false;
|
||||||
bool decoration = false;
|
bool decoration = false;
|
||||||
switch (window()->type()) {
|
switch (window()->type()) {
|
||||||
case Qt::Window:
|
case Qt::Window:
|
||||||
@ -503,9 +505,37 @@ bool QWaylandWindow::createDecoration()
|
|||||||
if (window()->flags() & Qt::BypassWindowManagerHint)
|
if (window()->flags() & Qt::BypassWindowManagerHint)
|
||||||
decoration = false;
|
decoration = false;
|
||||||
|
|
||||||
if (decoration) {
|
if (decoration && !decorationPluginFailed) {
|
||||||
if (!mWindowDecoration)
|
if (!mWindowDecoration) {
|
||||||
mWindowDecoration = new QWaylandAbstractDecoration(this);
|
QStringList decorations = QWaylandDecorationFactory::keys();
|
||||||
|
if (decorations.empty()) {
|
||||||
|
qWarning() << "No decoration plugins available. Running with no decorations.";
|
||||||
|
decorationPluginFailed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString targetKey;
|
||||||
|
QByteArray decorationPluginName = qgetenv("QT_WAYLAND_DECORATION");
|
||||||
|
if (!decorationPluginName.isEmpty()) {
|
||||||
|
targetKey = QString::fromLocal8Bit(decorationPluginName);
|
||||||
|
if (!decorations.contains(targetKey)) {
|
||||||
|
qWarning() << "Requested decoration " << targetKey << " not found, falling back to default";
|
||||||
|
targetKey = QString(); // fallthrough
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetKey.isEmpty())
|
||||||
|
targetKey = decorations.first(); // first come, first served.
|
||||||
|
|
||||||
|
|
||||||
|
mWindowDecoration = QWaylandDecorationFactory::create(targetKey, QStringList());
|
||||||
|
if (!mWindowDecoration) {
|
||||||
|
qWarning() << "Could not create decoration from factory! Running with no decorations.";
|
||||||
|
decorationPluginFailed = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mWindowDecoration->setWaylandWindow(this);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
delete mWindowDecoration;
|
delete mWindowDecoration;
|
||||||
mWindowDecoration = 0;
|
mWindowDecoration = 0;
|
||||||
@ -519,6 +549,7 @@ QWaylandAbstractDecoration *QWaylandWindow::decoration() const
|
|||||||
return mWindowDecoration;
|
return mWindowDecoration;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ### can't this go away? we directly set up our decorations, after all
|
||||||
void QWaylandWindow::setDecoration(QWaylandAbstractDecoration *decoration)
|
void QWaylandWindow::setDecoration(QWaylandAbstractDecoration *decoration)
|
||||||
{
|
{
|
||||||
mWindowDecoration = decoration;
|
mWindowDecoration = decoration;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user