Initial port of Aurorae to KDecoration2
The port to KDecoration2 means quite some changes in the way how Aurorae works. First of all: the theme to load is passed to the Deocoration ctor and not searched for by Aurorae itself. The rendering mechanismn didn't change significantly yet. It's still rendering to an FBO and passing the image on. This needs some further work as KDecoration2 does not support the padding any more. So all themes using shadow are currently broken. Another big change is the way how the rendering scene is constructed and used. KDecoration2 doesn't want the the Decoration to be a native window. But for being able to render a QtQuick scene at all we need a QQuickWindow. Thus it creates a window parented to the decoration id, but not accepting any input event. Input is nowadays controlled from the outside: events are passed into the Decoration, so we don't want the QtQuick window intercepting events. In case of non-composited the normal FBO mechanism doesn't work and Aurorae just renders to the QQuickWindow directly. This could use some optimization in the decoration renderer in KWin core to not even try to perform the normal rendering. On the other hand it's probably too much a hassle for the use case. The rendering architecture might hopefully be improved with Qt 5.4 and the new QQuickRenderControl class. The QQuickWindow also exposes a problem for preview in the kdecoration-viewer and the future KCM: we don't want a different window, but best would be to get to the QML scene directly. A small hack is added to have the previewers set a "visualParent" which Aurorae uses to parent the QML scene to without the need to create a QQuickWindow.
This commit is contained in:
parent
6a580d2b90
commit
5c3cd6f4bc
18 changed files with 626 additions and 886 deletions
|
@ -5,26 +5,23 @@ include_directories(
|
|||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
set(kwin3_aurorae_PART_SRCS
|
||||
set(kwin5_aurorae_PART_SRCS
|
||||
aurorae.cpp
|
||||
decorationoptions.cpp
|
||||
lib/auroraetheme.cpp
|
||||
lib/themeconfig.cpp
|
||||
)
|
||||
|
||||
add_library(kwin3_aurorae MODULE ${kwin3_aurorae_PART_SRCS})
|
||||
add_library(kwin5_aurorae MODULE ${kwin5_aurorae_PART_SRCS})
|
||||
|
||||
target_link_libraries(kwin3_aurorae
|
||||
KF5::ConfigCore
|
||||
target_link_libraries(kwin5_aurorae
|
||||
KDecoration2::KDecoration
|
||||
KF5::Service
|
||||
KF5::WindowSystem
|
||||
Qt5::Quick
|
||||
Qt5::Widgets
|
||||
kdecorations
|
||||
)
|
||||
|
||||
kservice_desktop_to_json(kwin3_aurorae aurorae.desktop)
|
||||
|
||||
install(TARGETS kwin3_aurorae DESTINATION ${PLUGIN_INSTALL_DIR}/kwin/kdecorations )
|
||||
install(TARGETS kwin5_aurorae DESTINATION ${PLUGIN_INSTALL_DIR}/org.kde.kdecoration2)
|
||||
|
||||
set(decoration_plugin_SRCS
|
||||
decorationplugin.cpp
|
||||
|
@ -35,9 +32,8 @@ set(decoration_plugin_SRCS
|
|||
add_library(decorationplugin SHARED ${decoration_plugin_SRCS})
|
||||
target_link_libraries(decorationplugin
|
||||
Qt5::Quick
|
||||
kdecorations
|
||||
KDecoration2::KDecoration
|
||||
KF5::ConfigWidgets
|
||||
KF5::Plasma
|
||||
)
|
||||
install(TARGETS decorationplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/kwin/decoration)
|
||||
|
||||
|
|
|
@ -20,54 +20,161 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "config-kwin.h"
|
||||
// qml imports
|
||||
#include "decorationoptions.h"
|
||||
|
||||
#include <QApplication>
|
||||
// KDecoration2
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
// KDE
|
||||
#include <KConfigGroup>
|
||||
#include <KPluginFactory>
|
||||
#include <KSharedConfig>
|
||||
#include <KService>
|
||||
#include <KServiceTypeTrader>
|
||||
// Qt
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
#include <QFileInfo>
|
||||
#include <QMutex>
|
||||
#include <QOpenGLFramebufferObject>
|
||||
#include <QPainter>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlContext>
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWindow>
|
||||
#include <QStandardPaths>
|
||||
#include <QWidget>
|
||||
|
||||
#include <KConfig>
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
#include <KPluginInfo>
|
||||
#include <KServiceTypeTrader>
|
||||
|
||||
K_PLUGIN_FACTORY_WITH_JSON(AuroraePluginFactory,
|
||||
K_PLUGIN_FACTORY_WITH_JSON(AuroraeDecoFactory,
|
||||
"aurorae.json",
|
||||
registerPlugin<Aurorae::AuroraeFactory>(QString(), &Aurorae::AuroraeFactory::createInstance);)
|
||||
K_EXPORT_PLUGIN_VERSION(KWIN_DECORATION_API_VERSION)
|
||||
registerPlugin<Aurorae::Decoration>();)
|
||||
|
||||
namespace Aurorae
|
||||
{
|
||||
|
||||
AuroraeFactory::AuroraeFactory(QObject *parent)
|
||||
: KDecorationFactory(parent)
|
||||
, m_theme(new AuroraeTheme(this))
|
||||
, m_engine(new QQmlEngine(this))
|
||||
, m_component(new QQmlComponent(m_engine, this))
|
||||
, m_engineType(AuroraeEngine)
|
||||
, m_mutex(new QMutex(QMutex::Recursive))
|
||||
class Helper
|
||||
{
|
||||
init();
|
||||
connect(options(), &KDecorationOptions::buttonsChanged, this, &AuroraeFactory::buttonsChanged);
|
||||
connect(options(), &KDecorationOptions::fontsChanged, this, &AuroraeFactory::titleFontChanged);
|
||||
connect(options(), &KDecorationOptions::configChanged, this, &AuroraeFactory::updateConfiguration);
|
||||
public:
|
||||
void ref();
|
||||
void unref();
|
||||
QQmlComponent *component(const QString &theme);
|
||||
QQmlContext *rootContext();
|
||||
QQmlComponent *svgComponent() {
|
||||
return m_svgComponent.data();
|
||||
}
|
||||
|
||||
static Helper &instance();
|
||||
private:
|
||||
Helper() = default;
|
||||
void init();
|
||||
QQmlComponent *loadComponent(const QString &themeName);
|
||||
int m_refCount = 0;
|
||||
QScopedPointer<QQmlEngine> m_engine;
|
||||
QHash<QString, QQmlComponent*> m_components;
|
||||
QScopedPointer<QQmlComponent> m_svgComponent;
|
||||
};
|
||||
|
||||
Helper &Helper::instance()
|
||||
{
|
||||
static Helper s_helper;
|
||||
return s_helper;
|
||||
}
|
||||
|
||||
void AuroraeFactory::init()
|
||||
void Helper::ref()
|
||||
{
|
||||
qRegisterMetaType<uint>("Qt::MouseButtons");
|
||||
m_refCount++;
|
||||
if (m_refCount == 1) {
|
||||
m_engine.reset(new QQmlEngine);
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
void Helper::unref()
|
||||
{
|
||||
m_refCount--;
|
||||
if (m_refCount == 0) {
|
||||
// cleanup
|
||||
m_svgComponent.reset();
|
||||
m_engine.reset();
|
||||
m_components.clear();
|
||||
}
|
||||
}
|
||||
|
||||
static const QString s_defaultTheme = QStringLiteral("kwin4_decoration_qml_plastik");
|
||||
|
||||
QQmlComponent *Helper::component(const QString &themeName)
|
||||
{
|
||||
// maybe it's an SVG theme?
|
||||
if (themeName.startsWith(QLatin1Literal("__aurorae__svg__"))) {
|
||||
if (m_svgComponent.isNull()) {
|
||||
/* 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" */
|
||||
QStringListIterator paths(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("module/imports"), QStandardPaths::LocateDirectory));
|
||||
paths.toBack();
|
||||
while (paths.hasPrevious()) {
|
||||
m_engine->addImportPath(paths.previous());
|
||||
}
|
||||
m_svgComponent.reset(new QQmlComponent(m_engine.data()));
|
||||
m_svgComponent->loadUrl(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/aurorae/aurorae.qml"))));
|
||||
}
|
||||
return m_svgComponent.data();
|
||||
}
|
||||
// try finding the QML package
|
||||
auto it = m_components.constFind(themeName);
|
||||
if (it != m_components.constEnd()) {
|
||||
return it.value();
|
||||
}
|
||||
auto component = loadComponent(themeName);
|
||||
if (component) {
|
||||
m_components.insert(themeName, component);
|
||||
return component;
|
||||
}
|
||||
// try loading default component
|
||||
if (themeName != s_defaultTheme) {
|
||||
return loadComponent(s_defaultTheme);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QQmlComponent *Helper::loadComponent(const QString &themeName)
|
||||
{
|
||||
qCDebug(AURORAE) << "Trying to load QML Decoration " << themeName;
|
||||
const QString internalname = themeName.toLower();
|
||||
|
||||
QString constraint = QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(internalname);
|
||||
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("KWin/Decoration"), constraint);
|
||||
if (offers.isEmpty()) {
|
||||
qCCritical(AURORAE) << "Couldn't find QML Decoration " << themeName << endl;
|
||||
// TODO: what to do in error case?
|
||||
return nullptr;
|
||||
}
|
||||
KService::Ptr service = offers.first();
|
||||
const QString pluginName = service->property(QStringLiteral("X-KDE-PluginInfo-Name")).toString();
|
||||
const QString scriptName = service->property(QStringLiteral("X-Plasma-MainScript")).toString();
|
||||
const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(KWIN_NAME) + QStringLiteral("/decorations/") + pluginName + QStringLiteral("/contents/") + scriptName);
|
||||
if (file.isNull()) {
|
||||
qCDebug(AURORAE) << "Could not find script file for " << pluginName;
|
||||
// TODO: what to do in error case?
|
||||
return nullptr;
|
||||
}
|
||||
// setup the QML engine
|
||||
/* 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" */
|
||||
QStringListIterator paths(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("module/imports"), QStandardPaths::LocateDirectory));
|
||||
paths.toBack();
|
||||
while (paths.hasPrevious()) {
|
||||
m_engine->addImportPath(paths.previous());
|
||||
}
|
||||
QQmlComponent *component = new QQmlComponent(m_engine.data(), m_engine.data());
|
||||
component->loadUrl(QUrl::fromLocalFile(file));
|
||||
return component;
|
||||
}
|
||||
|
||||
QQmlContext *Helper::rootContext()
|
||||
{
|
||||
return m_engine->rootContext();
|
||||
}
|
||||
|
||||
void Helper::init()
|
||||
{
|
||||
// we need to first load our decoration plugin
|
||||
// once it's loaded we can provide the Borders and access them from C++ side
|
||||
// so let's try to locate our plugin:
|
||||
|
@ -95,224 +202,80 @@ void AuroraeFactory::init()
|
|||
m_engine->importPlugin(pluginPath, "org.kde.kwin.decoration", nullptr);
|
||||
qmlRegisterType<KWin::Borders>("org.kde.kwin.decoration", 0, 1, "Borders");
|
||||
|
||||
KConfig conf(QStringLiteral("auroraerc"));
|
||||
KConfigGroup group(&conf, "Engine");
|
||||
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")) {
|
||||
const QString engineType = group.readEntry("EngineType", "aurorae").toLower();
|
||||
if (engineType == QStringLiteral("qml")) {
|
||||
initQML(group);
|
||||
} else {
|
||||
// fallback to classic Aurorae Themes
|
||||
initAurorae(conf, group);
|
||||
}
|
||||
} else {
|
||||
// fallback to classic Aurorae Themes
|
||||
initAurorae(conf, group);
|
||||
}
|
||||
qmlRegisterType<KDecoration2::Decoration>();
|
||||
qmlRegisterType<KDecoration2::DecoratedClient>();
|
||||
}
|
||||
|
||||
void AuroraeFactory::initAurorae(KConfig &conf, KConfigGroup &group)
|
||||
{
|
||||
m_engineType = AuroraeEngine;
|
||||
const QString themeName = group.readEntry("ThemeName");
|
||||
if (themeName.isEmpty()) {
|
||||
// no theme configured, fall back to Plastik QML theme
|
||||
initQML(group);
|
||||
return;
|
||||
}
|
||||
KConfig config(QStringLiteral("aurorae/themes/") + themeName + QStringLiteral("/") + themeName + QStringLiteral("rc"),
|
||||
KConfig::FullConfig, QStandardPaths::GenericDataLocation);
|
||||
KConfigGroup themeGroup(&conf, themeName);
|
||||
m_theme->loadTheme(themeName, config);
|
||||
m_theme->setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
|
||||
m_theme->setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
|
||||
m_theme->setTabDragMimeType(tabDragMimeType());
|
||||
// setup the QML engine
|
||||
/* 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" */
|
||||
QStringListIterator paths(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("module/imports"), QStandardPaths::LocateDirectory));
|
||||
paths.toBack();
|
||||
while (paths.hasPrevious()) {
|
||||
m_engine->addImportPath(paths.previous());
|
||||
}
|
||||
m_component->loadUrl(QUrl(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kwin/aurorae/aurorae.qml"))));
|
||||
m_engine->rootContext()->setContextProperty(QStringLiteral("auroraeTheme"), m_theme);
|
||||
m_themeName = themeName;
|
||||
}
|
||||
|
||||
void AuroraeFactory::initQML(const KConfigGroup &group)
|
||||
{
|
||||
// try finding the QML package
|
||||
const QString themeName = group.readEntry("ThemeName", "kwin4_decoration_qml_plastik");
|
||||
qCDebug(AURORAE) << "Trying to load QML Decoration " << themeName;
|
||||
const QString internalname = themeName.toLower();
|
||||
|
||||
QString constraint = QStringLiteral("[X-KDE-PluginInfo-Name] == '%1'").arg(internalname);
|
||||
KService::List offers = KServiceTypeTrader::self()->query(QStringLiteral("KWin/Decoration"), constraint);
|
||||
if (offers.isEmpty()) {
|
||||
qCCritical(AURORAE) << "Couldn't find QML Decoration " << themeName << endl;
|
||||
// TODO: what to do in error case?
|
||||
return;
|
||||
}
|
||||
KService::Ptr service = offers.first();
|
||||
const QString pluginName = service->property(QStringLiteral("X-KDE-PluginInfo-Name")).toString();
|
||||
const QString scriptName = service->property(QStringLiteral("X-Plasma-MainScript")).toString();
|
||||
const QString file = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral(KWIN_NAME) + QStringLiteral("/decorations/") + pluginName + QStringLiteral("/contents/") + scriptName);
|
||||
if (file.isNull()) {
|
||||
qCDebug(AURORAE) << "Could not find script file for " << pluginName;
|
||||
// TODO: what to do in error case?
|
||||
return;
|
||||
}
|
||||
m_engineType = QMLEngine;
|
||||
// setup the QML engine
|
||||
/* 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" */
|
||||
QStringListIterator paths(QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("module/imports"), QStandardPaths::LocateDirectory));
|
||||
paths.toBack();
|
||||
while (paths.hasPrevious()) {
|
||||
m_engine->addImportPath(paths.previous());
|
||||
}
|
||||
m_component->loadUrl(QUrl::fromLocalFile(file));
|
||||
m_themeName = themeName;
|
||||
}
|
||||
|
||||
AuroraeFactory::~AuroraeFactory()
|
||||
{
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
AuroraeFactory *AuroraeFactory::instance()
|
||||
{
|
||||
if (!s_instance) {
|
||||
s_instance = new AuroraeFactory;
|
||||
}
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
QObject *AuroraeFactory::createInstance(QWidget*, QObject*, const QList< QVariant >&)
|
||||
{
|
||||
return instance();
|
||||
}
|
||||
|
||||
void AuroraeFactory::updateConfiguration()
|
||||
{
|
||||
const KConfig conf(QStringLiteral("auroraerc"));
|
||||
const KConfigGroup group(&conf, "Engine");
|
||||
const QString themeName = group.readEntry("ThemeName", "example-deco");
|
||||
const KConfig config(QStringLiteral("aurorae/themes/") + themeName + QStringLiteral("/") + themeName + QStringLiteral("rc"),
|
||||
KConfig::FullConfig, QStandardPaths::GenericDataLocation);
|
||||
const KConfigGroup themeGroup(&conf, themeName);
|
||||
if (themeName != m_themeName) {
|
||||
m_engine->clearComponentCache();
|
||||
init();
|
||||
emit recreateDecorations();
|
||||
}
|
||||
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));
|
||||
} else {
|
||||
// we don't know how the settings change -> recreate
|
||||
emit recreateDecorations();
|
||||
}
|
||||
emit configChanged();
|
||||
}
|
||||
|
||||
bool AuroraeFactory::supports(Ability ability) const
|
||||
{
|
||||
switch (ability) {
|
||||
case AbilityAnnounceButtons:
|
||||
case AbilityUsesAlphaChannel:
|
||||
case AbilityAnnounceAlphaChannel:
|
||||
case AbilityButtonMenu:
|
||||
case AbilityButtonSpacer:
|
||||
case AbilityExtendIntoClientArea:
|
||||
case AbilityButtonMinimize:
|
||||
case AbilityButtonMaximize:
|
||||
case AbilityButtonClose:
|
||||
case AbilityButtonAboveOthers:
|
||||
case AbilityButtonBelowOthers:
|
||||
case AbilityButtonShade:
|
||||
case AbilityButtonOnAllDesktops:
|
||||
case AbilityButtonHelp:
|
||||
case AbilityButtonApplicationMenu:
|
||||
case AbilityProvidesShadow:
|
||||
return true; // TODO: correct value from theme
|
||||
case AbilityTabbing:
|
||||
return false;
|
||||
case AbilityUsesBlurBehind:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
KDecoration *AuroraeFactory::createDecoration(KDecorationBridge *bridge)
|
||||
{
|
||||
AuroraeClient *client = new AuroraeClient(bridge, this);
|
||||
return client;
|
||||
}
|
||||
|
||||
QList< KDecorationDefines::BorderSize > AuroraeFactory::borderSizes() const
|
||||
{
|
||||
return QList< BorderSize >() << BorderTiny << BorderNormal <<
|
||||
BorderLarge << BorderVeryLarge << BorderHuge <<
|
||||
BorderVeryHuge << BorderOversized;
|
||||
}
|
||||
|
||||
QQuickItem *AuroraeFactory::createQmlDecoration(Aurorae::AuroraeClient *client)
|
||||
{
|
||||
QQmlContext *context = new QQmlContext(m_engine->rootContext(), this);
|
||||
context->setContextProperty(QStringLiteral("decoration"), client);
|
||||
return qobject_cast< QQuickItem* >(m_component->create(context));
|
||||
}
|
||||
|
||||
AuroraeFactory *AuroraeFactory::s_instance = nullptr;
|
||||
|
||||
/*******************************************************
|
||||
* Client
|
||||
*******************************************************/
|
||||
AuroraeClient::AuroraeClient(KDecorationBridge *bridge, KDecorationFactory *factory)
|
||||
: KDecoration(bridge, factory)
|
||||
, m_view(nullptr)
|
||||
, m_item(AuroraeFactory::instance()->createQmlDecoration(this))
|
||||
Decoration::Decoration(QObject *parent, const QVariantList &args)
|
||||
: KDecoration2::Decoration(parent)
|
||||
, m_item(nullptr)
|
||||
, m_borders(nullptr)
|
||||
, m_maximizedBorders(nullptr)
|
||||
, m_extendedBorders(nullptr)
|
||||
, m_padding(nullptr)
|
||||
, m_themeName(s_defaultTheme)
|
||||
, m_mutex(QMutex::Recursive)
|
||||
{
|
||||
connect(AuroraeFactory::instance(), SIGNAL(buttonsChanged()), SIGNAL(buttonsChanged()));
|
||||
connect(AuroraeFactory::instance(), SIGNAL(configChanged()), SIGNAL(configChanged()));
|
||||
connect(AuroraeFactory::instance(), SIGNAL(titleFontChanged()), SIGNAL(fontChanged()));
|
||||
connect(m_item, SIGNAL(alphaChanged()), SLOT(slotAlphaChanged()));
|
||||
connect(this, SIGNAL(appMenuAvailable()), SIGNAL(appMenuAvailableChanged()));
|
||||
connect(this, SIGNAL(appMenuUnavailable()), SIGNAL(appMenuAvailableChanged()));
|
||||
if (!args.isEmpty()) {
|
||||
const auto map = args.first().toMap();
|
||||
auto it = map.constFind(QStringLiteral("theme"));
|
||||
if (it != map.constEnd()) {
|
||||
m_themeName = it.value().toString();
|
||||
}
|
||||
}
|
||||
Helper::instance().ref();
|
||||
}
|
||||
|
||||
AuroraeClient::~AuroraeClient()
|
||||
Decoration::~Decoration()
|
||||
{
|
||||
QMutexLocker locker(AuroraeFactory::instance()->mutex());
|
||||
Helper::instance().unref();
|
||||
}
|
||||
|
||||
void AuroraeClient::init()
|
||||
void Decoration::init()
|
||||
{
|
||||
m_view = new QQuickWindow();
|
||||
m_view->setFlags(initialWFlags());
|
||||
m_view->setColor(Qt::transparent);
|
||||
setMainWindow(m_view);
|
||||
if (compositingActive()) {
|
||||
connect(m_view, &QQuickWindow::beforeRendering, [this]() {
|
||||
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));
|
||||
KDecoration2::Decoration::init();
|
||||
QQmlContext *context = new QQmlContext(Helper::instance().rootContext(), this);
|
||||
context->setContextProperty(QStringLiteral("decoration"), this);
|
||||
auto component = Helper::instance().component(m_themeName);
|
||||
if (!component) {
|
||||
return;
|
||||
}
|
||||
if (component == Helper::instance().svgComponent()) {
|
||||
// load SVG theme
|
||||
const QString themeName = m_themeName.mid(16);
|
||||
KConfig config(QStringLiteral("aurorae/themes/") + themeName + QStringLiteral("/") + themeName + QStringLiteral("rc"),
|
||||
KConfig::FullConfig, QStandardPaths::GenericDataLocation);
|
||||
// KConfigGroup themeGroup(&conf, themeName);
|
||||
AuroraeTheme *theme = new AuroraeTheme(this);
|
||||
theme->loadTheme(themeName, config);
|
||||
// m_theme->setBorderSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("BorderSize", KDecorationDefines::BorderNormal));
|
||||
// m_theme->setButtonSize((KDecorationDefines::BorderSize)themeGroup.readEntry<int>("ButtonSize", KDecorationDefines::BorderNormal));
|
||||
// m_theme->setTabDragMimeType(tabDragMimeType());
|
||||
context->setContextProperty(QStringLiteral("auroraeTheme"), theme);
|
||||
}
|
||||
m_item = qobject_cast< QQuickItem* >(component->create(context));
|
||||
if (!m_item) {
|
||||
return;
|
||||
}
|
||||
m_item->setParent(this);
|
||||
|
||||
QVariant visualParent = property("visualParent");
|
||||
if (visualParent.isValid()) {
|
||||
m_item->setParentItem(visualParent.value<QQuickItem*>());
|
||||
} else {
|
||||
// we need a QQuickWindow till we depend on Qt 5.4
|
||||
m_decorationWindow.reset(QWindow::fromWinId(client()->decorationId()));
|
||||
m_view.reset(new QQuickWindow(m_decorationWindow.data()));
|
||||
m_view->setFlags(Qt::WindowDoesNotAcceptFocus | Qt::WindowTransparentForInput);
|
||||
m_view->setColor(Qt::transparent);
|
||||
connect(m_view.data(), &QQuickWindow::beforeRendering, [this]() {
|
||||
if (!KDecoration2::DecorationSettings::self()->isAlphaChannelSupported()) {
|
||||
// directly render to QQuickWindow
|
||||
return;
|
||||
}
|
||||
if (m_fbo.isNull() || m_fbo->size() != size()) {
|
||||
m_fbo.reset(new QOpenGLFramebufferObject(size(), QOpenGLFramebufferObject::CombinedDepthStencil));
|
||||
if (!m_fbo->isValid()) {
|
||||
qCWarning(AURORAE) << "Creating FBO as render target failed";
|
||||
m_fbo.reset();
|
||||
|
@ -321,315 +284,150 @@ void AuroraeClient::init()
|
|||
}
|
||||
m_view->setRenderTarget(m_fbo.data());
|
||||
});
|
||||
connect(m_view, &QQuickWindow::afterRendering, [this]{
|
||||
QMutexLocker locker(AuroraeFactory::instance()->mutex());
|
||||
connect(m_view.data(), &QQuickWindow::afterRendering, [this] {
|
||||
if (!m_fbo) {
|
||||
return;
|
||||
}
|
||||
QMutexLocker locker(&m_mutex);
|
||||
m_buffer = m_fbo->toImage();
|
||||
});
|
||||
connect(m_view, &QQuickWindow::afterRendering, this,
|
||||
static_cast<void (KDecoration::*)(void)>(&KDecoration::update), Qt::QueuedConnection);
|
||||
}
|
||||
if (m_item) {
|
||||
connect(KDecoration2::DecorationSettings::self(), &KDecoration2::DecorationSettings::alphaChannelSupportedChanged,
|
||||
m_view.data(), &QQuickWindow::update);
|
||||
connect(m_view.data(), &QQuickWindow::afterRendering, this, [this] { update(); }, Qt::QueuedConnection);
|
||||
m_item->setParentItem(m_view->contentItem());
|
||||
m_item->setParent(m_view);
|
||||
setupBorders();
|
||||
}
|
||||
slotAlphaChanged();
|
||||
|
||||
AuroraeFactory::instance()->theme()->setCompositingActive(compositingActive());
|
||||
}
|
||||
|
||||
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) {
|
||||
return KDecoration::eventFilter(object, event);
|
||||
setupBorders(m_item);
|
||||
if (m_extendedBorders) {
|
||||
auto updateExtendedBorders = [this] {
|
||||
setExtendedBorders(m_extendedBorders->left(), m_extendedBorders->right(), m_extendedBorders->top(), m_extendedBorders->bottom());
|
||||
};
|
||||
updateExtendedBorders();
|
||||
connect(m_extendedBorders, &KWin::Borders::leftChanged, this, updateExtendedBorders);
|
||||
connect(m_extendedBorders, &KWin::Borders::rightChanged, this, updateExtendedBorders);
|
||||
connect(m_extendedBorders, &KWin::Borders::topChanged, this, updateExtendedBorders);
|
||||
connect(m_extendedBorders, &KWin::Borders::bottomChanged, this, updateExtendedBorders);
|
||||
}
|
||||
QWheelEvent *wheel = static_cast<QWheelEvent*>(event);
|
||||
if (mousePosition(wheel->pos()) == PositionCenter) {
|
||||
titlebarMouseWheelOperation(wheel->delta());
|
||||
return true;
|
||||
connect(client().data(), &KDecoration2::DecoratedClient::maximizedChanged, this, &Decoration::updateBorders, Qt::QueuedConnection);
|
||||
updateBorders();
|
||||
if (!m_view.isNull()) {
|
||||
m_view->setVisible(true);
|
||||
m_view->lower();
|
||||
m_view->resize(m_item->width(), m_item->height());
|
||||
auto resizeWindow = [this] {
|
||||
m_view->resize(m_item->width(), m_item->height());
|
||||
m_view->lower();
|
||||
m_view->update();
|
||||
};
|
||||
connect(m_item, &QQuickItem::widthChanged, this, resizeWindow);
|
||||
connect(m_item, &QQuickItem::heightChanged, this, resizeWindow);
|
||||
resizeWindow();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AuroraeClient::resize(const QSize &s)
|
||||
{
|
||||
if (m_item) {
|
||||
m_item->setWidth(s.width());
|
||||
m_item->setHeight(s.height());
|
||||
}
|
||||
m_view->resize(s);
|
||||
}
|
||||
|
||||
void AuroraeClient::borders(int &left, int &right, int &top, int &bottom) const
|
||||
{
|
||||
if (!m_item) {
|
||||
left = right = top = bottom = 0;
|
||||
return;
|
||||
}
|
||||
KWin::Borders *borders = nullptr;
|
||||
if (maximizeMode() == MaximizeFull) {
|
||||
borders = m_maximizedBorders;
|
||||
} else {
|
||||
borders = m_borders;
|
||||
}
|
||||
sizesFromBorders(borders, left, right, top, bottom);
|
||||
}
|
||||
|
||||
void AuroraeClient::padding(int &left, int &right, int &top, int &bottom) const
|
||||
{
|
||||
if (!m_padding) {
|
||||
left = right = top = bottom = 0;
|
||||
return;
|
||||
}
|
||||
if (maximizeMode() == MaximizeFull) {
|
||||
left = right = top = bottom = 0;
|
||||
return;
|
||||
}
|
||||
sizesFromBorders(m_padding, left, right, top, bottom);
|
||||
}
|
||||
|
||||
void AuroraeClient::sizesFromBorders(const KWin::Borders *borders, int &left, int &right, int &top, int &bottom) const
|
||||
{
|
||||
if (!borders) {
|
||||
left = right = top = bottom = 0;
|
||||
return;
|
||||
}
|
||||
left = borders->left();
|
||||
right = borders->right();
|
||||
top = borders->top();
|
||||
bottom = borders->bottom();
|
||||
}
|
||||
|
||||
QSize AuroraeClient::minimumSize() const
|
||||
{
|
||||
return m_view->minimumSize();
|
||||
}
|
||||
|
||||
KDecorationDefines::Position AuroraeClient::mousePosition(const QPoint &point) const
|
||||
{
|
||||
// based on the code from deKorator
|
||||
int pos = PositionCenter;
|
||||
if (isShade() || isMaximized()) {
|
||||
return Position(pos);
|
||||
}
|
||||
|
||||
int borderLeft, borderTop, borderRight, borderBottom;
|
||||
borders(borderLeft, borderRight, borderTop, borderBottom);
|
||||
int paddingLeft, paddingTop, paddingRight, paddingBottom;
|
||||
padding(paddingLeft, paddingRight, paddingTop, paddingBottom);
|
||||
int titleEdgeLeft, titleEdgeRight, titleEdgeTop, titleEdgeBottom;
|
||||
AuroraeFactory::instance()->theme()->titleEdges(titleEdgeLeft, titleEdgeTop, titleEdgeRight, titleEdgeBottom, false);
|
||||
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
|
||||
}
|
||||
if (point.x() >= (m_view->width() - borderRight - paddingRight)) {
|
||||
pos |= PositionRight;
|
||||
} else if (point.x() <= borderLeft + paddingLeft) {
|
||||
pos |= PositionLeft;
|
||||
}
|
||||
|
||||
if (point.y() >= m_view->height() - borderBottom - paddingBottom) {
|
||||
pos |= PositionBottom;
|
||||
} else if (point.y() <= borderTop + paddingTop ) {
|
||||
pos |= PositionTop;
|
||||
}
|
||||
|
||||
return Position(pos);
|
||||
}
|
||||
|
||||
void AuroraeClient::menuClicked()
|
||||
{
|
||||
showWindowMenu(QCursor::pos());
|
||||
}
|
||||
|
||||
void AuroraeClient::appMenuClicked()
|
||||
{
|
||||
showApplicationMenu(QCursor::pos());
|
||||
}
|
||||
|
||||
void AuroraeClient::toggleShade()
|
||||
{
|
||||
setShade(!isShade());
|
||||
}
|
||||
|
||||
void AuroraeClient::toggleKeepAbove()
|
||||
{
|
||||
setKeepAbove(!keepAbove());
|
||||
}
|
||||
|
||||
void AuroraeClient::toggleKeepBelow()
|
||||
{
|
||||
setKeepBelow(!keepBelow());
|
||||
}
|
||||
|
||||
void AuroraeClient::titlePressed(int button, int buttons)
|
||||
{
|
||||
titlePressed(static_cast<Qt::MouseButton>(button), static_cast<Qt::MouseButtons>(buttons));
|
||||
}
|
||||
|
||||
void AuroraeClient::titlePressed(Qt::MouseButton button, Qt::MouseButtons buttons)
|
||||
{
|
||||
const QPoint cursor = QCursor::pos();
|
||||
QMouseEvent *event = new QMouseEvent(QEvent::MouseButtonPress, cursor - geometry().topLeft() + (m_padding ? QPoint(m_padding->left(), m_padding->top()) : QPoint(0, 0)),
|
||||
cursor, button, buttons, Qt::NoModifier);
|
||||
processMousePressEvent(event);
|
||||
delete event;
|
||||
event = nullptr;
|
||||
}
|
||||
|
||||
void AuroraeClient::themeChanged()
|
||||
{
|
||||
m_item->deleteLater();
|
||||
m_item = AuroraeFactory::instance()->createQmlDecoration(this);
|
||||
if (!m_item) {
|
||||
m_borders = nullptr;
|
||||
m_extendedBorders = nullptr;
|
||||
m_maximizedBorders = nullptr;
|
||||
m_padding = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
m_item->setParentItem(m_view->contentItem());
|
||||
m_item->setParent(m_view);
|
||||
setupBorders();
|
||||
connect(m_item, SIGNAL(alphaChanged()), SLOT(slotAlphaChanged()));
|
||||
slotAlphaChanged();
|
||||
}
|
||||
|
||||
int AuroraeClient::doubleClickInterval() const
|
||||
{
|
||||
return QApplication::doubleClickInterval();
|
||||
}
|
||||
|
||||
void AuroraeClient::closeWindow()
|
||||
{
|
||||
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this), "doCloseWindow", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void AuroraeClient::doCloseWindow()
|
||||
{
|
||||
KDecoration::closeWindow();
|
||||
}
|
||||
|
||||
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
|
||||
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this),
|
||||
"doMaximzie",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, button));
|
||||
}
|
||||
|
||||
void AuroraeClient::doMaximzie(int button)
|
||||
{
|
||||
KDecoration::maximize(static_cast<Qt::MouseButton>(button));
|
||||
}
|
||||
|
||||
void AuroraeClient::titlebarDblClickOperation()
|
||||
{
|
||||
// the double click operation can result in a window being maximized
|
||||
// see maximize
|
||||
QMetaObject::invokeMethod(qobject_cast< KDecoration* >(this), "doTitlebarDblClickOperation", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void AuroraeClient::doTitlebarDblClickOperation()
|
||||
{
|
||||
KDecoration::titlebarDblClickOperation();
|
||||
}
|
||||
|
||||
QVariant AuroraeClient::readConfig(const QString &key, const QVariant &defaultValue)
|
||||
QVariant Decoration::readConfig(const QString &key, const QVariant &defaultValue)
|
||||
{
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("auroraerc"));
|
||||
return config->group(AuroraeFactory::instance()->currentThemeName()).readEntry(key, defaultValue);
|
||||
return config->group(QStringLiteral("Plastik")).readEntry(key, defaultValue);
|
||||
}
|
||||
|
||||
void AuroraeClient::slotAlphaChanged()
|
||||
void Decoration::setupBorders(QQuickItem *item)
|
||||
{
|
||||
if (!m_item) {
|
||||
setAlphaEnabled(false);
|
||||
m_borders = item->findChild<KWin::Borders*>(QStringLiteral("borders"));
|
||||
m_maximizedBorders = item->findChild<KWin::Borders*>(QStringLiteral("maximizedBorders"));
|
||||
m_extendedBorders = item->findChild<KWin::Borders*>(QStringLiteral("extendedBorders"));
|
||||
m_padding = item->findChild<KWin::Borders*>(QStringLiteral("padding"));
|
||||
}
|
||||
|
||||
void Decoration::updateBorders()
|
||||
{
|
||||
KWin::Borders *b = m_borders;
|
||||
if (client()->isMaximized() && m_maximizedBorders) {
|
||||
b = m_maximizedBorders;
|
||||
}
|
||||
if (!b) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
setBorders(b->left(), b->right(), b->top(), b->bottom());
|
||||
}
|
||||
|
||||
QRegion AuroraeClient::region(KDecorationDefines::Region r)
|
||||
void Decoration::paint(QPainter *painter)
|
||||
{
|
||||
if (r != ExtendedBorderRegion) {
|
||||
return QRegion();
|
||||
}
|
||||
if (!m_item) {
|
||||
return QRegion();
|
||||
}
|
||||
if (isMaximized()) {
|
||||
// empty region for maximized windows
|
||||
return QRegion();
|
||||
}
|
||||
int left, right, top, bottom;
|
||||
left = right = top = bottom = 0;
|
||||
sizesFromBorders(m_extendedBorders, left, right, top, bottom);
|
||||
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);
|
||||
QRect rect = this->rect().adjusted(paddingLeft, paddingTop, -paddingRight, -paddingBottom);
|
||||
rect.translate(-paddingLeft, -paddingTop);
|
||||
|
||||
return QRegion(rect.adjusted(-left, -top, right, bottom)).subtract(rect);
|
||||
QMutexLocker locker(&m_mutex);
|
||||
painter->fillRect(rect(), Qt::transparent);
|
||||
// TODO: remove Shadow
|
||||
painter->drawImage(rect(), m_buffer);
|
||||
}
|
||||
|
||||
bool AuroraeClient::animationsSupported() const
|
||||
void Decoration::hoverEnterEvent(QHoverEvent *event)
|
||||
{
|
||||
return compositingActive();
|
||||
}
|
||||
|
||||
void AuroraeClient::render(QPaintDevice *device, const QRegion &sourceRegion)
|
||||
{
|
||||
QMutexLocker locker(AuroraeFactory::instance()->mutex());
|
||||
QPainter painter(device);
|
||||
painter.setClipRegion(sourceRegion);
|
||||
painter.drawImage(QPoint(0, 0), m_buffer);
|
||||
}
|
||||
|
||||
void AuroraeClient::setupBorders()
|
||||
{
|
||||
if (!m_item) {
|
||||
return;
|
||||
if (m_view) {
|
||||
event->setAccepted(false);
|
||||
QCoreApplication::sendEvent(m_view.data(), event);
|
||||
}
|
||||
m_borders = m_item->findChild<KWin::Borders*>(QStringLiteral("borders"));
|
||||
m_maximizedBorders = m_item->findChild<KWin::Borders*>(QStringLiteral("maximizedBorders"));
|
||||
m_extendedBorders = m_item->findChild<KWin::Borders*>(QStringLiteral("extendedBorders"));
|
||||
m_padding = m_item->findChild<KWin::Borders*>(QStringLiteral("padding"));
|
||||
KDecoration2::Decoration::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
} // namespace Aurorae
|
||||
void Decoration::hoverLeaveEvent(QHoverEvent *event)
|
||||
{
|
||||
if (m_view) {
|
||||
event->setAccepted(false);
|
||||
QCoreApplication::sendEvent(m_view.data(), event);
|
||||
}
|
||||
KDecoration2::Decoration::hoverLeaveEvent(event);
|
||||
}
|
||||
|
||||
void Decoration::hoverMoveEvent(QHoverEvent *event)
|
||||
{
|
||||
if (m_view) {
|
||||
QMouseEvent ev(QEvent::MouseMove, event->posF(), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||
QCoreApplication::sendEvent(m_view.data(), &ev);
|
||||
}
|
||||
KDecoration2::Decoration::hoverMoveEvent(event);
|
||||
}
|
||||
|
||||
void Decoration::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_view) {
|
||||
event->setAccepted(false);
|
||||
QCoreApplication::sendEvent(m_view.data(), event);
|
||||
}
|
||||
KDecoration2::Decoration::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void Decoration::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_view) {
|
||||
event->setAccepted(false);
|
||||
QCoreApplication::sendEvent(m_view.data(), event);
|
||||
}
|
||||
KDecoration2::Decoration::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void Decoration::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if (m_view) {
|
||||
event->setAccepted(false);
|
||||
QCoreApplication::sendEvent(m_view.data(), event);
|
||||
}
|
||||
KDecoration2::Decoration::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
void Decoration::installTitleItem(QQuickItem *item)
|
||||
{
|
||||
auto update = [this, item] {
|
||||
QRect rect = item->mapRectToScene(item->childrenRect()).toRect();
|
||||
if (rect.isNull()) {
|
||||
rect = item->parentItem()->mapRectToScene(QRectF(item->x(), item->y(), item->width(), item->height())).toRect();
|
||||
}
|
||||
setTitleRect(rect);
|
||||
};
|
||||
update();
|
||||
connect(item, &QQuickItem::widthChanged, this, update);
|
||||
connect(item, &QQuickItem::heightChanged, this, update);
|
||||
connect(item, &QQuickItem::xChanged, this, update);
|
||||
connect(item, &QQuickItem::yChanged, this, update);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "aurorae.moc"
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
[Desktop Entry]
|
||||
Name=Aurorae Decoration Theme Engine
|
||||
Name[ar]=محرك شفق لسمات التزيين
|
||||
Name[ast]=Motor de temes de decoración Aurorae
|
||||
Name[bg]=Теми за декорация на прозорци Aurorae
|
||||
Name[bs]=Aurore, tematski motor dekoracija
|
||||
Name[ca]=Motor del tema de decoració Aurorae
|
||||
Name[ca@valencia]=Motor del tema de decoració Aurorae
|
||||
Name[cs]=Stroj motivů dekorace Aurorae
|
||||
Name[csb]=Mòtór dekòracëji wëzdrzatkù Aurorae
|
||||
Name[da]=Temamotor til Aurorae-dekorationen
|
||||
Name[de]=Aurorae-Dekorationsdesign-Engine
|
||||
Name[el]=Μηχανισμός διακόσμησης θεμάτων Aurorae
|
||||
Name[en_GB]=Auroræ Decoration Theme Engine
|
||||
Name[eo]=Aurorae Ornamaĵ-etosa Modulo
|
||||
Name[es]=Motor de temas de decoración Aurorae
|
||||
Name[et]=Aurorae dekoratsioonide teema mootor
|
||||
Name[eu]=Aurorae apainketa-gaiaren motorra
|
||||
Name[fi]=Kehysten teemamoottori Aurorae
|
||||
Name[fr]=Moteur de thèmes pour la décoration « Aurorae »
|
||||
Name[fy]=Aurorae dekoraasje tema motor
|
||||
Name[ga]=Inneall Téama Maisiúcháin Aurorae
|
||||
Name[gl]=Motor de temas de decoración Aurorae
|
||||
Name[he]=מנוע ערכת התצוגה Aurorae Decoration
|
||||
Name[hr]=Tematski mehanizam za ukrase Aurorae
|
||||
Name[hu]=Aurorae ablakdekorációs témamodul
|
||||
Name[ia]=Motor de thema de decoration Aurorae
|
||||
Name[id]=Mesin Tema Dekorasi Aurorae
|
||||
Name[is]=Aurorae skjáskreytiþemavél
|
||||
Name[it]=Motore dei temi decorativi Aurorae
|
||||
Name[ja]=オーロラ装飾テーマエンジン
|
||||
Name[kk]=Aurorae безендіру нақыш теігі
|
||||
Name[km]=ម៉ាស៊ីនស្បែកតុបតែង Aurorae
|
||||
Name[kn]=ಅರೋರೆ ಪರಿಸರ ವಿನ್ಯಾಸ(ಥೀಮ್) ಎಂಜಿನ್
|
||||
Name[ko]=Aurorae 장식 테마 엔진
|
||||
Name[lt]=Aurorae dekoracijos temos variklis
|
||||
Name[lv]=Aurorae dekorācijas tēmu dzinējs
|
||||
Name[ml]=അറോറ അണിയിച്ചൊരുക്കാനുള്ള പ്രമേയ എഞ്ചിന്
|
||||
Name[mr]=ओरोरा सजावट शैली इंजिन
|
||||
Name[nb]=Aurorae motor for dekorasjonstema
|
||||
Name[nds]=Aurorae Dekoratschonen-Musterkarn
|
||||
Name[nl]=Aurorae decoratiethema-engine
|
||||
Name[nn]=Motor for pynting med temaet Aurorae
|
||||
Name[pa]=ਔਰੋਰਾਈ ਸਜਾਵਟ ਥੀਮ ਇੰਜਣ
|
||||
Name[pl]=Silnik zestawu ozdób Aurora
|
||||
Name[pt]=Motor do Tema de Decoração Aurorae
|
||||
Name[pt_BR]=Mecanismo do tema de decoração Aurorae
|
||||
Name[ro]=Motor pentru tematici de decorare Aurorae
|
||||
Name[ru]=Движок оформлений окон Aurorae
|
||||
Name[si]=Aurorae සැරසිලි තේමා එන්ජිම
|
||||
Name[sk]=Aurorae témy dekorácie
|
||||
Name[sl]=Pogon Aurorae za teme okraskov
|
||||
Name[sr]=Ауроре, тематски мотор декорација
|
||||
Name[sr@ijekavian]=Ауроре, тематски мотор декорација
|
||||
Name[sr@ijekavianlatin]=Aurore, tematski motor dekoracija
|
||||
Name[sr@latin]=Aurore, tematski motor dekoracija
|
||||
Name[sv]=Aurora dekorationstemagränssnitt
|
||||
Name[tg]=Системаи мавзӯъҳои аврора
|
||||
Name[th]=กลไกชุดตกแต่ง Aurorae
|
||||
Name[tr]=Aurorae Dekorasyon Teması Motoru
|
||||
Name[ug]=Aurorae زىننەتلەش ئۆرنەك ماتورى
|
||||
Name[uk]=Рушій декорації тем Aurorae
|
||||
Name[vi]=Cơ chế sắc thái trang trí Aurorae
|
||||
Name[wa]=Moteur di tinme di gåyotaedje Aurorae
|
||||
Name[x-test]=xxAurorae Decoration Theme Enginexx
|
||||
Name[zh_CN]=Aurorae 装饰主题引擎
|
||||
Name[zh_TW]=Aurorae 裝飾主題引擎
|
||||
X-KDE-PluginInfo-Name=aurorae
|
|
@ -18,19 +18,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef AURORAE_H
|
||||
#define AURORAE_H
|
||||
|
||||
#include "themeconfig.h"
|
||||
#include <KDecoration2/Decoration>
|
||||
#include <QVariant>
|
||||
#include <QMutex>
|
||||
|
||||
#include <kdecoration.h>
|
||||
#include <kdecorationfactory.h>
|
||||
|
||||
class QMutex;
|
||||
class QOpenGLFramebufferObject;
|
||||
class QQmlComponent;
|
||||
class QQmlEngine;
|
||||
class QQuickItem;
|
||||
class QQuickWindow;
|
||||
class KConfig;
|
||||
class KConfigGroup;
|
||||
class QWindow;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -39,144 +36,44 @@ class Borders;
|
|||
|
||||
namespace Aurorae
|
||||
{
|
||||
class AuroraeTheme;
|
||||
class AuroraeClient;
|
||||
|
||||
class AuroraeFactory : public KDecorationFactory
|
||||
class Decoration : public KDecoration2::Decoration
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~AuroraeFactory();
|
||||
explicit Decoration(QObject *parent = nullptr, const QVariantList &args = QVariantList());
|
||||
virtual ~Decoration();
|
||||
|
||||
static AuroraeFactory* instance();
|
||||
static QObject *createInstance(QWidget *, QObject *, const QList<QVariant> &);
|
||||
KDecoration *createDecoration(KDecorationBridge*);
|
||||
bool supports(Ability ability) const;
|
||||
virtual QList< BorderSize > borderSizes() const;
|
||||
|
||||
AuroraeTheme *theme() const {
|
||||
return m_theme;
|
||||
}
|
||||
QQuickItem *createQmlDecoration(AuroraeClient *client);
|
||||
const QString ¤tThemeName() const {
|
||||
return m_themeName;
|
||||
}
|
||||
|
||||
QMutex *mutex() {
|
||||
return m_mutex.data();
|
||||
}
|
||||
|
||||
private:
|
||||
enum EngineType {
|
||||
AuroraeEngine,
|
||||
QMLEngine
|
||||
};
|
||||
explicit AuroraeFactory(QObject *parent = nullptr);
|
||||
void init();
|
||||
void initAurorae(KConfig &conf, KConfigGroup &group);
|
||||
void initQML(const KConfigGroup& group);
|
||||
|
||||
Q_SIGNALS:
|
||||
void buttonsChanged();
|
||||
void titleFontChanged();
|
||||
void configChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateConfiguration();
|
||||
|
||||
private:
|
||||
static AuroraeFactory *s_instance;
|
||||
|
||||
AuroraeTheme *m_theme;
|
||||
QQmlEngine *m_engine;
|
||||
QQmlComponent *m_component;
|
||||
EngineType m_engineType;
|
||||
QString m_themeName;
|
||||
QScopedPointer<QMutex> m_mutex;
|
||||
};
|
||||
|
||||
class AuroraeClient : public KDecoration
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QRect geometry READ geometry)
|
||||
Q_PROPERTY(int height READ height)
|
||||
Q_PROPERTY(bool closeable READ isCloseable CONSTANT)
|
||||
Q_PROPERTY(bool maximizeable READ isMaximizable CONSTANT)
|
||||
Q_PROPERTY(bool minimizeable READ isMinimizable CONSTANT)
|
||||
Q_PROPERTY(bool modal READ isModal)
|
||||
Q_PROPERTY(bool moveable READ isMovable CONSTANT)
|
||||
Q_PROPERTY(bool preview READ isPreview CONSTANT)
|
||||
Q_PROPERTY(bool resizeable READ isResizable CONSTANT)
|
||||
Q_PROPERTY(bool shadeable READ isShadeable)
|
||||
Q_PROPERTY(bool providesContextHelp READ providesContextHelp)
|
||||
Q_PROPERTY(bool appMenu READ menuAvailable NOTIFY appMenuAvailableChanged)
|
||||
Q_PROPERTY(QRect transparentRect READ transparentRect)
|
||||
Q_PROPERTY(int width READ width)
|
||||
Q_PROPERTY(qulonglong windowId READ windowId CONSTANT)
|
||||
Q_PROPERTY(int doubleClickInterval READ doubleClickInterval)
|
||||
Q_PROPERTY(bool animationsSupported READ animationsSupported CONSTANT)
|
||||
// TODO: window tabs - they suck for dynamic features
|
||||
public:
|
||||
AuroraeClient(KDecorationBridge* bridge, KDecorationFactory* factory);
|
||||
virtual ~AuroraeClient();
|
||||
virtual bool eventFilter(QObject *object, QEvent *event);
|
||||
virtual void borders(int& left, int& right, int& top, int& bottom) const;
|
||||
virtual void init();
|
||||
virtual QSize minimumSize() const;
|
||||
virtual Position mousePosition(const QPoint& p) const;
|
||||
virtual void resize(const QSize& s);
|
||||
// optional overrides
|
||||
virtual void padding(int &left, int &right, int &top, int &bottom) const;
|
||||
int doubleClickInterval() const;
|
||||
|
||||
bool animationsSupported() const;
|
||||
void paint(QPainter *painter) override;
|
||||
|
||||
Q_INVOKABLE QVariant readConfig(const QString &key, const QVariant &defaultValue = QVariant());
|
||||
|
||||
virtual void render(QPaintDevice *device, const QRegion &sourceRegion);
|
||||
|
||||
Q_SIGNALS:
|
||||
void buttonsChanged();
|
||||
/**
|
||||
* Signal emitted when the decoration's configuration might have changed.
|
||||
* A decoration could reload it's configuration when this signal is emitted.
|
||||
**/
|
||||
void configChanged();
|
||||
void fontChanged();
|
||||
void appMenuAvailableChanged();
|
||||
|
||||
public Q_SLOTS:
|
||||
void menuClicked();
|
||||
void appMenuClicked();
|
||||
void toggleShade();
|
||||
void toggleKeepAbove();
|
||||
void toggleKeepBelow();
|
||||
void titlePressed(int button, int buttons);
|
||||
void titlePressed(Qt::MouseButton button, Qt::MouseButtons buttons);
|
||||
void closeWindow();
|
||||
void titlebarDblClickOperation();
|
||||
void maximize(int button);
|
||||
void init() override;
|
||||
void installTitleItem(QQuickItem *item);
|
||||
|
||||
QRegion region(KDecorationDefines::Region r);
|
||||
|
||||
private Q_SLOTS:
|
||||
void themeChanged();
|
||||
void doCloseWindow();
|
||||
void doTitlebarDblClickOperation();
|
||||
void doMaximzie(int button);
|
||||
void slotAlphaChanged();
|
||||
protected:
|
||||
void hoverEnterEvent(QHoverEvent *event) override;
|
||||
void hoverLeaveEvent(QHoverEvent *event) override;
|
||||
void hoverMoveEvent(QHoverEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
|
||||
private:
|
||||
void sizesFromBorders(const KWin::Borders *borders, int &left, int &right, int &top, int &bottom) const;
|
||||
void setupBorders();
|
||||
QQuickWindow *m_view;
|
||||
QQuickItem *m_item;
|
||||
void setupBorders(QQuickItem *item);
|
||||
void updateBorders();
|
||||
QScopedPointer<QOpenGLFramebufferObject> m_fbo;
|
||||
QImage m_buffer;
|
||||
QScopedPointer<QWindow> m_decorationWindow;
|
||||
QScopedPointer<QQuickWindow> m_view;
|
||||
QQuickItem *m_item;
|
||||
KWin::Borders *m_borders;
|
||||
KWin::Borders *m_maximizedBorders;
|
||||
KWin::Borders *m_extendedBorders;
|
||||
KWin::Borders *m_padding;
|
||||
QString m_themeName;
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
14
clients/aurorae/src/aurorae.json
Normal file
14
clients/aurorae/src/aurorae.json
Normal file
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"Type": "Service",
|
||||
"X-KDE-Library": "kwin5_aurorae",
|
||||
"X-KDE-PluginInfo-EnabledByDefault": true,
|
||||
"X-KDE-PluginInfo-Name": "org.kde.kwin.aurorae",
|
||||
"X-KDE-ServiceTypes": [
|
||||
"org.kde.kdecoration2"
|
||||
],
|
||||
"org.kde.kdecoration2": {
|
||||
"blur": true,
|
||||
"themes": true,
|
||||
"defaultTheme": "kwin4_decoration_qml_plastik"
|
||||
}
|
||||
}
|
|
@ -15,19 +15,55 @@ 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 "decorationoptions.h"
|
||||
#include <kdecoration.h>
|
||||
#include <KDecoration2/DecoratedClient>
|
||||
#include <KDecoration2/DecorationSettings>
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
ColorSettings::ColorSettings(const QPalette &pal)
|
||||
{
|
||||
init(pal);
|
||||
}
|
||||
|
||||
void ColorSettings::update(const QPalette &pal)
|
||||
{
|
||||
init(pal);
|
||||
}
|
||||
|
||||
void ColorSettings::init(const QPalette &pal)
|
||||
{
|
||||
m_palette = pal;
|
||||
KConfigGroup wmConfig(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("WM"));
|
||||
m_activeFrameColor = wmConfig.readEntry("frame", pal.color(QPalette::Active, QPalette::Background));
|
||||
m_inactiveFrameColor = wmConfig.readEntry("inactiveFrame", m_activeFrameColor);
|
||||
m_activeTitleBarColor = wmConfig.readEntry("activeBackground", pal.color(QPalette::Active, QPalette::Highlight));
|
||||
m_inactiveTitleBarColor = wmConfig.readEntry("inactiveBackground", m_inactiveFrameColor);
|
||||
m_activeTitleBarBlendColor = wmConfig.readEntry("activeBlend", m_activeTitleBarColor.dark(110));
|
||||
m_inactiveTitleBarBlendColor = wmConfig.readEntry("inactiveBlend", m_inactiveTitleBarColor.dark(110));
|
||||
m_activeFontColor = wmConfig.readEntry("activeForeground", pal.color(QPalette::Active, QPalette::HighlightedText));
|
||||
m_inactiveFontColor = wmConfig.readEntry("inactiveForeground", m_activeFontColor.dark());
|
||||
m_activeButtonColor = wmConfig.readEntry("activeTitleBtnBg", m_activeFrameColor.light(130));
|
||||
m_inactiveButtonColor = wmConfig.readEntry("inactiveTitleBtnBg", m_inactiveFrameColor.light(130));
|
||||
m_activeHandle = wmConfig.readEntry("handle", m_activeFrameColor);
|
||||
m_inactiveHandle = wmConfig.readEntry("inactiveHandle", m_activeHandle);
|
||||
}
|
||||
|
||||
|
||||
DecorationOptions::DecorationOptions(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_active(true)
|
||||
, m_decoration(nullptr)
|
||||
, m_colors(ColorSettings(QPalette()))
|
||||
{
|
||||
connect(this, &DecorationOptions::decorationChanged, this, &DecorationOptions::slotActiveChanged);
|
||||
connect(this, &DecorationOptions::decorationChanged, this, &DecorationOptions::colorsChanged);
|
||||
connect(this, &DecorationOptions::decorationChanged, this, &DecorationOptions::fontChanged);
|
||||
connect(KDecoration2::DecorationSettings::self(), &KDecoration2::DecorationSettings::fontChanged, this, &DecorationOptions::fontChanged);
|
||||
connect(KDecoration2::DecorationSettings::self(), &KDecoration2::DecorationSettings::decorationButtonsLeftChanged, this, &DecorationOptions::titleButtonsChanged);
|
||||
connect(KDecoration2::DecorationSettings::self(), &KDecoration2::DecorationSettings::decorationButtonsRightChanged, this, &DecorationOptions::titleButtonsChanged);
|
||||
}
|
||||
|
||||
DecorationOptions::~DecorationOptions()
|
||||
|
@ -36,89 +72,101 @@ DecorationOptions::~DecorationOptions()
|
|||
|
||||
QColor DecorationOptions::borderColor() const
|
||||
{
|
||||
return KDecoration::options()->color(KDecorationDefines::ColorFrame, m_active);
|
||||
return m_active ? m_colors.activeFrame() : m_colors.inactiveFrame();
|
||||
}
|
||||
|
||||
QColor DecorationOptions::buttonColor() const
|
||||
{
|
||||
return KDecoration::options()->color(KDecorationDefines::ColorButtonBg, m_active);
|
||||
return m_active ? m_colors.activeButtonColor() : m_colors.inactiveButtonColor();
|
||||
}
|
||||
|
||||
QColor DecorationOptions::fontColor() const
|
||||
{
|
||||
return KDecoration::options()->color(KDecorationDefines::ColorFont, m_active);
|
||||
return m_active ? m_colors.activeFont() : m_colors.inactiveFont();
|
||||
}
|
||||
|
||||
QColor DecorationOptions::resizeHandleColor() const
|
||||
{
|
||||
return KDecoration::options()->color(KDecorationDefines::ColorHandle, m_active);
|
||||
return m_active ? m_colors.activeHandle() : m_colors.inactiveHandle();
|
||||
}
|
||||
|
||||
QColor DecorationOptions::titleBarBlendColor() const
|
||||
{
|
||||
return KDecoration::options()->color(KDecorationDefines::ColorTitleBlend, m_active);
|
||||
return m_active ? m_colors.activeTitleBarBlendColor() : m_colors.inactiveTitleBarBlendColor();
|
||||
}
|
||||
|
||||
QColor DecorationOptions::titleBarColor() const
|
||||
{
|
||||
return KDecoration::options()->color(KDecorationDefines::ColorTitleBar, m_active);
|
||||
return m_active ? m_colors.activeTitleBarColor() : m_colors.inactiveTitleBarColor();
|
||||
}
|
||||
|
||||
QFont DecorationOptions::titleFont() const
|
||||
{
|
||||
return KDecoration::options()->font(m_active);
|
||||
return KDecoration2::DecorationSettings::self()->font();
|
||||
}
|
||||
|
||||
static int decorationButton(KDecoration2::DecorationButtonType type)
|
||||
{
|
||||
switch (type) {
|
||||
case KDecoration2::DecorationButtonType::Menu:
|
||||
return DecorationOptions::DecorationButtonMenu;
|
||||
case KDecoration2::DecorationButtonType::ApplicationMenu:
|
||||
return DecorationOptions::DecorationButtonApplicationMenu;
|
||||
case KDecoration2::DecorationButtonType::OnAllDesktops:
|
||||
return DecorationOptions::DecorationButtonOnAllDesktops;
|
||||
case KDecoration2::DecorationButtonType::Minimize:
|
||||
return DecorationOptions::DecorationButtonMinimize;
|
||||
case KDecoration2::DecorationButtonType::Maximize:
|
||||
return DecorationOptions::DecorationButtonMaximizeRestore;
|
||||
case KDecoration2::DecorationButtonType::Close:
|
||||
return DecorationOptions::DecorationButtonClose;
|
||||
case KDecoration2::DecorationButtonType::QuickHelp:
|
||||
return DecorationOptions::DecorationButtonQuickHelp;
|
||||
case KDecoration2::DecorationButtonType::Shade:
|
||||
return DecorationOptions::DecorationButtonShade;
|
||||
case KDecoration2::DecorationButtonType::KeepBelow:
|
||||
return DecorationOptions::DecorationButtonKeepBelow;
|
||||
case KDecoration2::DecorationButtonType::KeepAbove:
|
||||
return DecorationOptions::DecorationButtonKeepAbove;
|
||||
default:
|
||||
return DecorationOptions::DecorationButtonNone;
|
||||
}
|
||||
}
|
||||
|
||||
QList<int> DecorationOptions::titleButtonsLeft() const
|
||||
{
|
||||
QList<KDecorationDefines::DecorationButton> buttons;
|
||||
if (KDecoration::options()->customButtonPositions()) {
|
||||
buttons = KDecoration::options()->titleButtonsLeft();
|
||||
} else {
|
||||
buttons = KDecorationOptions::defaultTitleButtonsLeft();
|
||||
}
|
||||
QList<int> ret;
|
||||
for (auto it : buttons) {
|
||||
ret << static_cast<int>(it);
|
||||
for (auto it : KDecoration2::DecorationSettings::self()->decorationButtonsLeft()) {
|
||||
ret << decorationButton(it);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QList<int> DecorationOptions::titleButtonsRight() const
|
||||
{
|
||||
QList<KDecorationDefines::DecorationButton> buttons;
|
||||
if (KDecoration::options()->customButtonPositions()) {
|
||||
buttons = KDecoration::options()->titleButtonsRight();
|
||||
} else {
|
||||
buttons = KDecorationOptions::defaultTitleButtonsRight();
|
||||
}
|
||||
QList<int> ret;
|
||||
for (auto it : buttons) {
|
||||
ret << static_cast<int>(it);
|
||||
for (auto it : KDecoration2::DecorationSettings::self()->decorationButtonsRight()) {
|
||||
ret << decorationButton(it);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
QObject *DecorationOptions::decoration() const
|
||||
KDecoration2::Decoration *DecorationOptions::decoration() const
|
||||
{
|
||||
return m_decoration;
|
||||
}
|
||||
|
||||
void DecorationOptions::setDecoration(QObject *decoration)
|
||||
void DecorationOptions::setDecoration(KDecoration2::Decoration *decoration)
|
||||
{
|
||||
if (m_decoration == decoration) {
|
||||
return;
|
||||
}
|
||||
if (m_decoration) {
|
||||
// disconnect from existing decoration
|
||||
disconnect(m_decoration, SIGNAL(activeChanged()), this, SLOT(slotActiveChanged()));
|
||||
disconnect(m_decoration, SIGNAL(buttonsChanged()), this, SIGNAL(titleButtonsChanged()));
|
||||
disconnect(m_decoration, SIGNAL(fontChanged()), this, SIGNAL(fontChanged()));
|
||||
disconnect(m_decoration->client().data(), &KDecoration2::DecoratedClient::activeChanged, this, &DecorationOptions::slotActiveChanged);
|
||||
}
|
||||
m_decoration = decoration;
|
||||
connect(m_decoration, SIGNAL(activeChanged()), SLOT(slotActiveChanged()));
|
||||
connect(m_decoration, SIGNAL(buttonsChanged()), SIGNAL(titleButtonsChanged()));
|
||||
connect(m_decoration, SIGNAL(fontChanged()), SIGNAL(fontChanged()));
|
||||
connect(m_decoration->client().data(), &KDecoration2::DecoratedClient::activeChanged, this, &DecorationOptions::slotActiveChanged);
|
||||
emit decorationChanged();
|
||||
}
|
||||
|
||||
|
@ -127,10 +175,10 @@ void DecorationOptions::slotActiveChanged()
|
|||
if (!m_decoration) {
|
||||
return;
|
||||
}
|
||||
if (m_active == m_decoration->property("active").toBool()) {
|
||||
if (m_active == m_decoration->client()->isActive()) {
|
||||
return;
|
||||
}
|
||||
m_active = m_decoration->property("active").toBool();
|
||||
m_active = m_decoration->client()->isActive();
|
||||
emit colorsChanged();
|
||||
emit fontChanged();
|
||||
}
|
||||
|
|
|
@ -17,13 +17,89 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#ifndef KWIN_DECORATION_OPTIONS_H
|
||||
#define KWIN_DECORATION_OPTIONS_H
|
||||
|
||||
#include <KDecoration2/Decoration>
|
||||
|
||||
#include <QObject>
|
||||
#include <QColor>
|
||||
#include <QFont>
|
||||
#include <QPalette>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
||||
// TODO: move to deco API
|
||||
class ColorSettings
|
||||
{
|
||||
public:
|
||||
ColorSettings(const QPalette &pal);
|
||||
|
||||
void update(const QPalette &pal);
|
||||
|
||||
const QColor &titleBarColor(bool active) const {
|
||||
return active ? m_activeTitleBarColor : m_inactiveTitleBarColor;
|
||||
}
|
||||
const QColor &activeTitleBarColor() const {
|
||||
return m_activeTitleBarColor;
|
||||
}
|
||||
const QColor &inactiveTitleBarColor() const {
|
||||
return m_inactiveTitleBarColor;
|
||||
}
|
||||
const QColor &activeTitleBarBlendColor() const {
|
||||
return m_activeTitleBarBlendColor;
|
||||
}
|
||||
const QColor &inactiveTitleBarBlendColor() const {
|
||||
return m_inactiveTitleBarBlendColor;
|
||||
}
|
||||
const QColor &frame(bool active) const {
|
||||
return active ? m_activeFrameColor : m_inactiveFrameColor;
|
||||
}
|
||||
const QColor &activeFrame() const {
|
||||
return m_activeFrameColor;
|
||||
}
|
||||
const QColor &inactiveFrame() const {
|
||||
return m_inactiveFrameColor;
|
||||
}
|
||||
const QColor &font(bool active) const {
|
||||
return active ? m_activeFontColor : m_inactiveFontColor;
|
||||
}
|
||||
const QColor &activeFont() const {
|
||||
return m_activeFontColor;
|
||||
}
|
||||
const QColor &inactiveFont() const {
|
||||
return m_inactiveFontColor;
|
||||
}
|
||||
const QColor &activeButtonColor() const {
|
||||
return m_activeButtonColor;
|
||||
}
|
||||
const QColor &inactiveButtonColor() const {
|
||||
return m_inactiveButtonColor;
|
||||
}
|
||||
const QColor &activeHandle() const {
|
||||
return m_activeHandle;
|
||||
}
|
||||
const QColor &inactiveHandle() const {
|
||||
return m_inactiveHandle;
|
||||
}
|
||||
const QPalette &palette() const {
|
||||
return m_palette;
|
||||
}
|
||||
private:
|
||||
void init(const QPalette &pal);
|
||||
QColor m_activeTitleBarColor;
|
||||
QColor m_inactiveTitleBarColor;
|
||||
QColor m_activeTitleBarBlendColor;
|
||||
QColor m_inactiveTitleBarBlendColor;
|
||||
QColor m_activeFrameColor;
|
||||
QColor m_inactiveFrameColor;
|
||||
QColor m_activeFontColor;
|
||||
QColor m_inactiveFontColor;
|
||||
QColor m_activeButtonColor;
|
||||
QColor m_inactiveButtonColor;
|
||||
QColor m_activeHandle;
|
||||
QColor m_inactiveHandle;
|
||||
QPalette m_palette;
|
||||
};
|
||||
|
||||
/**
|
||||
* @short Common Window Decoration Options.
|
||||
*
|
||||
|
@ -60,7 +136,7 @@ class DecorationOptions : public QObject
|
|||
*
|
||||
* Best pass the decoration object available as a context property to this property.
|
||||
**/
|
||||
Q_PROPERTY(QObject *deco READ decoration WRITE setDecoration NOTIFY decorationChanged)
|
||||
Q_PROPERTY(KDecoration2::Decoration *deco READ decoration WRITE setDecoration NOTIFY decorationChanged)
|
||||
/**
|
||||
* The color for the titlebar depending on the decoration's active state.
|
||||
**/
|
||||
|
@ -149,8 +225,8 @@ public:
|
|||
QFont titleFont() const;
|
||||
QList<int> titleButtonsLeft() const;
|
||||
QList<int> titleButtonsRight() const;
|
||||
QObject *decoration() const;
|
||||
void setDecoration(QObject *decoration);
|
||||
KDecoration2::Decoration *decoration() const;
|
||||
void setDecoration(KDecoration2::Decoration *decoration);
|
||||
|
||||
Q_SIGNALS:
|
||||
void colorsChanged();
|
||||
|
@ -163,7 +239,8 @@ private Q_SLOTS:
|
|||
|
||||
private:
|
||||
bool m_active;
|
||||
QObject *m_decoration;
|
||||
KDecoration2::Decoration *m_decoration;
|
||||
ColorSettings m_colors;
|
||||
};
|
||||
|
||||
class Borders : public QObject
|
||||
|
|
|
@ -21,9 +21,9 @@ import org.kde.kwin.decoration 0.1
|
|||
DecorationButton {
|
||||
id: appMenuButton
|
||||
buttonType: DecorationOptions.DecorationButtonApplicationMenu
|
||||
visible: decoration.appMenu
|
||||
visible: false //decoration.appMenu
|
||||
KQuickControlsAddons.QIconItem {
|
||||
icon: decoration.icon
|
||||
icon: decoration.client.icon
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonActive
|
||||
property bool shown: (decoration.active || !buttonSvg.supportsInactive) && ((!pressed && !toggled) || !buttonSvg.supportsPressed) && (!hovered || !buttonSvg.supportsHover) && (enabled || !buttonSvg.supportsDeactivated)
|
||||
property bool shown: (decoration.client.active || !buttonSvg.supportsInactive) && ((!pressed && !toggled) || !buttonSvg.supportsPressed) && (!hovered || !buttonSvg.supportsHover) && (enabled || !buttonSvg.supportsDeactivated)
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "active"
|
||||
|
@ -116,7 +116,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonActiveHover
|
||||
property bool shown: hovered && !pressed && !toggled && buttonSvg.supportsHover && (decoration.active || !buttonSvg.supportsInactiveHover)
|
||||
property bool shown: hovered && !pressed && !toggled && buttonSvg.supportsHover && (decoration.client.active || !buttonSvg.supportsInactiveHover)
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "hover"
|
||||
|
@ -129,7 +129,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonActivePressed
|
||||
property bool shown: (toggled || pressed) && buttonSvg.supportsPressed && (decoration.active || !buttonSvg.supportsInactivePressed)
|
||||
property bool shown: (toggled || pressed) && buttonSvg.supportsPressed && (decoration.client.active || !buttonSvg.supportsInactivePressed)
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "pressed"
|
||||
|
@ -142,7 +142,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonActiveDeactivated
|
||||
property bool shown: !enabled && buttonSvg.supportsDeactivated && (decoration.active || !buttonSvg.supportsInactiveDeactivated)
|
||||
property bool shown: !enabled && buttonSvg.supportsDeactivated && (decoration.client.active || !buttonSvg.supportsInactiveDeactivated)
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "deactivated"
|
||||
|
@ -155,7 +155,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonInactive
|
||||
property bool shown: !decoration.active && buttonSvg.supportsInactive && !hovered && !pressed && !toggled && enabled
|
||||
property bool shown: !decoration.client.active && buttonSvg.supportsInactive && !hovered && !pressed && !toggled && enabled
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "inactive"
|
||||
|
@ -168,7 +168,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonInactiveHover
|
||||
property bool shown: !decoration.active && hovered && !pressed && !toggled && buttonSvg.supportsInactiveHover
|
||||
property bool shown: !decoration.client.active && hovered && !pressed && !toggled && buttonSvg.supportsInactiveHover
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "hover-inactive"
|
||||
|
@ -181,7 +181,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonInactivePressed
|
||||
property bool shown: !decoration.active && (toggled || pressed) && buttonSvg.supportsInactivePressed
|
||||
property bool shown: !decoration.client.active && (toggled || pressed) && buttonSvg.supportsInactivePressed
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "pressed-inactive"
|
||||
|
@ -194,7 +194,7 @@ DecorationButton {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: buttonInactiveDeactivated
|
||||
property bool shown: !decoration.active && !enabled && buttonSvg.supportsInactiveDeactivated
|
||||
property bool shown: !decoration.client.active && !enabled && buttonSvg.supportsInactiveDeactivated
|
||||
anchors.fill: parent
|
||||
imagePath: buttonSvg.imagePath
|
||||
prefix: "deactivated-inactive"
|
||||
|
|
|
@ -55,6 +55,6 @@ Item {
|
|||
}
|
||||
anchors {
|
||||
top: root.top
|
||||
topMargin: (decoration.maximized ? auroraeTheme.titleEdgeTopMaximized : auroraeTheme.titleEdgeTop + root.padding.top) + auroraeTheme.buttonMarginTop
|
||||
topMargin: (decoration.client.maximized ? auroraeTheme.titleEdgeTopMaximized : auroraeTheme.titleEdgeTop + root.padding.top) + auroraeTheme.buttonMarginTop
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ Item {
|
|||
id: maximizeButton
|
||||
anchors.fill: parent
|
||||
buttonType: DecorationOptions.DecorationButtonMaximizeRestore
|
||||
opacity: (!decoration.maximized || auroraeTheme.restoreButtonPath == "") ? 1 : 0
|
||||
opacity: (!decoration.client.maximized || auroraeTheme.restoreButtonPath == "") ? 1 : 0
|
||||
hovered: button.hovered
|
||||
pressed: button.pressed
|
||||
toggled: button.toggled
|
||||
|
@ -42,7 +42,7 @@ Item {
|
|||
id: restoreButton
|
||||
anchors.fill: parent
|
||||
buttonType: DecorationOptions.DecorationButtonMaximizeRestore + 100
|
||||
opacity: (decoration.maximized && auroraeTheme.restoreButtonPath != "") ? 1 : 0
|
||||
opacity: (decoration.client.maximized && auroraeTheme.restoreButtonPath != "") ? 1 : 0
|
||||
hovered: button.hovered
|
||||
pressed: button.pressed
|
||||
toggled: button.toggled
|
||||
|
@ -63,7 +63,7 @@ Item {
|
|||
onPressed: button.pressed = true
|
||||
onReleased: button.pressed = false
|
||||
onClicked: {
|
||||
decoration.maximize(mouse.button);
|
||||
decoration.requestMaximize(mouse.button);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,6 @@ Item {
|
|||
objectName: "padding"
|
||||
}
|
||||
property bool alpha: true
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onPressed: decoration.titlePressed(mouse.button, mouse.buttons)
|
||||
onDoubleClicked: decoration.titlebarDblClickOperation()
|
||||
}
|
||||
width: decoration.client.width + decoration.borderLeft + decoration.borderRight
|
||||
height: decoration.client.height + decoration.borderTop + decoration.borderBottom
|
||||
}
|
||||
|
|
|
@ -26,11 +26,11 @@ Item {
|
|||
enabled: {
|
||||
switch (button.buttonType) {
|
||||
case DecorationOptions.DecorationButtonClose:
|
||||
return decoration.closeable;
|
||||
return decoration.client.closeable;
|
||||
case DecorationOptions.DecorationButtonMaximizeRestore:
|
||||
return decoration.maximizeable;
|
||||
return decoration.client.maximizeable;
|
||||
case DecorationOptions.DecorationButtonMinimize:
|
||||
return decoration.minimizeable;
|
||||
return decoration.client.minimizeable;
|
||||
case DecorationOptions.DecorationButtonExplicitSpacer:
|
||||
return false;
|
||||
default:
|
||||
|
@ -58,93 +58,93 @@ Item {
|
|||
switch (button.buttonType) {
|
||||
case DecorationOptions.DecorationButtonMenu:
|
||||
// menu
|
||||
decoration.menuClicked();
|
||||
decoration.requestShowWindowMenu();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonApplicationMenu:
|
||||
// app menu
|
||||
decoration.appMenuClicked();
|
||||
// decoration.appMenuClicked();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonOnAllDesktops:
|
||||
// all desktops
|
||||
decoration.toggleOnAllDesktops();
|
||||
decoration.requestToggleOnAllDesktops();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonQuickHelp:
|
||||
// help
|
||||
decoration.showContextHelp();
|
||||
decoration.requestContextHelp();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonMinimize:
|
||||
// minimize
|
||||
decoration.minimize();
|
||||
decoration.requestMinimize();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonMaximizeRestore:
|
||||
// maximize
|
||||
decoration.maximize(mouse.button);
|
||||
decoration.requestMaximize(mouse.button);
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonClose:
|
||||
// close
|
||||
decoration.closeWindow();
|
||||
decoration.requestClose();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonKeepAbove:
|
||||
// keep above
|
||||
decoration.toggleKeepAbove();
|
||||
decoration.requestToggleKeepAbove();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonKeepBelow:
|
||||
// keep below
|
||||
decoration.toggleKeepBelow();
|
||||
decoration.requestToggleKeepBelow();
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonShade:
|
||||
// shade
|
||||
decoration.toggleShade();
|
||||
decoration.requestToggleShade();
|
||||
break;
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if (button.buttonType == DecorationOptions.DecorationButtonMenu) {
|
||||
decoration.closeWindow();
|
||||
decoration.requestClose();
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
switch (button.buttonType) {
|
||||
case DecorationOptions.DecorationButtonOnAllDesktops:
|
||||
// all desktops
|
||||
button.toggled = decoration.onAllDesktops;
|
||||
button.toggled = decoration.client.onAllDesktops;
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonKeepAbove:
|
||||
button.toggled = decoration.keepAbove;
|
||||
button.toggled = decoration.client.keepAbove;
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonKeepBelow:
|
||||
button.toggled = decoration.keepBelow;
|
||||
button.toggled = decoration.client.keepBelow;
|
||||
break;
|
||||
case DecorationOptions.DecorationButtonShade:
|
||||
button.toggled = decoration.shade;
|
||||
button.toggled = decoration.client.shaded;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: decoration
|
||||
onShadeChanged: {
|
||||
target: decoration.client
|
||||
onShadedChanged: {
|
||||
if (button.buttonType != DecorationOptions.DecorationButtonShade) {
|
||||
return;
|
||||
}
|
||||
button.toggled = decoration.shade;
|
||||
button.toggled = decoration.client.shaded;
|
||||
}
|
||||
onKeepBelowChanged: {
|
||||
if (button.buttonType != DecorationOptions.DecorationButtonKeepBelow) {
|
||||
return;
|
||||
}
|
||||
button.toggled = decoration.keepBelow;
|
||||
button.toggled = decoration.client.keepBelow;
|
||||
}
|
||||
onKeepAboveChanged: {
|
||||
if (button.buttonType != DecorationOptions.DecorationButtonKeepAbove) {
|
||||
return;
|
||||
}
|
||||
button.toggled = decoration.keepAbove;
|
||||
button.toggled = decoration.client.keepAbove;
|
||||
}
|
||||
onDesktopChanged: {
|
||||
if (button.buttonType != DecorationOptions.DecorationButtonOnAllDesktops) {
|
||||
return;
|
||||
}
|
||||
button.toggled = decoration.onAllDesktops;
|
||||
button.toggled = decoration.client.onAllDesktops;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,14 +23,14 @@ DecorationButton {
|
|||
id: menuButton
|
||||
buttonType: DecorationOptions.DecorationButtonMenu
|
||||
KQuickControlsAddons.QIconItem {
|
||||
icon: decoration.icon
|
||||
icon: decoration.client.icon
|
||||
anchors.fill: parent
|
||||
}
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 150
|
||||
repeat: false
|
||||
onTriggered: decoration.menuClicked()
|
||||
onTriggered: decoration.requestShowWindowMenu()
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
@ -64,13 +64,13 @@ DecorationButton {
|
|||
// for right clicks we show the menu instantly
|
||||
// and if the option is disabled we always show menu directly
|
||||
if (!menuButton.closeOnDoubleClick || mouse.button == Qt.RightButton) {
|
||||
decoration.menuClicked();
|
||||
decoration.requestShowWindowMenu();
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
onDoubleClicked: {
|
||||
if (menuButton.closeOnDoubleClick) {
|
||||
decoration.closeWindow();
|
||||
decoration.requestClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,16 @@ Decoration {
|
|||
id: options
|
||||
deco: decoration
|
||||
}
|
||||
Item {
|
||||
id: titleRect
|
||||
x: decoration.client.maximized ? maximizedBorders.left : borders.left
|
||||
y: 0
|
||||
width: decoration.client.width//parent.width - x - (decoration.client.maximized ? maximizedBorders.right : borders.right)
|
||||
height: decoration.client.maximized ? maximizedBorders.top : borders.top
|
||||
Component.onCompleted: {
|
||||
decoration.installTitleItem(titleRect);
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvg {
|
||||
property bool supportsInactive: hasElementPrefix("decoration-inactive")
|
||||
property bool supportsMaximized: hasElementPrefix("decoration-maximized")
|
||||
|
@ -51,12 +61,12 @@ Decoration {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: decorationActive
|
||||
property bool shown: (!decoration.maxized || !backgroundSvg.supportsMaximized) && (decoration.active || !backgroundSvg.supportsInactive)
|
||||
property bool shown: (!decoration.client.maxized || !backgroundSvg.supportsMaximized) && (decoration.client.active || !backgroundSvg.supportsInactive)
|
||||
anchors.fill: parent
|
||||
imagePath: backgroundSvg.imagePath
|
||||
prefix: "decoration"
|
||||
opacity: shown ? 1 : 0
|
||||
enabledBorders: decoration.maximized ? PlasmaCore.FrameSvg.NoBorder : PlasmaCore.FrameSvg.TopBorder | PlasmaCore.FrameSvg.BottomBorder | PlasmaCore.FrameSvg.LeftBorder | PlasmaCore.FrameSvg.RightBorder
|
||||
enabledBorders: decoration.client.maximized ? PlasmaCore.FrameSvg.NoBorder : PlasmaCore.FrameSvg.TopBorder | PlasmaCore.FrameSvg.BottomBorder | PlasmaCore.FrameSvg.LeftBorder | PlasmaCore.FrameSvg.RightBorder
|
||||
Behavior on opacity {
|
||||
enabled: root.animate
|
||||
NumberAnimation {
|
||||
|
@ -69,8 +79,8 @@ Decoration {
|
|||
anchors.fill: parent
|
||||
imagePath: backgroundSvg.imagePath
|
||||
prefix: "decoration-inactive"
|
||||
opacity: (!decoration.active && backgroundSvg.supportsInactive) ? 1 : 0
|
||||
enabledBorders: decoration.maximized ? PlasmaCore.FrameSvg.NoBorder : PlasmaCore.FrameSvg.TopBorder | PlasmaCore.FrameSvg.BottomBorder | PlasmaCore.FrameSvg.LeftBorder | PlasmaCore.FrameSvg.RightBorder
|
||||
opacity: (!decoration.client.active && backgroundSvg.supportsInactive) ? 1 : 0
|
||||
enabledBorders: decoration.client.maximized ? PlasmaCore.FrameSvg.NoBorder : PlasmaCore.FrameSvg.TopBorder | PlasmaCore.FrameSvg.BottomBorder | PlasmaCore.FrameSvg.LeftBorder | PlasmaCore.FrameSvg.RightBorder
|
||||
Behavior on opacity {
|
||||
enabled: root.animate
|
||||
NumberAnimation {
|
||||
|
@ -80,7 +90,7 @@ Decoration {
|
|||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: decorationMaximized
|
||||
property bool shown: decoration.maximized && backgroundSvg.supportsMaximized && (decoration.active || !backgroundSvg.supportsMaximizedInactive)
|
||||
property bool shown: decoration.client.maximized && backgroundSvg.supportsMaximized && (decoration.client.active || !backgroundSvg.supportsMaximizedInactive)
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
|
@ -114,7 +124,7 @@ Decoration {
|
|||
imagePath: backgroundSvg.imagePath
|
||||
prefix: "decoration-maximized-inactive"
|
||||
height: parent.maximizedBorders.top
|
||||
opacity: (!decoration.active && decoration.maximized && backgroundSvg.supportsMaximizedInactive) ? 1 : 0
|
||||
opacity: (!decoration.client.active && decoration.client.maximized && backgroundSvg.supportsMaximizedInactive) ? 1 : 0
|
||||
enabledBorders: PlasmaCore.FrameSvg.NoBorder
|
||||
Behavior on opacity {
|
||||
enabled: root.animate
|
||||
|
@ -130,7 +140,7 @@ Decoration {
|
|||
animate: root.animate
|
||||
anchors {
|
||||
left: root.left
|
||||
leftMargin: decoration.maximized ? auroraeTheme.titleEdgeLeftMaximized : (auroraeTheme.titleEdgeLeft + root.padding.left)
|
||||
leftMargin: decoration.client.maximized ? auroraeTheme.titleEdgeLeftMaximized : (auroraeTheme.titleEdgeLeft + root.padding.left)
|
||||
}
|
||||
}
|
||||
AuroraeButtonGroup {
|
||||
|
@ -140,40 +150,28 @@ Decoration {
|
|||
animate: root.animate
|
||||
anchors {
|
||||
right: root.right
|
||||
rightMargin: decoration.maximized ? auroraeTheme.titleEdgeRightMaximized : (auroraeTheme.titleEdgeRight + root.padding.right)
|
||||
rightMargin: decoration.client.maximized ? auroraeTheme.titleEdgeRightMaximized : (auroraeTheme.titleEdgeRight + root.padding.right)
|
||||
}
|
||||
}
|
||||
Text {
|
||||
id: caption
|
||||
text: decoration.caption
|
||||
text: decoration.client.caption
|
||||
textFormat: Text.PlainText
|
||||
horizontalAlignment: auroraeTheme.horizontalAlignment
|
||||
verticalAlignment: auroraeTheme.verticalAlignment
|
||||
elide: Text.ElideRight
|
||||
height: Math.max(auroraeTheme.titleHeight, auroraeTheme.buttonHeight * auroraeTheme.buttonSizeFactor)
|
||||
color: decoration.active ? auroraeTheme.activeTextColor : auroraeTheme.inactiveTextColor
|
||||
color: decoration.client.active ? auroraeTheme.activeTextColor : auroraeTheme.inactiveTextColor
|
||||
font: options.titleFont
|
||||
renderType: Text.NativeRendering
|
||||
anchors {
|
||||
left: leftButtonGroup.right
|
||||
right: rightButtonGroup.left
|
||||
top: root.top
|
||||
topMargin: decoration.maximized ? auroraeTheme.titleEdgeTopMaximized : (auroraeTheme.titleEdgeTop + root.padding.top)
|
||||
topMargin: decoration.client.maximized ? auroraeTheme.titleEdgeTopMaximized : (auroraeTheme.titleEdgeTop + root.padding.top)
|
||||
leftMargin: auroraeTheme.titleBorderLeft
|
||||
rightMargin: auroraeTheme.titleBorderRight
|
||||
}
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: decoration.titlebarDblClickOperation()
|
||||
onPressed: {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
mouse.accepted = false;
|
||||
} else {
|
||||
decoration.titlePressed(mouse.button, mouse.buttons);
|
||||
}
|
||||
}
|
||||
}
|
||||
Behavior on color {
|
||||
enabled: root.animate
|
||||
ColorAnimation {
|
||||
|
@ -192,7 +190,7 @@ Decoration {
|
|||
}
|
||||
imagePath: backgroundSvg.imagePath
|
||||
prefix: "innerborder"
|
||||
opacity: (decoration.active && !decoration.maximized && backgroundSvg.supportsInnerBorder) ? 1 : 0
|
||||
opacity: (decoration.client.active && !decoration.client.maximized && backgroundSvg.supportsInnerBorder) ? 1 : 0
|
||||
Behavior on opacity {
|
||||
enabled: root.animate
|
||||
NumberAnimation {
|
||||
|
@ -211,7 +209,7 @@ Decoration {
|
|||
}
|
||||
imagePath: backgroundSvg.imagePath
|
||||
prefix: "innerborder-inactive"
|
||||
opacity: (!decoration.active && !decoration.maximized && backgroundSvg.supportsInnerBorderInactive) ? 1 : 0
|
||||
opacity: (!decoration.client.active && !decoration.client.maximized && backgroundSvg.supportsInnerBorderInactive) ? 1 : 0
|
||||
Behavior on opacity {
|
||||
enabled: root.animate
|
||||
NumberAnimation {
|
||||
|
|
|
@ -21,6 +21,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "plastikbutton.h"
|
||||
#include <kdecoration.h>
|
||||
#include <KColorScheme>
|
||||
#include <KConfigGroup>
|
||||
#include <KSharedConfig>
|
||||
#include <QPainter>
|
||||
|
||||
namespace KWin
|
||||
|
@ -118,7 +120,8 @@ QPixmap PlastikButtonProvider::icon(ButtonIcon icon, int size, bool active, bool
|
|||
QPixmap image(size, size);
|
||||
image.fill(Qt::transparent);
|
||||
QPainter p(&image);
|
||||
const QColor color = KDecoration::options()->color(KDecoration::ColorFont, active);
|
||||
KConfigGroup wmConfig(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), QStringLiteral("WM"));
|
||||
const QColor color = wmConfig.readEntry("activeForeground", QPalette().color(QPalette::Active, QPalette::HighlightedText));
|
||||
|
||||
if (shadow) {
|
||||
p.setPen(KColorScheme::shade(color, KColorScheme::ShadowShade));
|
||||
|
|
|
@ -24,7 +24,7 @@ DecorationButton {
|
|||
var highlightColor = null;
|
||||
if (button.pressed) {
|
||||
if (button.buttonType == DecorationOptions.DecorationButtonClose) {
|
||||
highlightColor = colorHelper.foreground(decoration.active, ColorHelper.NegativeText);
|
||||
highlightColor = colorHelper.foreground(decoration.client.active, ColorHelper.NegativeText);
|
||||
} else {
|
||||
highlightColor = options.titleBarColor;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ DecorationButton {
|
|||
highlightColor = colorHelper.multiplyAlpha(highlightColor, 0.3);
|
||||
} else if (button.hovered) {
|
||||
if (button.buttonType == DecorationOptions.DecorationButtonClose) {
|
||||
highlightColor = colorHelper.foreground(decoration.active, ColorHelper.NegativeText);
|
||||
highlightColor = colorHelper.foreground(decoration.client.active, ColorHelper.NegativeText);
|
||||
} else {
|
||||
highlightColor = options.titleBarColor;
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ DecorationButton {
|
|||
Item {
|
||||
property int imageWidth: button.width > 14 ? button.width - 2 * Math.floor(button.width/3.5) : button.width - 6
|
||||
property int imageHeight: button.height > 14 ? button.height - 2 * Math.floor(button.height/3.5) : button.height - 6
|
||||
property string source: "image://plastik/" + button.buttonType + "/" + decoration.active + "/" + ((buttonType == "A") ? decoration.maximized : button.toggled)
|
||||
property string source: "image://plastik/" + button.buttonType + "/" + decoration.client.active + "/" + ((buttonType == "A") ? decoration.client.maximized : button.toggled)
|
||||
anchors.fill: parent
|
||||
Image {
|
||||
id: shadowImage
|
||||
|
@ -141,22 +141,18 @@ DecorationButton {
|
|||
Component.onCompleted: {
|
||||
colorize();
|
||||
if (buttonType == DecorationOptions.DecorationButtonQuickHelp) {
|
||||
visible = decoration.providesContextHelp;
|
||||
visible = Qt.binding(function() { return decoration.client.providesContextHelp});
|
||||
}
|
||||
if (buttonType == DecorationOptions.DecorationButtonApplicationMenu) {
|
||||
visible = decoration.appMenu;
|
||||
// visible = decoration.appMenu;
|
||||
visible = false;
|
||||
}
|
||||
}
|
||||
onHoveredChanged: colorize()
|
||||
onPressedChanged: colorize()
|
||||
Connections {
|
||||
target: decoration
|
||||
target: decoration.client
|
||||
onActiveChanged: button.colorize()
|
||||
onAppMenuChanged: {
|
||||
if (buttonType == DecorationOptions.DecorationButtonApplicationMenu) {
|
||||
visible = decoration.appMenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: options
|
||||
|
|
|
@ -107,7 +107,7 @@ Decoration {
|
|||
fill: parent
|
||||
}
|
||||
border {
|
||||
width: decoration.maximized ? 0 : 2
|
||||
width: decoration.client.maximized ? 0 : 2
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.DarkShade)
|
||||
}
|
||||
Rectangle {
|
||||
|
@ -120,7 +120,7 @@ Decoration {
|
|||
bottomMargin: 1
|
||||
topMargin: 1
|
||||
}
|
||||
visible: !decoration.maximized
|
||||
visible: !decoration.client.maximized
|
||||
width: root.borders.left
|
||||
color: root.titleBarColor
|
||||
Rectangle {
|
||||
|
@ -130,7 +130,7 @@ Decoration {
|
|||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.LightShade, colorHelper.contrast - (decoration.active ? 0.4 : 0.8))
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.LightShade, colorHelper.contrast - (decoration.client.active ? 0.4 : 0.8))
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
|
@ -143,7 +143,7 @@ Decoration {
|
|||
bottomMargin: 1
|
||||
topMargin: 1
|
||||
}
|
||||
visible: !decoration.maximzied
|
||||
visible: !decoration.client.maximzied
|
||||
width: root.borders.right -1
|
||||
color: root.titleBarColor
|
||||
Rectangle {
|
||||
|
@ -153,7 +153,7 @@ Decoration {
|
|||
top: parent.top
|
||||
}
|
||||
x: parent.x + parent.width - 1
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.DarkShade, colorHelper.contrast - (decoration.active ? 0.4 : 0.8))
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.DarkShade, colorHelper.contrast - (decoration.client.active ? 0.4 : 0.8))
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
|
@ -166,7 +166,7 @@ Decoration {
|
|||
rightMargin: 1
|
||||
}
|
||||
height: root.borders.bottom
|
||||
visible: !decoration.maximzied
|
||||
visible: !decoration.client.maximzied
|
||||
color: root.titleBarColor
|
||||
Rectangle {
|
||||
height: 1
|
||||
|
@ -175,7 +175,7 @@ Decoration {
|
|||
right: parent.right
|
||||
}
|
||||
y: parent.y + parent.height - 1
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.DarkShade, colorHelper.contrast - (decoration.active ? 0.4 : 0.8))
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.DarkShade, colorHelper.contrast - (decoration.client.active ? 0.4 : 0.8))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,14 +184,14 @@ Decoration {
|
|||
property int topMargin: 1
|
||||
property real normalHeight: titleRow.normalHeight + topMargin + 1
|
||||
property real maximizedHeight: titleRow.maximizedHeight + 1
|
||||
height: decoration.maximized ? maximizedHeight : normalHeight
|
||||
height: decoration.client.maximized ? maximizedHeight : normalHeight
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: decoration.maximized ? 0 : top.topMargin
|
||||
leftMargin: decoration.maximized ? 0 : 2
|
||||
rightMargin: decoration.maximized ? 0 : 2
|
||||
topMargin: decoration.client.maximized ? 0 : top.topMargin
|
||||
leftMargin: decoration.client.maximized ? 0 : 2
|
||||
rightMargin: decoration.client.maximized ? 0 : 2
|
||||
}
|
||||
gradient: Gradient {
|
||||
id: topGradient
|
||||
|
@ -201,7 +201,7 @@ Decoration {
|
|||
}
|
||||
GradientStop {
|
||||
id: middleGradientStop
|
||||
position: 4.0/(decoration.maximized ? top.maximizedHeight : top.normalHeight)
|
||||
position: 4.0/(decoration.client.maximized ? top.maximizedHeight : top.normalHeight)
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.MidShade, colorHelper.contrast - 0.4)
|
||||
}
|
||||
GradientStop {
|
||||
|
@ -216,21 +216,8 @@ Decoration {
|
|||
left: top.left
|
||||
right: top.right
|
||||
}
|
||||
visible: !decoration.maximized
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.LightShade, colorHelper.contrast - (decoration.active ? 0.4 : 0.8))
|
||||
}
|
||||
MouseArea {
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
anchors.fill: parent
|
||||
onDoubleClicked: decoration.titlebarDblClickOperation()
|
||||
onPressed: {
|
||||
if (mouse.button == Qt.LeftButton) {
|
||||
mouse.accepted = false;
|
||||
} else {
|
||||
decoration.titlePressed(mouse.button, mouse.buttons);
|
||||
}
|
||||
}
|
||||
onReleased: decoration.titleReleased(mouse.button, mouse.buttons)
|
||||
visible: !decoration.client.maximized
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.LightShade, colorHelper.contrast - (decoration.client.active ? 0.4 : 0.8))
|
||||
}
|
||||
|
||||
Item {
|
||||
|
@ -244,9 +231,9 @@ Decoration {
|
|||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
topMargin: decoration.maximized ? 0 : titleRow.topMargin
|
||||
leftMargin: decoration.maximized ? 0 : 3
|
||||
rightMargin: decoration.maximized ? 0 : 3
|
||||
topMargin: decoration.client.maximized ? 0 : titleRow.topMargin
|
||||
leftMargin: decoration.client.maximized ? 0 : 3
|
||||
rightMargin: decoration.client.maximized ? 0 : 3
|
||||
bottomMargin: titleRow.bottomMargin
|
||||
}
|
||||
ButtonGroup {
|
||||
|
@ -284,7 +271,7 @@ Decoration {
|
|||
Behavior on color {
|
||||
ColorAnimation { duration: root.animationDuration }
|
||||
}
|
||||
text: decoration.caption
|
||||
text: decoration.client.caption
|
||||
font: options.titleFont
|
||||
style: root.titleShadow ? Text.Raised : Text.Normal
|
||||
styleColor: colorHelper.shade(color, ColorHelper.ShadowShade)
|
||||
|
@ -311,6 +298,9 @@ Decoration {
|
|||
right: parent.right
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
decoration.installTitleItem(titleRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,7 +315,7 @@ Decoration {
|
|||
}
|
||||
height: 1
|
||||
y: top.height - 1
|
||||
visible: decoration.maximized
|
||||
visible: decoration.client.maximized
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.MidShade)
|
||||
}
|
||||
|
||||
|
@ -341,7 +331,7 @@ Decoration {
|
|||
width: 1
|
||||
color: colorHelper.shade(root.titleBarColor, ColorHelper.MidShade)
|
||||
}
|
||||
visible: !decoration.maximized
|
||||
visible: !decoration.client.maximized
|
||||
color: root.titleBarColor
|
||||
}
|
||||
}
|
||||
|
@ -423,8 +413,4 @@ Decoration {
|
|||
maximizedBorders.setTitle(top.maximizedHeight);
|
||||
readConfig();
|
||||
}
|
||||
Connections {
|
||||
target: decoration
|
||||
onConfigChanged: readConfig()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue