From 0b90411b1d1ecf86dc49ea786cc31ab5dd0d252b Mon Sep 17 00:00:00 2001
From: Michail Vourlakos <mvourlakos@gmail.com>
Date: Sat, 23 Mar 2019 17:49:09 +0200
Subject: [PATCH] IMPORTANT: All new Indicators architecture

--this huge commit contains all the changes needed
in order for Latte to load Indicators dynamically
from their own packages
---
 CMakeLists.txt                                |   1 +
 app/CMakeLists.txt                            |   2 +
 app/importer.cpp                              |  19 +-
 app/importer.h                                |   3 +
 app/indicator/factory.cpp                     |  95 +++++
 .../Common.qml => app/indicator/factory.h     |  38 +-
 app/lattecorona.cpp                           |   8 +
 app/lattecorona.h                             |   7 +
 app/shortcuts/globalshortcuts.cpp             |   4 +-
 app/view/indicator.cpp                        | 329 ++++++++++++++++
 app/view/indicator.h                          | 149 +++++++
 app/view/view.cpp                             | 148 +++----
 app/view/view.h                               |  14 +-
 containment/package/contents/config/main.xml  |  42 --
 .../package/contents/ui/VisibilityManager.qml |   9 +-
 .../package/contents/ui/applet/AppletItem.qml |  19 +-
 .../indicator/{Manager.qml => Bridge.qml}     |  16 +-
 .../contents/ui/applet/indicator/Loader.qml   |   9 +-
 .../package/contents/ui/colorizer/Manager.qml |  10 +-
 .../contents/ui/indicators/Manager.qml        |  64 +--
 .../contents/ui/indicators/options/Latte.qml  |  39 --
 .../package/contents/ui/loaders/Pager.qml     |   3 +-
 containment/package/contents/ui/main.qml      |   7 +-
 declarativeimports/components/GlowPoint.qml   |  15 +-
 .../components/IndicatorItem.qml              |  15 +-
 declarativeimports/components/qmldir          |   1 +
 indicators/CMakeLists.txt                     |   3 +
 indicators/Messages.sh                        |   4 +
 .../metadata.desktop                          |  19 +
 .../package/config/config.qml                 |  46 +--
 .../package/config/main.xml                   |  42 ++
 .../package/ui/main.qml                       | 291 ++++++++++++++
 .../metadata.desktop                          |  17 +
 .../package/ui/BackLayer.qml                  | 137 +++++++
 .../package/ui/FrontLayer.qml                 | 103 +++++
 .../package/ui/main.qml                       |  31 +-
 .../metadata.desktop                          |  17 +
 .../package/ui/BackLayer.qml                  | 160 ++++++++
 .../package/ui/FrontLayer.qml                 | 206 ++++++++++
 .../package/ui/main.qml                       |  71 ++++
 liblatte2/CMakeLists.txt                      |   2 -
 liblatte2/qml/code/ColorizerTools.js          |  42 --
 liblatte2/qml/indicators/PlasmaIndicator.qml  | 238 -----------
 liblatte2/qml/indicators/UnityIndicator.qml   | 372 ------------------
 liblatte2/qmldir                              |   4 -
 .../contents/ui/indicators/Manager.qml        |  46 +--
 .../contents/ui/indicators/options/Latte.qml  |   8 +-
 .../ui/indicators/styles}/LatteIndicator.qml  | 149 +++----
 plasmoid/package/contents/ui/main.qml         |   4 +-
 .../package/contents/ui/task/TaskItem.qml     |  11 +-
 .../indicator/{Manager.qml => Bridge.qml}     |  12 +-
 .../contents/ui/task/indicator/Loader.qml     |   8 +-
 .../configuration/LatteDockConfiguration.qml  |   2 +-
 .../configuration/pages/EffectsConfig.qml     |  52 +--
 .../configuration/pages/TasksConfig.qml       |   2 +-
 55 files changed, 2068 insertions(+), 1097 deletions(-)
 create mode 100644 app/indicator/factory.cpp
 rename plasmoid/package/contents/ui/indicators/options/Common.qml => app/indicator/factory.h (59%)
 create mode 100644 app/view/indicator.cpp
 create mode 100644 app/view/indicator.h
 rename containment/package/contents/ui/applet/indicator/{Manager.qml => Bridge.qml} (81%)
 delete mode 100644 containment/package/contents/ui/indicators/options/Latte.qml
 rename containment/package/contents/ui/indicators/options/Plasma.qml => declarativeimports/components/IndicatorItem.qml (69%)
 create mode 100644 indicators/CMakeLists.txt
 create mode 100644 indicators/Messages.sh
 create mode 100644 indicators/org.kde.latte.indicator.default/metadata.desktop
 rename shell/package/contents/configuration/pages/indicator/LatteOptions.qml => indicators/org.kde.latte.indicator.default/package/config/config.qml (78%)
 create mode 100644 indicators/org.kde.latte.indicator.default/package/config/main.xml
 create mode 100644 indicators/org.kde.latte.indicator.default/package/ui/main.qml
 create mode 100644 indicators/org.kde.latte.indicator.plasma/metadata.desktop
 create mode 100644 indicators/org.kde.latte.indicator.plasma/package/ui/BackLayer.qml
 create mode 100644 indicators/org.kde.latte.indicator.plasma/package/ui/FrontLayer.qml
 rename containment/package/contents/ui/indicators/options/Common.qml => indicators/org.kde.latte.indicator.plasma/package/ui/main.qml (55%)
 create mode 100644 indicators/org.kde.latte.indicator.unity/metadata.desktop
 create mode 100644 indicators/org.kde.latte.indicator.unity/package/ui/BackLayer.qml
 create mode 100644 indicators/org.kde.latte.indicator.unity/package/ui/FrontLayer.qml
 create mode 100644 indicators/org.kde.latte.indicator.unity/package/ui/main.qml
 delete mode 100644 liblatte2/qml/code/ColorizerTools.js
 delete mode 100644 liblatte2/qml/indicators/PlasmaIndicator.qml
 delete mode 100644 liblatte2/qml/indicators/UnityIndicator.qml
 rename {liblatte2/qml/indicators => plasmoid/package/contents/ui/indicators/styles}/LatteIndicator.qml (56%)
 rename plasmoid/package/contents/ui/task/indicator/{Manager.qml => Bridge.qml} (88%)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2c4457a13..4bb1916c4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -68,6 +68,7 @@ include(Definitions.cmake)
 
 add_subdirectory(declarativeimports)
 add_subdirectory(liblatte2)
