diff --git a/kcmkwin/kwintabbox/CMakeLists.txt b/kcmkwin/kwintabbox/CMakeLists.txt
index 4f7245acc7..6aa6c6a0f0 100644
--- a/kcmkwin/kwintabbox/CMakeLists.txt
+++ b/kcmkwin/kwintabbox/CMakeLists.txt
@@ -8,11 +8,7 @@ set(kcm_kwintabbox_PART_SRCS
main.cpp
layoutpreview.cpp
thumbnailitem.cpp
- ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/clientmodel.cpp
- ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/declarative.cpp
- ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/desktopmodel.cpp
${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/tabboxconfig.cpp
- ${KDEBASE_WORKSPACE_SOURCE_DIR}/kwin/tabbox/tabboxhandler.cpp
)
kde4_add_ui_files( kcm_kwintabbox_PART_SRCS main.ui )
@@ -21,17 +17,11 @@ add_library(kcm_kwintabbox MODULE ${kcm_kwintabbox_PART_SRCS})
target_link_libraries(kcm_kwintabbox
Qt5::Quick
- Qt5::X11Extras
KF5::KCMUtils
KF5::Completion
- KF5::Declarative
KF5::GlobalAccel
KF5::I18n
- KF5::IconThemes
KF5::Service
- KF5::WindowSystem
- KF5::Plasma
- KF5::XmlGui
KF5::NewStuff
${XCB_XCB_LIBRARY})
@@ -40,6 +30,5 @@ install(TARGETS kcm_kwintabbox DESTINATION ${PLUGIN_INSTALL_DIR} )
########### install files ###############
install( FILES kwintabbox.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
-install( FILES qml/main.qml DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwintabbox)
install( FILES thumbnails/konqueror.png thumbnails/kmail.png thumbnails/systemsettings.png thumbnails/dolphin.png DESTINATION ${DATA_INSTALL_DIR}/kwin/kcm_kwintabbox)
install( FILES kwinswitcher.knsrc DESTINATION ${CONFIG_INSTALL_DIR} )
diff --git a/kcmkwin/kwintabbox/layoutpreview.cpp b/kcmkwin/kwintabbox/layoutpreview.cpp
index 4cff8734dd..0e100b0e89 100644
--- a/kcmkwin/kwintabbox/layoutpreview.cpp
+++ b/kcmkwin/kwintabbox/layoutpreview.cpp
@@ -20,12 +20,13 @@ along with this program. If not, see .
// own
#include "layoutpreview.h"
#include "thumbnailitem.h"
+#include
+#include
+#include
#include
#include
#include
#include
-#include
-#include
#include
#include
@@ -34,65 +35,77 @@ namespace KWin
namespace TabBox
{
-LayoutPreview::LayoutPreview(QWindow *parent)
- : QQuickView(parent)
+LayoutPreview::LayoutPreview(const QString &path, QObject *parent)
+ : QObject(parent)
+ , m_item(nullptr)
{
- setColor(Qt::white);
- setMinimumSize(QSize(480, 300));
- setResizeMode(QQuickView::SizeRootObjectToView);
- foreach (const QString &importPath, QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, "kwin/tabbox", QStandardPaths::LocateDirectory)) {
- engine()->addImportPath(importPath);
+ QQmlEngine *engine = new QQmlEngine(this);
+ QQmlComponent *component = new QQmlComponent(engine, this);
+ qmlRegisterType("org.kde.kwin", 2, 0, "ThumbnailItem");
+ qmlRegisterType("org.kde.kwin", 2, 0, "Switcher");
+ component->loadUrl(QUrl::fromLocalFile(path));
+ QObject *item = component->create();
+ auto findSwitcher = [item]() -> SwitcherItem* {
+ if (!item) {
+ return nullptr;
+ }
+ if (SwitcherItem *i = qobject_cast(item)) {
+ return i;
+ } else if (QQuickWindow *w = qobject_cast(item)) {
+ return w->contentItem()->findChild();
+ }
+ return item->findChild();
+ };
+ if (SwitcherItem *switcher = findSwitcher()) {
+ m_item = switcher;
+ switcher->setVisible(true);
+ }
+ auto findWindow = [item]() -> QQuickWindow* {
+ if (!item) {
+ return nullptr;
+ }
+ if (QQuickWindow *w = qobject_cast(item)) {
+ return w;
+ }
+ return item->findChild();
+ };
+ if (QQuickWindow *w = findWindow()) {
+ w->setKeyboardGrabEnabled(true);
+ w->setMouseGrabEnabled(true);
+ w->installEventFilter(this);
}
- ExampleClientModel *model = new ExampleClientModel(this);
- engine()->addImageProvider(QLatin1String("client"), new TabBoxImageProvider(model));
- qmlRegisterType("org.kde.kwin", 0, 1, "ThumbnailItem");
- rootContext()->setContextProperty("clientModel", model);
- rootContext()->setContextProperty("sourcePath", QString());
- rootContext()->setContextProperty("name", QString());
- setSource(QUrl::fromLocalFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kwin/kcm_kwintabbox/main.qml")));
}
LayoutPreview::~LayoutPreview()
{
}
-void LayoutPreview::setLayout(const QString &path, const QString &name)
-{
- rootContext()->setContextProperty("sourcePath", path);
- rootContext()->setContextProperty("name", name);
-}
-
-TabBoxImageProvider::TabBoxImageProvider(QAbstractListModel* model)
- : QQuickImageProvider(QQuickImageProvider::Pixmap)
- , m_model(model)
-{
-}
-
-QPixmap TabBoxImageProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize)
+bool LayoutPreview::eventFilter(QObject *object, QEvent *event)
{
- bool ok = false;
- QStringList parts = id.split('/');
- const int index = parts.first().toInt(&ok);
- if (!ok) {
- return QQuickImageProvider::requestPixmap(id, size, requestedSize);
- }
- QSize s(32, 32);
- if (requestedSize.isValid()) {
- s = requestedSize;
- }
- *size = s;
- QPixmap icon(QIcon::fromTheme(m_model->data(m_model->index(index), Qt::UserRole+3).toString()).pixmap(s));
- if (parts.size() > 2) {
- KIconEffect *effect = KIconLoader::global()->iconEffect();
- KIconLoader::States state = KIconLoader::DefaultState;
- if (parts.at(2) == QLatin1String("selected")) {
- state = KIconLoader::ActiveState;
- } else if (parts.at(2) == QLatin1String("disabled")) {
- state = KIconLoader::DisabledState;
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = dynamic_cast(event);
+ if (keyEvent->key() == Qt::Key_Escape ||
+ keyEvent->key() == Qt::Key_Return ||
+ keyEvent->key() == Qt::Key_Enter ||
+ keyEvent->key() == Qt::Key_Space) {
+ object->deleteLater();
+ deleteLater();
+ }
+ if (m_item && keyEvent->key() == Qt::Key_Tab) {
+ m_item->incrementIndex();
+ }
+ if (m_item && keyEvent->key() == Qt::Key_Backtab) {
+ m_item->decrementIndex();
+ }
+ } else if (event->type() == QEvent::MouseButtonPress) {
+ if (QWindow *w = qobject_cast(object)) {
+ if (!w->geometry().contains(static_cast(event)->globalPos())) {
+ object->deleteLater();
+ deleteLater();
+ }
}
- icon = effect->apply(icon, KIconLoader::Desktop, state);
}
- return icon;
+ return QObject::eventFilter(object, event);
}
ExampleClientModel::ExampleClientModel (QObject* parent)
@@ -161,6 +174,62 @@ int ExampleClientModel::rowCount(const QModelIndex &parent) const
return m_nameList.size();
}
+SwitcherItem::SwitcherItem(QObject *parent)
+ : QObject(parent)
+ , m_model(new ExampleClientModel(this))
+ , m_item(nullptr)
+ , m_currentIndex(0)
+ , m_visible(false)
+{
+}
+
+SwitcherItem::~SwitcherItem()
+{
+}
+
+void SwitcherItem::setVisible(bool visible)
+{
+ if (m_visible == visible) {
+ return;
+ }
+ m_visible = visible;
+ emit visibleChanged();
+}
+
+void SwitcherItem::setItem(QObject *item)
+{
+ m_item = item;
+ emit itemChanged();
+}
+
+void SwitcherItem::setCurrentIndex(int index)
+{
+ if (m_currentIndex == index) {
+ return;
+ }
+ m_currentIndex = index;
+ emit currentIndexChanged(m_currentIndex);
+}
+
+QRect SwitcherItem::screenGeometry() const
+{
+ return qApp->desktop()->screenGeometry(qApp->desktop()->primaryScreen());
+}
+
+void SwitcherItem::incrementIndex()
+{
+ setCurrentIndex((m_currentIndex + 1) % m_model->rowCount());
+}
+
+void SwitcherItem::decrementIndex()
+{
+ int index = m_currentIndex -1;
+ if (index < 0) {
+ index = m_model->rowCount() -1;
+ }
+ setCurrentIndex(index);
+}
+
} // namespace KWin
} // namespace TabBox
diff --git a/kcmkwin/kwintabbox/layoutpreview.h b/kcmkwin/kwintabbox/layoutpreview.h
index 6839b94aa0..7db9a07e9f 100644
--- a/kcmkwin/kwintabbox/layoutpreview.h
+++ b/kcmkwin/kwintabbox/layoutpreview.h
@@ -22,7 +22,7 @@ along with this program. If not, see .
#include
#include
-#include
+#include
namespace KWin
{
@@ -30,23 +30,18 @@ namespace KWin
namespace TabBox
{
-class LayoutPreview : public QQuickView
+class SwitcherItem;
+
+class LayoutPreview : public QObject
{
Q_OBJECT
public:
- explicit LayoutPreview(QWindow *parent = nullptr);
+ explicit LayoutPreview(const QString &path, QObject *parent = nullptr);
virtual ~LayoutPreview();
- void setLayout(const QString &path, const QString &name);
-};
-
-class TabBoxImageProvider : public QQuickImageProvider
-{
-public:
- explicit TabBoxImageProvider(QAbstractListModel *model);
- virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize);
+ virtual bool eventFilter(QObject *object, QEvent *event) override;
private:
- QAbstractListModel *m_model;
+ SwitcherItem *m_item;
};
class ExampleClientModel : public QAbstractListModel
@@ -64,6 +59,79 @@ private:
QStringList m_nameList;
};
+
+class SwitcherItem : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractItemModel *model READ model NOTIFY modelChanged)
+ Q_PROPERTY(QRect screenGeometry READ screenGeometry NOTIFY screenGeometryChanged)
+ Q_PROPERTY(bool visible READ isVisible NOTIFY visibleChanged)
+ Q_PROPERTY(bool allDesktops READ isAllDesktops NOTIFY allDesktopsChanged)
+ Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
+
+ /**
+ * The main QML item that will be displayed in the Dialog
+ */
+ Q_PROPERTY(QObject *item READ item WRITE setItem NOTIFY itemChanged)
+
+ Q_CLASSINFO("DefaultProperty", "item")
+public:
+ SwitcherItem(QObject *parent = nullptr);
+ virtual ~SwitcherItem();
+
+ QAbstractItemModel *model() const;
+ QRect screenGeometry() const;
+ bool isVisible() const;
+ bool isAllDesktops() const;
+ int currentIndex() const;
+ void setCurrentIndex(int index);
+ QObject *item() const;
+ void setItem(QObject *item);
+
+ void setVisible(bool visible);
+ void incrementIndex();
+ void decrementIndex();
+
+Q_SIGNALS:
+ void visibleChanged();
+ void currentIndexChanged(int index);
+ void modelChanged();
+ void allDesktopsChanged();
+ void screenGeometryChanged();
+ void itemChanged();
+
+private:
+ QAbstractItemModel *m_model;
+ QObject *m_item;
+ int m_currentIndex;
+ bool m_visible;
+};
+
+inline QAbstractItemModel *SwitcherItem::model() const
+{
+ return m_model;
+}
+
+inline bool SwitcherItem::isVisible() const
+{
+ return m_visible;
+}
+
+inline bool SwitcherItem::isAllDesktops() const
+{
+ return true;
+}
+
+inline int SwitcherItem::currentIndex() const
+{
+ return m_currentIndex;
+}
+
+inline QObject *SwitcherItem::item() const
+{
+ return m_item;
+}
+
} // namespace TabBox
} // namespace KWin
diff --git a/kcmkwin/kwintabbox/main.cpp b/kcmkwin/kwintabbox/main.cpp
index 819c4dac70..5bda6887e0 100644
--- a/kcmkwin/kwintabbox/main.cpp
+++ b/kcmkwin/kwintabbox/main.cpp
@@ -61,7 +61,6 @@ KWinTabBoxConfigForm::KWinTabBoxConfigForm(QWidget* parent)
KWinTabBoxConfig::KWinTabBoxConfig(QWidget* parent, const QVariantList& args)
: KCModule(parent, args)
, m_config(KSharedConfig::openConfig("kwinrc"))
- , m_layoutPreview(NULL)
{
QTabWidget* tabWidget = new QTabWidget(this);
m_primaryTabBoxUi = new KWinTabBoxConfigForm(tabWidget);
@@ -475,12 +474,6 @@ void KWinTabBoxConfig::effectSelectionChanged(int index)
if (!ui->showTabBox->isChecked())
return;
ui->highlightWindowCheck->setEnabled(index >= Layout);
- if (m_layoutPreview && m_layoutPreview->isVisible()) {
- if (index < Layout)
- m_layoutPreview->hide();
- else
- m_layoutPreview->setLayout(ui->effectCombo->itemData(index, Qt::UserRole+1).toString(), ui->effectCombo->itemText(index));
- }
}
void KWinTabBoxConfig::tabBoxToggled(bool on) {
@@ -496,13 +489,8 @@ void KWinTabBoxConfig::configureEffectClicked()
const int effect = ui->effectCombo->currentIndex();
if (effect >= Layout) {
- if (!m_layoutPreview) {
- m_layoutPreview = new LayoutPreview();
- m_layoutPreview->setTitle(i18n("Tabbox layout preview"));
- m_layoutPreview->setFlags(Qt::Dialog);
- }
- m_layoutPreview->setLayout(ui->effectCombo->itemData(effect, Qt::UserRole+1).toString(), ui->effectCombo->itemText(effect));
- m_layoutPreview->show();
+ // TODO: here we need to show the preview
+ new LayoutPreview(ui->effectCombo->itemData(effect, Qt::UserRole+1).toString(), this);
} else {
QPointer configDialog = new QDialog(this);
configDialog->setLayout(new QVBoxLayout);
diff --git a/kcmkwin/kwintabbox/main.h b/kcmkwin/kwintabbox/main.h
index 3344d00e0b..f8b5ac257d 100644
--- a/kcmkwin/kwintabbox/main.h
+++ b/kcmkwin/kwintabbox/main.h
@@ -35,7 +35,6 @@ namespace KWin
namespace TabBox
{
-class LayoutPreview;
}
@@ -87,7 +86,6 @@ private:
KShortcutsEditor* m_editor;
TabBox::TabBoxConfig m_tabBoxConfig;
TabBox::TabBoxConfig m_tabBoxAlternativeConfig;
- TabBox::LayoutPreview *m_layoutPreview;
bool effectEnabled(const QString& effect, const KConfigGroup& cfg) const;
};
diff --git a/kcmkwin/kwintabbox/qml/main.qml b/kcmkwin/kwintabbox/qml/main.qml
deleted file mode 100644
index 911e81a749..0000000000
--- a/kcmkwin/kwintabbox/qml/main.qml
+++ /dev/null
@@ -1,59 +0,0 @@
-/********************************************************************
- KWin - the KDE window manager
- This file is part of the KDE project.
-
-Copyright (C) 2011 Martin Gräßlin
-
-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 .
-*********************************************************************/
-import QtQuick 2.0
-
-Item {
- id : preview
- Loader {
- property int screenWidth : preview.width
- property int screenHeight : preview.height
- property bool allDesktops: true
- width: preview.width
- height: preview.height - textElement.height
- source: sourcePath
- anchors.centerIn: parent
- onLoaded: {
- if (item.allDesktops != undefined) {
- item.allDesktops = allDesktops;
- }
- if (item.setModel) {
- item.setModel(clientModel);
- }
- if (item.screenWidth != undefined) {
- item.screenWidth = screenWidth;
- }
- if (item.screenHeight != undefined) {
- item.screenHeight = screenHeight;
- }
- item.width = preview.width;
- item.height = preview.height - textElement.height;
- }
- }
- Text {
- id: textElement
- font.bold: true
- text: name
- anchors {
- horizontalCenter: parent.horizontalCenter
- bottom: parent.bottom
- }
- visible: true
- }
-}