2009-06-19 09:18:07 +00:00
|
|
|
/********************************************************************
|
2012-01-07 16:05:22 +00:00
|
|
|
Copyright (C) 2009, 2010, 2012 Martin Gräßlin <mgraesslin@kde.org>
|
2009-06-19 09:18:07 +00:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*********************************************************************/
|
|
|
|
|
|
|
|
#include "aurorae.h"
|
2010-04-12 19:28:58 +00:00
|
|
|
#include "auroraetheme.h"
|
2012-07-22 15:35:18 +00:00
|
|
|
#include "config-kwin.h"
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
#include <QApplication>
|
2013-09-02 09:12:14 +00:00
|
|
|
#include <QDebug>
|
2013-11-14 08:01:42 +00:00
|
|
|
#include <QMutex>
|
2013-10-02 12:54:43 +00:00
|
|
|
#include <QOpenGLFramebufferObject>
|
|
|
|
#include <QPainter>
|
2013-10-02 08:04:10 +00:00
|
|
|
#include <QQmlComponent>
|
|
|
|
#include <QQmlContext>
|
|
|
|
#include <QQmlEngine>
|
|
|
|
#include <QQuickItem>
|
|
|
|
#include <QQuickWindow>
|
2013-08-03 20:29:13 +00:00
|
|
|
#include <QStandardPaths>
|
2013-10-02 08:04:10 +00:00
|
|
|
#include <QWidget>
|
2009-06-19 09:18:07 +00:00
|
|
|
|
|
|
|
#include <KConfig>
|
|
|
|
#include <KConfigGroup>
|
2014-03-29 08:05:08 +00:00
|
|
|
#include <KSharedConfig>
|
2012-07-22 15:35:18 +00:00
|
|
|
#include <KPluginInfo>
|
|
|
|
#include <KServiceTypeTrader>
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2014-03-12 13:53:43 +00:00
|
|
|
K_PLUGIN_FACTORY_WITH_JSON(AuroraePluginFactory,
|
|
|
|
"aurorae.json",
|
|
|
|
registerPlugin<Aurorae::AuroraeFactory>(QString(), &Aurorae::AuroraeFactory::createInstance);)
|
2014-02-21 09:48:24 +00:00
|
|
|
K_EXPORT_PLUGIN_VERSION(KWIN_DECORATION_API_VERSION)
|
|
|
|
|
2009-06-19 09:18:07 +00:00
|
|
|
namespace Aurorae
|
|
|
|
{
|
|
|
|
|
2013-08-23 07:05:59 +00:00
|
|
|
AuroraeFactory::AuroraeFactory(QObject *parent)
|
|
|
|
: KDecorationFactory(parent)
|
2010-04-12 19:28:58 +00:00
|
|
|
, m_theme(new AuroraeTheme(this))
|
2013-10-02 08:04:10 +00:00
|
|
|
, m_engine(new QQmlEngine(this))
|
|
|
|
, m_component(new QQmlComponent(m_engine, this))
|
2012-07-22 15:35:18 +00:00
|
|
|
, m_engineType(AuroraeEngine)
|
2014-03-27 13:17:07 +00:00
|
|
|
, m_mutex(new QMutex(QMutex::Recursive))
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
|
|
|
init();
|
2013-08-23 11:36:40 +00:00
|
|
|
connect(options(), &KDecorationOptions::buttonsChanged, this, &AuroraeFactory::buttonsChanged);
|
|
|
|
connect(options(), &KDecorationOptions::fontsChanged, this, &AuroraeFactory::titleFontChanged);
|
|
|
|
connect(options(), &KDecorationOptions::configChanged, this, &AuroraeFactory::updateConfiguration);
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AuroraeFactory::init()
|
|
|
|
{
|
2011-12-05 14:29:26 +00:00
|
|
|
qRegisterMetaType<uint>("Qt::MouseButtons");
|
|
|
|
|
2013-07-25 16:04:27 +00:00
|
|
|
KConfig conf(QStringLiteral("auroraerc"));
|
2009-06-19 09:18:07 +00:00
|
|
|
KConfigGroup group(&conf, "Engine");
|
2012-10-12 06:23:00 +00:00
|
|
|
if (!group.hasKey("EngineType") && !group.hasKey("ThemeName")) {
|
|
|
|
// neither engine type and theme name are configured, use the only available theme
|
|
|
|
initQML(group);
|
|
|
|
} else if (group.hasKey("EngineType")) {
|
2012-07-22 15:35:18 +00:00
|
|
|
const QString engineType = group.readEntry("EngineType", "aurorae").toLower();
|
2013-07-25 16:04:27 +00:00
|
|
|
if (engineType == QStringLiteral("qml")) {
|
2012-07-22 15:35:18 +00:00
|
|
|
initQML(group);
|
|
|
|
} else {
|
|
|
|
// fallback to classic Aurorae Themes
|
|
|
|
initAurorae(conf, group);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// fallback to classic Aurorae Themes
|
|
|
|
initAurorae(conf, group);
|
|
|
|
}
|
|
|
|
}
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2012-07-22 15:35:18 +00:00
|
|
|
void AuroraeFactory::initAurorae(KConfig &conf, KConfigGroup &group)
|
|
|
|
{
|
|
|
|
m_engineType = AuroraeEngine;
|
2012-10-12 06:23:00 +00:00
|
|
|
const QString themeName = group.readEntry("ThemeName");
|
|
|
|
if (themeName.isEmpty()) {
|
|
|
|
// no theme configured, fall back to Plastik QML theme
|
|
|
|
initQML(group);
|
|
|
|
return;
|
|
|
|
}
|
2013-10-02 07:57:48 +00:00
|
|
|
KConfig config(QStringLiteral("aurorae/themes/") + themeName + QStringLiteral("/") + themeName + QStringLiteral("rc"),
|
|
|
|
KConfig::FullConfig, QStandardPaths::GenericDataLocation);
|
2010-04-21 18:18:45 +00:00
|
|
|
KConfigGroup themeGroup(&conf, themeName);
|
2010-04-12 19:28:58 +00:00
|
|
|
m_theme->loadTheme(themeName, config);
|
2010-04-21 18:18:45 +00:00
|
|
|
m_theme->setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
|
|
|
|
m_theme->setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
|
2012-01-12 06:42:55 +00:00
|
|
|
m_theme->setTabDragMimeType(tabDragMimeType());
|
2012-01-11 20:14:29 +00:00
|
|
|
// setup the QML engine
|
2013-05-26 13:32:21 +00:00
|
|
|
/* use logic from KDeclarative::setupBindings():
|
|
|
|
"addImportPath adds the path at the beginning, so to honour user's
|
|
|
|
paths we need to traverse the list in reverse order" */
|
2013-08-03 20:29:13 +00:00
|
|
|
QStringListIterator paths(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("module/imports"), QStandardPaths::LocateDirectory));
|
2013-05-26 13:32:21 +00:00
|
|
|
paths.toBack();
|
|
|
|
while (paths.hasPrevious()) {
|
|
|
|
m_engine->addImportPath(paths.previous());
|
2012-01-11 20:14:29 +00:00
|
|
|
}
|
2013-08-03 20:29:13 +00:00
|
|
|
m_component->loadUrl(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/aurorae/aurorae.qml"))));
|
2013-07-25 16:04:27 +00:00
|
|
|
m_engine->rootContext()->setContextProperty(QStringLiteral("auroraeTheme"), m_theme);
|
2012-07-29 09:20:48 +00:00
|
|
|
m_themeName = themeName;
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2012-07-22 15:35:18 +00:00
|
|
|
void AuroraeFactory::initQML(const KConfigGroup &group)
|
|
|
|
{
|
|
|
|
// try finding the QML package
|
2012-10-12 06:23:00 +00:00
|
|
|
const QString themeName = group.readEntry("ThemeName", "kwin4_decoration_qml_plastik");
|
2013-11-25 13:55:58 +00:00
|
|
|
qCDebug(AURORAE) << "Trying to load QML Decoration " << themeName;
|
2012-07-22 15:35:18 +00:00
|
|
|
const QString internalname = themeName.toLower();
|
|
|
|
|
2013-07-25 16:04:27 +00:00
|
|
|
QString constraint = QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(internalname);
|
|
|
|
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("KWin/Decoration"), constraint);
|
2012-07-22 15:35:18 +00:00
|
|
|
if (offers.isEmpty()) {
|
2013-11-25 13:55:58 +00:00
|
|
|
qCCritical(AURORAE) << "Couldn't find QML Decoration " << themeName << endl;
|
2012-07-22 15:35:18 +00:00
|
|
|
// TODO: what to do in error case?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
KService::Ptr service = offers.first();
|
2013-07-25 16:04:27 +00:00
|
|
|
const QString pluginName = service->property(QStringLiteral("X-KDE-PluginInfo-Name")).toString();
|
|
|
|
const QString scriptName = service->property(QStringLiteral("X-Plasma-MainScript")).toString();
|
2013-08-03 20:29:13 +00:00
|
|
|
const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(KWIN_NAME) + QStringLiteral("/decorations/") + pluginName + QStringLiteral("/contents/") + scriptName);
|
2012-07-22 15:35:18 +00:00
|
|
|
if (file.isNull()) {
|
2013-11-25 13:55:58 +00:00
|
|
|
qCDebug(AURORAE) << "Could not find script file for " << pluginName;
|
2012-07-22 15:35:18 +00:00
|
|
|
// TODO: what to do in error case?
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_engineType = QMLEngine;
|
|
|
|
// setup the QML engine
|
2013-05-26 13:32:21 +00:00
|
|
|
/* use logic from KDeclarative::setupBindings():
|
|
|
|
"addImportPath adds the path at the beginning, so to honour user's
|
|
|
|
paths we need to traverse the list in reverse order" */
|
2013-08-03 20:29:13 +00:00
|
|
|
QStringListIterator paths(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("module/imports"), QStandardPaths::LocateDirectory));
|
2013-05-26 13:32:21 +00:00
|
|
|
paths.toBack();
|
|
|
|
while (paths.hasPrevious()) {
|
|
|
|
m_engine->addImportPath(paths.previous());
|
2012-07-22 15:35:18 +00:00
|
|
|
}
|
|
|
|
m_component->loadUrl(QUrl::fromLocalFile(file));
|
2012-07-29 09:20:48 +00:00
|
|
|
m_themeName = themeName;
|
2012-07-22 15:35:18 +00:00
|
|
|
}
|
|
|
|
|
2009-06-19 09:18:07 +00:00
|
|
|
AuroraeFactory::~AuroraeFactory()
|
|
|
|
{
|
2014-02-24 16:02:11 +00:00
|
|
|
s_instance = nullptr;
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
AuroraeFactory *AuroraeFactory::instance()
|
|
|
|
{
|
|
|
|
if (!s_instance) {
|
|
|
|
s_instance = new AuroraeFactory;
|
|
|
|
}
|
|
|
|
|
|
|
|
return s_instance;
|
|
|
|
}
|
|
|
|
|
2014-02-21 09:48:24 +00:00
|
|
|
QObject *AuroraeFactory::createInstance(QWidget*, QObject*, const QList< QVariant >&)
|
|
|
|
{
|
|
|
|
return instance();
|
|
|
|
}
|
|
|
|
|
2013-08-23 11:36:40 +00:00
|
|
|
void AuroraeFactory::updateConfiguration()
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2013-07-25 16:04:27 +00:00
|
|
|
const KConfig conf(QStringLiteral("auroraerc"));
|
2012-01-13 11:58:00 +00:00
|
|
|
const KConfigGroup group(&conf, "Engine");
|
|
|
|
const QString themeName = group.readEntry("ThemeName", "example-deco");
|
2013-10-02 07:57:48 +00:00
|
|
|
const KConfig config(QStringLiteral("aurorae/themes/") + themeName + QStringLiteral("/") + themeName + QStringLiteral("rc"),
|
|
|
|
KConfig::FullConfig, QStandardPaths::GenericDataLocation);
|
2012-01-13 11:58:00 +00:00
|
|
|
const KConfigGroup themeGroup(&conf, themeName);
|
2013-03-03 20:46:43 +00:00
|
|
|
if (themeName != m_themeName) {
|
|
|
|
m_engine->clearComponentCache();
|
2012-07-29 09:12:29 +00:00
|
|
|
init();
|
2013-08-23 11:36:40 +00:00
|
|
|
emit recreateDecorations();
|
2012-07-29 09:12:29 +00:00
|
|
|
}
|
|
|
|
if (m_engineType == AuroraeEngine) {
|
|
|
|
m_theme->setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
|
|
|
|
m_theme->setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
|
2012-01-13 11:58:00 +00:00
|
|
|
}
|
2012-07-29 09:20:48 +00:00
|
|
|
emit configChanged();
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool AuroraeFactory::supports(Ability ability) const
|
|
|
|
{
|
|
|
|
switch (ability) {
|
|
|
|
case AbilityAnnounceButtons:
|
|
|
|
case AbilityUsesAlphaChannel:
|
2012-10-12 09:34:05 +00:00
|
|
|
case AbilityAnnounceAlphaChannel:
|
2009-06-19 09:18:07 +00:00
|
|
|
case AbilityButtonMenu:
|
|
|
|
case AbilityButtonSpacer:
|
2009-12-16 17:51:58 +00:00
|
|
|
case AbilityExtendIntoClientArea:
|
2009-06-19 09:18:07 +00:00
|
|
|
case AbilityButtonMinimize:
|
|
|
|
case AbilityButtonMaximize:
|
|
|
|
case AbilityButtonClose:
|
|
|
|
case AbilityButtonAboveOthers:
|
|
|
|
case AbilityButtonBelowOthers:
|
|
|
|
case AbilityButtonShade:
|
|
|
|
case AbilityButtonOnAllDesktops:
|
|
|
|
case AbilityButtonHelp:
|
2012-12-27 09:29:13 +00:00
|
|
|
case AbilityButtonApplicationMenu:
|
2009-06-19 09:18:07 +00:00
|
|
|
case AbilityProvidesShadow:
|
2010-04-12 19:28:58 +00:00
|
|
|
return true; // TODO: correct value from theme
|
2012-01-12 06:42:55 +00:00
|
|
|
case AbilityTabbing:
|
2012-01-10 19:53:41 +00:00
|
|
|
return false;
|
2010-11-10 18:33:07 +00:00
|
|
|
case AbilityUsesBlurBehind:
|
|
|
|
return true;
|
2009-06-19 09:18:07 +00:00
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
KDecoration *AuroraeFactory::createDecoration(KDecorationBridge *bridge)
|
|
|
|
{
|
|
|
|
AuroraeClient *client = new AuroraeClient(bridge, this);
|
2010-04-12 19:28:58 +00:00
|
|
|
return client;
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2009-11-08 20:35:34 +00:00
|
|
|
QList< KDecorationDefines::BorderSize > AuroraeFactory::borderSizes() const
|
|
|
|
{
|
|
|
|
return QList< BorderSize >() << BorderTiny << BorderNormal <<
|
|
|
|
BorderLarge << BorderVeryLarge << BorderHuge <<
|
|
|
|
BorderVeryHuge << BorderOversized;
|
|
|
|
}
|
|
|
|
|
2013-10-02 08:04:10 +00:00
|
|
|
QQuickItem *AuroraeFactory::createQmlDecoration(Aurorae::AuroraeClient *client)
|
2012-01-11 20:14:29 +00:00
|
|
|
{
|
2013-10-02 08:04:10 +00:00
|
|
|
QQmlContext *context = new QQmlContext(m_engine->rootContext(), this);
|
2013-07-25 16:04:27 +00:00
|
|
|
context->setContextProperty(QStringLiteral("decoration"), client);
|
2013-10-02 08:04:10 +00:00
|
|
|
return qobject_cast< QQuickItem* >(m_component->create(context));
|
2012-01-11 20:14:29 +00:00
|
|
|
}
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2014-02-24 16:02:11 +00:00
|
|
|
AuroraeFactory *AuroraeFactory::s_instance = nullptr;
|
2009-06-19 09:18:07 +00:00
|
|
|
|
|
|
|
/*******************************************************
|
2010-04-12 19:28:58 +00:00
|
|
|
* Client
|
2009-06-19 09:18:07 +00:00
|
|
|
*******************************************************/
|
2010-04-12 19:28:58 +00:00
|
|
|
AuroraeClient::AuroraeClient(KDecorationBridge *bridge, KDecorationFactory *factory)
|
2013-08-20 09:58:02 +00:00
|
|
|
: KDecoration(bridge, factory)
|
2014-02-24 16:02:11 +00:00
|
|
|
, m_view(nullptr)
|
2012-01-11 20:14:29 +00:00
|
|
|
, m_item(AuroraeFactory::instance()->createQmlDecoration(this))
|
2012-01-07 16:25:21 +00:00
|
|
|
{
|
2012-07-27 08:03:22 +00:00
|
|
|
connect(AuroraeFactory::instance(), SIGNAL(buttonsChanged()), SIGNAL(buttonsChanged()));
|
2012-07-29 09:20:48 +00:00
|
|
|
connect(AuroraeFactory::instance(), SIGNAL(configChanged()), SIGNAL(configChanged()));
|
2012-08-24 09:40:02 +00:00
|
|
|
connect(AuroraeFactory::instance(), SIGNAL(titleFontChanged()), SIGNAL(fontChanged()));
|
2014-05-30 09:10:01 +00:00
|
|
|
connect(m_item, SIGNAL(alphaChanged()), SLOT(slotAlphaChanged()));
|
2012-12-27 09:29:13 +00:00
|
|
|
connect(this, SIGNAL(appMenuAvailable()), SIGNAL(appMenuAvailableChanged()));
|
|
|
|
connect(this, SIGNAL(appMenuUnavailable()), SIGNAL(appMenuAvailableChanged()));
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2010-06-19 15:23:48 +00:00
|
|
|
AuroraeClient::~AuroraeClient()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::init()
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2013-10-02 08:04:10 +00:00
|
|
|
m_view = new QQuickWindow();
|
2013-10-09 09:19:03 +00:00
|
|
|
m_view->setFlags(initialWFlags());
|
|
|
|
m_view->setColor(Qt::transparent);
|
|
|
|
setMainWindow(m_view);
|
2013-10-02 12:54:43 +00:00
|
|
|
if (compositingActive()) {
|
|
|
|
connect(m_view, &QQuickWindow::beforeRendering, [this]() {
|
2013-10-09 09:19:03 +00:00
|
|
|
int left, right, top, bottom;
|
|
|
|
left = right = top = bottom = 0;
|
|
|
|
padding(left, right, top, bottom);
|
|
|
|
if (m_fbo.isNull() || m_fbo->size() != QSize(width() + left + right, height() + top + bottom)) {
|
|
|
|
m_fbo.reset(new QOpenGLFramebufferObject(QSize(width() + left + right, height() + top + bottom),
|
|
|
|
QOpenGLFramebufferObject::CombinedDepthStencil));
|
2013-10-02 12:54:43 +00:00
|
|
|
if (!m_fbo->isValid()) {
|
2013-11-25 13:55:58 +00:00
|
|
|
qCWarning(AURORAE) << "Creating FBO as render target failed";
|
2013-10-02 12:54:43 +00:00
|
|
|
m_fbo.reset();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_view->setRenderTarget(m_fbo.data());
|
|
|
|
});
|
|
|
|
connect(m_view, &QQuickWindow::afterRendering, [this]{
|
2014-03-27 13:17:07 +00:00
|
|
|
QMutexLocker locker(AuroraeFactory::instance()->mutex());
|
2013-10-02 12:54:43 +00:00
|
|
|
m_buffer = m_fbo->toImage();
|
|
|
|
});
|
2013-10-07 12:40:12 +00:00
|
|
|
connect(m_view, &QQuickWindow::afterRendering, this,
|
|
|
|
static_cast<void (KDecoration::*)(void)>(&KDecoration::update), Qt::QueuedConnection);
|
2013-10-02 12:54:43 +00:00
|
|
|
}
|
2013-10-02 08:04:10 +00:00
|
|
|
if (m_item) {
|
|
|
|
m_item->setParentItem(m_view->contentItem());
|
2014-05-30 09:10:01 +00:00
|
|
|
m_item->setParent(m_view);
|
2013-10-02 08:04:10 +00:00
|
|
|
}
|
2012-10-12 09:34:05 +00:00
|
|
|
slotAlphaChanged();
|
2012-01-07 16:25:21 +00:00
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
AuroraeFactory::instance()->theme()->setCompositingActive(compositingActive());
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2012-07-30 18:00:25 +00:00
|
|
|
bool AuroraeClient::eventFilter(QObject *object, QEvent *event)
|
|
|
|
{
|
|
|
|
// we need to filter the wheel events on the decoration
|
|
|
|
// QML does not yet provide a way to accept wheel events, this will change with Qt 5
|
|
|
|
// TODO: remove in KDE5
|
|
|
|
// see BUG: 304248
|
|
|
|
if (object != widget() || event->type() != QEvent::Wheel) {
|
2013-08-20 09:58:02 +00:00
|
|
|
return KDecoration::eventFilter(object, event);
|
2012-07-30 18:00:25 +00:00
|
|
|
}
|
|
|
|
QWheelEvent *wheel = static_cast<QWheelEvent*>(event);
|
|
|
|
if (mousePosition(wheel->pos()) == PositionCenter) {
|
|
|
|
titlebarMouseWheelOperation(wheel->delta());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::resize(const QSize &s)
|
2010-01-29 12:37:42 +00:00
|
|
|
{
|
2012-01-11 20:14:29 +00:00
|
|
|
if (m_item) {
|
|
|
|
m_item->setWidth(s.width());
|
|
|
|
m_item->setHeight(s.height());
|
|
|
|
}
|
2013-10-09 09:19:03 +00:00
|
|
|
m_view->resize(s);
|
2010-01-29 12:37:42 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::borders(int &left, int &right, int &top, int &bottom) const
|
2010-01-29 12:37:42 +00:00
|
|
|
{
|
2012-01-11 20:14:29 +00:00
|
|
|
if (!m_item) {
|
2012-01-09 22:07:22 +00:00
|
|
|
left = right = top = bottom = 0;
|
|
|
|
return;
|
|
|
|
}
|
2014-02-24 16:02:11 +00:00
|
|
|
QObject *borders = nullptr;
|
2013-08-20 09:25:32 +00:00
|
|
|
if (maximizeMode() == MaximizeFull) {
|
2013-07-25 16:04:27 +00:00
|
|
|
borders = m_item->findChild<QObject*>(QStringLiteral("maximizedBorders"));
|
2012-01-07 16:25:21 +00:00
|
|
|
} else {
|
2013-07-25 16:04:27 +00:00
|
|
|
borders = m_item->findChild<QObject*>(QStringLiteral("borders"));
|
2012-01-07 16:25:21 +00:00
|
|
|
}
|
2013-01-16 07:43:53 +00:00
|
|
|
sizesFromBorders(borders, left, right, top, bottom);
|
2010-01-29 12:37:42 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::padding(int &left, int &right, int &top, int &bottom) const
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2012-01-11 20:14:29 +00:00
|
|
|
if (!m_item) {
|
2012-01-09 22:07:22 +00:00
|
|
|
left = right = top = bottom = 0;
|
|
|
|
return;
|
|
|
|
}
|
2013-08-20 09:25:32 +00:00
|
|
|
if (maximizeMode() == MaximizeFull) {
|
2012-09-25 20:26:35 +00:00
|
|
|
left = right = top = bottom = 0;
|
2012-01-09 22:07:22 +00:00
|
|
|
return;
|
|
|
|
}
|
2013-07-25 16:04:27 +00:00
|
|
|
sizesFromBorders(m_item->findChild<QObject*>(QStringLiteral("padding")), left, right, top, bottom);
|
2013-01-16 07:43:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AuroraeClient::sizesFromBorders(const QObject *borders, int &left, int &right, int &top, int &bottom) const
|
|
|
|
{
|
|
|
|
if (!borders) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
left = borders->property("left").toInt();
|
|
|
|
right = borders->property("right").toInt();
|
|
|
|
top = borders->property("top").toInt();
|
|
|
|
bottom = borders->property("bottom").toInt();
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
QSize AuroraeClient::minimumSize() const
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2013-10-09 09:19:03 +00:00
|
|
|
return m_view->minimumSize();
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
KDecorationDefines::Position AuroraeClient::mousePosition(const QPoint &point) const
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2010-04-12 19:28:58 +00:00
|
|
|
// based on the code from deKorator
|
|
|
|
int pos = PositionCenter;
|
2013-09-30 10:46:21 +00:00
|
|
|
if (isShade() || isMaximized()) {
|
2010-04-12 19:28:58 +00:00
|
|
|
return Position(pos);
|
2009-10-31 17:06:31 +00:00
|
|
|
}
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
int borderLeft, borderTop, borderRight, borderBottom;
|
|
|
|
borders(borderLeft, borderRight, borderTop, borderBottom);
|
|
|
|
int paddingLeft, paddingTop, paddingRight, paddingBottom;
|
|
|
|
padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
|
2010-04-27 17:50:13 +00:00
|
|
|
int titleEdgeLeft, titleEdgeRight, titleEdgeTop, titleEdgeBottom;
|
2013-09-30 10:46:21 +00:00
|
|
|
AuroraeFactory::instance()->theme()->titleEdges(titleEdgeLeft, titleEdgeTop, titleEdgeRight, titleEdgeBottom, false);
|
2010-04-27 17:50:13 +00:00
|
|
|
switch (AuroraeFactory::instance()->theme()->decorationPosition()) {
|
|
|
|
case DecorationTop:
|
|
|
|
borderTop = titleEdgeTop;
|
|
|
|
break;
|
|
|
|
case DecorationLeft:
|
|
|
|
borderLeft = titleEdgeLeft;
|
|
|
|
break;
|
|
|
|
case DecorationRight:
|
|
|
|
borderRight = titleEdgeRight;
|
|
|
|
break;
|
|
|
|
case DecorationBottom:
|
|
|
|
borderBottom = titleEdgeBottom;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break; // nothing
|
|
|
|
}
|
2013-10-09 09:19:03 +00:00
|
|
|
if (point.x() >= (m_view->width() - borderRight - paddingRight)) {
|
2010-04-12 19:28:58 +00:00
|
|
|
pos |= PositionRight;
|
|
|
|
} else if (point.x() <= borderLeft + paddingLeft) {
|
|
|
|
pos |= PositionLeft;
|
|
|
|
}
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2013-10-09 09:19:03 +00:00
|
|
|
if (point.y() >= m_view->height() - borderBottom - paddingBottom) {
|
2010-04-12 19:28:58 +00:00
|
|
|
pos |= PositionBottom;
|
2010-04-27 17:50:13 +00:00
|
|
|
} else if (point.y() <= borderTop + paddingTop ) {
|
2010-04-12 19:28:58 +00:00
|
|
|
pos |= PositionTop;
|
|
|
|
}
|
2009-06-19 09:18:07 +00:00
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
return Position(pos);
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::menuClicked()
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2010-04-12 19:28:58 +00:00
|
|
|
showWindowMenu(QCursor::pos());
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2012-12-27 09:29:13 +00:00
|
|
|
void AuroraeClient::appMenuClicked()
|
|
|
|
{
|
|
|
|
showApplicationMenu(QCursor::pos());
|
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::toggleShade()
|
2009-06-19 09:18:07 +00:00
|
|
|
{
|
2010-04-12 19:28:58 +00:00
|
|
|
setShade(!isShade());
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::toggleKeepAbove()
|
2009-11-01 12:12:30 +00:00
|
|
|
{
|
2010-04-12 19:28:58 +00:00
|
|
|
setKeepAbove(!keepAbove());
|
2009-11-01 12:12:30 +00:00
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::toggleKeepBelow()
|
2009-11-01 12:12:30 +00:00
|
|
|
{
|
2010-04-12 19:28:58 +00:00
|
|
|
setKeepBelow(!keepBelow());
|
2009-06-19 09:18:07 +00:00
|
|
|
}
|
|
|
|
|
2012-01-07 16:05:22 +00:00
|
|
|
void AuroraeClient::titlePressed(int button, int buttons)
|
|
|
|
{
|
|
|
|
titlePressed(static_cast<Qt::MouseButton>(button), static_cast<Qt::MouseButtons>(buttons));
|
|
|
|
}
|
|
|
|
|
2010-04-12 19:28:58 +00:00
|
|
|
void AuroraeClient::titlePressed(Qt::MouseButton button, Qt::MouseButtons buttons)
|
2010-01-29 12:37:42 +00:00
|
|
|
{
|
2013-02-26 07:45:44 +00:00
|
|
|
const QPoint cursor = QCursor::pos();
|
2013-10-09 09:19:03 +00:00
|
|
|
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, m_view->mapFromGlobal(cursor),
|
2013-02-26 07:45:44 +00:00
|
|
|
cursor, button, buttons, Qt::NoModifier);
|
2010-04-12 19:28:58 +00:00
|
|
|
processMousePressEvent(event);
|
|
|
|
delete event;
|
2014-02-24 16:02:11 +00:00
|
|
|
event = nullptr;
|
2010-01-29 12:37:42 +00:00
|
|
|
}
|
|
|
|
|
2012-01-11 20:14:29 +00:00
|
|
|
void AuroraeClient::themeChanged()
|
|
|
|
{
|
2014-05-30 09:10:01 +00:00
|
|
|
m_item->deleteLater();
|
|
|
|
m_item = AuroraeFactory::instance()->createQmlDecoration(this);
|
2013-05-01 11:25:59 +00:00
|
|
|
if (!m_item) {
|
|
|
|
return;
|
2012-01-11 20:14:29 +00:00
|
|
|
}
|
2013-05-01 11:25:59 +00:00
|
|
|
|
2013-10-02 08:04:10 +00:00
|
|
|
m_item->setParentItem(m_view->contentItem());
|
2014-05-30 09:10:01 +00:00
|
|
|
m_item->setParent(m_view);
|
|
|
|
connect(m_item, SIGNAL(alphaChanged()), SLOT(slotAlphaChanged()));
|
2012-10-12 09:34:05 +00:00
|
|
|
slotAlphaChanged();
|
2012-01-11 20:14:29 +00:00
|
|
|
}
|
|
|
|
|
2012-02-16 10:30:28 +00:00
|
|
|
int AuroraeClient::doubleClickInterval() const
|
|
|
|
{
|
|
|
|
return QApplication::doubleClickInterval();
|
|
|
|
}
|
|
|
|
|
2012-07-14 09:11:02 +00:00
|
|
|
void AuroraeClient::closeWindow()
|
|
|
|
{
|
2013-08-20 09:58:02 +00:00
|
|
|
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this), "doCloseWindow", Qt::QueuedConnection);
|
2012-07-14 09:11:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AuroraeClient::doCloseWindow()
|
|
|
|
{
|
2013-08-20 09:58:02 +00:00
|
|
|
KDecoration::closeWindow();
|
2012-07-14 09:11:02 +00:00
|
|
|
}
|
|
|
|
|
2012-08-10 06:52:11 +00:00
|
|
|
void AuroraeClient::maximize(int button)
|
|
|
|
{
|
|
|
|
// a maximized window does not need to have a window decoration
|
|
|
|
// in that case we need to delay handling by one cycle
|
|
|
|
// BUG: 304870
|
2013-08-20 09:58:02 +00:00
|
|
|
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this),
|
2012-08-10 06:52:11 +00:00
|
|
|
"doMaximzie",
|
|
|
|
Qt::QueuedConnection,
|
|
|
|
Q_ARG(int, button));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AuroraeClient::doMaximzie(int button)
|
|
|
|
{
|
2013-08-20 09:58:02 +00:00
|
|
|
KDecoration::maximize(static_cast<Qt::MouseButton>(button));
|
2012-08-10 06:52:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AuroraeClient::titlebarDblClickOperation()
|
|
|
|
{
|
|
|
|
// the double click operation can result in a window being maximized
|
|
|
|
// see maximize
|
2013-08-20 09:58:02 +00:00
|
|
|
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this), "doTitlebarDblClickOperation", Qt::QueuedConnection);
|
2012-08-10 06:52:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void AuroraeClient::doTitlebarDblClickOperation()
|
|
|
|
{
|
2013-08-20 09:58:02 +00:00
|
|
|
KDecoration::titlebarDblClickOperation();
|
2012-08-10 06:52:11 +00:00
|
|
|
}
|
|
|
|
|
2012-07-29 09:20:48 +00:00
|
|
|
QVariant AuroraeClient::readConfig(const QString &key, const QVariant &defaultValue)
|
|
|
|
{
|
2013-07-25 16:04:27 +00:00
|
|
|
KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("auroraerc"));
|
2012-07-29 09:20:48 +00:00
|
|
|
return config->group(AuroraeFactory::instance()->currentThemeName()).readEntry(key, defaultValue);
|
|
|
|
}
|
|
|
|
|
2012-10-12 09:34:05 +00:00
|
|
|
void AuroraeClient::slotAlphaChanged()
|
|
|
|
{
|
2013-05-01 11:25:59 +00:00
|
|
|
if (!m_item) {
|
|
|
|
setAlphaEnabled(false);
|
|
|
|
return;
|
|
|
|
}
|
2012-10-12 09:34:05 +00:00
|
|
|
QVariant alphaProperty = m_item->property("alpha");
|
|
|
|
if (alphaProperty.isValid() && alphaProperty.canConvert<bool>()) {
|
|
|
|
setAlphaEnabled(alphaProperty.toBool());
|
|
|
|
} else {
|
|
|
|
// by default all Aurorae themes use the alpha channel
|
|
|
|
setAlphaEnabled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-27 07:51:15 +00:00
|
|
|
QRegion AuroraeClient::region(KDecorationDefines::Region r)
|
|
|
|
{
|
|
|
|
if (r != ExtendedBorderRegion) {
|
|
|
|
return QRegion();
|
|
|
|
}
|
|
|
|
if (!m_item) {
|
|
|
|
return QRegion();
|
|
|
|
}
|
|
|
|
if (isMaximized()) {
|
|
|
|
// empty region for maximized windows
|
|
|
|
return QRegion();
|
|
|
|
}
|
2013-01-16 07:43:53 +00:00
|
|
|
int left, right, top, bottom;
|
|
|
|
left = right = top = bottom = 0;
|
2013-07-25 16:04:27 +00:00
|
|
|
sizesFromBorders(m_item->findChild<QObject*>(QStringLiteral("extendedBorders")), left, right, top, bottom);
|
2012-12-27 07:51:15 +00:00
|
|
|
if (top == 0 && right == 0 && bottom == 0 && left == 0) {
|
|
|
|
// no extended borders
|
|
|
|
return QRegion();
|
|
|
|
}
|
|
|
|
|
|
|
|
int paddingLeft, paddingRight, paddingTop, paddingBottom;
|
|
|
|
paddingLeft = paddingRight = paddingTop = paddingBottom = 0;
|
|
|
|
padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
|
2013-10-09 09:19:03 +00:00
|
|
|
QRect rect = this->rect().adjusted(paddingLeft, paddingTop, -paddingRight, -paddingBottom);
|
2012-12-27 07:51:15 +00:00
|
|
|
rect.translate(-paddingLeft, -paddingTop);
|
|
|
|
|
2013-01-04 14:25:08 +00:00
|
|
|
return QRegion(rect.adjusted(-left, -top, right, bottom)).subtract(rect);
|
2012-12-27 07:51:15 +00:00
|
|
|
}
|
|
|
|
|
2013-03-12 17:36:21 +00:00
|
|
|
bool AuroraeClient::animationsSupported() const
|
|
|
|
{
|
2013-10-02 08:01:28 +00:00
|
|
|
return compositingActive();
|
2013-03-12 17:36:21 +00:00
|
|
|
}
|
|
|
|
|
2013-10-07 12:40:12 +00:00
|
|
|
void AuroraeClient::render(QPaintDevice *device, const QRegion &sourceRegion)
|
|
|
|
{
|
2014-03-27 13:17:07 +00:00
|
|
|
QMutexLocker locker(AuroraeFactory::instance()->mutex());
|
2013-10-07 12:40:12 +00:00
|
|
|
QPainter painter(device);
|
|
|
|
painter.setClipRegion(sourceRegion);
|
|
|
|
painter.drawImage(QPoint(0, 0), m_buffer);
|
|
|
|
}
|
|
|
|
|
2009-06-19 09:18:07 +00:00
|
|
|
} // namespace Aurorae
|
|
|
|
|
|
|
|
#include "aurorae.moc"
|