+add_subdirectory(indicators)
 add_subdirectory(app)
 add_subdirectory(containmentactions)
 add_subdirectory(containment)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index c8cb30094..3875aefda 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -9,6 +9,7 @@ set(lattedock-app_SRCS
     layoutmanager.cpp
     schemecolors.cpp
     screenpool.cpp
+    indicator/factory.cpp
     layout/layout.cpp
     layout/shortcuts.cpp
     package/lattepackage.cpp
@@ -26,6 +27,7 @@ set(lattedock-app_SRCS
     shortcuts/shortcutstracker.cpp
     view/contextmenu.cpp
     view/effects.cpp
+    view/indicator.cpp
     view/panelshadows.cpp
     view/positioner.cpp
     view/screenedgeghostwindow.cpp
diff --git a/app/importer.cpp b/app/importer.cpp
index c182c951b..0346f2eb3 100644
--- a/app/importer.cpp
+++ b/app/importer.cpp
@@ -184,10 +184,27 @@ bool Importer::importOldLayout(QString oldAppletsPath, QString newName, bool alt
     return true;
 }
 
-QString Importer::standardPath(QString subPath, bool localfirst)
+QStringList Importer::standardPaths(bool localfirst)
 {
     QStringList paths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
 
+    if (localfirst) {
+        return paths;
+    } else {
+        QStringList reversed;
+
+        for (int i=paths.count()-1; i>=0; i--) {
+            reversed << paths[i];
+        }
+
+        return reversed;
+    }
+}
+
+QString Importer::standardPath(QString subPath, bool localfirst)
+{
+    QStringList paths = standardPaths(localfirst);
+
     if (localfirst) {
         foreach (auto pt, paths) {
             QString ptF = pt + "/" +subPath;
diff --git a/app/importer.h b/app/importer.h
index f8df31053..3b18874e6 100644
--- a/app/importer.h
+++ b/app/importer.h
@@ -74,6 +74,9 @@ public:
     //! returns the standard path found that contains the subPath
     //! local paths have higher priority by default
     static QString standardPath(QString subPath, bool localFirst = true);
+    //! returns all application data standard paths
+    //! local paths have higher priority by default
+    static QStringList standardPaths(bool localfirst = true);
 
     //! check if this layout exists already in the latte directory
     static bool layoutExists(QString layoutName);
diff --git a/app/indicator/factory.cpp b/app/indicator/factory.cpp
new file mode 100644
index 000000000..ee88c8fdf
--- /dev/null
+++ b/app/indicator/factory.cpp
@@ -0,0 +1,95 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "factory.h"
+
+// local
+#include "../importer.h"
+
+// Qt
+#include <QDebug>
+#include <QDir>
+
+// KDE
+#include <KPluginMetaData>
+
+namespace Latte {
+namespace Indicator {
+
+Factory::Factory(QObject *parent)
+    : QObject(parent)
+{
+    reload();
+
+    qDebug() << m_plugins["org.kde.latte.indicator.default"].name();
+}
+
+Factory::~Factory()
+{
+}
+
+KPluginMetaData Factory::metadata(QString pluginId)
+{
+    if (m_plugins.contains(pluginId)) {
+        return m_plugins[pluginId];
+    }
+
+    return KPluginMetaData();
+}
+
+void Factory::reload()
+{
+    QStringList standardPaths = Latte::Importer::standardPaths();
+
+    m_plugins.clear();
+
+    foreach(auto path, standardPaths) {
+        QDir standard(path + "/latte/indicators");
+
+        if (standard.exists()) {
+            QStringList pluginDirs = standard.entryList(QStringList(),QDir::AllDirs | QDir::NoSymLinks);
+
+            foreach (auto pluginDir, pluginDirs) {
+                if (pluginDir != "." && pluginDir != "..") {
+                    QString metadataFile = standard.absolutePath() + "/" + pluginDir + "/metadata.desktop";
+
+                    if (QFileInfo(metadataFile).exists()) {
+
+                        KPluginMetaData metadata = KPluginMetaData::fromDesktopFile(metadataFile);
+                        QString uiFile = standard.absolutePath() + "/" + pluginDir + "/package/" + metadata.value("X-Latte-MainScript");
+
+                        if (metadata.isValid() && QFileInfo(uiFile).exists() && !m_plugins.contains(metadata.pluginId())) {
+                            m_plugins[metadata.pluginId()] = metadata;
+                            QString pluginPath = metadata.fileName().remove("metadata.desktop");
+                            qDebug() << " Indicator Package Loaded ::: " << metadata.name() << " [" << metadata.pluginId() << "]" << " - [" <<pluginPath<<"]";
+                            /*qDebug() << " Indicator value ::: " << metadata.pluginId();
+                            qDebug() << " Indicator value ::: " << metadata.fileName();
+                            qDebug() << " Indicator value ::: " << metadata.value("X-Latte-MainScript");
+                            qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigUi");
+                            qDebug() << " Indicator value ::: " << metadata.value("X-Latte-ConfigXml");*/
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+}
+}
diff --git a/plasmoid/package/contents/ui/indicators/options/Common.qml b/app/indicator/factory.h
similarity index 59%
rename from plasmoid/package/contents/ui/indicators/options/Common.qml
rename to app/indicator/factory.h
index 4925d5478..a8931a0bd 100644
--- a/plasmoid/package/contents/ui/indicators/options/Common.qml
+++ b/app/indicator/factory.h
@@ -1,5 +1,5 @@
 /*
-*  Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
 *
 *  This file is part of Latte-Dock
 *
@@ -17,18 +17,36 @@
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-import QtQuick 2.7
+#ifndef INDICATORFACTORY_H
+#define INDICATORFACTORY_H
 
-import org.kde.plasma.plasmoid 2.0
-import org.kde.plasma.core 2.0 as PlasmaCore
+// Qt
+#include <QHash>
+#include <QObject>
 
-import org.kde.latte 0.2 as Latte
+class KPluginMetaData;
 
-Item{
-    id: common
+namespace Latte {
+namespace Indicator {
 
-    readonly property bool indicatorsEnabled: true
-    readonly property bool reversedEnabled: plasmoid.configuration.reverseLinesPosition
+class Factory : public QObject
+{
+    Q_OBJECT
 
-    readonly property int indicatorStyle: Latte.Types.LatteIndicator
+public:
+    Factory(QObject *parent);
+    ~Factory() override;
+
+    void reload();
+
+    KPluginMetaData metadata(QString pluginId);
+
+private:
+    QHash<QString, KPluginMetaData> m_plugins;
+
+};
+
+}
 }
+
+#endif
diff --git a/app/lattecorona.cpp b/app/lattecorona.cpp
index b14e8dbcf..cc4ec577b 100644
--- a/app/lattecorona.cpp
+++ b/app/lattecorona.cpp
@@ -27,6 +27,7 @@
 #include "launcherssignals.h"
 #include "layoutmanager.h"
 #include "screenpool.h"
+#include "indicator/factory.h"
 #include "shortcuts/globalshortcuts.h"
 #include "package/lattepackage.h"
 #include "plasma/extended/screenpool.h"
@@ -79,6 +80,7 @@ Corona::Corona(bool defaultLayoutOnStartup, QString layoutNameOnStartUp, int use
       m_layoutNameOnStartUp(layoutNameOnStartUp),
       m_activityConsumer(new KActivities::Consumer(this)),
       m_screenPool(new ScreenPool(KSharedConfig::openConfig(), this)),
+      m_indicatorFactory(new Indicator::Factory(this)),
       m_universalSettings(new UniversalSettings(KSharedConfig::openConfig(), this)),
       m_globalShortcuts(new GlobalShortcuts(this)),
       m_plasmaScreenPool(new PlasmaExtended::ScreenPool(this)),
@@ -178,6 +180,7 @@ Corona::~Corona()
     m_plasmaScreenPool->deleteLater();
     m_backgroundTracer->deleteLater();
     m_themeExtended->deleteLater();
+    m_indicatorFactory->deleteLater();
 
     disconnect(m_activityConsumer, &KActivities::Consumer::serviceStatusChanged, this, &Corona::load);
     delete m_activityConsumer;
@@ -392,6 +395,11 @@ AbstractWindowInterface *Corona::wm() const
     return m_wm;
 }
 
+Indicator::Factory *Corona::indicatorFactory() const
+{
+    return m_indicatorFactory;
+}
+
 PlasmaExtended::ScreenPool *Corona::plasmaScreenPool() const
 {
     return m_plasmaScreenPool;
diff --git a/app/lattecorona.h b/app/lattecorona.h
index 7d71e6f98..328fa85e8 100644
--- a/app/lattecorona.h
+++ b/app/lattecorona.h
@@ -66,6 +66,9 @@ class GlobalShortcuts;
 class UniversalSettings;
 class LayoutManager;
 class LaunchersSignals;
+namespace Indicator{
+class Factory;
+}
 namespace PlasmaExtended{
 class ScreenPool;
 class Theme;
@@ -111,6 +114,8 @@ public:
     UniversalSettings *universalSettings() const;
     LayoutManager *layoutManager() const;
 
+    Indicator::Factory *indicatorFactory() const;
+
     PlasmaExtended::ScreenPool *plasmaScreenPool() const;
     PlasmaExtended::Theme *themeExtended() const;
 
@@ -189,6 +194,8 @@ private:
     GlobalShortcuts *m_globalShortcuts{nullptr};
     LayoutManager *m_layoutManager{nullptr};
 
+    Indicator::Factory *m_indicatorFactory{nullptr};
+
     PlasmaExtended::ScreenPool *m_plasmaScreenPool{nullptr};
     PlasmaExtended::Theme *m_themeExtended{nullptr};
 
diff --git a/app/shortcuts/globalshortcuts.cpp b/app/shortcuts/globalshortcuts.cpp
index 4d494a8f3..15addf44e 100644
--- a/app/shortcuts/globalshortcuts.cpp
+++ b/app/shortcuts/globalshortcuts.cpp
@@ -398,7 +398,7 @@ void GlobalShortcuts::activateEntry(int index, Qt::Key modifier)
             continue;
         }
 
-        if ((!view->latteTasksPresent() && view->tasksPresent() &&
+        if ((!view->latteTasksArePresent() && view->tasksPresent() &&
              activatePlasmaTaskManagerEntryAtContainment(view->containment(), index, modifier))
                 || activateLatteEntryAtContainment(view, index, modifier)) {
 
@@ -475,7 +475,7 @@ void GlobalShortcuts::updateViewItemBadge(QString identifier, QString value)
 
 bool GlobalShortcuts::isCapableToShowShortcutBadges(Latte::View *view)
 {
-    if (!view->latteTasksPresent() && view->tasksPresent()) {
+    if (!view->latteTasksArePresent() && view->tasksPresent()) {
         return false;
     }
 
diff --git a/app/view/indicator.cpp b/app/view/indicator.cpp
new file mode 100644
index 000000000..703d6ce20
--- /dev/null
+++ b/app/view/indicator.cpp
@@ -0,0 +1,329 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "indicator.h"
+
+// local
+#include "view.h"
+#include "../lattecorona.h"
+#include "../indicator/factory.h"
+
+// KDE
+#include <KPluginMetaData>
+#include <KDeclarative/ConfigPropertyMap>
+#include <KDeclarative/QmlObjectSharedEngine>
+
+
+namespace Latte {
+namespace ViewPart {
+
+Indicator::Indicator(Latte::View *parent)
+    : QObject(parent),
+      m_view(parent)
+{
+    m_corona = qobject_cast<Latte::Corona *>(m_view->corona());
+    loadConfig();
+
+    connect(this, &Indicator::enabledChanged, this, &Indicator::saveConfig);
+    connect(this, &Indicator::enabledForAppletsChanged, this, &Indicator::saveConfig);
+    connect(this, &Indicator::paddingChanged, this, &Indicator::saveConfig);
+    connect(this, &Indicator::reversedChanged, this, &Indicator::saveConfig);
+    connect(this, &Indicator::typeChanged, this, &Indicator::saveConfig);
+
+    connect(m_view, &Latte::View::latteTasksArePresentChanged, this, &Indicator::latteTasksArePresentChanged);
+
+    load(m_type);
+
+    loadPlasmaComponent();
+}
+
+Indicator::~Indicator()
+{
+    if (m_component) {
+        m_component->deleteLater();
+    }
+
+    if (m_configLoader) {
+        m_configLoader->deleteLater();
+    }
+
+    if (m_configuration) {
+        m_configuration->deleteLater();
+    }
+}
+
+bool Indicator::enabled() const
+{
+    return m_enabled;
+}
+
+void Indicator::setEnabled(bool enabled)
+{
+    if (m_enabled == enabled) {
+        return;
+    }
+
+    m_enabled = enabled;
+    emit enabledChanged();
+}
+
+bool Indicator::enabledForApplets() const
+{
+    return m_enabledForApplets;
+}
+
+void Indicator::setEnabledForApplets(bool enabled)
+{
+    if (m_enabledForApplets == enabled) {
+        return;
+    }
+
+    m_enabledForApplets = enabled;
+    emit enabledForAppletsChanged();
+}
+
+bool Indicator::latteTasksArePresent()
+{
+    return m_view->latteTasksArePresent();
+}
+
+bool Indicator::providesConfigUi() const
+{
+    return m_providesConfigUi;
+}
+
+void Indicator::setProvidesConfigUi(bool provides)
+{
+    if (m_providesConfigUi == provides) {
+        return;
+    }
+
+    m_providesConfigUi = provides;
+    emit providesConfigUiChanged();
+}
+
+bool Indicator::reversed() const
+{
+    return m_reversed;
+}
+
+void Indicator::setReversed(bool reversed)
+{
+    if (m_reversed == reversed) {
+        return;
+    }
+
+    m_reversed = reversed;
+    emit reversedChanged();
+}
+
+float Indicator::padding() const
+{
+    return m_padding;
+}
+
+void Indicator::setPadding(float padding)
+{
+    if (m_padding == padding) {
+        return;
+    }
+
+    m_padding = padding;
+    emit paddingChanged();
+}
+
+QString Indicator::type() const
+{
+    return m_type;
+}
+
+void Indicator::setType(QString type)
+{
+    if (m_type == type) {
+        return;
+    }
+
+    load(type);
+}
+
+QQmlComponent *Indicator::component() const
+{
+    return m_component;
+}
+
+QQmlComponent *Indicator::plasmaComponent() const
+{
+    return m_plasmaComponent;
+}
+
+QObject *Indicator::configuration() const
+{
+    return m_configuration;
+}
+
+void Indicator::load(QString type)
+{
+    KPluginMetaData metadata = m_corona->indicatorFactory()->metadata(type);
+
+    if (metadata.isValid()) {
+        m_metadata = metadata;
+        m_type = type;
+
+        QString path = m_metadata.fileName();
+        m_pluginPath = path.remove("metadata.desktop");
+
+        updateScheme();
+        updateComponent();
+
+        emit typeChanged();
+    } else if (type!="org.kde.latte.indicator.default") {
+        setType("org.kde.latte.indicator.default");
+    }
+}
+
+void Indicator::updateComponent()
+{
+    auto prevComponent = m_component;
+
+    QString uiPath = m_metadata.value("X-Latte-MainScript");
+
+    if (!uiPath.isEmpty()) {
+        uiPath = m_pluginPath + "package/" + uiPath;
+        m_component = new QQmlComponent(m_view->engine(), uiPath);
+    }
+
+    if (prevComponent) {
+        prevComponent->deleteLater();
+    }
+
+    emit componentChanged();
+}
+
+void Indicator::loadPlasmaComponent()
+{
+    auto prevComponent = m_plasmaComponent;
+
+    KPluginMetaData metadata = m_corona->indicatorFactory()->metadata("org.kde.latte.indicator.plasma");
+    QString uiPath = metadata.value("X-Latte-MainScript");
+
+    if (!uiPath.isEmpty()) {
+        QString path = metadata.fileName();
+        path = path.remove("metadata.desktop");
+
+        uiPath = path + "package/" + uiPath;
+        m_plasmaComponent = new QQmlComponent(m_view->engine(), uiPath);
+    }
+
+    if (prevComponent) {
+        prevComponent->deleteLater();
+    }
+
+    emit plasmaComponentChanged();
+}
+
+void Indicator::configUiFor(QString type, QQuickItem *parent)
+{
+    if (m_lastCreatedConfigUi) {
+        delete m_lastCreatedConfigUi;
+        m_lastCreatedConfigUi = nullptr;
+    }
+    auto prevConfigUi = m_lastCreatedConfigUi;
+
+    KPluginMetaData metadata;
+
+    if (m_metadata.pluginId() == type) {
+        metadata = m_metadata;
+    } else {
+        metadata = m_corona->indicatorFactory()->metadata(type);
+    }
+
+    if (metadata.isValid()) {
+        QString uiPath = metadata.value("X-Latte-ConfigUi");
+
+        if (!uiPath.isEmpty()) {
+            m_lastCreatedConfigUi = new KDeclarative::QmlObjectSharedEngine(parent);
+            m_lastCreatedConfigUi->setInitializationDelayed(true);
+            uiPath = m_pluginPath + "package/" + uiPath;
+            m_lastCreatedConfigUi->setSource(QUrl::fromLocalFile(uiPath));
+            m_lastCreatedConfigUi->rootContext()->setContextProperty(QStringLiteral("indicator"), this);
+            m_lastCreatedConfigUi->completeInitialization();
+
+            m_lastCreatedConfigUi->setTranslationDomain(QLatin1String("latte_indicator_") + m_metadata.pluginId());
+
+            QQuickItem *qmlItem = qobject_cast<QQuickItem*>(m_lastCreatedConfigUi->rootObject());
+            qmlItem->setParentItem(parent);
+
+            setProvidesConfigUi(true);
+        } else {
+            setProvidesConfigUi(false);
+        }
+    }
+}
+
+void Indicator::updateScheme()
+{
+    auto prevConfigLoader = m_configLoader;
+    auto prevConfiguration = m_configuration;
+
+    QString xmlPath = m_metadata.value("X-Latte-ConfigXml");
+
+    if (!xmlPath.isEmpty()) {
+        QFile file(m_pluginPath + "package/" + xmlPath);
+        m_configLoader = new KConfigLoader(m_view->containment()->config().group("Indicator").group(m_metadata.pluginId()), &file);
+        m_configuration = new KDeclarative::ConfigPropertyMap(m_configLoader, this);
+    } else {
+        m_configLoader = nullptr;
+        m_configuration = nullptr;
+    }
+
+    if (prevConfigLoader) {
+        prevConfigLoader->deleteLater();
+    }
+
+    if (prevConfiguration) {
+        prevConfiguration->deleteLater();
+    }
+
+    emit configurationChanged();
+}
+
+void Indicator::loadConfig()
+{
+    auto config = m_view->containment()->config().group("Indicator");
+    m_enabled = config.readEntry("enabled", true);
+    m_enabledForApplets = config.readEntry("enabledForApplets", true);
+    m_padding = config.readEntry("padding", (float)0.08);
+    m_reversed = config.readEntry("reversed", false);
+    m_type = config.readEntry("type", "org.kde.latte.indicator.default");
+}
+
+void Indicator::saveConfig()
+{
+    auto config = m_view->containment()->config().group("Indicator");
+    config.writeEntry("enabled", m_enabled);
+    config.writeEntry("enabledForApplets", m_enabledForApplets);
+    config.writeEntry("padding", m_padding);
+    config.writeEntry("reversed", m_reversed);
+    config.writeEntry("type", m_type);
+
+    config.sync();
+}
+
+}
+}
diff --git a/app/view/indicator.h b/app/view/indicator.h
new file mode 100644
index 000000000..3c538c6f4
--- /dev/null
+++ b/app/view/indicator.h
@@ -0,0 +1,149 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef VIEWINDICATOR_H
+#define VIEWINDICATOR_H
+
+// Qt
+#include <QObject>
+#include <QPointer>
+#include <QQmlComponent>
+#include <QQmlContext>
+#include <QQuickItem>
+
+// KDE
+#include <KConfigLoader>
+#include <KPluginMetaData>
+
+namespace KDeclarative
+{
+class ConfigPropertyMap;
+class QmlObjectSharedEngine;
+}
+
+namespace Latte {
+class Corona;
+class View;
+}
+
+namespace Latte {
+namespace ViewPart {
+
+class Indicator: public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
+    Q_PROPERTY(bool enabledForApplets READ enabledForApplets WRITE setEnabledForApplets NOTIFY enabledForAppletsChanged)
+    Q_PROPERTY(bool latteTasksArePresent READ latteTasksArePresent NOTIFY latteTasksArePresentChanged)
+    Q_PROPERTY(bool providesConfigUi READ providesConfigUi NOTIFY providesConfigUiChanged)
+    Q_PROPERTY(bool reversed READ reversed WRITE setReversed NOTIFY reversedChanged)
+
+    Q_PROPERTY(float padding READ padding WRITE setPadding NOTIFY paddingChanged)
+
+    Q_PROPERTY(QString type READ type WRITE setType NOTIFY typeChanged)
+
+    /**
+     * Configuration object: each config key will be a writable property of this object. property bindings work.
+     */
+    Q_PROPERTY(QObject *configuration READ configuration NOTIFY configurationChanged)
+
+    Q_PROPERTY(QQmlComponent *component READ component NOTIFY componentChanged)
+    Q_PROPERTY(QQmlComponent *plasmaComponent READ plasmaComponent NOTIFY plasmaComponentChanged)
+
+public:
+    Indicator(Latte::View *parent);
+    virtual ~Indicator();
+
+    bool enabled() const;
+    void setEnabled(bool enabled);
+
+    bool enabledForApplets() const;
+    void setEnabledForApplets(bool enabled);
+
+    bool latteTasksArePresent();
+    bool providesConfigUi() const;
+
+    bool reversed() const;
+    void setReversed(bool reversed);
+
+    float padding() const;
+    void setPadding(float padding);
+
+    QString type() const;
+    void setType(QString type);
+
+    QObject *configuration() const;
+    QQmlComponent *component() const;
+    QQmlComponent *plasmaComponent() const;
+
+    void load(QString type);
+
+public slots:
+    Q_INVOKABLE void configUiFor(QString type, QQuickItem *parent);
+
+signals:
+    void componentChanged();
+    void configurationChanged();
+    void enabledChanged();
+    void enabledForAppletsChanged();
+    void latteTasksArePresentChanged();
+    void paddingChanged();
+    void plasmaComponentChanged();
+    void providesConfigUiChanged();
+    void reversedChanged();
+    void typeChanged();
+
+private:
+    void loadConfig();
+    void saveConfig();
+
+    void setProvidesConfigUi(bool provides);
+
+    void loadPlasmaComponent();
+    void updateComponent();
+    void updateScheme();
+
+private:
+    bool m_enabled{true};
+    bool m_enabledForApplets{true};
+    bool m_providesConfigUi{true};
+    bool m_reversed{false};
+
+    float m_padding{0.08};
+
+    QString m_pluginPath;
+    QString m_type{"org.kde.latte.indicator.default"};
+
+    QPointer<QQmlComponent> m_component;
+    QPointer<QQmlComponent> m_plasmaComponent;
+    QPointer<QQmlComponent> m_configUi;
+    QPointer<KConfigLoader> m_configLoader;
+    QPointer<Latte::Corona> m_corona;
+    QPointer<Latte::View> m_view;
+
+    KPluginMetaData m_metadata;
+
+    QPointer<KDeclarative::ConfigPropertyMap> m_configuration;
+    QPointer<KDeclarative::QmlObjectSharedEngine> m_lastCreatedConfigUi;
+};
+
+}
+}
+
+#endif
diff --git a/app/view/view.cpp b/app/view/view.cpp
index 604cc211e..9b51a0939 100644
--- a/app/view/view.cpp
+++ b/app/view/view.cpp
@@ -74,9 +74,9 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
     setClearBeforeRendering(true);
 
     const auto flags = Qt::FramelessWindowHint
-                       | Qt::WindowStaysOnTopHint
-                       | Qt::NoDropShadowWindowHint
-                       | Qt::WindowDoesNotAcceptFocus;
+            | Qt::WindowStaysOnTopHint
+            | Qt::NoDropShadowWindowHint
+            | Qt::WindowDoesNotAcceptFocus;
 
     if (byPassWM) {
         setFlags(flags | Qt::BypassWindowManagerHint);
@@ -92,7 +92,7 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
         m_positioner->setScreenToFollow(qGuiApp->primaryScreen());
 
     connect(this, &View::containmentChanged
-    , this, [ &, byPassWM]() {
+            , this, [ &, byPassWM]() {
         qDebug() << "dock view c++ containment changed 1...";
 
         if (!this->containment())
@@ -112,6 +112,7 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
         //! needs to be created before visibility creation because visibility uses it
         if (!m_windowsTracker) {
             m_windowsTracker = new ViewPart::WindowsTracker(this);
+            emit windowsTrackerChanged();
         }
 
         if (!m_visibility) {
@@ -122,6 +123,13 @@ View::View(Plasma::Corona *corona, QScreen *targetScreen, bool byPassWM)
                     deactivateApplets();
                 }
             });
+
+            emit visibilityChanged();
+        }
+
+        if (!m_indicator) {
+            m_indicator = new ViewPart::Indicator(this);
+            emit indicatorChanged();
         }
 
         connect(this->containment(), SIGNAL(statusChanged(Plasma::Types::ItemStatus)), SLOT(statusChanged(Plasma::Types::ItemStatus)));
@@ -168,6 +176,10 @@ View::~View()
         delete m_positioner;
     }
 
+    if (m_indicator) {
+        delete m_indicator;
+    }
+
     if (m_effects) {
         delete m_effects;
     }
@@ -414,7 +426,7 @@ void View::updateAbsDockGeometry(bool bypassChecks)
     //! behavior and keeping this comment in order to check for
     //! multi-screen breakage
     QRect absGeometry {x() + m_localGeometry.x(), y() + m_localGeometry.y()
-                       , m_localGeometry.width(), m_localGeometry.height()};
+                , m_localGeometry.width(), m_localGeometry.height()};
 
     if (m_absGeometry == absGeometry && !bypassChecks)
         return;
@@ -433,7 +445,7 @@ void View::statusChanged(Plasma::Types::ItemStatus status)
 {
     if (containment()) {
         if (containment()->status() >= Plasma::Types::NeedsAttentionStatus &&
-            containment()->status() != Plasma::Types::HiddenStatus) {
+                containment()->status() != Plasma::Types::HiddenStatus) {
             setBlockHiding(true);
         } else if (!containment()->isUserConfiguring()){
             setBlockHiding(false);
@@ -578,6 +590,21 @@ void View::setIsPreferredForShortcuts(bool preferred)
     }
 }
 
+bool View::latteTasksArePresent() const
+{
+    return m_latteTasksArePresent;
+}
+
+void View::setLatteTasksArePresent(bool present)
+{
+    if (m_latteTasksArePresent == present) {
+        return;
+    }
+
+    m_latteTasksArePresent = present;
+    emit latteTasksArePresentChanged();
+}
+
 void View::preferredViewForShortcutsChangedSlot(Latte::View *view)
 {
     if (view != this) {
@@ -920,26 +947,6 @@ bool View::tasksPresent()
     return false;
 }
 
-
-//! check if the tasks plasmoid exist in the dock
-bool View::latteTasksPresent()
-{
-    if (!this->containment()) {
-        return false;
-    }
-
-    foreach (Plasma::Applet *applet, this->containment()->applets()) {
-        KPluginMetaData metadata = applet->pluginMetaData();
-
-        if (metadata.pluginId() == "org.kde.latte.plasmoid") {
-            return true;
-        }
-    }
-
-    return false;
-}
-
-
 //!check if the plasmoid with _name_ exists in the midedata
 bool View::mimeContainsPlasmoid(QMimeData *mimeData, QString name)
 {
@@ -965,6 +972,11 @@ ViewPart::Effects *View::effects() const
     return m_effects;
 }
 
+ViewPart::Indicator *View::indicator() const
+{
+    return m_indicator;
+}
+
 ViewPart::Positioner *View::positioner() const
 {
     return m_positioner;
@@ -986,56 +998,56 @@ bool View::event(QEvent *e)
         emit eventTriggered(e);
 
         switch (e->type()) {
-            case QEvent::Enter:
-                m_containsMouse = true;
-
-                if (m_configView && KWindowSystem::isPlatformX11()) {
-                    ViewPart::PrimaryConfigView *primaryConfigView = qobject_cast<ViewPart::PrimaryConfigView *>(m_configView);
+        case QEvent::Enter:
+            m_containsMouse = true;
 
-                    if (primaryConfigView) {
-                        if (primaryConfigView->secondaryWindow()) {
-                            primaryConfigView->secondaryWindow()->requestActivate();
-                        }
+            if (m_configView && KWindowSystem::isPlatformX11()) {
+                ViewPart::PrimaryConfigView *primaryConfigView = qobject_cast<ViewPart::PrimaryConfigView *>(m_configView);
 
-                        primaryConfigView->requestActivate();
+                if (primaryConfigView) {
+                    if (primaryConfigView->secondaryWindow()) {
+                        primaryConfigView->secondaryWindow()->requestActivate();
                     }
+
+                    primaryConfigView->requestActivate();
                 }
-                break;
-
-            case QEvent::Leave:
-                m_containsMouse = false;
-                engine()->trimComponentCache();
-                break;
-
-            case QEvent::PlatformSurface:
-                if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) {
-                    switch (pe->surfaceEventType()) {
-                        case QPlatformSurfaceEvent::SurfaceCreated:
-                            setupWaylandIntegration();
-
-                            if (m_shellSurface) {
-                                m_positioner->syncGeometry();
-                                m_effects->updateShadows();
-                            }
-
-                            break;
-
-                        case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
-                            if (m_shellSurface) {
-                                delete m_shellSurface;
-                                m_shellSurface = nullptr;
-                                qDebug() << "WAYLAND dock window surface was deleted...";
-                                m_effects->clearShadows();
-                            }
-
-                            break;
+            }
+            break;
+
+        case QEvent::Leave:
+            m_containsMouse = false;
+            engine()->trimComponentCache();
+            break;
+
+        case QEvent::PlatformSurface:
+            if (auto pe = dynamic_cast<QPlatformSurfaceEvent *>(e)) {
+                switch (pe->surfaceEventType()) {
+                case QPlatformSurfaceEvent::SurfaceCreated:
+                    setupWaylandIntegration();
+
+                    if (m_shellSurface) {
+                        m_positioner->syncGeometry();
+                        m_effects->updateShadows();
                     }
+
+                    break;
+
+                case QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed:
+                    if (m_shellSurface) {
+                        delete m_shellSurface;
+                        m_shellSurface = nullptr;
+                        qDebug() << "WAYLAND dock window surface was deleted...";
+                        m_effects->clearShadows();
+                    }
+
+                    break;
                 }
+            }
 
-                break;
+            break;
 
-            default:
-                break;
+        default:
+            break;
         }
     }
 
diff --git a/app/view/view.h b/app/view/view.h
index 3cf8ca4f6..767100fe8 100644
--- a/app/view/view.h
+++ b/app/view/view.h
@@ -23,6 +23,7 @@
 
 // local
 #include "effects.h"
+#include "indicator.h"
 #include "positioner.h"
 #include "visibilitymanager.h"
 #include "windowstracker.h"
@@ -80,6 +81,7 @@ class View : public PlasmaQuick::ContainmentView
     //! when the isUserConfiguring changes value
     Q_PROPERTY(bool inEditMode READ inEditMode WRITE setInEditMode NOTIFY inEditModeChanged)
     Q_PROPERTY(bool isPreferredForShortcuts READ isPreferredForShortcuts WRITE setIsPreferredForShortcuts NOTIFY isPreferredForShortcutsChanged)
+    Q_PROPERTY(bool latteTasksArePresent READ latteTasksArePresent WRITE setLatteTasksArePresent NOTIFY latteTasksArePresentChanged)
     Q_PROPERTY(bool onPrimary READ onPrimary WRITE setOnPrimary NOTIFY onPrimaryChanged)
 
     Q_PROPERTY(int alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
@@ -95,8 +97,9 @@ class View : public PlasmaQuick::ContainmentView
 
     Q_PROPERTY(float maxLength READ maxLength WRITE setMaxLength NOTIFY maxLengthChanged)
 
-    Q_PROPERTY(Latte::ViewPart::Effects *effects READ effects NOTIFY effectsChanged)
     Q_PROPERTY(Layout *managedLayout READ managedLayout WRITE setManagedLayout NOTIFY managedLayoutChanged)
+    Q_PROPERTY(Latte::ViewPart::Effects *effects READ effects NOTIFY effectsChanged)
+    Q_PROPERTY(Latte::ViewPart::Indicator *indicator READ indicator NOTIFY indicatorChanged)
     Q_PROPERTY(Latte::ViewPart::Positioner *positioner READ positioner NOTIFY positionerChanged)
     Q_PROPERTY(Latte::ViewPart::VisibilityManager *visibility READ visibility NOTIFY visibilityChanged)
     Q_PROPERTY(Latte::ViewPart::WindowsTracker *windowsTracker READ windowsTracker NOTIFY windowsTrackerChanged)
@@ -140,6 +143,9 @@ public:
     bool isPreferredForShortcuts() const;
     void setIsPreferredForShortcuts(bool preferred);
 
+    bool latteTasksArePresent() const;
+    void setLatteTasksArePresent(bool present);
+
     float maxLength() const;
     void setMaxLength(float length);
 
@@ -173,6 +179,7 @@ public:
     PlasmaQuick::ConfigView *configView();
 
     ViewPart::Effects *effects() const;
+    ViewPart::Indicator *indicator() const;
     ViewPart::Positioner *positioner() const;
     ViewPart::VisibilityManager *visibility() const;
     ViewPart::WindowsTracker *windowsTracker() const;
@@ -202,7 +209,6 @@ public slots:
 
     Q_INVOKABLE bool mimeContainsPlasmoid(QMimeData *mimeData, QString name);
     Q_INVOKABLE bool tasksPresent();
-    Q_INVOKABLE bool latteTasksPresent();
 
     void updateAbsDockGeometry(bool bypassChecks = false);
 
@@ -237,7 +243,9 @@ signals:
     void widthChanged();
     void heightChanged();
     void inEditModeChanged();
+    void indicatorChanged();
     void isPreferredForShortcutsChanged();
+    void latteTasksArePresentChanged();
     void localGeometryChanged();
     void managedLayoutChanged();
     void maxLengthChanged();
@@ -281,6 +289,7 @@ private:
     bool m_inDelete{false};
     bool m_inEditMode{false};
     bool m_isPreferredForShortcuts{false};
+    bool m_latteTasksArePresent{false};
     bool m_onPrimary{true};
     int m_fontPixelSize{ -1};
     int m_editThickness{24};
@@ -300,6 +309,7 @@ private:
 
     QPointer<ViewPart::ContextMenu> m_contextMenu;
     QPointer<ViewPart::Effects> m_effects;
+    QPointer<ViewPart::Indicator> m_indicator;
     QPointer<ViewPart::Positioner> m_positioner;
     QPointer<ViewPart::VisibilityManager> m_visibility;
     QPointer<ViewPart::WindowsTracker> m_windowsTracker;
diff --git a/containment/package/contents/config/main.xml b/containment/package/contents/config/main.xml
index 6b69419e2..7405acf6f 100644
--- a/containment/package/contents/config/main.xml
+++ b/containment/package/contents/config/main.xml
@@ -41,10 +41,6 @@
       <default>20</default>
       <label>this is a percentage value</label>
     </entry>
-    <entry name="lengthIntMargin" type="Int">
-      <default>8</default>
-      <label>this is a percentage value</label>
-    </entry>
     <entry name="lengthExtMargin" type="Int">
       <default>0</default>
       <label>this is a percentage value</label>
@@ -153,44 +149,6 @@
     <entry name="showGlow" type="Bool">
        <default>false</default>
     </entry>
-    <entry name="glowOption" type="Enum">
-      <label>Glow for active indicators</label>
-        <choices>
-          <choice name="None"/>
-          <choice name="OnActive"/>
-          <choice name="All"/>
-        </choices>
-      <default>0</default>
-    </entry>
-    <entry name="glow3D" type="Bool">
-       <default>true</default>
-    </entry>
-    <entry name="glowOpacity" type="Int">
-       <default>30</default>
-    </entry>
-    <entry name="indicatorsEnabled" type="Bool">
-        <default>true</default>
-    </entry>
-    <entry name="indicatorsForApplets" type="Bool">
-        <default>false</default>
-    </entry>
-    <entry name="indicatorStyle" type="Enum">
-      <label>Indicator style</label>
-        <choices>
-          <choice name="LatteIndicator"/>
-          <choice name="PlasmaIndicator"/>
-          <choice name="UnityIndicator"/>
-        </choices>
-      <default>0</default>
-    </entry>
-    <entry name="activeIndicatorType" type="Enum">
-      <label>Active indicator style</label>
-        <choices>
-          <choice name="LineIndicator"/>
-          <choice name="DotIndicator"/>
-        </choices>
-      <default>0</default>
-    </entry>
     <entry name="maxLength" type="Int">
       <default>100</default>
     </entry>
diff --git a/containment/package/contents/ui/VisibilityManager.qml b/containment/package/contents/ui/VisibilityManager.qml
index dd1c45678..a3e62b32b 100644
--- a/containment/package/contents/ui/VisibilityManager.qml
+++ b/containment/package/contents/ui/VisibilityManager.qml
@@ -136,6 +136,13 @@ Item{
         value: root.editMode
     }
 
+    Binding{
+        target: latteView
+        property:"latteTasksArePresent"
+        when: latteView
+        value: latteApplet !== null
+    }
+
     Binding{
         target: latteView
         property: "maxLength"
@@ -221,7 +228,7 @@ Item{
         target: latteView && latteView.windowsTracker ? latteView.windowsTracker : null
         property: "enabled"
         when: latteView && latteView.windowsTracker
-        value: (latteView.visibility && latteView.visibility.mode === Latte.Types.DodgeAllWindows)
+        value: (latteView && latteView.visibility && latteView.visibility.mode === Latte.Types.DodgeAllWindows)
                || ((root.backgroundOnlyOnMaximized
                     || plasmoid.configuration.solidBackgroundForMaximized
                     || root.disablePanelShadowMaximized
diff --git a/containment/package/contents/ui/applet/AppletItem.qml b/containment/package/contents/ui/applet/AppletItem.qml
index 9c311094e..3f665f627 100644
--- a/containment/package/contents/ui/applet/AppletItem.qml
+++ b/containment/package/contents/ui/applet/AppletItem.qml
@@ -331,6 +331,12 @@ Item {
         if (isHidden)
             parabolicManager.setHidden(previousIndex, -1);
 
+        if(root.latteAppletPos>=0 && root.latteAppletPos === index){
+            root.latteApplet = null;
+            root.latteAppletContainer = null;
+            root.latteAppletPos = -1;
+        }
+
         root.updateIndexes.disconnect(checkIndex);
         root.clearZoomSignal.disconnect(clearZoom);
 
@@ -494,14 +500,15 @@ Item {
             width: wrapper.width
             height: wrapper.height
 
-            Indicator.Manager{
-                id: indicatorManager
+            Indicator.Bridge{
+                id: indicatorBridge
             }
 
             //! Indicator Back Layer
             Indicator.Loader{
                 id: indicatorBackLayer
-                manager: indicatorManager
+                bridge: indicatorBridge
+                isBackground: true
             }
 
             ItemWrapper{
@@ -534,8 +541,8 @@ Item {
             //! Indicator Front Layer
             Indicator.Loader{
                 id: indicatorFrontLayer
-                manager: indicatorManager
-                isBackLayer: false
+                bridge: indicatorBridge
+                isBackground: false
             }
 
             //! Applet Shortcut Visual Badge
@@ -584,7 +591,7 @@ Item {
             wrapMode: Text.WordWrap
             elide: Text.ElideRight
             fontSizeMode: Text.Fit
-            color: colorizerManager.applyTheme.textColor
+            color: colorizerManager.textColor
 
             rotation: {
                 if (root.isHorizontal)
diff --git a/containment/package/contents/ui/applet/indicator/Manager.qml b/containment/package/contents/ui/applet/indicator/Bridge.qml
similarity index 81%
rename from containment/package/contents/ui/applet/indicator/Manager.qml
rename to containment/package/contents/ui/applet/indicator/Bridge.qml
index d473e1619..3ec27e3e3 100644
--- a/containment/package/contents/ui/applet/indicator/Manager.qml
+++ b/containment/package/contents/ui/applet/indicator/Bridge.qml
@@ -22,16 +22,16 @@ import QtQuick 2.7
 import org.kde.latte 0.2 as Latte
 
 Item{
-    id: indicatorManager
+    id: indicatorBridge
     anchors.fill: parent
 
    property bool appletIsValid: true
 
     readonly property bool active: appletIsValid &&
-                                   ((indicators.common.indicatorsEnabled
+                                   ((indicators.isEnabled
                                      && appletItem.communicatorAlias.activeIndicatorEnabled
-                                     && indicators.common.indicatorsForApplets)
-                                    || (!indicators.common.indicatorsForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive))
+                                     && indicators.enabledForApplets)
+                                    || (!indicators.enabledForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive))
 
     /* Indicators Properties in order use them*/
     readonly property bool isTask: false
@@ -60,11 +60,15 @@ Item{
     readonly property real scaleFactor: appletIsValid ? appletItem.wrapperAlias.zoomScale : 1
     readonly property color shadowColor: root.appShadowColorSolid
 
+    readonly property bool usePlasmaTabsStyle: !indicators.enabledForApplets
+
+    readonly property QtObject palette: colorizerManager.applyTheme
+
     //!icon colors
     property color backgroundColor: appletIsValid ? appletItem.wrapperAlias.overlayIconLoader.backgroundColor : "black"
     property color glowColor: appletIsValid ? appletItem.wrapperAlias.overlayIconLoader.glowColor : "white"
 
     //! grouped options
-    readonly property Item common: indicators.common
-    readonly property Item explicit: indicators.explicit
+    readonly property Item shared: indicators
+    readonly property QtObject configuration: indicators.configuration
 }
diff --git a/containment/package/contents/ui/applet/indicator/Loader.qml b/containment/package/contents/ui/applet/indicator/Loader.qml
index 40f14a4a6..0d5756dc3 100644
--- a/containment/package/contents/ui/applet/indicator/Loader.qml
+++ b/containment/package/contents/ui/applet/indicator/Loader.qml
@@ -25,15 +25,16 @@ Loader{
     id: indicatorLoader
     anchors.fill: parent
 
-    active: manager && manager.active && (isBackLayer || (!isBackLayer && indicators.info.providesFrontLayer))
+    active: bridge && bridge.active && (isBackground || (isForeground && indicators.info.providesFrontLayer))
     sourceComponent: {
-        if (!indicators.common.indicatorsForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive) {
+        if (!indicators.enabledForApplets && appletItem.communicatorAlias.overlayLatteIconIsActive) {
             return indicators.plasmaStyleComponent;
         }
 
         return indicators.indicatorComponent;
     }
 
-    property bool isBackLayer: true
-    property Item manager
+    property bool isBackground: true
+    readonly property bool isForeground: !isBackground
+    property Item bridge
 }
diff --git a/containment/package/contents/ui/colorizer/Manager.qml b/containment/package/contents/ui/colorizer/Manager.qml
index 5139d43a2..2973fea85 100644
--- a/containment/package/contents/ui/colorizer/Manager.qml
+++ b/containment/package/contents/ui/colorizer/Manager.qml
@@ -59,11 +59,13 @@ Loader{
 
     readonly property real currentBackgroundBrightness: item ? item.currentBrightness : -1000
 
-    readonly property bool applyingWindowColors: (root.windowColors === Latte.Types.ActiveWindowColors && latteView.windowsTracker.activeWindowScheme)
-                                                 || (root.windowColors === Latte.Types.TouchingWindowColors && latteView.windowsTracker.touchingWindowScheme)
+    readonly property bool applyingWindowColors: (root.windowColors === Latte.Types.ActiveWindowColors && latteView && latteView.windowsTracker
+                                                  && latteView.windowsTracker.activeWindowScheme)
+                                                 || (root.windowColors === Latte.Types.TouchingWindowColors && latteView && latteView.windowsTracker
+                                                     && latteView.windowsTracker.touchingWindowScheme)
 
     property QtObject applyTheme: {
-        if (!root.hasExpandedApplet) {
+        if (latteView && latteView.windowsTracker && !root.hasExpandedApplet) {
             if (root.windowColors === Latte.Types.ActiveWindowColors && latteView.windowsTracker.activeWindowScheme) {
                 return latteView.windowsTracker.activeWindowScheme;
             }
@@ -110,7 +112,7 @@ Loader{
 
     readonly property color backgroundColor:applyTheme.backgroundColor
     readonly property color textColor: {
-        if (root.inConfigureAppletsMode && (root.themeColors === Latte.Types.SmartThemeColors)) {
+        if (latteView && latteView.managedLayout && root.inConfigureAppletsMode && (root.themeColors === Latte.Types.SmartThemeColors)) {
             return latteView.managedLayout.textColor;
         }
 
diff --git a/containment/package/contents/ui/indicators/Manager.qml b/containment/package/contents/ui/indicators/Manager.qml
index 63d811374..72365b519 100644
--- a/containment/package/contents/ui/indicators/Manager.qml
+++ b/containment/package/contents/ui/indicators/Manager.qml
@@ -24,29 +24,21 @@ import org.kde.plasma.core 2.0 as PlasmaCore
 
 import org.kde.latte 0.2 as Latte
 
-import "options" as Options
 import "../applet/indicator" as AppletIndicator
 
 Item{
     id: managerIndicator
 
-    readonly property Item common: commonOptions
-    readonly property Item explicit: explicitOptions.item
+    readonly property QtObject configuration: latteView && latteView.indicator ? latteView.indicator.configuration : null
 
-    readonly property Component plasmaStyleComponent: plasmaStyleIndicator
+    readonly property bool isEnabled: latteView && latteView.indicator ? latteView.indicator.enabled : false
+    readonly property bool enabledForApplets: latteView && latteView.indicator ? latteView.indicator.enabledForApplets : true
+    readonly property bool reversed: latteView && latteView.indicator ? latteView.indicator.reversed : false
+    readonly property real padding: latteView && latteView.indicator ? latteView.indicator.padding: 0.08
+    readonly property string type: latteView && latteView.indicator ? latteView.indicator.type : "org.kde.latte.indicator.default"
 
-    readonly property Component indicatorComponent: {
-        switch (indicators.common.indicatorStyle) {
-        case Latte.Types.LatteIndicator:
-            return latteStyleIndicator;
-        case Latte.Types.PlasmaIndicator:
-            return plasmaStyleIndicator;
-        case Latte.Types.UnityIndicator:
-            return unityStyleIndicator;
-        default:
-            return latteStyleIndicator;
-        };
-    }
+    readonly property Component plasmaStyleComponent: latteView && latteView.indicator ? latteView.indicator.plasmaComponent : null
+    readonly property Component indicatorComponent: latteView && latteView.indicator ? latteView.indicator.component : null
 
     readonly property Item info: Item{
         readonly property bool needsIconColors: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("needsIconColors")
@@ -63,48 +55,14 @@ Item{
         }
     }
 
-
-    Options.Common {
-        id: commonOptions
-    }
-
-    Loader{
-        id: explicitOptions
-        active: true
-        source: {
-            if (commonOptions.indicatorStyle === Latte.Types.LatteIndicator) {
-                return "options/Latte.qml";
-            } else if (commonOptions.indicatorStyle === Latte.Types.PlasmaIndicator) {
-                return "options/Plasma.qml";
-            }
-
-            return "options/Latte.qml";
-        }
-    }
-
-    //! Indicators Components
-    Component {
-        id: latteStyleIndicator
-        Latte.LatteIndicator{}
-    }
-
-    Component {
-        id: plasmaStyleIndicator
-        Latte.PlasmaIndicator{}
-    }
-
-    Component{
-        id:unityStyleIndicator
-        Latte.UnityIndicator{}
-    }
-
     //! Metrics and values provided from an invisible indicator
     Loader{
         id: metricsLoader
         opacity: 0
+        active: managerIndicator.isEnabled
 
-        readonly property bool isBackLayer: true
-        readonly property Item manager: AppletIndicator.Manager{
+        readonly property bool isBackground: true
+        readonly property Item bridge: AppletIndicator.Bridge{
             appletIsValid: false
         }
 
diff --git a/containment/package/contents/ui/indicators/options/Latte.qml b/containment/package/contents/ui/indicators/options/Latte.qml
deleted file mode 100644
index 42bdec406..000000000
--- a/containment/package/contents/ui/indicators/options/Latte.qml
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-*  Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
-*
-*  This file is part of Latte-Dock
-*
-*  Latte-Dock 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.
-*
-*  Latte-Dock is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  You should have received a copy of the GNU General Public License
-*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-import QtQuick 2.7
-
-import org.kde.plasma.plasmoid 2.0
-import org.kde.plasma.core 2.0 as PlasmaCore
-
-import org.kde.latte 0.2 as Latte
-
-Item{
-    readonly property string styleName: "Latte"
-
-    readonly property bool dotsOnActive: plasmoid.configuration.dotsOnActive
-    readonly property bool multiColorEnabled: plasmoid.configuration.threeColorsWindows
-    readonly property int activeIndicatorType: plasmoid.configuration.activeIndicatorType
-
-    //!glow options
-    readonly property bool glowEnabled: plasmoid.configuration.showGlow
-    readonly property bool glow3D: plasmoid.configuration.glow3D
-    readonly property int glowOption: plasmoid.configuration.glowOption
-    readonly property real glowOpacity: plasmoid.configuration.glowOpacity/100
-}
diff --git a/containment/package/contents/ui/loaders/Pager.qml b/containment/package/contents/ui/loaders/Pager.qml
index 754a3ef6c..97f1ad144 100644
--- a/containment/package/contents/ui/loaders/Pager.qml
+++ b/containment/package/contents/ui/loaders/Pager.qml
@@ -19,6 +19,7 @@
 
 import QtQuick 2.7
 
+import org.kde.plasma.plasmoid 2.0
 import org.kde.plasma.private.pager 2.0
 
 import org.kde.latte 0.2 as Latte
@@ -35,7 +36,7 @@ Loader {
             enabled: true
             showDesktop: true
             showOnlyCurrentScreen: true
-            screenGeometry: latteView.screenGeometry
+            screenGeometry: latteView ? latteView.screenGeometry : plasmoid.screenGeometry
             pagerType: root.scrollAction === Latte.Types.ScrollDesktops ? PagerModel.VirtualDesktops : PagerModel.Activities
         }
 
diff --git a/containment/package/contents/ui/main.qml b/containment/package/contents/ui/main.qml
index b45d26107..a064fda13 100644
--- a/containment/package/contents/ui/main.qml
+++ b/containment/package/contents/ui/main.qml
@@ -241,7 +241,8 @@ DragDrop.DropArea {
 
         if (( (plasmoid.configuration.panelShadows && !root.backgroundOnlyOnMaximized)
              || (plasmoid.configuration.panelShadows && root.backgroundOnlyOnMaximized && !root.forceTransparentPanel))
-                && !(disablePanelShadowMaximized && latteView.windowsTracker.activeWindowMaximized)) {
+                && !(disablePanelShadowMaximized && latteView && latteView.windowsTracker
+                     && latteView.windowsTracker.activeWindowMaximized)) {
             return true;
         }
 
@@ -317,7 +318,7 @@ DragDrop.DropArea {
 
     property int lengthIntMargin: lengthIntMarginFactor * root.iconSize
     property int lengthExtMargin: lengthExtMarginFactor * root.iconSize
-    property real lengthIntMarginFactor: indicators.common.indicatorsEnabled ? plasmoid.configuration.lengthIntMargin / 100 : 0
+    property real lengthIntMarginFactor: indicators.isEnabled ? indicators.padding : 0
     property real lengthExtMarginFactor: plasmoid.configuration.lengthExtMargin / 100
 
     property real thickMarginFactor: {
@@ -1434,7 +1435,7 @@ DragDrop.DropArea {
 
     function updateContainsOnlyPlasmaTasks() {
         if (latteView) {
-            root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteView.latteTasksPresent());
+            root.containsOnlyPlasmaTasks = (latteView.tasksPresent() && !latteApplet);
         } else {
             root.containsOnlyPlasmaTasks = false;
         }
diff --git a/declarativeimports/components/GlowPoint.qml b/declarativeimports/components/GlowPoint.qml
index aa3420149..bb3349c76 100644
--- a/declarativeimports/components/GlowPoint.qml
+++ b/declarativeimports/components/GlowPoint.qml
@@ -205,24 +205,27 @@ Item{
     //! add border around indicator without reducing its size
     Loader{
         anchors.centerIn: mainElement
-        active: glowItem.showBorder && !glowItem.showGlow
+        active: glowItem.showBorder
 
         sourceComponent:Rectangle {
-            width: size
-            height: size
+            width: mainElement.width + size
+            height: mainElement.height + size
             anchors.centerIn: parent
 
             color: contrastColorAlpha2
             radius: glowItem.roundCorners ? Math.min(width,height) / 2 : 0
 
-            property int size: Math.min(mainElement.width + 2*Math.max(1,mainElement.width/5 ),
-                                        mainElement.height + 2*Math.max(1,mainElement.height/5 ))
+            property int size: Math.min(2*Math.max(1,mainElement.width/5 ),
+                                        2*Math.max(1,mainElement.height/5 ))
         }
     }
 
     Item{
         id:mainElement
-        anchors.fill: parent
+
+        width: Math.max(glowItem.size, parent.width)
+        height: Math.max(glowItem.size, parent.height)
+        anchors.centerIn: parent
 
         Rectangle {
             id: smallCircle
diff --git a/containment/package/contents/ui/indicators/options/Plasma.qml b/declarativeimports/components/IndicatorItem.qml
similarity index 69%
rename from containment/package/contents/ui/indicators/options/Plasma.qml
rename to declarativeimports/components/IndicatorItem.qml
index 08f9cdcfa..f48921a80 100644
--- a/containment/package/contents/ui/indicators/options/Plasma.qml
+++ b/declarativeimports/components/IndicatorItem.qml
@@ -1,5 +1,5 @@
 /*
-*  Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
 *
 *  This file is part of Latte-Dock
 *
@@ -19,14 +19,7 @@
 
 import QtQuick 2.7
 
-import org.kde.plasma.plasmoid 2.0
-import org.kde.plasma.core 2.0 as PlasmaCore
-
-import org.kde.latte 0.2 as Latte
-
-Item{
-    readonly property string styleName: "Plasma"
-
-    readonly property bool usePlasmaTabsStyle: !commonOptions.indicatorsForApplets
+Item {
+    readonly property Item indicator: parent && parent.hasOwnProperty("bridge") ? parent.bridge : null
+    readonly property Item attributes: parent
 }
-
diff --git a/declarativeimports/components/qmldir b/declarativeimports/components/qmldir
index 9070b65af..b6bbb31a0 100644
--- a/declarativeimports/components/qmldir
+++ b/declarativeimports/components/qmldir
@@ -6,6 +6,7 @@ ExternalShadow 1.0 ExternalShadow.qml
 GlowPoint 1.0 GlowPoint.qml
 Header 1.0 Header.qml
 HeaderSwitch 1.0 HeaderSwitch.qml
+IndicatorItem 1.0 IndicatorItem.qml
 Slider 1.0 Slider.qml
 SpinBox 1.0 SpinBox.qml
 SubHeader 1.0 SubHeader.qml
diff --git a/indicators/CMakeLists.txt b/indicators/CMakeLists.txt
new file mode 100644
index 000000000..b125fa53c
--- /dev/null
+++ b/indicators/CMakeLists.txt
@@ -0,0 +1,3 @@
+install(DIRECTORY org.kde.latte.indicator.default DESTINATION ${CMAKE_INSTALL_PREFIX}/share/latte/indicators)
+install(DIRECTORY org.kde.latte.indicator.plasma DESTINATION ${CMAKE_INSTALL_PREFIX}/share/latte/indicators)
+install(DIRECTORY org.kde.latte.indicator.unity DESTINATION ${CMAKE_INSTALL_PREFIX}/share/latte/indicators)
diff --git a/indicators/Messages.sh b/indicators/Messages.sh
new file mode 100644
index 000000000..79b2aebfb
--- /dev/null
+++ b/indicators/Messages.sh
@@ -0,0 +1,4 @@
+#! /usr/bin/env bash
+
+$XGETTEXT `find org.kde.latte.indicator.default -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/latte_indicator_org.kde.latte.indicator.default.pot
+$XGETTEXT `find org.kde.latte.indicator.plasma -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/latte_indicator_org.kde.latte.indicator.plasma.pot 
diff --git a/indicators/org.kde.latte.indicator.default/metadata.desktop b/indicators/org.kde.latte.indicator.default/metadata.desktop
new file mode 100644
index 000000000..827461305
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.default/metadata.desktop
@@ -0,0 +1,19 @@
+[Desktop Entry]
+Name=Latte
+Comment=Latte default indicator
+
+Type=Service
+Icon=latte-dock
+X-Plasma-API=declarativeappletscript
+X-Latte-MainScript=ui/main.qml
+X-Latte-ConfigUi=config/config.qml
+X-Latte-ConfigXml=config/main.xml
+
+X-KDE-PluginInfo-Author=Michail Vourlakos
+X-KDE-PluginInfo-Email=mvourlakos@gmail.com
+X-KDE-PluginInfo-Name=org.kde.latte.indicator.default
+X-KDE-PluginInfo-Version=0.1
+X-KDE-PluginInfo-Category=Windows and Tasks
+X-KDE-PluginInfo-License=GPL v2+
+X-KDE-PluginInfo-EnabledByDefault=true
+ 
diff --git a/shell/package/contents/configuration/pages/indicator/LatteOptions.qml b/indicators/org.kde.latte.indicator.default/package/config/config.qml
similarity index 78%
rename from shell/package/contents/configuration/pages/indicator/LatteOptions.qml
rename to indicators/org.kde.latte.indicator.default/package/config/config.qml
index 602a9edd3..50005373e 100644
--- a/shell/package/contents/configuration/pages/indicator/LatteOptions.qml
+++ b/indicators/org.kde.latte.indicator.default/package/config/config.qml
@@ -31,6 +31,8 @@ import org.kde.latte 0.2 as Latte
 import org.kde.latte.components 1.0 as LatteComponents
 
 ColumnLayout {
+    Layout.fillWidth: true
+
     LatteComponents.SubHeader {
         text: i18nc("active indicator style","Style For Active")
     }
@@ -39,13 +41,13 @@ ColumnLayout {
         Layout.fillWidth: true
         spacing: 2
 
-        property int indicatorType: plasmoid.configuration.activeIndicatorType
+        property int indicatorType: indicator.configuration.activeStyle
 
         ExclusiveGroup {
             id: activeIndicatorTypeGroup
             onCurrentChanged: {
                 if (current.checked) {
-                    plasmoid.configuration.activeIndicatorType = current.indicatorType;
+                    indicator.configuration.activeStyle = current.indicatorType;
                 }
             }
         }
@@ -59,7 +61,7 @@ ColumnLayout {
             exclusiveGroup: activeIndicatorTypeGroup
             tooltip: i18n("Show a line indicator for active items")
 
-            readonly property int indicatorType: Latte.Types.LineIndicator
+            readonly property int indicatorType: 0 /*Line*/
         }
 
         PlasmaComponents.Button {
@@ -71,38 +73,38 @@ ColumnLayout {
             exclusiveGroup: activeIndicatorTypeGroup
             tooltip: i18n("Show a dot indicator for active items")
 
-            readonly property int indicatorType: Latte.Types.DotIndicator
+            readonly property int indicatorType: 1 /*Dot*/
         }
     }
 
     LatteComponents.HeaderSwitch {
-        id: showGlow
+        id: glowEnabled
         Layout.fillWidth: true
         Layout.minimumHeight: implicitHeight
         Layout.bottomMargin: units.smallSpacing
 
-        checked: plasmoid.configuration.showGlow
+        checked: indicator.configuration.glowEnabled
         level: 2
         text: i18n("Glow")
         tooltip: i18n("Enable/disable indicator glow")
 
         onPressed: {
-            plasmoid.configuration.showGlow = !plasmoid.configuration.showGlow;
+            indicator.configuration.glowEnabled = !indicator.configuration.glowEnabled;
         }
     }
 
     RowLayout {
         Layout.fillWidth: true
         spacing: 2
-        enabled: plasmoid.configuration.showGlow
+        enabled: indicator.configuration.glowEnabled
 
-        property int option: plasmoid.configuration.glowOption
+        property int option: indicator.configuration.glowApplyTo
 
         ExclusiveGroup {
             id: glowGroup
             onCurrentChanged: {
                 if (current.checked)
-                    plasmoid.configuration.glowOption = current.option
+                    indicator.configuration.glowApplyTo = current.option
             }
         }
 
@@ -114,7 +116,7 @@ ColumnLayout {
             exclusiveGroup:  glowGroup
             tooltip: i18n("Add glow only to active task/applet indicator")
 
-            readonly property int option: Latte.Types.GlowOnlyOnActive
+            readonly property int option: 1 /*OnActive*/
         }
 
         PlasmaComponents.Button {
@@ -125,7 +127,7 @@ ColumnLayout {
             exclusiveGroup: glowGroup
             tooltip: i18n("Add glow to all task/applet indicators")
 
-            readonly property int option: Latte.Types.GlowAll
+            readonly property int option: 2 /*All*/
         }
     }
 
@@ -133,7 +135,7 @@ ColumnLayout {
         Layout.fillWidth: true
         spacing: 2
 
-        enabled: plasmoid.configuration.showGlow
+        enabled: indicator.configuration.glowEnabled
 
         PlasmaComponents.Label {
             Layout.minimumWidth: implicitWidth
@@ -147,7 +149,7 @@ ColumnLayout {
             Layout.fillWidth: true
 
             leftPadding: 0
-            value: plasmoid.configuration.glowOpacity
+            value: indicator.configuration.glowOpacity * 100
             from: 0
             to: 100
             stepSize: 5
@@ -155,7 +157,7 @@ ColumnLayout {
 
             function updateGlowOpacity() {
                 if (!pressed)
-                    plasmoid.configuration.glowOpacity = value;
+                    indicator.configuration.glowOpacity = value/100;
             }
 
             onPressedChanged: {
@@ -181,32 +183,32 @@ ColumnLayout {
 
     ColumnLayout {
         spacing: 0
-        visible: latteView.latteTasksPresent()
+        visible: indicator.latteTasksArePresent
 
         LatteComponents.SubHeader {
-            enabled: plasmoid.configuration.glowOption!==Latte.Types.GlowNone
+            enabled: indicator.configuration.glowApplyTo!==0/*None*/
             text: i18n("Tasks")
         }
 
         PlasmaComponents.CheckBox {
             id: threeColorsWindows
             text: i18n("Different color for minimized windows")
-            checked: plasmoid.configuration.threeColorsWindows
+            checked: indicator.configuration.minimizedTaskColoredDifferently
 
             onClicked: {
-                plasmoid.configuration.threeColorsWindows = checked
+                indicator.configuration.minimizedTaskColoredDifferently = checked;
             }
         }
 
         PlasmaComponents.CheckBox {
             id: dotsOnActive
             text: i18n("Show an extra dot for grouped windows when active")
-            checked: plasmoid.configuration.dotsOnActive
+            checked: indicator.configuration.extraDotOnActive
             tooltip: i18n("Grouped windows show both a line and a dot when one of them is active and the Line Active Indicator is enabled")
-            enabled: plasmoid.configuration.activeIndicatorType === Latte.Types.LineIndicator
+            enabled: indicator.configuration.activeStyle === 0 /*Line*/
 
             onClicked: {
-                plasmoid.configuration.dotsOnActive = checked
+                indicator.configuration.extraDotOnActive = checked;
             }
         }
     }
diff --git a/indicators/org.kde.latte.indicator.default/package/config/main.xml b/indicators/org.kde.latte.indicator.default/package/config/main.xml
new file mode 100644
index 000000000..4e3f44087
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.default/package/config/main.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+      http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+  <kcfgfile name=""/>
+  <group name="General">
+    <entry name="activeStyle" type="Enum">
+      <label>Active indicator style</label>
+        <choices>
+          <choice name="Line"/>
+          <choice name="Dot"/>
+        </choices>
+      <default>0</default>
+    </entry>
+    <entry name="minimizedTaskColoredDifferently" type="Bool">
+      <default>false</default>
+    </entry>
+    <entry name="extraDotOnActive" type="Bool">
+      <default>false</default>
+    </entry>
+    <entry name="glowEnabled" type="Bool">
+       <default>false</default>
+    </entry>
+    <entry name="glowApplyTo" type="Enum">
+      <label>Glow for active indicators</label>
+        <choices>
+          <choice name="None"/>
+          <choice name="OnActive"/>
+          <choice name="All"/>
+        </choices>
+      <default>2</default>
+    </entry>
+    <entry name="glow3D" type="Bool">
+       <default>true</default>
+    </entry>
+    <entry name="glowOpacity" type="Double">
+       <default>0.35</default>
+    </entry>
+  </group>
+</kcfg>
+
diff --git a/indicators/org.kde.latte.indicator.default/package/ui/main.qml b/indicators/org.kde.latte.indicator.default/package/ui/main.qml
new file mode 100644
index 000000000..a7a605ee5
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.default/package/ui/main.qml
@@ -0,0 +1,291 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.1
+import QtGraphicalEffects 1.0
+
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+import org.kde.plasma.components 2.0 as PlasmaComponents
+
+import org.kde.latte 0.2 as Latte
+import org.kde.latte.components 1.0 as LatteComponents
+
+LatteComponents.IndicatorItem{
+    id: root
+
+    readonly property real factor: 0.08
+    readonly property int size: factor * indicator.currentIconSize
+    readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * indicator.maxIconSize) : 0
+
+    property real textColorBrightness: colorBrightness(theme.textColor)
+
+    property color isActiveColor: theme.buttonFocusColor
+    property color minimizedColor: {
+        if (minimizedTaskColoredDifferently) {
+            return (textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7));
+        }
+
+        return isActiveColor;
+    }
+    property color notActiveColor: indicator.isMinimized ? minimizedColor : isActiveColor
+
+    //! Common Options
+    readonly property bool reversedEnabled: indicator.shared.reversed
+
+    //! Configuration Options
+    readonly property bool extraDotOnActive: indicator.configuration.extraDotOnActive
+    readonly property bool minimizedTaskColoredDifferently: indicator.configuration.minimizedTaskColoredDifferently
+    readonly property int activeStyle: indicator.configuration.activeStyle
+    //!glow options
+    readonly property bool glowEnabled: indicator.configuration.glowEnabled
+    readonly property bool glow3D: indicator.configuration.glow3D
+    readonly property int glowApplyTo: indicator.configuration.glowApplyTo
+    readonly property real glowOpacity: indicator.configuration.glowOpacity
+
+    /*Rectangle{
+        anchors.fill: parent
+        border.width: 1
+        border.color: "yellow"
+        color: "transparent"
+        opacity:0.6
+    }*/
+
+    function colorBrightness(color) {
+        return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
+    }
+
+    // formula for brightness according to:
+    // https://www.w3.org/TR/AERT/#color-contrast
+    function colorBrightnessFromRGB(r, g, b) {
+        return (r * 299 + g * 587 + b * 114) / 1000
+    }
+
+    Item{
+        id: mainIndicatorElement
+
+        width: flowItem.width
+        height: flowItem.height
+
+        Flow{
+            id: flowItem
+            flow: plasmoid.formFactor === PlasmaCore.Types.Vertical ? Flow.TopToBottom : Flow.LeftToRight
+
+            LatteComponents.GlowPoint{
+                id:firstPoint
+                opacity: {
+                    if (indicator.isTask) {
+                        return indicator.isLauncher || (indicator.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
+                    }
+
+                    if (indicator.isApplet) {
+                        return (indicator.isActive || activeAndReverseAnimation.running) ? 1 : 0
+                    }
+                }
+
+                basicColor: indicator.isActive || (indicator.isGroup && indicator.hasShown) ? root.isActiveColor : root.notActiveColor
+
+                size: root.size
+                glow3D: glow3D
+                animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
+                location: plasmoid.location
+                glowOpacity: root.glowOpacity
+                contrastColor: indicator.shadowColor
+                attentionColor: theme.negativeTextColor
+
+                roundCorners: true
+                showAttention: indicator.inAttention
+                showGlow: {
+                    if (glowEnabled && (glowApplyTo === 2 /*All*/ || showAttention ))
+                        return true;
+                    else if (glowEnabled && glowApplyTo === 1 /*OnActive*/ && indicator.hasActive)
+                        return true;
+                    else
+                        return false;
+                }
+                showBorder: glowEnabled && glow3D
+
+                property int stateWidth: indicator.isGroup ? root.width - secondPoint.width : root.width - spacer.width
+                property int stateHeight: indicator.isGroup ? root.height - secondPoint.height : root.width - spacer.height
+
+                property int animationTime: indicator.durationTime* (0.7*units.longDuration)
+
+                property bool isActive: indicator.hasActive || indicator.isActive
+
+                property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
+
+                property real scaleFactor: indicator.scaleFactor
+
+                function updateInitialSizes(){
+                    if(root){
+                        if(vertical)
+                            width = root.size;
+                        else
+                            height = root.size;
+
+                        if(vertical && isActive && activeStyle === 0 /*Line*/)
+                            height = stateHeight;
+                        else
+                            height = root.size;
+
+                        if(!vertical && isActive && activeStyle === 0 /*Line*/)
+                            width = stateWidth;
+                        else
+                            width = root.size;
+                    }
+                }
+
+
+                onIsActiveChanged: {
+                    if (activeStyle === 0 /*Line*/)
+                        activeAndReverseAnimation.start();
+                }
+
+                onScaleFactorChanged: {
+                    if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/){
+                        width = stateWidth;
+                    }
+                    else if (!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/){
+                        height = stateHeight;
+                    }
+                }
+
+                onStateWidthChanged:{
+                    if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/)
+                        width = stateWidth;
+                }
+
+                onStateHeightChanged:{
+                    if(!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/)
+                        height = stateHeight;
+                }
+
+                onVerticalChanged: updateInitialSizes();
+
+                Component.onCompleted: {
+                    updateInitialSizes();
+
+                    if (indicator) {
+                        indicator.onCurrentIconSizeChanged.connect(updateInitialSizes);
+                    }
+                }
+
+                Component.onDestruction: {
+                    if (indicator) {
+                        indicator.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
+                    }
+                }
+
+                NumberAnimation{
+                    id: activeAndReverseAnimation
+                    target: firstPoint
+                    property: plasmoid.formFactor === PlasmaCore.Types.Vertical ? "height" : "width"
+                    to: indicator.hasActive && activeStyle === 0 /*Line*/
+                        ? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : root.size
+                    duration: firstPoint.animationTime
+                    easing.type: Easing.InQuad
+
+                    onStopped: firstPoint.updateInitialSizes()
+                }
+            }
+
+            Item{
+                id:spacer
+                width: secondPoint.visible ? 0.5*root.size : 0
+                height: secondPoint.visible ? 0.5*root.size : 0
+            }
+
+            LatteComponents.GlowPoint{
+                id:secondPoint
+                width: visible ? root.size : 0
+                height: width
+
+                size: root.size
+                glow3D: glow3D
+                animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
+                location: plasmoid.location
+                glowOpacity: root.glowOpacity
+                contrastColor: indicator.shadowColor
+                showBorder: glowEnabled && glow3D
+
+                basicColor: state2Color
+                roundCorners: true
+                showGlow: glowEnabled  && glowApplyTo === 2 /*All*/
+                visible:  ( indicator.isGroup && ((extraDotOnActive && activeStyle === 0) /*Line*/
+                                                  || activeStyle === 1 /*Dot*/
+                                                  || !indicator.hasActive) ) ? true: false
+
+                //when there is no active window
+                property color state1Color: indicator.hasShown ? root.isActiveColor : root.minimizedColor
+                //when there is active window
+                property color state2Color: indicator.hasMinimized ? root.minimizedColor : root.isActiveColor
+            }
+        }
+
+        states: [
+            State {
+                name: "left"
+                when: ((plasmoid.location === PlasmaCore.Types.LeftEdge && !reversedEnabled) ||
+                       (plasmoid.location === PlasmaCore.Types.RightEdge && reversedEnabled))
+
+                AnchorChanges {
+                    target: mainIndicatorElement
+                    anchors{ verticalCenter:parent.verticalCenter; horizontalCenter:undefined;
+                        top:undefined; bottom:undefined; left:parent.left; right:undefined;}
+                }
+            },
+            State {
+                name: "bottom"
+                when: (plasmoid.location === PlasmaCore.Types.Floating ||
+                       (plasmoid.location === PlasmaCore.Types.BottomEdge && !reversedEnabled) ||
+                       (plasmoid.location === PlasmaCore.Types.TopEdge && reversedEnabled))
+
+                AnchorChanges {
+                    target: mainIndicatorElement
+                    anchors{ verticalCenter:undefined; horizontalCenter:parent.horizontalCenter;
+                        top:undefined; bottom:parent.bottom; left:undefined; right:undefined;}
+                }
+            },
+            State {
+                name: "top"
+                when: ((plasmoid.location === PlasmaCore.Types.TopEdge && !reversedEnabled) ||
+                       (plasmoid.location === PlasmaCore.Types.BottomEdge && reversedEnabled))
+
+                AnchorChanges {
+                    target: mainIndicatorElement
+                    anchors{ verticalCenter:undefined; horizontalCenter:parent.horizontalCenter;
+                        top:parent.top; bottom:undefined; left:undefined; right:undefined;}
+                }
+            },
+            State {
+                name: "right"
+                when: ((plasmoid.location === PlasmaCore.Types.RightEdge && !reversedEnabled) ||
+                       (plasmoid.location === PlasmaCore.Types.LeftEdge && reversedEnabled))
+
+                AnchorChanges {
+                    target: mainIndicatorElement
+                    anchors{ verticalCenter:parent.verticalCenter; horizontalCenter:undefined;
+                        top:undefined; bottom:undefined; left:undefined; right:parent.right;}
+                }
+            }
+        ]
+    }
+}// number of windows indicator
+
diff --git a/indicators/org.kde.latte.indicator.plasma/metadata.desktop b/indicators/org.kde.latte.indicator.plasma/metadata.desktop
new file mode 100644
index 000000000..de996c2e5
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.plasma/metadata.desktop
@@ -0,0 +1,17 @@
+[Desktop Entry]
+Name=Plasma
+Comment=Latte Plasma style indicator
+
+Type=Service
+Icon=latte-dock
+X-Plasma-API=declarativeappletscript
+X-Latte-MainScript=ui/main.qml
+
+X-KDE-PluginInfo-Author=Michail Vourlakos
+X-KDE-PluginInfo-Email=mvourlakos@gmail.com
+X-KDE-PluginInfo-Name=org.kde.latte.indicator.plasma
+X-KDE-PluginInfo-Version=0.1
+X-KDE-PluginInfo-Category=Windows and Tasks
+X-KDE-PluginInfo-License=GPL v2+
+X-KDE-PluginInfo-EnabledByDefault=true
+ 
diff --git a/indicators/org.kde.latte.indicator.plasma/package/ui/BackLayer.qml b/indicators/org.kde.latte.indicator.plasma/package/ui/BackLayer.qml
new file mode 100644
index 000000000..8c0e2905c
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.plasma/package/ui/BackLayer.qml
@@ -0,0 +1,137 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import QtQuick 2.0
+
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+import org.kde.latte 0.2 as Latte
+
+PlasmaCore.FrameSvgItem {
+    id: frame
+    property string basePrefix: "normal"
+
+    imagePath: indicator.usePlasmaTabsStyle ? "widgets/tabbar" : "widgets/tasks"
+
+    prefix: {
+        if (indicator.usePlasmaTabsStyle) {
+            if (!indicator.isActive) {
+                return "";
+            }
+
+            if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !indicator.shared.reversed)
+                    || (plasmoid.location === PlasmaCore.Types.RightEdge && indicator.shared.reversed)) {
+                return "west-active-tab";
+            }
+
+            if ((plasmoid.location === PlasmaCore.Types.TopEdge && !indicator.shared.reversed)
+                    || (plasmoid.location === PlasmaCore.Types.BottomEdge && indicator.shared.reversed)) {
+                return "north-active-tab";
+            }
+
+            if ((plasmoid.location === PlasmaCore.Types.RightEdge && !indicator.shared.reversed)
+                    || (plasmoid.location === PlasmaCore.Types.LeftEdge && indicator.shared.reversed)) {
+                return "east-active-tab";
+            }
+
+            if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !indicator.shared.reversed)
+                    || (plasmoid.location === PlasmaCore.Types.TopEdge && indicator.shared.reversed)) {
+                return "south-active-tab";
+            }
+
+            return  "south-active-tab";
+        } else {
+            return taskPrefix(basePrefix);
+        }
+    }
+
+    function taskPrefix(prefix) {
+        var effectivePrefix;
+
+        if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !indicator.shared.reversed)
+                || (plasmoid.location === PlasmaCore.Types.RightEdge && indicator.shared.reversed)) {
+            effectivePrefix = "west-" + prefix;
+        }
+
+        if ((plasmoid.location === PlasmaCore.Types.TopEdge && !indicator.shared.reversed)
+                || (plasmoid.location === PlasmaCore.Types.BottomEdge && indicator.shared.reversed)) {
+            effectivePrefix = "north-" + prefix;
+        }
+
+        if ((plasmoid.location === PlasmaCore.Types.RightEdge && !indicator.shared.reversed)
+                || (plasmoid.location === PlasmaCore.Types.LeftEdge && indicator.shared.reversed)) {
+            effectivePrefix = "east-" + prefix;
+        }
+
+        if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !indicator.shared.reversed)
+                || (plasmoid.location === PlasmaCore.Types.TopEdge && indicator.shared.reversed)) {
+            effectivePrefix = "south-" + prefix;
+        }
+
+        return [effectivePrefix, prefix];
+    }
+
+    states: [
+        State {
+            name: "launcher"
+            when: indicator.isLauncher || (indicator.isApplet && !indicator.isActive)
+
+            PropertyChanges {
+                target: frame
+                basePrefix: ""
+            }
+        },
+        State {
+            name: "hovered"
+            when: indicator.isHovered && frame.hasElementPrefix("hover")
+
+            PropertyChanges {
+                target: frame
+                basePrefix: "hover"
+            }
+        },
+        State {
+            name: "attention"
+            when: indicator.inAttention
+
+            PropertyChanges {
+                target: frame
+                basePrefix: "attention"
+            }
+        },
+        State {
+            name: "minimized"
+            when: indicator.isMinimized
+
+            PropertyChanges {
+                target: frame
+                basePrefix: "minimized"
+            }
+        },
+        State {
+            name: "active"
+            when: indicator.isActive
+
+            PropertyChanges {
+                target: frame
+                basePrefix: "focus"
+            }
+        }
+    ]
+}
diff --git a/indicators/org.kde.latte.indicator.plasma/package/ui/FrontLayer.qml b/indicators/org.kde.latte.indicator.plasma/package/ui/FrontLayer.qml
new file mode 100644
index 000000000..9d483faf8
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.plasma/package/ui/FrontLayer.qml
@@ -0,0 +1,103 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import QtQuick 2.0
+
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+import org.kde.latte 0.2 as Latte
+
+Item {
+    anchors.fill: parent
+
+    PlasmaCore.Svg {
+        id: taskSvg
+        imagePath: "widgets/tasks"
+    }
+
+    Item {
+        id: iconBox
+        anchors.centerIn: parent
+        width: indicator.currentIconSize
+        height: width
+    }
+
+    PlasmaCore.SvgItem {
+        id: arrow
+
+        implicitWidth: 0.25 * iconBox.width
+        implicitHeight: implicitWidth
+
+        svg: taskSvg
+        elementId: elementForLocation(plasmoid.location)
+
+        function elementForLocation(location) {
+            switch (location) {
+            case PlasmaCore.Types.LeftEdge:
+                return "group-expander-left";
+            case PlasmaCore.Types.TopEdge:
+                return "group-expander-top";
+            case PlasmaCore.Types.RightEdge:
+                return "group-expander-right";
+            case PlasmaCore.Types.BottomEdge:
+            default:
+                return "group-expander-bottom";
+            }
+        }
+    }
+
+    states: [
+        State {
+            name: "bottom"
+            when: plasmoid.location === PlasmaCore.Types.BottomEdge
+            AnchorChanges {
+                target: arrow
+                anchors.top: undefined; anchors.left: undefined; anchors.right: undefined; anchors.bottom: arrow.parent.bottom;
+                anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
+            }
+        },
+        State {
+            name: "top"
+            when: plasmoid.location === PlasmaCore.Types.TopEdge
+            AnchorChanges {
+                target: arrow
+                anchors.top: arrow.parent.top; anchors.left: undefined; anchors.right: undefined; anchors.bottom: undefined;
+                anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
+            }
+        },
+        State {
+            name: "left"
+            when: plasmoid.location === PlasmaCore.Types.LeftEdge
+            AnchorChanges {
+                target: arrow
+                anchors.top: undefined; anchors.left: arrow.parent.left; anchors.right: undefined; anchors.bottom: undefined;
+                anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
+            }
+        },
+        State {
+            name: "right"
+            when: plasmoid.location === PlasmaCore.Types.RightEdge
+            AnchorChanges {
+                target: arrow
+                anchors.top: undefined; anchors.left: undefined; anchors.right: arrow.parent.right; anchors.bottom: undefined;
+                anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
+            }
+        }
+    ]
+}
diff --git a/containment/package/contents/ui/indicators/options/Common.qml b/indicators/org.kde.latte.indicator.plasma/package/ui/main.qml
similarity index 55%
rename from containment/package/contents/ui/indicators/options/Common.qml
rename to indicators/org.kde.latte.indicator.plasma/package/ui/main.qml
index f52a308ed..08cafdcaf 100644
--- a/containment/package/contents/ui/indicators/options/Common.qml
+++ b/indicators/org.kde.latte.indicator.plasma/package/ui/main.qml
@@ -1,5 +1,5 @@
 /*
-*  Copyright 2019 Michail Vourlakos <mvourlakos@gmail.com>
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
 *
 *  This file is part of Latte-Dock
 *
@@ -17,19 +17,32 @@
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-import QtQuick 2.7
+import QtQuick 2.0
 
-import org.kde.plasma.plasmoid 2.0
 import org.kde.plasma.core 2.0 as PlasmaCore
 
 import org.kde.latte 0.2 as Latte
+import org.kde.latte.components 1.0 as LatteComponents
 
-Item{
-    id: common
+LatteComponents.IndicatorItem {
+    readonly property bool providesFrontLayer: true
 
-    readonly property bool indicatorsEnabled: plasmoid.configuration.indicatorsEnabled
-    readonly property bool indicatorsForApplets: plasmoid.configuration.indicatorsForApplets
-    readonly property bool reversedEnabled: plasmoid.configuration.reverseLinesPosition
+    //! Background Layer
+    Loader{
+        id: backLayer
+        anchors.fill: parent
+        active: attributes.isBackground
+
+        sourceComponent: BackLayer{}
+    }
+
+    //! Foreground Layer to draw arrows
+    Loader{
+        id: frontLayer
+        anchors.fill: parent
+        active: attributes.isForeground && !indicator.isApplet && indicator.isGroup
+
+        sourceComponent: FrontLayer{}
+    }
 
-    readonly property int indicatorStyle: plasmoid.configuration.indicatorStyle
 }
diff --git a/indicators/org.kde.latte.indicator.unity/metadata.desktop b/indicators/org.kde.latte.indicator.unity/metadata.desktop
new file mode 100644
index 000000000..ae20b6297
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.unity/metadata.desktop
@@ -0,0 +1,17 @@
+[Desktop Entry]
+Name=Unity
+Comment=Latte Unity style indicator
+
+Type=Service
+Icon=latte-dock
+X-Plasma-API=declarativeappletscript
+X-Latte-MainScript=ui/main.qml
+
+X-KDE-PluginInfo-Author=Michail Vourlakos
+X-KDE-PluginInfo-Email=mvourlakos@gmail.com
+X-KDE-PluginInfo-Name=org.kde.latte.indicator.unity
+X-KDE-PluginInfo-Version=0.1
+X-KDE-PluginInfo-Category=Windows and Tasks
+X-KDE-PluginInfo-License=GPL v2+
+X-KDE-PluginInfo-EnabledByDefault=true
+ 
diff --git a/indicators/org.kde.latte.indicator.unity/package/ui/BackLayer.qml b/indicators/org.kde.latte.indicator.unity/package/ui/BackLayer.qml
new file mode 100644
index 000000000..75ff89fe0
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.unity/package/ui/BackLayer.qml
@@ -0,0 +1,160 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+Item{
+    Item{
+        id: rectangleItem
+        width: indicator.isTask ? Math.min(parent.width, parent.height) : parent.width
+        height: indicator.isTask ? width : parent.height
+        anchors.centerIn: parent
+
+        property bool isActive: indicator.isActive || (indicator.isWindow && indicator.hasActive)
+        readonly property int size: Math.min(parent.width, parent.height)
+
+        Rectangle {
+            id: unityRect
+            anchors.fill: parent
+            visible: indicator.isActive || (indicator.isWindow && indicator.hasShown)
+
+            radius: indicator.currentIconSize / 12
+            color: indicator.backgroundColor
+            clip: true
+        }
+
+        RadialGradient{
+            id: glowGradient
+            anchors.verticalCenter: parent.top
+            anchors.horizontalCenter: parent.horizontalCenter
+            width: parent.width - unityRect.anchors.margins * 2 - 1
+            height: (width * 0.85) - unityRect.anchors.margins * 2 - 1
+            visible: false
+
+            gradient: Gradient {
+                GradientStop { position: 0.0;
+                    color: {
+                        if (indicator.isMinimized) {
+                            return "#aafcfcfc";
+                        }
+
+                        return indicator.glowColor;
+                    }
+                }
+                GradientStop { position: 0.6; color: "transparent" }
+            }
+            //! States
+            states: [
+                State {
+                    name: "top"
+                    when: !indicator.shared.reversed
+
+                    AnchorChanges {
+                        target: glowGradient
+                        anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.top}
+                    }
+                },
+                State {
+                    name: "bottom"
+                    when: indicator.shared.reversed
+
+                    AnchorChanges {
+                        target: glowGradient
+                        anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.bottom}
+                    }
+                }
+            ]
+        }
+
+        Item {
+            id: gradientMask
+            anchors.fill: glowGradient
+
+            Rectangle {
+                id: glowMaskRect
+                width: glowGradient.width
+                height: glowGradient.height / 2
+                radius: unityRect.radius
+
+                //! States
+                states: [
+                    State {
+                        name: "top"
+                        when: !indicator.shared.reversed
+
+                        AnchorChanges {
+                            target: glowMaskRect
+                            anchors{bottom: undefined; top: parent.verticalCenter;}
+                        }
+                        PropertyChanges{
+                            target: gradientMask
+                            anchors{bottomMargin: undefined; topMargin: unityRect.anchors.margins}
+                        }
+                    },
+                    State {
+                        name: "bottom"
+                        when: indicator.shared.reversed
+
+                        AnchorChanges {
+                            target: glowMaskRect
+                            anchors{bottom: parent.verticalCenter; top: undefined;}
+                        }
+                        PropertyChanges{
+                            target: gradientMask
+                            anchors{bottomMargin: unityRect.anchors.margins; topMargin: undefined}
+                        }
+                    }
+                ]
+            }
+
+            visible: false
+        }
+
+        OpacityMask {
+            anchors.fill: glowGradient
+            source: glowGradient
+            maskSource: gradientMask
+            visible: unityRect.visible || borderRectangle.visible
+        }
+
+        Rectangle {
+            id: borderRectangle
+            anchors.fill: parent
+            visible: (indicator.isTask && indicator.isWindow) || (indicator.isApplet && indicator.isActive)
+            color: "transparent"
+            border.width: 1
+            border.color: "#303030"
+            radius: unityRect.radius
+            clip: true
+
+            Rectangle {
+                anchors.fill: parent
+                anchors.margins: parent.border.width
+                radius: unityRect.radius
+                color: "transparent"
+                border.width: 1
+                border.color: "#25dedede"
+            }
+        }
+    }
+}
diff --git a/indicators/org.kde.latte.indicator.unity/package/ui/FrontLayer.qml b/indicators/org.kde.latte.indicator.unity/package/ui/FrontLayer.qml
new file mode 100644
index 000000000..8154712dd
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.unity/package/ui/FrontLayer.qml
@@ -0,0 +1,206 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+Item {
+    anchors.fill: parent
+
+    Row {
+        id: upperIndicators
+        spacing: 2
+        readonly property bool alwaysActive: true
+        readonly property bool reversed: true
+
+        Repeater {
+            model: indicator.isTask && (indicator.isActive || indicator.hasActive) ? 1 : 0
+            delegate: triangleComponent
+        }
+    }
+
+    Grid {
+        id: lowerIndicators
+        rows: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? 1 : Math.min(3, indicator.windowsCount)
+        columns: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Math.min(3, indicator.windowsCount) : 1
+        rowSpacing: 2
+        columnSpacing: 2
+
+        readonly property bool alwaysActive: false
+        readonly property bool reversed: false
+
+        Repeater {
+            model: Math.min(3, indicator.windowsCount)
+            delegate: triangleComponent
+        }
+    }
+
+
+    //! Triangle Indicator Component
+    Component {
+        id: triangleComponent
+        Canvas {
+            id: canvas
+            width: indicator.currentIconSize / 6
+            height: width
+
+            rotation: {
+                if (!parent.reversed) {
+                    if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
+                        return 0;
+                    } else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
+                        return 90;
+                    } else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
+                        return 180;
+                    } else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
+                        return 270;
+                    }
+                } else {
+                    if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
+                        return 180;
+                    } else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
+                        return 270;
+                    } else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
+                        return 0;
+                    } else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
+                        return 90;
+                    }
+                }
+
+                return 0;
+            }
+
+            property bool fillTriangle: {
+                if (!parent.alwaysActive && indicator.windowsMinimizedCount!==0
+                        && ((index < maxDrawnMinimizedWindows)
+                            || (indicator.windowsCount === indicator.windowsMinimizedCount))) {
+                    return false;
+                }
+
+                return true;
+            }
+
+            readonly property int lineWidth: 2
+
+            onFillTriangleChanged: requestPaint();
+
+            Connections {
+                target: root
+                onActiveColorChanged: canvas.requestPaint();
+                onBackgroundColorChanged: canvas.requestPaint();
+                onOutlineColorChanged: canvas.requestPaint();
+            }
+
+
+            onPaint: {
+                var ctx = getContext('2d');
+                ctx.clearRect(0, 0, canvas.width, canvas.height);
+                ctx.strokeStyle = root.outlineColor;
+                ctx.lineWidth = lineWidth;
+
+                ctx.beginPath();
+                ctx.moveTo(0, canvas.height);
+                ctx.lineTo(canvas.width/2, 0);
+                ctx.lineTo(canvas.width, canvas.height);
+                ctx.lineTo(0, canvas.height);
+                ctx.closePath();
+                ctx.stroke();
+
+                ctx.strokeStyle = root.activeColor;
+                ctx.fillStyle = fillTriangle ? root.activeColor : root.backgroundColor;
+
+                ctx.beginPath();
+                ctx.moveTo(lineWidth, canvas.height - lineWidth);
+                ctx.lineTo(canvas.width/2, lineWidth);
+                ctx.lineTo(canvas.width - lineWidth, canvas.height - lineWidth);
+                ctx.lineTo(lineWidth, canvas.height - lineWidth);
+                ctx.closePath();
+                ctx.stroke();
+                ctx.fill();
+            }
+        }
+    }
+
+    //! States
+    states: [
+        State {
+            name: "bottom"
+            when: (plasmoid.location === PlasmaCore.Types.BottomEdge)
+
+            AnchorChanges {
+                target: lowerIndicators
+                anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
+                    horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
+            }
+            AnchorChanges {
+                target: upperIndicators
+                anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
+                    horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
+            }
+        },
+        State {
+            name: "top"
+            when: (plasmoid.location === PlasmaCore.Types.TopEdge)
+
+            AnchorChanges {
+                target: lowerIndicators
+                anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
+                    horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
+            }
+            AnchorChanges {
+                target: upperIndicators
+                anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
+                    horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
+            }
+        },
+        State {
+            name: "left"
+            when: (plasmoid.location === PlasmaCore.Types.LeftEdge)
+
+            AnchorChanges {
+                target: lowerIndicators
+                anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
+                    horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
+            }
+            AnchorChanges {
+                target: upperIndicators
+                anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
+                    horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
+            }
+        },
+        State {
+            name: "right"
+            when: (plasmoid.location === PlasmaCore.Types.RightEdge)
+
+            AnchorChanges {
+                target: lowerIndicators
+                anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
+                    horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
+            }
+            AnchorChanges {
+                target: upperIndicators
+                anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
+                    horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
+            }
+        }
+    ]
+}
diff --git a/indicators/org.kde.latte.indicator.unity/package/ui/main.qml b/indicators/org.kde.latte.indicator.unity/package/ui/main.qml
new file mode 100644
index 000000000..46e0c08a3
--- /dev/null
+++ b/indicators/org.kde.latte.indicator.unity/package/ui/main.qml
@@ -0,0 +1,71 @@
+/*
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
+*
+*  This file is part of Latte-Dock
+*
+*  Latte-Dock 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.
+*
+*  Latte-Dock is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  You should have received a copy of the GNU General Public License
+*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+import org.kde.plasma.plasmoid 2.0
+import org.kde.plasma.core 2.0 as PlasmaCore
+
+import org.kde.latte.components 1.0 as LatteComponents
+
+LatteComponents.IndicatorItem {
+    id: root
+
+    readonly property bool needsIconColors: true
+    readonly property bool providesFrontLayer: true
+
+    readonly property int thickness: plasmoid.formFactor === PlasmaCore.Types.Vertical ? width : height
+
+    readonly property int shownWindows: indicator.windowsCount - indicator.windowsMinimizedCount
+    readonly property int maxDrawnMinimizedWindows: shownWindows > 0 ? Math.min(indicator.windowsMinimizedCount,2) : 3
+
+    readonly property real backColorBrightness: colorBrightness(indicator.palette.backgroundColor)
+    readonly property color activeColor: indicator.palette.buttonFocusColor
+    readonly property color outlineColor: backColorBrightness < 127 ? indicator.palette.backgroundColor : indicator.palette.textColor
+    readonly property color backgroundColor: indicator.palette.backgroundColor
+
+    function colorBrightness(color) {
+        return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
+    }
+
+    // formula for brightness according to:
+    // https://www.w3.org/TR/AERT/#color-contrast
+    function colorBrightnessFromRGB(r, g, b) {
+        return (r * 299 + g * 587 + b * 114) / 1000
+    }
+
+    //! Background Layer
+    Loader{
+        id: backLayer
+        anchors.fill: parent
+        active: attributes.isBackground
+
+        sourceComponent: BackLayer{}
+    }
+
+    //! Foreground Layer to draw Triangles
+    Loader{
+        id: frontLayer
+        anchors.fill: parent
+        active: attributes.isForeground
+
+        sourceComponent:FrontLayer{}
+    }
+}
diff --git a/liblatte2/CMakeLists.txt b/liblatte2/CMakeLists.txt
index 8c31f0d59..e6012e29e 100644
--- a/liblatte2/CMakeLists.txt
+++ b/liblatte2/CMakeLists.txt
@@ -29,6 +29,4 @@ endif()
 
 install(TARGETS latte2plugin DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte)
 
-install(DIRECTORY qml/ DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte)
-
 install(FILES qmldir DESTINATION ${KDE_INSTALL_QMLDIR}/org/kde/latte)
diff --git a/liblatte2/qml/code/ColorizerTools.js b/liblatte2/qml/code/ColorizerTools.js
deleted file mode 100644
index f409bffac..000000000
--- a/liblatte2/qml/code/ColorizerTools.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-*  Copyright 2018 Michail Vourlakos <mvourlakos@gmail.com>
-*
-*  This file is part of Latte-Dock
-*
-*  Latte-Dock 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.
-*
-*  Latte-Dock is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  You should have received a copy of the GNU General Public License
-*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-function colorBrightness(color) {
-    return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
-}
-
-// formula for brightness according to:
-// https://www.w3.org/TR/AERT/#color-contrast
-function colorBrightnessFromRGB(r, g, b) {
-    return (r * 299 + g * 587 + b * 114) / 1000
-}
-
-function colorLuminas(color) {
-    return colorLuminasFromRGB(color.r, color.g, color.b)
-}
-
-// formula for luminance according to:
-// https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
-function colorLuminasFromRGB(r, g, b) {
-    var rS =  (r <= 0.03928) ? ( r / 12.92) : Math.pow( ((r + 0.055) / 1.055), 2.4 );
-    var gS =  (g <= 0.03928) ? ( g / 12.92) : Math.pow( ((g + 0.055) / 1.055), 2.4 );
-    var bS =  (b <= 0.03928) ? ( b / 12.92) : Math.pow( ((b + 0.055) / 1.055), 2.4 );
-
-    return 0.2126*rS + 0.7152*gS + 0.0722*bS;
-}
diff --git a/liblatte2/qml/indicators/PlasmaIndicator.qml b/liblatte2/qml/indicators/PlasmaIndicator.qml
deleted file mode 100644
index b82ecd35a..000000000
--- a/liblatte2/qml/indicators/PlasmaIndicator.qml
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
-*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
-*
-*  This file is part of Latte-Dock
-*
-*  Latte-Dock 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.
-*
-*  Latte-Dock is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  You should have received a copy of the GNU General Public License
-*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-import QtQuick 2.0
-
-import org.kde.plasma.core 2.0 as PlasmaCore
-
-import org.kde.latte 0.2 as Latte
-
-Item {
-    readonly property Item options: parent.manager
-    readonly property Item rootItem: parent
-
-    readonly property bool providesFrontLayer: true
-
-    //! Background Layer
-    Loader{
-        id: backLayer
-        anchors.fill: parent
-        active: rootItem.isBackLayer
-
-        sourceComponent: PlasmaCore.FrameSvgItem {
-            id: frame
-            property string basePrefix: "normal"
-
-            imagePath: options.explicit.usePlasmaTabsStyle ? "widgets/tabbar" : "widgets/tasks"
-
-            prefix: {
-                if (options.explicit.usePlasmaTabsStyle) {
-                    if (!options.isActive) {
-                        return "";
-                    }
-
-                    if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !options.common.reversedEnabled)
-                            || (plasmoid.location === PlasmaCore.Types.RightEdge && options.common.reversedEnabled)) {
-                        return "west-active-tab";
-                    }
-
-                    if ((plasmoid.location === PlasmaCore.Types.TopEdge && !options.common.reversedEnabled)
-                            || (plasmoid.location === PlasmaCore.Types.BottomEdge && options.common.reversedEnabled)) {
-                        return "north-active-tab";
-                    }
-
-                    if ((plasmoid.location === PlasmaCore.Types.RightEdge && !options.common.reversedEnabled)
-                            || (plasmoid.location === PlasmaCore.Types.LeftEdge && options.common.reversedEnabled)) {
-                        return "east-active-tab";
-                    }
-
-                    if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !options.common.reversedEnabled)
-                            || (plasmoid.location === PlasmaCore.Types.TopEdge && options.common.reversedEnabled)) {
-                        return "south-active-tab";
-                    }
-
-                    return  "south-active-tab";
-                } else {
-                    return taskPrefix(basePrefix);
-                }
-            }
-
-            function taskPrefix(prefix) {
-                var effectivePrefix;
-
-                if ((plasmoid.location === PlasmaCore.Types.LeftEdge && !options.common.reversedEnabled)
-                        || (plasmoid.location === PlasmaCore.Types.RightEdge && options.common.reversedEnabled)) {
-                    effectivePrefix = "west-" + prefix;
-                }
-
-                if ((plasmoid.location === PlasmaCore.Types.TopEdge && !options.common.reversedEnabled)
-                        || (plasmoid.location === PlasmaCore.Types.BottomEdge && options.common.reversedEnabled)) {
-                    effectivePrefix = "north-" + prefix;
-                }
-
-                if ((plasmoid.location === PlasmaCore.Types.RightEdge && !options.common.reversedEnabled)
-                        || (plasmoid.location === PlasmaCore.Types.LeftEdge && options.common.reversedEnabled)) {
-                    effectivePrefix = "east-" + prefix;
-                }
-
-                if ((plasmoid.location === PlasmaCore.Types.BottomEdge && !options.common.reversedEnabled)
-                        || (plasmoid.location === PlasmaCore.Types.TopEdge && options.common.reversedEnabled)) {
-                    effectivePrefix = "south-" + prefix;
-                }
-
-                return [effectivePrefix, prefix];
-            }
-
-            states: [
-                State {
-                    name: "launcher"
-                    when: options.isLauncher || (options.isApplet && !options.isActive)
-
-                    PropertyChanges {
-                        target: frame
-                        basePrefix: ""
-                    }
-                },
-                State {
-                    name: "hovered"
-                    when: options.isHovered && frame.hasElementPrefix("hover")
-
-                    PropertyChanges {
-                        target: frame
-                        basePrefix: "hover"
-                    }
-                },
-                State {
-                    name: "attention"
-                    when: options.inAttention
-
-                    PropertyChanges {
-                        target: frame
-                        basePrefix: "attention"
-                    }
-                },
-                State {
-                    name: "minimized"
-                    when: options.isMinimized
-
-                    PropertyChanges {
-                        target: frame
-                        basePrefix: "minimized"
-                    }
-                },
-                State {
-                    name: "active"
-                    when: options.isActive
-
-                    PropertyChanges {
-                        target: frame
-                        basePrefix: "focus"
-                    }
-                }
-            ]
-        }
-    }
-
-    //! Foreground Layer to draw arrows
-    Loader{
-        id: frontLayer
-        anchors.fill: parent
-        active: !rootItem.isBackLayer && !options.isApplet && options.isGroup
-
-        sourceComponent: Item {
-            anchors.fill: parent
-
-            PlasmaCore.Svg {
-                id: taskSvg
-                imagePath: "widgets/tasks"
-            }
-
-            Item {
-                id: iconBox
-                anchors.centerIn: parent
-                width: options.currentIconSize
-                height: width
-            }
-
-            PlasmaCore.SvgItem {
-                id: arrow
-
-                implicitWidth: 0.25 * iconBox.width
-                implicitHeight: implicitWidth
-
-                svg: taskSvg
-                elementId: elementForLocation(plasmoid.location)
-
-                function elementForLocation(location) {
-                    switch (location) {
-                    case PlasmaCore.Types.LeftEdge:
-                        return "group-expander-left";
-                    case PlasmaCore.Types.TopEdge:
-                        return "group-expander-top";
-                    case PlasmaCore.Types.RightEdge:
-                        return "group-expander-right";
-                    case PlasmaCore.Types.BottomEdge:
-                    default:
-                        return "group-expander-bottom";
-                    }
-                }
-            }
-
-            states: [
-                State {
-                    name: "bottom"
-                    when: plasmoid.location == PlasmaCore.Types.BottomEdge
-                    AnchorChanges {
-                        target: arrow
-                        anchors.top: undefined; anchors.left: undefined; anchors.right: undefined; anchors.bottom: arrow.parent.bottom;
-                        anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
-                    }
-                },
-                State {
-                    name: "top"
-                    when: plasmoid.location == PlasmaCore.Types.TopEdge
-                    AnchorChanges {
-                        target: arrow
-                        anchors.top: arrow.parent.top; anchors.left: undefined; anchors.right: undefined; anchors.bottom: undefined;
-                        anchors.horizontalCenter: iconBox.horizontalCenter; anchors.verticalCenter: undefined;
-                    }
-                },
-                State {
-                    name: "left"
-                    when: plasmoid.location == PlasmaCore.Types.LeftEdge
-                    AnchorChanges {
-                        target: arrow
-                        anchors.top: undefined; anchors.left: arrow.parent.left; anchors.right: undefined; anchors.bottom: undefined;
-                        anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
-                    }
-                },
-                State {
-                    name: "right"
-                    when: plasmoid.location == PlasmaCore.Types.RightEdge
-                    AnchorChanges {
-                        target: arrow
-                        anchors.top: undefined; anchors.left: undefined; anchors.right: arrow.parent.right; anchors.bottom: undefined;
-                        anchors.horizontalCenter: undefined; anchors.verticalCenter: iconBox.verticalCenter;
-                    }
-                }
-            ]
-        }
-    }
-
-}
diff --git a/liblatte2/qml/indicators/UnityIndicator.qml b/liblatte2/qml/indicators/UnityIndicator.qml
deleted file mode 100644
index 23137abb3..000000000
--- a/liblatte2/qml/indicators/UnityIndicator.qml
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
-*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
-*
-*  This file is part of Latte-Dock
-*
-*  Latte-Dock 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.
-*
-*  Latte-Dock is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-*  GNU General Public License for more details.
-*
-*  You should have received a copy of the GNU General Public License
-*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-import QtQuick 2.0
-import QtGraphicalEffects 1.0
-
-import org.kde.plasma.plasmoid 2.0
-import org.kde.plasma.core 2.0 as PlasmaCore
-
-import org.kde.latte 0.2 as Latte
-
-import "../code/ColorizerTools.js" as ColorizerTools
-
-Item{
-    id: indicatorItem
-    readonly property Item options: parent.manager
-    readonly property Item rootItem: parent
-
-    readonly property bool needsIconColors: true
-    readonly property bool providesFrontLayer: true
-
-    readonly property int thickness: plasmoid.formFactor === PlasmaCore.Types.Vertical ? width : height
-
-    readonly property int shownWindows: options.windowsCount - options.windowsMinimizedCount
-    readonly property int maxDrawnMinimizedWindows: shownWindows > 0 ? Math.min(options.windowsMinimizedCount,2) : 3
-
-    readonly property real backColorBrightness: ColorizerTools.colorBrightness(theme.backgroundColor)
-    readonly property color backgroundColor: backColorBrightness < 127 ? theme.backgroundColor : theme.textColor
-
-    //! Background Layer
-    Loader{
-        id: backLayer
-        anchors.fill: parent
-        active: rootItem.isBackLayer
-
-        sourceComponent: Item{
-            Item{
-                id: rectangleItem
-                width: options.isTask ? Math.min(parent.width, parent.height) : parent.width
-                height: options.isTask ? width : parent.height
-                anchors.centerIn: parent
-
-                property bool isActive: options.isActive || (options.isWindow && options.hasActive)
-                readonly property int size: Math.min(parent.width, parent.height)
-
-                Rectangle {
-                    id: unityRect
-                    anchors.fill: parent
-                    visible: options.isActive || (options.isWindow && options.hasShown)
-
-                    radius: options.currentIconSize / 12
-                    color: options.backgroundColor
-                    clip: true
-                }
-
-                RadialGradient{
-                    id: glowGradient
-                    anchors.verticalCenter: parent.top
-                    anchors.horizontalCenter: parent.horizontalCenter
-                    width: parent.width - unityRect.anchors.margins * 2 - 1
-                    height: (width * 0.85) - unityRect.anchors.margins * 2 - 1
-                    visible: false
-
-                    gradient: Gradient {
-                        GradientStop { position: 0.0;
-                            color: {
-                                if (options.isMinimized) {
-                                    return "#aafcfcfc";
-                                }
-
-                                return options.glowColor;
-                            }
-                        }
-                        GradientStop { position: 0.6; color: "transparent" }
-                    }
-                    //! States
-                    states: [
-                        State {
-                            name: "top"
-                            when: !options.common.reversedEnabled
-
-                            AnchorChanges {
-                                target: glowGradient
-                                anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.top}
-                            }
-                        },
-                        State {
-                            name: "bottom"
-                            when: options.common.reversedEnabled
-
-                            AnchorChanges {
-                                target: glowGradient
-                                anchors{horizontalCenter:parent.horizontalCenter; verticalCenter:parent.bottom}
-                            }
-                        }
-                    ]
-                }
-
-                Item {
-                    id: gradientMask
-                    anchors.fill: glowGradient
-
-                    Rectangle {
-                        id: glowMaskRect
-                        width: glowGradient.width
-                        height: glowGradient.height / 2
-                        radius: unityRect.radius
-
-                        //! States
-                        states: [
-                            State {
-                                name: "top"
-                                when: !options.common.reversedEnabled
-
-                                AnchorChanges {
-                                    target: glowMaskRect
-                                    anchors{bottom: undefined; top: parent.verticalCenter;}
-                                }
-                                PropertyChanges{
-                                    target: gradientMask
-                                    anchors{bottomMargin: undefined; topMargin: unityRect.anchors.margins}
-                                }
-                            },
-                            State {
-                                name: "bottom"
-                                when: options.common.reversedEnabled
-
-                                AnchorChanges {
-                                    target: glowMaskRect
-                                    anchors{bottom: parent.verticalCenter; top: undefined;}
-                                }
-                                PropertyChanges{
-                                    target: gradientMask
-                                    anchors{bottomMargin: unityRect.anchors.margins; topMargin: undefined}
-                                }
-                            }
-                        ]
-                    }
-
-                    visible: false
-                }
-
-                OpacityMask {
-                    anchors.fill: glowGradient
-                    source: glowGradient
-                    maskSource: gradientMask
-                    visible: unityRect.visible || borderRectangle.visible
-                }
-
-                Rectangle {
-                    id: borderRectangle
-                    anchors.fill: parent
-                    visible: (options.isTask && options.isWindow) || (options.isApplet && options.isActive)
-                    color: "transparent"
-                    border.width: 1
-                    border.color: "#303030"
-                    radius: unityRect.radius
-                    clip: true
-
-                    Rectangle {
-                        anchors.fill: parent
-                        anchors.margins: parent.border.width
-                        radius: unityRect.radius
-                        color: "transparent"
-                        border.width: 1
-                        border.color: "#25dedede"
-                    }
-                }
-            }
-        }
-    }
-
-
-    //! Foreground Layer to draw Triangles
-    Loader{
-        id: frontLayer
-        anchors.fill: parent
-        active: !rootItem.isBackLayer
-
-        sourceComponent: Item {
-            anchors.fill: parent
-
-            Row {
-                id: upperIndicators
-                spacing: 2
-                readonly property bool alwaysActive: true
-                readonly property bool reversed: true
-
-                Repeater {
-                    model: options.isTask && (options.isActive || options.hasActive) ? 1 : 0
-                    delegate: triangleComponent
-                }
-            }
-
-            Grid {
-                id: lowerIndicators
-                rows: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? 1 : Math.min(3, options.windowsCount)
-                columns: plasmoid.formFactor === PlasmaCore.Types.Horizontal ? Math.min(3, options.windowsCount) : 1
-                rowSpacing: 2
-                columnSpacing: 2
-
-                readonly property bool alwaysActive: false
-                readonly property bool reversed: false
-
-                Repeater {
-                    model: Math.min(3, options.windowsCount)
-                    delegate: triangleComponent
-                }
-            }
-
-
-            //! Triangle Indicator Component
-            Component {
-                id: triangleComponent
-                Canvas {
-                    id: canvas
-                    width: options.currentIconSize / 6
-                    height: width
-
-                    rotation: {
-                        if (!parent.reversed) {
-                            if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
-                                return 0;
-                            } else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
-                                return 90;
-                            } else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
-                                return 180;
-                            } else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
-                                return 270;
-                            }
-                        } else {
-                            if (plasmoid.location === PlasmaCore.Types.BottomEdge) {
-                                return 180;
-                            } else if (plasmoid.location === PlasmaCore.Types.LeftEdge) {
-                                return 270;
-                            } else if (plasmoid.location === PlasmaCore.Types.TopEdge) {
-                                return 0;
-                            } else if (plasmoid.location === PlasmaCore.Types.RightEdge) {
-                                return 90;
-                            }
-                        }
-
-                        return 0;
-                    }
-
-                    property color drawColor:  theme.buttonFocusColor;
-                    property bool fillTriangle: {
-                        if (!parent.alwaysActive && options.windowsMinimizedCount!==0
-                                && ((index < maxDrawnMinimizedWindows)
-                                    || (options.windowsCount === options.windowsMinimizedCount))) {
-                            return false;
-                        }
-
-                        return true;
-                    }
-
-                    readonly property int lineWidth: 2
-
-                    onFillTriangleChanged: requestPaint();
-                    onDrawColorChanged: requestPaint();
-
-                    onPaint: {
-                        var ctx = getContext('2d');
-                        ctx.clearRect(0, 0, canvas.width, canvas.height);
-                        ctx.strokeStyle = indicatorItem.backgroundColor;
-                        ctx.lineWidth = lineWidth;
-
-                        ctx.beginPath();
-                        ctx.moveTo(0, canvas.height);
-                        ctx.lineTo(canvas.width/2, 0);
-                        ctx.lineTo(canvas.width, canvas.height);
-                        ctx.lineTo(0, canvas.height);
-                        ctx.closePath();
-                        ctx.stroke();
-
-                        ctx.strokeStyle = drawColor;
-                        ctx.fillStyle = fillTriangle ? drawColor : indicatorItem.backgroundColor;
-
-                        ctx.beginPath();
-                        ctx.moveTo(lineWidth, canvas.height - lineWidth);
-                        ctx.lineTo(canvas.width/2, lineWidth);
-                        ctx.lineTo(canvas.width - lineWidth, canvas.height - lineWidth);
-                        ctx.lineTo(lineWidth, canvas.height - lineWidth);
-                        ctx.closePath();
-                        ctx.stroke();
-                        ctx.fill();
-                    }
-                }
-            }
-
-            //! States
-            states: [
-                State {
-                    name: "bottom"
-                    when: (plasmoid.location === PlasmaCore.Types.BottomEdge)
-
-                    AnchorChanges {
-                        target: lowerIndicators
-                        anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
-                            horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
-                    }
-                    AnchorChanges {
-                        target: upperIndicators
-                        anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
-                            horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
-                    }
-                },
-                State {
-                    name: "top"
-                    when: (plasmoid.location === PlasmaCore.Types.TopEdge)
-
-                    AnchorChanges {
-                        target: lowerIndicators
-                        anchors{ top:parent.top; bottom:undefined; left:undefined; right:undefined;
-                            horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
-                    }
-                    AnchorChanges {
-                        target: upperIndicators
-                        anchors{ top:undefined; bottom:parent.bottom; left:undefined; right:undefined;
-                            horizontalCenter:parent.horizontalCenter; verticalCenter:undefined}
-                    }
-                },
-                State {
-                    name: "left"
-                    when: (plasmoid.location === PlasmaCore.Types.LeftEdge)
-
-                    AnchorChanges {
-                        target: lowerIndicators
-                        anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
-                            horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
-                    }
-                    AnchorChanges {
-                        target: upperIndicators
-                        anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
-                            horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
-                    }
-                },
-                State {
-                    name: "right"
-                    when: (plasmoid.location === PlasmaCore.Types.RightEdge)
-
-                    AnchorChanges {
-                        target: lowerIndicators
-                        anchors{ top:undefined; bottom:undefined; left:undefined; right:parent.right;
-                            horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
-                    }
-                    AnchorChanges {
-                        target: upperIndicators
-                        anchors{ top:undefined; bottom:undefined; left:parent.left; right:undefined;
-                            horizontalCenter:undefined; verticalCenter:parent.verticalCenter}
-                    }
-                }
-            ]
-        }
-    }
-}
diff --git a/liblatte2/qmldir b/liblatte2/qmldir
index edf32df61..bed7b8b11 100644
--- a/liblatte2/qmldir
+++ b/liblatte2/qmldir
@@ -1,6 +1,2 @@
 module org.kde.latte
 plugin latte2plugin
-
-LatteIndicator 0.2 indicators/LatteIndicator.qml
-PlasmaIndicator 0.2 indicators/PlasmaIndicator.qml
-UnityIndicator 0.2 indicators/UnityIndicator.qml
diff --git a/plasmoid/package/contents/ui/indicators/Manager.qml b/plasmoid/package/contents/ui/indicators/Manager.qml
index 3367e318a..99a8bbd18 100644
--- a/plasmoid/package/contents/ui/indicators/Manager.qml
+++ b/plasmoid/package/contents/ui/indicators/Manager.qml
@@ -24,57 +24,35 @@ import org.kde.plasma.core 2.0 as PlasmaCore
 
 import org.kde.latte 0.2 as Latte
 
-import "options" as Options
+import "options" as IndicatorOptions
+import "styles" as IndicatorStyles
 import "../task/indicator" as TaskIndicator
 
 Item{
     id: managerIndicator
 
-    readonly property Item common: commonOptions
-    readonly property Item explicit: explicitOptions
+    readonly property Item configuration: explicitOptions
+
+    readonly property bool isEnabled: true
+    readonly property bool reversed: plasmoid.configuration.reverseLinesPosition
+    readonly property string type: "org.kde.latte.indicator.default"
 
     readonly property Component indicatorComponent: latteStyleIndicator
 
     readonly property Item info: Item{
-        readonly property bool needsIconColors: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("needsIconColors")
-                                                && metricsLoader.item.needsIconColors
-        readonly property bool providesFrontLayer: metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("providesFrontLayer")
-                                                   && metricsLoader.item.providesFrontLayer
-
-        readonly property int extraMaskThickness: {
-            if (metricsLoader.active && metricsLoader.item && metricsLoader.item.hasOwnProperty("extraMaskThickness")) {
-                return metricsLoader.item.extraMaskThickness;
-            }
-
-            return 0;
-        }
-    }
-
-    Options.Common {
-        id: commonOptions
+        readonly property bool needsIconColors: false
+        readonly property bool providesFrontLayer: false
+        readonly property int extraMaskThickness: 0
     }
 
-    Options.Latte {
+    IndicatorOptions.Latte {
         id : explicitOptions
     }
 
     //! Indicators Components
     Component {
         id: latteStyleIndicator
-        Latte.LatteIndicator{}
-    }
-
-    //! Metrics and values provided from an invisible indicator
-    Loader{
-        id: metricsLoader
-        opacity: 0
-
-        readonly property bool isBackLayer: true
-        readonly property Item manager: TaskIndicator.Manager{
-            taskIsValid: false
-        }
-
-        sourceComponent: managerIndicator.indicatorComponent
+        IndicatorStyles.LatteIndicator{}
     }
 }
 
diff --git a/plasmoid/package/contents/ui/indicators/options/Latte.qml b/plasmoid/package/contents/ui/indicators/options/Latte.qml
index 19149fd31..1d725aa73 100644
--- a/plasmoid/package/contents/ui/indicators/options/Latte.qml
+++ b/plasmoid/package/contents/ui/indicators/options/Latte.qml
@@ -27,13 +27,13 @@ import org.kde.latte 0.2 as Latte
 Item{
     readonly property string styleName: "Latte"
 
-    readonly property bool dotsOnActive: plasmoid.configuration.dotsOnActive
-    readonly property bool multiColorEnabled: plasmoid.configuration.threeColorsWindows
-    readonly property int activeIndicatorType: Latte.Types.LineIndicator
+    readonly property bool extraDotOnActive: plasmoid.configuration.dotsOnActive
+    readonly property bool minimizedTaskColoredDifferently: plasmoid.configuration.threeColorsWindows
+    readonly property int activeStyle: Latte.Types.LineIndicator
 
     //!glow options
     readonly property bool glowEnabled: plasmoid.configuration.showGlow
     readonly property bool glow3D: false
-    readonly property int glowOption: Latte.Types.GlowAll
+    readonly property int glowApplyTo: 2 /*All*/
     readonly property real glowOpacity: 0.35
 }
diff --git a/liblatte2/qml/indicators/LatteIndicator.qml b/plasmoid/package/contents/ui/indicators/styles/LatteIndicator.qml
similarity index 56%
rename from liblatte2/qml/indicators/LatteIndicator.qml
rename to plasmoid/package/contents/ui/indicators/styles/LatteIndicator.qml
index 4ff6a9c79..750eaca32 100644
--- a/liblatte2/qml/indicators/LatteIndicator.qml
+++ b/plasmoid/package/contents/ui/indicators/styles/LatteIndicator.qml
@@ -1,6 +1,5 @@
 /*
-*  Copyright 2016  Smith AR <audoban@openmailbox.org>
-*                  Michail Vourlakos <mvourlakos@gmail.com>
+*  Copyright 2019  Michail Vourlakos <mvourlakos@gmail.com>
 *
 *  This file is part of Latte-Dock
 *
@@ -29,45 +28,39 @@ import org.kde.plasma.components 2.0 as PlasmaComponents
 import org.kde.latte 0.2 as Latte
 import org.kde.latte.components 1.0 as LatteComponents
 
-import "../code/ColorizerTools.js" as ColorizerTools
-
-Item{
-    id: indicatorRoot
-    readonly property Item options: parent.manager
+LatteComponents.IndicatorItem{
+    id: root
 
     readonly property real factor: 0.08
-    readonly property int size: factor * options.currentIconSize
-    readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * options.maxIconSize) : 0
+    readonly property int size: indicator ? factor * indicator.currentIconSize : factor * 64
+    readonly property int extraMaskThickness: reversedEnabled && glowEnabled ? 1.7 * (factor * indicator.maxIconSize) : 0
 
-    property real textColorBrightness: ColorizerTools.colorBrightness(theme.textColor)
+    property real textColorBrightness: colorBrightness(theme.textColor)
 
     property color isActiveColor: theme.buttonFocusColor
     property color minimizedColor: {
-        if (multiColorEnabled) {
+        if (minimizedTaskColoredDifferently) {
             return (textColorBrightness > 127.5 ? Qt.darker(theme.textColor, 1.7) : Qt.lighter(theme.textColor, 7));
         }
 
         return isActiveColor;
     }
-    property color notActiveColor: options.isMinimized ? minimizedColor : isActiveColor
+    property color notActiveColor: indicator && indicator.isMinimized ? minimizedColor : isActiveColor
 
     //! Common Options
-    readonly property bool reversedEnabled: options && options.common && options.common.hasOwnProperty("reversedEnabled") ?
-                                                options.common.reversedEnabled : false
+    readonly property bool reversedEnabled: indicator && indicator.general ? indicator.general.reversed : false
 
-    //! Explicit Options
-    readonly property bool explicitOptionsEnabled: options.explicit
-                                                   && options.explicit.hasOwnProperty("styleName")
-                                                   && options.explicit.styleName === "Latte"
+    //! Configuration Options
+    readonly property bool configurationEnabled: (indicator!==null) && (indicator.configuration !== null)
 
-    readonly property bool dotsOnActive: explicitOptionsEnabled ? options.explicit.dotsOnActive : true
-    readonly property bool multiColorEnabled: explicitOptionsEnabled ? options.explicit.multiColorEnabled : false
-    readonly property int activeIndicatorType: explicitOptionsEnabled ? options.explicit.activeIndicatorType : Latte.Types.LineIndicator
+    readonly property bool extraDotOnActive: configurationEnabled ? indicator.configuration.extraDotOnActive : true
+    readonly property bool minimizedTaskColoredDifferently: configurationEnabled ? indicator.configuration.minimizedTaskColoredDifferently : false
+    readonly property int activeStyle: configurationEnabled ? indicator.configuration.activeStyle : 0 /*Line*/
     //!glow options
-    readonly property bool glowEnabled: explicitOptionsEnabled ? options.explicit.glowEnabled : true
-    readonly property bool glow3D: explicitOptionsEnabled ? options.explicit.glow3D : false
-    readonly property int glowOption: explicitOptionsEnabled ? options.explicit.glowOption : Latte.Types.GlowAll
-    readonly property real glowOpacity: explicitOptionsEnabled ? options.explicit.glowOpacity : 0.35
+    readonly property bool glowEnabled: configurationEnabled ? indicator.configuration.glowEnabled : true
+    readonly property bool glow3D: configurationEnabled ? indicator.configuration.glow3D : false
+    readonly property int glowApplyTo: configurationEnabled ? indicator.configuration.glowApplyTo : 2 /*All*/
+    readonly property real glowOpacity: configurationEnabled ? indicator.configuration.glowOpacity : 0.35
 
     /*Rectangle{
         anchors.fill: parent
@@ -77,6 +70,16 @@ Item{
         opacity:0.6
     }*/
 
+    function colorBrightness(color) {
+        return colorBrightnessFromRGB(color.r * 255, color.g * 255, color.b * 255);
+    }
+
+    // formula for brightness according to:
+    // https://www.w3.org/TR/AERT/#color-contrast
+    function colorBrightnessFromRGB(r, g, b) {
+        return (r * 299 + g * 587 + b * 114) / 1000
+    }
+
     Item{
         id: mainIndicatorElement
 
@@ -90,89 +93,89 @@ Item{
             LatteComponents.GlowPoint{
                 id:firstPoint
                 opacity: {
-                    if (options.isTask) {
-                        return options.isLauncher || (options.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
+                    if (indicator.isTask) {
+                        return indicator.isLauncher || (indicator.inRemoving && !activeAndReverseAnimation.running) ? 0 : 1
                     }
 
-                    if (options.isApplet) {
-                        return (options.isActive || activeAndReverseAnimation.running) ? 1 : 0
+                    if (indicator.isApplet) {
+                        return (indicator.isActive || activeAndReverseAnimation.running) ? 1 : 0
                     }
                 }
 
-                basicColor: options.isActive || (options.isGroup && options.hasShown) ? indicatorRoot.isActiveColor : indicatorRoot.notActiveColor
+                basicColor: indicator.isActive || (indicator.isGroup && indicator.hasShown) ? root.isActiveColor : root.notActiveColor
 
-                size: indicatorRoot.size
+                size: root.size
                 glow3D: glow3D
-                animation: Math.max(1.65*3*units.longDuration,options.durationTime*3*units.longDuration)
+                animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
                 location: plasmoid.location
-                glowOpacity: indicatorRoot.glowOpacity
-                contrastColor: options.shadowColor
+                glowOpacity: root.glowOpacity
+                contrastColor: indicator.shadowColor
                 attentionColor: theme.negativeTextColor
 
                 roundCorners: true
-                showAttention: options.inAttention
+                showAttention: indicator.inAttention
                 showGlow: {
-                    if (glowEnabled && (glowOption === Latte.Types.GlowAll || showAttention ))
+                    if (glowEnabled && (glowApplyTo === 2 /*All*/ || showAttention ))
                         return true;
-                    else if (glowEnabled && glowOption === Latte.Types.GlowOnlyOnActive && options.hasActive)
+                    else if (glowEnabled && glowApplyTo === 1 /*OnActive*/ && indicator.hasActive)
                         return true;
                     else
                         return false;
                 }
                 showBorder: glowEnabled && glow3D
 
-                property int stateWidth: options.isGroup ? indicatorRoot.width - secondPoint.width : indicatorRoot.width - spacer.width
-                property int stateHeight: options.isGroup ? indicatorRoot.height - secondPoint.height : indicatorRoot.width - spacer.height
+                property int stateWidth: indicator.isGroup ? root.width - secondPoint.width : root.width - spacer.width
+                property int stateHeight: indicator.isGroup ? root.height - secondPoint.height : root.width - spacer.height
 
-                property int animationTime: options.durationTime* (0.7*units.longDuration)
+                property int animationTime: indicator.durationTime* (0.7*units.longDuration)
 
-                property bool isActive: options.hasActive || options.isActive
+                property bool isActive: indicator.hasActive || indicator.isActive
 
                 property bool vertical: plasmoid.formFactor === PlasmaCore.Types.Vertical
 
-                property real scaleFactor: options.scaleFactor
+                property real scaleFactor: indicator.scaleFactor
 
                 function updateInitialSizes(){
-                    if(indicatorRoot){
+                    if(root){
                         if(vertical)
-                            width = indicatorRoot.size;
+                            width = root.size;
                         else
-                            height = indicatorRoot.size;
+                            height = root.size;
 
-                        if(vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
+                        if(vertical && isActive && activeStyle === 0 /*Line*/)
                             height = stateHeight;
                         else
-                            height = indicatorRoot.size;
+                            height = root.size;
 
-                        if(!vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
+                        if(!vertical && isActive && activeStyle === 0 /*Line*/)
                             width = stateWidth;
                         else
-                            width = indicatorRoot.size;
+                            width = root.size;
                     }
                 }
 
 
                 onIsActiveChanged: {
-                    if (activeIndicatorType === Latte.Types.LineIndicator)
+                    if (activeStyle === 0 /*Line*/)
                         activeAndReverseAnimation.start();
                 }
 
                 onScaleFactorChanged: {
-                    if(!activeAndReverseAnimation.running && !vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator){
+                    if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/){
                         width = stateWidth;
                     }
-                    else if (!activeAndReverseAnimation.running && vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator){
+                    else if (!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/){
                         height = stateHeight;
                     }
                 }
 
                 onStateWidthChanged:{
-                    if(!activeAndReverseAnimation.running && !vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
+                    if(!activeAndReverseAnimation.running && !vertical && isActive && activeStyle === 0 /*Line*/)
                         width = stateWidth;
                 }
 
                 onStateHeightChanged:{
-                    if(!activeAndReverseAnimation.running && vertical && isActive && activeIndicatorType === Latte.Types.LineIndicator)
+                    if(!activeAndReverseAnimation.running && vertical && isActive && activeStyle === 0 /*Line*/)
                         height = stateHeight;
                 }
 
@@ -181,14 +184,14 @@ Item{
                 Component.onCompleted: {
                     updateInitialSizes();
 
-                    if (options) {
-                        options.onCurrentIconSizeChanged.connect(updateInitialSizes);
+                    if (indicator) {
+                        indicator.onCurrentIconSizeChanged.connect(updateInitialSizes);
                     }
                 }
 
                 Component.onDestruction: {
-                    if (options) {
-                        options.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
+                    if (indicator) {
+                        indicator.onCurrentIconSizeChanged.disconnect(updateInitialSizes);
                     }
                 }
 
@@ -196,8 +199,8 @@ Item{
                     id: activeAndReverseAnimation
                     target: firstPoint
                     property: plasmoid.formFactor === PlasmaCore.Types.Vertical ? "height" : "width"
-                    to: options.hasActive && activeIndicatorType === Latte.Types.LineIndicator
-                        ? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : indicatorRoot.size
+                    to: indicator.hasActive && activeStyle === 0 /*Line*/
+                        ? (plasmoid.formFactor === PlasmaCore.Types.Vertical ? firstPoint.stateHeight : firstPoint.stateWidth) : root.size
                     duration: firstPoint.animationTime
                     easing.type: Easing.InQuad
 
@@ -207,34 +210,34 @@ Item{
 
             Item{
                 id:spacer
-                width: secondPoint.visible ? 0.5*indicatorRoot.size : 0
-                height: secondPoint.visible ? 0.5*indicatorRoot.size : 0
+                width: secondPoint.visible ? 0.5*root.size : 0
+                height: secondPoint.visible ? 0.5*root.size : 0
             }
 
             LatteComponents.GlowPoint{
                 id:secondPoint
-                width: visible ? indicatorRoot.size : 0
+                width: visible ? root.size : 0
                 height: width
 
-                size: indicatorRoot.size
+                size: root.size
                 glow3D: glow3D
-                animation: Math.max(1.65*3*units.longDuration,options.durationTime*3*units.longDuration)
+                animation: Math.max(1.65*3*units.longDuration,indicator.durationTime*3*units.longDuration)
                 location: plasmoid.location
-                glowOpacity: indicatorRoot.glowOpacity
-                contrastColor: options.shadowColor
+                glowOpacity: root.glowOpacity
+                contrastColor: indicator.shadowColor
                 showBorder: glowEnabled && glow3D
 
                 basicColor: state2Color
                 roundCorners: true
-                showGlow: glowEnabled  && glowOption === Latte.Types.GlowAll
-                visible:  ( options.isGroup && ((dotsOnActive && activeIndicatorType === Latte.Types.LineIndicator)
-                                                || activeIndicatorType === Latte.Types.DotIndicator
-                                                || !options.hasActive) )? true: false
+                showGlow: glowEnabled  && glowApplyTo === 2 /*All*/
+                visible:  ( indicator.isGroup && ((extraDotOnActive && activeStyle === 0) /*Line*/
+                                                  || activeStyle === 1 /*Dot*/
+                                                  || !indicator.hasActive) ) ? true: false
 
                 //when there is no active window
-                property color state1Color: options.hasShown ? indicatorRoot.isActiveColor : indicatorRoot.minimizedColor
+                property color state1Color: indicator.hasShown ? root.isActiveColor : root.minimizedColor
                 //when there is active window
-                property color state2Color: options.hasMinimized ? indicatorRoot.minimizedColor : indicatorRoot.isActiveColor
+                property color state2Color: indicator.hasMinimized ? root.minimizedColor : root.isActiveColor
             }
         }
 
diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package/contents/ui/main.qml
index d8bf63345..9880f07c7 100644
--- a/plasmoid/package/contents/ui/main.qml
+++ b/plasmoid/package/contents/ui/main.qml
@@ -63,7 +63,7 @@ Item {
 
     property bool editMode: latteView ? latteView.editMode : plasmoid.userConfiguring
     property bool disableRestoreZoom: false //blocks restore animation in rightClick
-    property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicatorsEnabled
+    property bool disableAllWindowsFunctionality: root.showWindowsOnlyFromLaunchers && !indicators.isEnabled
     property bool dropNewLauncher: false
     readonly property bool hasInternalSeparator: parabolicManager.hasInternalSeparator
     property bool inActivityChange: false
@@ -349,7 +349,7 @@ Item {
 
     Loader {
         id: indicatorsStandaloneLoader
-        active: !latteView
+        active: !latteView && !plasmoid.configuration.isInLatteDock
         source: "indicators/Manager.qml"
     }
 
diff --git a/plasmoid/package/contents/ui/task/TaskItem.qml b/plasmoid/package/contents/ui/task/TaskItem.qml
index a796debe9..468de34be 100644
--- a/plasmoid/package/contents/ui/task/TaskItem.qml
+++ b/plasmoid/package/contents/ui/task/TaskItem.qml
@@ -421,21 +421,22 @@ MouseArea{
             width: wrapper.width
             height: wrapper.height
 
-            Indicator.Manager{
-                id: indicatorManager
+            Indicator.Bridge{
+                id: indicatorBridge
             }
 
             Indicator.Loader{
                 id: indicatorBackLayer
-                manager: indicatorManager
+                bridge: indicatorBridge
+                isBackground: true
             }
 
             Wrapper{id: wrapper}
 
             Indicator.Loader{
                 id: indicatorFrontLayer
-                manager: indicatorManager
-                isBackLayer: false
+                bridge: indicatorBridge
+                isBackground: false
             }
         }
 
diff --git a/plasmoid/package/contents/ui/task/indicator/Manager.qml b/plasmoid/package/contents/ui/task/indicator/Bridge.qml
similarity index 88%
rename from plasmoid/package/contents/ui/task/indicator/Manager.qml
rename to plasmoid/package/contents/ui/task/indicator/Bridge.qml
index bcf477744..bdf4b5b3d 100644
--- a/plasmoid/package/contents/ui/task/indicator/Manager.qml
+++ b/plasmoid/package/contents/ui/task/indicator/Bridge.qml
@@ -26,10 +26,10 @@ import org.kde.latte 0.2 as Latte
 import "../../indicators/options" as TaskIndicator
 
 Item {
-    id: indicatorManager
+    id: indicatorBridge
     property bool taskIsValid: true
 
-    readonly property bool active: indicators && indicators.common ? indicators.common.indicatorsEnabled : true
+    readonly property bool active: indicators ? indicators.isEnabled : false
     readonly property bool locked: taskIsValid ? (inAttentionAnimation || inNewWindowAnimation) : false
 
     /* Indicators Properties in order for indicators to use them*/
@@ -63,13 +63,17 @@ Item {
     readonly property real scaleFactor: taskIsValid ? taskItem.wrapperAlias.mScale : 1
     readonly property color shadowColor: root.appShadowColorSolid
 
+    readonly property bool usePlasmaTabsStyle: false
+
+    readonly property QtObject palette: enforceLattePalette ? latteBridge.palette.applyTheme : theme
+
     //!icon colors
     property color backgroundColor: taskIsValid ? taskItem.wrapperAlias.backgroundColor : "black"
     property color glowColor: taskIsValid ? taskItem.wrapperAlias.glowColor : "white"
 
     //! grouped options
-    readonly property Item common: indicators ? indicators.common : emptyOptions
-    readonly property Item explicit: indicators ? indicators.explicit : emptyOptions
+    readonly property Item shared: indicators ? indicators : emptyOptions
+    readonly property QtObject configuration: indicators ? indicators.configuration : null
 
     Item{id: emptyOptions}
 }
diff --git a/plasmoid/package/contents/ui/task/indicator/Loader.qml b/plasmoid/package/contents/ui/task/indicator/Loader.qml
index 19d0eb101..a7df7364a 100644
--- a/plasmoid/package/contents/ui/task/indicator/Loader.qml
+++ b/plasmoid/package/contents/ui/task/indicator/Loader.qml
@@ -19,6 +19,7 @@
 
 import QtQuick 2.7
 
+import org.kde.plasma.plasmoid 2.0
 import org.kde.plasma.core 2.0 as PlasmaCore
 
 import org.kde.latte 0.2 as Latte
@@ -33,10 +34,11 @@ Loader {
     anchors.horizontalCenter: !root.vertical ? parent.horizontalCenter : undefined
     anchors.verticalCenter: root.vertical ? parent.verticalCenter : undefined
 
-    property bool isBackLayer: true
-    property Item manager
+    property bool isBackground: true
+    readonly property bool isForeground: !isBackground
+    property Item bridge
 
-    active: manager && manager.active && (isBackLayer || (!isBackLayer && indicators.info.providesFrontLayer))
+    active: bridge && bridge.active && (isBackground || (isForeground && indicators.info.providesFrontLayer))
     sourceComponent: indicators.indicatorComponent
 
     width: {
diff --git a/shell/package/contents/configuration/LatteDockConfiguration.qml b/shell/package/contents/configuration/LatteDockConfiguration.qml
index 744f7991a..2a32e8d27 100644
--- a/shell/package/contents/configuration/LatteDockConfiguration.qml
+++ b/shell/package/contents/configuration/LatteDockConfiguration.qml
@@ -388,7 +388,7 @@ FocusScope {
                 text: i18n("Tasks")
                 tab: tasksPage
 
-                visible: latteView.latteTasksPresent()
+                visible: latteView.latteTasksArePresent
             }
         }
 
diff --git a/shell/package/contents/configuration/pages/EffectsConfig.qml b/shell/package/contents/configuration/pages/EffectsConfig.qml
index 2bc4fb608..d0e733f6e 100644
--- a/shell/package/contents/configuration/pages/EffectsConfig.qml
+++ b/shell/package/contents/configuration/pages/EffectsConfig.qml
@@ -384,7 +384,7 @@ PlasmaComponents.Page {
 
                     ColumnLayout {
                         spacing: units.smallSpacing
-                        visible: latteView.latteTasksPresent()
+                        visible: latteView.latteTasksArePresent
 
                         LatteComponents.SubHeader {
                             Layout.leftMargin: units.smallSpacing * 2
@@ -451,12 +451,12 @@ PlasmaComponents.Page {
                 Layout.fillWidth: true
                 Layout.minimumHeight: implicitHeight
 
-                checked: plasmoid.configuration.indicatorsEnabled
+                checked: latteView.indicator.enabled
                 text: i18n("Indicators")
                 tooltip: i18n("Enable/disable indicators")
 
                 onPressed: {
-                    plasmoid.configuration.indicatorsEnabled = !plasmoid.configuration.indicatorsEnabled;
+                    latteView.indicator.enabled = !latteView.indicator.enabled;
                 }
             }
 
@@ -473,13 +473,13 @@ PlasmaComponents.Page {
                     Layout.fillWidth: true
                     spacing: 2
 
-                    property int style: plasmoid.configuration.indicatorStyle
+                    property string type: latteView.indicator.type
 
                     ExclusiveGroup {
                         id: indicatorStyleGroup
                         onCurrentChanged: {
                             if (current.checked) {
-                                plasmoid.configuration.indicatorStyle = current.style
+                                latteView.indicator.type = current.type
                             }
                         }
                     }
@@ -487,34 +487,34 @@ PlasmaComponents.Page {
                     PlasmaComponents.Button {
                         Layout.fillWidth: true
                         text: i18nc("latte indicator style", "Latte")
-                        checked: parent.style === style
+                        checked: parent.type === type
                         checkable: true
                         exclusiveGroup:  indicatorStyleGroup
                         tooltip: i18n("Use Latte style for your indicators")
 
-                        readonly property int style: Latte.Types.LatteIndicator
+                        readonly property string type: "org.kde.latte.indicator.default"
                     }
 
                     PlasmaComponents.Button {
                         Layout.fillWidth: true
                         text: i18nc("plasma indicator style", "Plasma")
-                        checked: parent.style === style
+                        checked: parent.type === type
                         checkable: true
                         exclusiveGroup:  indicatorStyleGroup
                         tooltip: i18n("Use Plasma style for your indicators")
 
-                        readonly property int style: Latte.Types.PlasmaIndicator
+                        readonly property string type: "org.kde.latte.indicator.plasma"
                     }
 
                     PlasmaComponents.Button {
                         Layout.fillWidth: true
                         text: i18nc("unity indicator style", "Unity")
-                        checked: parent.style === style
+                        checked: parent.type === type
                         checkable: true
                         exclusiveGroup:  indicatorStyleGroup
                         tooltip: i18n("Use Unity style for your indicators")
 
-                        readonly property int style: Latte.Types.UnityIndicator
+                        readonly property string type: "org.kde.latte.indicator.unity"
                     }
                 }
 
@@ -537,7 +537,7 @@ PlasmaComponents.Page {
                         id: lengthIntMarginSlider
                         Layout.fillWidth: true
 
-                        value: plasmoid.configuration.lengthIntMargin
+                        value: Math.round(latteView.indicator.padding * 100)
                         from: 0
                         to: maxMargin
                         stepSize: 1
@@ -547,7 +547,7 @@ PlasmaComponents.Page {
 
                         onPressedChanged: {
                             if (!pressed) {
-                                plasmoid.configuration.lengthIntMargin = value;
+                                latteView.indicator.padding = value / 100;
                             }
                         }
                     }
@@ -568,21 +568,21 @@ PlasmaComponents.Page {
 
                 PlasmaComponents.CheckBox {
                     text: i18n("Show indicators for applets")
-                    checked: plasmoid.configuration.indicatorsForApplets
+                    checked: latteView.indicator.enabledForApplets
                     tooltip: i18n("Indicators are shown for applets")
 
                     onClicked: {
-                        plasmoid.configuration.indicatorsForApplets = !plasmoid.configuration.indicatorsForApplets;
+                        latteView.indicator.enabledForApplets = !latteView.indicator.enabledForApplets;
                     }
                 }
 
                 PlasmaComponents.CheckBox {
                     text: i18n("Reverse indicator style")
-                    checked: plasmoid.configuration.reverseLinesPosition
+                    checked: latteView.indicator.reversed
                     tooltip: i18n("Reverse indicator style e.g. from bottom to top")
 
                     onClicked: {
-                        plasmoid.configuration.reverseLinesPosition = !plasmoid.configuration.reverseLinesPosition;
+                        latteView.indicator.reversed = !latteView.indicator.reversed;
                     }
                 }
             }
@@ -595,18 +595,26 @@ PlasmaComponents.Page {
             Layout.topMargin: units.smallSpacing
             Layout.rightMargin: units.smallSpacing
             spacing: units.smallSpacing
-            visible: plasmoid.configuration.indicatorStyle === Latte.Types.LatteIndicator
-            enabled: indicatorsSwitch.checked
+            visible: latteView.indicator.providesConfigUi
 
             LatteComponents.Header {
                 text: i18n("%0 Indicator Options").arg(indicatorStyleGroup.current.text)
             }
 
-            Loader{
+            ColumnLayout {
+                id: indicatorSpecificOptions
                 Layout.fillWidth: true
                 Layout.leftMargin: units.smallSpacing * 2
-                active: plasmoid.configuration.indicatorStyle === Latte.Types.LatteIndicator
-                source: "indicator/LatteOptions.qml"
+                spacing: 0
+
+                Component.onCompleted: {
+                    latteView.indicator.configUiFor(latteView.indicator.type, indicatorSpecificOptions);
+                }
+
+                Connections {
+                    target: latteView.indicator
+                    onTypeChanged: latteView.indicator.configUiFor(latteView.indicator.type, indicatorSpecificOptions);
+                }
             }
         }
         //! END: Indicator specific sub-options
diff --git a/shell/package/contents/configuration/pages/TasksConfig.qml b/shell/package/contents/configuration/pages/TasksConfig.qml
index 551e0688d..f2952fe86 100644
--- a/shell/package/contents/configuration/pages/TasksConfig.qml
+++ b/shell/package/contents/configuration/pages/TasksConfig.qml
@@ -475,7 +475,7 @@ PlasmaComponents.Page {
                 Layout.fillWidth: true
 
                 text: i18n("Remove Latte Tasks Applet")
-                enabled: latteView.latteTasksPresent()
+                enabled: latteView.latteTasksArePresent
                 tooltip: i18n("Remove Latte Tasks plasmoid")
 
                 onClicked: {