diff --git a/app/universalsettings.cpp b/app/universalsettings.cpp index d38dbda51..bd6e2991c 100644 --- a/app/universalsettings.cpp +++ b/app/universalsettings.cpp @@ -28,13 +28,14 @@ #include <QtDBus/QtDBus> +#include <KDirWatch> #include <KActivities/Consumer> -namespace Latte { - -const QString UniversalSettings::KWinMetaForwardToLatteString = "org.kde.lattedock,/Latte,org.kde.LatteDock,activateLauncherMenu"; -const QString UniversalSettings::KWinMetaForwardToPlasmaString = "org.kde.plasmashell,/PlasmaShell,org.kde.PlasmaShell,activateLauncherMenu"; +#define GLOBALSHORTCUTSCONFIG "kglobalshortcutsrc" +#define KWINMETAFORWARDTOLATTESTRING "org.kde.lattedock,/Latte,org.kde.LatteDock,activateLauncherMenu" +#define KWINMETAFORWARDTOPLASMASTRING "org.kde.plasmashell,/PlasmaShell,org.kde.PlasmaShell,activateLauncherMenu" +namespace Latte { UniversalSettings::UniversalSettings(KSharedConfig::Ptr config, QObject *parent) : QObject(parent), @@ -65,6 +66,74 @@ UniversalSettings::~UniversalSettings() } } +void UniversalSettings::initGlobalShortcutsWatcher() +{ + const QString globalShortcutsFilePath = QDir::homePath() + "/.config/" + GLOBALSHORTCUTSCONFIG; + m_shortcutsConfigPtr = KSharedConfig::openConfig(globalShortcutsFilePath); + + KDirWatch::self()->addFile(globalShortcutsFilePath); + + QObject::connect(KDirWatch::self(), &KDirWatch::dirty, this, &UniversalSettings::shortcutsFileChanged, Qt::QueuedConnection); + QObject::connect(KDirWatch::self(), &KDirWatch::created, this, &UniversalSettings::shortcutsFileChanged, Qt::QueuedConnection); +} + +void UniversalSettings::shortcutsFileChanged(const QString &file) +{ + if (!file.endsWith(GLOBALSHORTCUTSCONFIG)) { + return; + } + + m_shortcutsConfigPtr->reparseConfiguration(); + parseGlobalShortcuts(); +} + +void UniversalSettings::parseGlobalShortcuts() +{ + KConfigGroup latteGroup = KConfigGroup(m_shortcutsConfigPtr, "lattedock"); + + //! make sure that latte dock records in global shortcuts where found correctly + bool recordsExist{true}; + + if (!latteGroup.exists()) { + recordsExist = false; + } + + if (recordsExist) { + for (int i = 1; i <= 19; ++i) { + QString entry = "activate entry " + QString::number(i); + + if (!latteGroup.hasKey(entry)) { + recordsExist = false; + break; + } + } + } + + if (recordsExist) { + m_badgesForActivate.clear(); + + for (int i = 1; i <= 19; ++i) { + QString entry = "activate entry " + QString::number(i); + QStringList records = latteGroup.readEntry(entry, QStringList()); + + QString badge; + + if (records[0] != "none") { + QStringList modifiers = records[0].split("+"); + + if (modifiers.count() >= 1) { + badge = modifiers[modifiers.count() - 1].toLower(); + } + } + + m_badgesForActivate << badge; + emit badgesForActivateChanged(); + } + + qDebug() << "badges updated to :: " << m_badgesForActivate; + } +} + void UniversalSettings::load() { //! check if user has set the autostart option @@ -76,6 +145,10 @@ void UniversalSettings::load() //! load configuration loadConfig(); + + //! load global shortcuts badges at startup + initGlobalShortcutsWatcher(); + parseGlobalShortcuts(); } bool UniversalSettings::showInfoWindow() const @@ -185,6 +258,11 @@ void UniversalSettings::setLayoutsWindowSize(QSize size) emit layoutsWindowSizeChanged(); } +QStringList UniversalSettings::badgesForActivate() const +{ + return m_badgesForActivate; +} + QStringList UniversalSettings::layoutsColumnWidths() const { return m_layoutsColumnWidths; @@ -288,7 +366,7 @@ bool UniversalSettings::kwin_metaForwardedToLatte() const output = output.remove("\n"); - return (output == UniversalSettings::KWinMetaForwardToLatteString); + return (output == KWINMETAFORWARDTOLATTESTRING); } void UniversalSettings::kwin_forwardMetaToLatte(bool forward) @@ -302,9 +380,9 @@ void UniversalSettings::kwin_forwardMetaToLatte(bool forward) parameters << "--file" << "kwinrc" << "--group" << "ModifierOnlyShortcuts" << "--key" << "Meta"; if (forward) { - parameters << UniversalSettings::KWinMetaForwardToLatteString; + parameters << KWINMETAFORWARDTOLATTESTRING; } else { - parameters << UniversalSettings::KWinMetaForwardToPlasmaString;; + parameters << KWINMETAFORWARDTOPLASMASTRING; } process.start("kwriteconfig5", parameters); diff --git a/app/universalsettings.h b/app/universalsettings.h index 89e86bdb9..808352c31 100644 --- a/app/universalsettings.h +++ b/app/universalsettings.h @@ -44,6 +44,7 @@ class UniversalSettings : public QObject Q_PROPERTY(bool showInfoWindow READ showInfoWindow WRITE setShowInfoWindow NOTIFY showInfoWindowChanged) Q_PROPERTY(QString currentLayoutName READ currentLayoutName WRITE setCurrentLayoutName NOTIFY currentLayoutNameChanged) + Q_PROPERTY(QStringList badgesForActivate READ badgesForActivate NOTIFY badgesForActivateChanged) Q_PROPERTY(QStringList launchers READ launchers WRITE setLaunchers NOTIFY launchersChanged) Q_PROPERTY(Latte::Dock::MouseSensitivity mouseSensitivity READ mouseSensitivity WRITE setMouseSensitivity NOTIFY mouseSensitivityChanged) @@ -85,6 +86,8 @@ public: QSize layoutsWindowSize() const; void setLayoutsWindowSize(QSize size); + QStringList badgesForActivate() const; + QStringList layoutsColumnWidths() const; void setLayoutsColumnWidths(QStringList widths); @@ -107,6 +110,7 @@ public slots: signals: void autostartChanged(); + void badgesForActivateChanged(); void canDisableBordersChanged(); void currentLayoutNameChanged(); void downloadWindowSizeChanged(); @@ -125,12 +129,15 @@ private slots: void loadConfig(); void saveConfig(); -private: - static const QString KWinMetaForwardToLatteString; - static const QString KWinMetaForwardToPlasmaString; + void shortcutsFileChanged(const QString &file); +private: void cleanupSettings(); + void initGlobalShortcutsWatcher(); + //! access user set global shortcuts for activate entries + void parseGlobalShortcuts(); + bool kwin_metaForwardedToLatte() const; void kwin_forwardMetaToLatte(bool forward); @@ -151,6 +158,7 @@ private: QSize m_downloadWindowSize{800, 550}; QSize m_layoutsWindowSize{700, 450}; + QStringList m_badgesForActivate{"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "z", "x", "c", "v", "b", "n", "m", ",", "."}; QStringList m_layoutsColumnWidths; QStringList m_launchers; @@ -159,6 +167,7 @@ private: KConfigGroup m_universalGroup; KSharedConfig::Ptr m_config; + KSharedConfig::Ptr m_shortcutsConfigPtr; SortedActivitiesModel *m_runningActivitiesModel{nullptr}; diff --git a/containment/package/contents/ui/applet/AppletItemWrapper.qml b/containment/package/contents/ui/applet/AppletItemWrapper.qml index a9448ff5b..981bda3c1 100644 --- a/containment/package/contents/ui/applet/AppletItemWrapper.qml +++ b/containment/package/contents/ui/applet/AppletItemWrapper.qml @@ -617,10 +617,12 @@ Item{ Loader{ id: appletNumberLoader anchors.fill: container.appletWrapper - active: opacityN>0 + active: isValidDelayer > 0 asynchronous: true + visible: badgeString!=="" - property int fixedIndex:-1 + property int fixedIndex: -1 + property string badgeString: "" onActiveChanged: { if (active) { @@ -630,12 +632,31 @@ Item{ Component.onCompleted: fixedIndex = parabolicManager.pseudoAppletIndex(index); - property real opacityN: container.canShowAppletNumberBadge && - ((root.unifiedGlobalShortcuts && root.showAppletsNumbers && fixedIndex<20) - || (root.showMetaBadge && applet.id===applicationLauncherId)) ? 1 : 0 + property real isValidDelayer: container.canShowAppletNumberBadge && + ((root.showAppletsNumbers && root.unifiedGlobalShortcuts) + || (root.showMetaBadge && applet.id===applicationLauncherId)) ? 1 : 0 - Behavior on opacityN { - NumberAnimation { duration: root.durationTime*2*units.longDuration } + Behavior on isValidDelayer { + NumberAnimation { duration: root.durationTime*units.longDuration } + } + + Binding{ + target: appletNumberLoader + property:"badgeString" + value: { + //! dont change value on hiding/releasing + if (!root.showMetaBadge && !root.showAppletsNumbers) { + return; + } + + if (root.showMetaBadge && applet && applet.id === applicationLauncherId) { + return '\u2318'; + } else if (appletNumberLoader.fixedIndex>=1 && appletNumberLoader.fixedIndex<20) { + return root.badgesForActivate[appletNumberLoader.fixedIndex-1]; + } else { + return ""; + } + } } sourceComponent: Item{ @@ -660,67 +681,11 @@ Item{ minimumWidth: 0.4 * root.iconSize height: width border.color: root.minimizedDotColor - numberValue: appletNumberLoader.fixedIndex < 10 ? appletNumberLoader.fixedIndex : 0 - - Binding{ - target: appletNumber - property:"textValue" - value: { - //! dont change value on hiding/releasing - if (!root.showMetaBadge && !root.showAppletsNumbers) { - return; - } - - if (root.showMetaBadge && applet.id === applicationLauncherId) { - return '\u2318'; - } else if (appletNumber.keysArrayIndex>=0 && appletNumber.keysArrayIndex<10) { - return appletNumber.keysAboveTen[appletNumber.keysArrayIndex]; - } else { - return ''; - } - } - } - - Binding{ - target: appletNumber - property:"showNumber" - value: { - //! dont change value on hiding/releasing - if (!root.showMetaBadge && !root.showAppletsNumbers) { - return; - } - - if (appletNumberLoader.fixedIndex < 10 && !(root.showMetaBadge && applet.id === applicationLauncherId)) { - return true; - } else { - return false; - } - } - } - - Binding{ - target: appletNumber - property:"showText" - value: { - //! dont change value on hiding/releasing - if (!root.showMetaBadge && !root.showAppletsNumbers) { - return; - } - - if ((appletNumberLoader.fixedIndex>=10 && appletNumberLoader.fixedIndex<20) || - (root.showMetaBadge && applet.id === applicationLauncherId)) { - return true; - } else { - return false; - } - } - } - proportion: 0 radiusPerCentage: 50 - - property int keysArrayIndex: appletNumberLoader.fixedIndex-10; - property var keysAboveTen: ['0', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.'] + showNumber: false + showText: true + textValue: appletNumberLoader.badgeString } } } diff --git a/containment/package/contents/ui/main.qml b/containment/package/contents/ui/main.qml index 6d756d32f..f003f61d6 100644 --- a/containment/package/contents/ui/main.qml +++ b/containment/package/contents/ui/main.qml @@ -300,6 +300,14 @@ DragDrop.DropArea { readonly property string plasmoidName: "org.kde.latte.plasmoid" + property var badgesForActivate: { + if (!universalSettings) { + return ['1','2','3','4','5','6','7','8','9','0', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.']; + } + + return universalSettings.badgesForActivate; + } + property var iconsArray: [16, 22, 32, 48, 64, 96, 128, 256] property var layoutManager: LayoutManager diff --git a/plasmoid/package/contents/ui/main.qml b/plasmoid/package/contents/ui/main.qml index 6e2c8c1e7..ac0030c00 100644 --- a/plasmoid/package/contents/ui/main.qml +++ b/plasmoid/package/contents/ui/main.qml @@ -244,6 +244,8 @@ Item { property alias hoveredIndex: icList.hoveredIndex property QtObject currentLayout : latteDock && latteDock.dockManagedLayout ? latteDock.dockManagedLayout : null + + property var badgesForActivate: latteDock ? latteDock.badgesForActivate : [] property var managedLayoutName: currentLayout ? currentLayout.name : "" property Item latteDock: null diff --git a/plasmoid/package/contents/ui/task/TaskIconItem.qml b/plasmoid/package/contents/ui/task/TaskIconItem.qml index 3e57804b8..2dbfaecc6 100644 --- a/plasmoid/package/contents/ui/task/TaskIconItem.qml +++ b/plasmoid/package/contents/ui/task/TaskIconItem.qml @@ -458,10 +458,13 @@ Item{ Loader{ id: taskNumberLoader anchors.fill: iconImageBuffer - active: opacityN>0 && !launcherAnimation.running + active: isValidDelayer>0 && !launcherAnimation.running asynchronous: true + visible: badgeString !== "" property int fixedIndex:-1 + property string badgeString: (taskNumberLoader.fixedIndex>=1 && taskNumberLoader.fixedIndex<20 && root.badgesForActivate.length===19) ? + root.badgesForActivate[taskNumberLoader.fixedIndex-1] : "" onActiveChanged: { if (active) { @@ -471,10 +474,10 @@ Item{ Component.onCompleted: fixedIndex = parabolicManager.pseudoTaskIndex(index+1); - property real opacityN: root.showTasksNumbers && !mainItemContainer.isSeparator && fixedIndex<20 ? 1 : 0 + property real isValidDelayer: root.showTasksNumbers && !mainItemContainer.isSeparator && fixedIndex<20 ? 1 : 0 - Behavior on opacityN { - NumberAnimation { duration: root.durationTime*2*units.longDuration } + Behavior on isValidDelayer { + NumberAnimation { duration: root.durationTime*units.longDuration } } sourceComponent: Item{ @@ -496,21 +499,16 @@ Item{ id: taskNumber anchors.centerIn: parent border.color: root.minimizedDotColor - //opacity: taskNumberLoader.opacityN && !root.enableShadows ? 1 : 0 minimumWidth: 0.4 * root.iconSize height: width - numberValue: taskNumberLoader.fixedIndex < 10 ? taskNumberLoader.fixedIndex : 0 - textValue: (keysArrayIndex>=0 && keysArrayIndex<10) ? keysAboveTen[keysArrayIndex] : '' + textValue: taskNumberLoader.badgeString - showNumber: taskNumberLoader.fixedIndex < 10 - showText: taskNumberLoader.fixedIndex>=10 && taskNumberLoader.fixedIndex<20 + showNumber: false + showText: true proportion: 0 radiusPerCentage: 50 - - property int keysArrayIndex: taskNumberLoader.fixedIndex-10; - property var keysAboveTen: ['0', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.'] } } }