diff --git a/app/settings/universalsettings.cpp b/app/settings/universalsettings.cpp index 2be545a5..11fcec21 100644 --- a/app/settings/universalsettings.cpp +++ b/app/settings/universalsettings.cpp @@ -1,556 +1,559 @@ /* * Copyright 2017 Smith AR * Michail Vourlakos * * 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 . */ #include "universalsettings.h" // local #include "../layouts/importer.h" #include "../layouts/manager.h" // Qt #include #include #include #include // KDE #include #include #define KWINMETAFORWARDTOLATTESTRING "org.kde.lattedock,/Latte,org.kde.LatteDock,activateLauncherMenu" #define KWINMETAFORWARDTOPLASMASTRING "org.kde.plasmashell,/PlasmaShell,org.kde.PlasmaShell,activateLauncherMenu" #define KWINCOLORSSCRIPT "kwin/scripts/lattewindowcolors" namespace Latte { UniversalSettings::UniversalSettings(KSharedConfig::Ptr config, QObject *parent) : QObject(parent), m_config(config), m_universalGroup(KConfigGroup(config, QStringLiteral("UniversalSettings"))) { m_corona = qobject_cast(parent); connect(this, &UniversalSettings::canDisableBordersChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::currentLayoutNameChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::downloadWindowSizeChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::lastNonAssignedLayoutNameChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::launchersChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::layoutsColumnWidthsChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::layoutsMemoryUsageChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::layoutsWindowSizeChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::metaPressAndHoldEnabledChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::mouseSensitivityChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::screenTrackerIntervalChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::showInfoWindowChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::versionChanged, this, &UniversalSettings::saveConfig); connect(this, &UniversalSettings::screenScalesChanged, this, &UniversalSettings::saveScalesConfig); + + connect(qGuiApp, &QGuiApplication::screenAdded, this, &UniversalSettings::screensCountChanged); + connect(qGuiApp, &QGuiApplication::screenRemoved, this, &UniversalSettings::screensCountChanged); } UniversalSettings::~UniversalSettings() { saveConfig(); cleanupSettings(); } void UniversalSettings::load() { //! check if user has set the autostart option bool autostartUserSet = m_universalGroup.readEntry("userConfiguredAutostart", false); if (!autostartUserSet && !autostart()) { setAutostart(true); } //! init screen scales m_screenScalesGroup = m_universalGroup.group("ScreenScales"); //! load configuration loadConfig(); //! Track KWin Colors Script Presence updateColorsScriptIsPresent(); QStringList colorsScriptPaths = Layouts::Importer::standardPathsFor(KWINCOLORSSCRIPT); for(auto path: colorsScriptPaths) { KDirWatch::self()->addDir(path); } connect(KDirWatch::self(), &KDirWatch::created, this, &UniversalSettings::colorsScriptChanged); connect(KDirWatch::self(), &KDirWatch::deleted, this, &UniversalSettings::colorsScriptChanged); //! this is needed to inform globalshortcuts to update its modifiers tracking emit metaPressAndHoldEnabledChanged(); } bool UniversalSettings::showInfoWindow() const { return m_showInfoWindow; } void UniversalSettings::setShowInfoWindow(bool show) { if (m_showInfoWindow == show) { return; } m_showInfoWindow = show; emit showInfoWindowChanged(); } int UniversalSettings::version() const { return m_version; } void UniversalSettings::setVersion(int ver) { if (m_version == ver) { return; } m_version = ver; emit versionChanged(); } int UniversalSettings::screenTrackerInterval() const { return m_screenTrackerInterval; } void UniversalSettings::setScreenTrackerInterval(int duration) { if (m_screenTrackerInterval == duration) { return; } m_screenTrackerInterval = duration; emit screenTrackerIntervalChanged(); } QString UniversalSettings::currentLayoutName() const { return m_currentLayoutName; } void UniversalSettings::setCurrentLayoutName(QString layoutName) { if (m_currentLayoutName == layoutName) { return; } m_currentLayoutName = layoutName; emit currentLayoutNameChanged(); } QString UniversalSettings::lastNonAssignedLayoutName() const { return m_lastNonAssignedLayoutName; } void UniversalSettings::setLastNonAssignedLayoutName(QString layoutName) { if (m_lastNonAssignedLayoutName == layoutName) { return; } m_lastNonAssignedLayoutName = layoutName; emit lastNonAssignedLayoutNameChanged(); } QSize UniversalSettings::downloadWindowSize() const { return m_downloadWindowSize; } void UniversalSettings::setDownloadWindowSize(QSize size) { if (m_downloadWindowSize == size) { return; } m_downloadWindowSize = size; emit downloadWindowSizeChanged(); } QSize UniversalSettings::layoutsWindowSize() const { return m_layoutsWindowSize; } void UniversalSettings::setLayoutsWindowSize(QSize size) { if (m_layoutsWindowSize == size) { return; } m_layoutsWindowSize = size; emit layoutsWindowSizeChanged(); } QStringList UniversalSettings::layoutsColumnWidths() const { return m_layoutsColumnWidths; } void UniversalSettings::setLayoutsColumnWidths(QStringList widths) { if (m_layoutsColumnWidths == widths) { return; } m_layoutsColumnWidths = widths; emit layoutsColumnWidthsChanged(); } QStringList UniversalSettings::launchers() const { return m_launchers; } void UniversalSettings::setLaunchers(QStringList launcherList) { if (m_launchers == launcherList) { return; } m_launchers = launcherList; emit launchersChanged(); } bool UniversalSettings::autostart() const { QFile autostartFile(QDir::homePath() + "/.config/autostart/org.kde.latte-dock.desktop"); return autostartFile.exists(); } void UniversalSettings::setAutostart(bool state) { //! remove old autostart file QFile oldAutostartFile(QDir::homePath() + "/.config/autostart/latte-dock.desktop"); if (oldAutostartFile.exists()) { oldAutostartFile.remove(); } //! end of removal of old autostart file QFile autostartFile(QDir::homePath() + "/.config/autostart/org.kde.latte-dock.desktop"); QFile metaFile(Layouts::Importer::standardPath("applications", false)+"/org.kde.latte-dock.desktop"); if (!state && autostartFile.exists()) { //! the first time that the user disables the autostart, this is recorded //! and from now own it will not be recreated it in the beginning if (!m_universalGroup.readEntry("userConfiguredAutostart", false)) { m_universalGroup.writeEntry("userConfiguredAutostart", true); } autostartFile.remove(); emit autostartChanged(); } else if (state && metaFile.exists()) { //! check if autostart folder exists and create otherwise QDir autostartDir(QDir::homePath() + "/.config/autostart"); if (!autostartDir.exists()) { QDir configDir(QDir::homePath() + "/.config"); configDir.mkdir("autostart"); } metaFile.copy(autostartFile.fileName()); //! I haven't added the flag "OnlyShowIn=KDE;" into the autostart file //! because I fall onto a Plasma 5.8 case that this flag //! didn't let the plasma desktop to start emit autostartChanged(); } } bool UniversalSettings::canDisableBorders() const { return m_canDisableBorders; } void UniversalSettings::setCanDisableBorders(bool enable) { if (m_canDisableBorders == enable) { return; } m_canDisableBorders = enable; emit canDisableBordersChanged(); } bool UniversalSettings::colorsScriptIsPresent() const { return m_colorsScriptIsPresent; } void UniversalSettings::setColorsScriptIsPresent(bool present) { if (m_colorsScriptIsPresent == present) { return; } m_colorsScriptIsPresent = present; emit colorsScriptIsPresentChanged(); } void UniversalSettings::updateColorsScriptIsPresent() { setColorsScriptIsPresent(!Layouts::Importer::standardPath(KWINCOLORSSCRIPT).isEmpty()); } void UniversalSettings::colorsScriptChanged(const QString &file) { if (!file.endsWith(KWINCOLORSSCRIPT)) { return; } updateColorsScriptIsPresent(); } bool UniversalSettings::metaForwardedToLatte() const { return kwin_metaForwardedToLatte(); } void UniversalSettings::forwardMetaToLatte(bool forward) { kwin_forwardMetaToLatte(forward); } bool UniversalSettings::kwin_metaForwardedToLatte() const { QProcess process; process.start("kreadconfig5 --file kwinrc --group ModifierOnlyShortcuts --key Meta"); process.waitForFinished(); QString output(process.readAllStandardOutput()); output = output.remove("\n"); return (output == KWINMETAFORWARDTOLATTESTRING); } void UniversalSettings::kwin_forwardMetaToLatte(bool forward) { if (kwin_metaForwardedToLatte() == forward) { return; } QProcess process; QStringList parameters; parameters << "--file" << "kwinrc" << "--group" << "ModifierOnlyShortcuts" << "--key" << "Meta"; if (forward) { parameters << KWINMETAFORWARDTOLATTESTRING; } else { parameters << KWINMETAFORWARDTOPLASMASTRING; } process.start("kwriteconfig5", parameters); process.waitForFinished(); QDBusInterface iface("org.kde.KWin", "/KWin", "", QDBusConnection::sessionBus()); if (iface.isValid()) { iface.call("reconfigure"); } } bool UniversalSettings::metaPressAndHoldEnabled() const { return m_metaPressAndHoldEnabled; } void UniversalSettings::setMetaPressAndHoldEnabled(bool enabled) { if (m_metaPressAndHoldEnabled == enabled) { return; } m_metaPressAndHoldEnabled = enabled; emit metaPressAndHoldEnabledChanged(); } Types::LayoutsMemoryUsage UniversalSettings::layoutsMemoryUsage() const { return m_memoryUsage; } void UniversalSettings::setLayoutsMemoryUsage(Types::LayoutsMemoryUsage layoutsMemoryUsage) { if (m_memoryUsage == layoutsMemoryUsage) { return; } m_memoryUsage = layoutsMemoryUsage; emit layoutsMemoryUsageChanged(); } Types::MouseSensitivity UniversalSettings::mouseSensitivity() const { return m_mouseSensitivity; } void UniversalSettings::setMouseSensitivity(Types::MouseSensitivity sensitivity) { if (m_mouseSensitivity == sensitivity) { return; } m_mouseSensitivity = sensitivity; emit mouseSensitivityChanged(); } float UniversalSettings::screenWidthScale(QString screenName) const { if (!m_screenScales.contains(screenName)) { return 1; } return m_screenScales[screenName].first; } float UniversalSettings::screenHeightScale(QString screenName) const { if (!m_screenScales.contains(screenName)) { return 1; } return m_screenScales[screenName].second; } void UniversalSettings::setScreenScales(QString screenName, float widthScale, float heightScale) { if (!m_screenScales.contains(screenName)) { m_screenScales[screenName].first = widthScale; m_screenScales[screenName].second = heightScale; } else { if (m_screenScales[screenName].first == widthScale && m_screenScales[screenName].second == heightScale) { return; } m_screenScales[screenName].first = widthScale; m_screenScales[screenName].second = heightScale; } emit screenScalesChanged(); } void UniversalSettings::loadConfig() { m_version = m_universalGroup.readEntry("version", 1); m_canDisableBorders = m_universalGroup.readEntry("canDisableBorders", false); m_currentLayoutName = m_universalGroup.readEntry("currentLayout", QString()); m_downloadWindowSize = m_universalGroup.readEntry("downloadWindowSize", QSize(800, 550)); m_lastNonAssignedLayoutName = m_universalGroup.readEntry("lastNonAssignedLayout", QString()); m_layoutsWindowSize = m_universalGroup.readEntry("layoutsWindowSize", QSize(700, 450)); m_layoutsColumnWidths = m_universalGroup.readEntry("layoutsColumnWidths", QStringList()); m_launchers = m_universalGroup.readEntry("launchers", QStringList()); m_metaPressAndHoldEnabled = m_universalGroup.readEntry("metaPressAndHoldEnabled", true); m_screenTrackerInterval = m_universalGroup.readEntry("screenTrackerInterval", 2500); m_showInfoWindow = m_universalGroup.readEntry("showInfoWindow", true); m_memoryUsage = static_cast(m_universalGroup.readEntry("memoryUsage", (int)Types::SingleLayout)); m_mouseSensitivity = static_cast(m_universalGroup.readEntry("mouseSensitivity", (int)Types::HighSensitivity)); loadScalesConfig(); } void UniversalSettings::saveConfig() { m_universalGroup.writeEntry("version", m_version); m_universalGroup.writeEntry("canDisableBorders", m_canDisableBorders); m_universalGroup.writeEntry("currentLayout", m_currentLayoutName); m_universalGroup.writeEntry("downloadWindowSize", m_downloadWindowSize); m_universalGroup.writeEntry("lastNonAssignedLayout", m_lastNonAssignedLayoutName); m_universalGroup.writeEntry("layoutsWindowSize", m_layoutsWindowSize); m_universalGroup.writeEntry("layoutsColumnWidths", m_layoutsColumnWidths); m_universalGroup.writeEntry("launchers", m_launchers); m_universalGroup.writeEntry("metaPressAndHoldEnabled", m_metaPressAndHoldEnabled); m_universalGroup.writeEntry("screenTrackerInterval", m_screenTrackerInterval); m_universalGroup.writeEntry("showInfoWindow", m_showInfoWindow); m_universalGroup.writeEntry("memoryUsage", (int)m_memoryUsage); m_universalGroup.writeEntry("mouseSensitivity", (int)m_mouseSensitivity); m_universalGroup.sync(); } void UniversalSettings::cleanupSettings() { KConfigGroup containments = KConfigGroup(m_config, QStringLiteral("Containments")); containments.deleteGroup(); containments.sync(); } QString UniversalSettings::splitterIconPath() { return m_corona->kPackage().filePath("splitter"); } QString UniversalSettings::trademarkIconPath() { return m_corona->kPackage().filePath("trademark"); } QQmlListProperty UniversalSettings::screens() { return QQmlListProperty(this, nullptr, &countScreens, &atScreens); } int UniversalSettings::countScreens(QQmlListProperty *property) { Q_UNUSED(property) return qGuiApp->screens().count(); } QScreen *UniversalSettings::atScreens(QQmlListProperty *property, int index) { Q_UNUSED(property) return qGuiApp->screens().at(index); } void UniversalSettings::loadScalesConfig() { for (const auto &screenName : m_screenScalesGroup.keyList()) { QString scalesStr = m_screenScalesGroup.readEntry(screenName, QString()); QStringList scales = scalesStr.split(";"); if (scales.count() == 2) { m_screenScales[screenName] = qMakePair(scales[0].toFloat(), scales[1].toFloat()); } } } void UniversalSettings::saveScalesConfig() { for (const auto &screenName : m_screenScales.keys()) { QStringList scales; scales << QString::number(m_screenScales[screenName].first) << QString::number(m_screenScales[screenName].second); m_screenScalesGroup.writeEntry(screenName, scales.join(";")); } m_screenScalesGroup.sync(); } } diff --git a/app/settings/universalsettings.h b/app/settings/universalsettings.h index 2ace19e8..1b0842da 100644 --- a/app/settings/universalsettings.h +++ b/app/settings/universalsettings.h @@ -1,205 +1,206 @@ /* * Copyright 2017 Smith AR * Michail Vourlakos * * 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 . */ #ifndef UNIVERSALSETTINGS_H #define UNIVERSALSETTINGS_H // local #include "../lattecorona.h" #include "../liblatte2/types.h" // Qt #include #include #include #include #include #include #include // KDE #include #include namespace Latte { namespace Layouts { class Manager; } } namespace Latte { //width_scale, height_scale typedef QPair ScreenScales; //! This class holds all the settings that are universally available //! independent of layouts class UniversalSettings : public QObject { Q_OBJECT Q_PROPERTY(bool autostart READ autostart WRITE setAutostart NOTIFY autostartChanged) Q_PROPERTY(bool colorsScriptIsPresent READ colorsScriptIsPresent NOTIFY colorsScriptIsPresentChanged) Q_PROPERTY(bool showInfoWindow READ showInfoWindow WRITE setShowInfoWindow NOTIFY showInfoWindowChanged) Q_PROPERTY(QString currentLayoutName READ currentLayoutName WRITE setCurrentLayoutName NOTIFY currentLayoutNameChanged) Q_PROPERTY(QStringList launchers READ launchers WRITE setLaunchers NOTIFY launchersChanged) Q_PROPERTY(Latte::Types::MouseSensitivity mouseSensitivity READ mouseSensitivity WRITE setMouseSensitivity NOTIFY mouseSensitivityChanged) Q_PROPERTY(QQmlListProperty screens READ screens) public: UniversalSettings(KSharedConfig::Ptr config, QObject *parent = nullptr); ~UniversalSettings() override; void load(); bool autostart() const; void setAutostart(bool state); bool canDisableBorders() const; void setCanDisableBorders(bool enable); bool colorsScriptIsPresent() const; bool metaForwardedToLatte() const; void forwardMetaToLatte(bool forward); bool metaPressAndHoldEnabled() const; void setMetaPressAndHoldEnabled(bool enabled); bool showInfoWindow() const; void setShowInfoWindow(bool show); int version() const; void setVersion(int ver); int screenTrackerInterval() const; void setScreenTrackerInterval(int duration); QString currentLayoutName() const; void setCurrentLayoutName(QString layoutName); QString lastNonAssignedLayoutName() const; void setLastNonAssignedLayoutName(QString layoutName); QSize downloadWindowSize() const; void setDownloadWindowSize(QSize size); QSize layoutsWindowSize() const; void setLayoutsWindowSize(QSize size); QStringList layoutsColumnWidths() const; void setLayoutsColumnWidths(QStringList widths); QStringList launchers() const; void setLaunchers(QStringList launcherList); Types::MouseSensitivity mouseSensitivity() const; void setMouseSensitivity(Types::MouseSensitivity sensitivity); QQmlListProperty screens(); static int countScreens(QQmlListProperty *property); //! is needed by screens() static QScreen *atScreens(QQmlListProperty *property, int index); //! is needed by screens() public slots: Q_INVOKABLE QString splitterIconPath(); Q_INVOKABLE QString trademarkIconPath(); Q_INVOKABLE float screenWidthScale(QString screenName) const; Q_INVOKABLE float screenHeightScale(QString screenName) const; Q_INVOKABLE void setScreenScales(QString screenName, float widthScale, float heightScale); signals: void autostartChanged(); void canDisableBordersChanged(); void colorsScriptIsPresentChanged(); void currentLayoutNameChanged(); void downloadWindowSizeChanged(); void lastNonAssignedLayoutNameChanged(); void layoutsColumnWidthsChanged(); void layoutsWindowSizeChanged(); void launchersChanged(); void layoutsMemoryUsageChanged(); void metaPressAndHoldEnabledChanged(); void mouseSensitivityChanged(); + void screensCountChanged(); void screenScalesChanged(); void screenTrackerIntervalChanged(); void showInfoWindowChanged(); void versionChanged(); private slots: void loadConfig(); void loadScalesConfig(); void saveConfig(); void saveScalesConfig(); void updateColorsScriptIsPresent(); void colorsScriptChanged(const QString &file); private: void cleanupSettings(); bool kwin_metaForwardedToLatte() const; void kwin_forwardMetaToLatte(bool forward); void setColorsScriptIsPresent(bool present); Types::LayoutsMemoryUsage layoutsMemoryUsage() const; void setLayoutsMemoryUsage(Types::LayoutsMemoryUsage layoutsMemoryUsage); private: bool m_canDisableBorders{false}; bool m_colorsScriptIsPresent{false}; bool m_metaPressAndHoldEnabled{true}; bool m_showInfoWindow{true}; //when there isnt a version it is an old universal file int m_version{1}; int m_screenTrackerInterval{2500}; QString m_currentLayoutName; QString m_lastNonAssignedLayoutName; QSize m_downloadWindowSize{800, 550}; QSize m_layoutsWindowSize{700, 450}; QStringList m_layoutsColumnWidths; QStringList m_launchers; Types::LayoutsMemoryUsage m_memoryUsage; Types::MouseSensitivity m_mouseSensitivity{Types::HighSensitivity}; //! ScreenName, QHash m_screenScales; QPointer m_corona; KConfigGroup m_screenScalesGroup; KConfigGroup m_universalGroup; KSharedConfig::Ptr m_config; friend class Layouts::Manager; friend class Latte::Corona; }; } #endif //UNIVERSALSETTINGS_H diff --git a/declarativeimports/components/ComboBox.qml b/declarativeimports/components/ComboBox.qml index a32e8808..4ac487e1 100644 --- a/declarativeimports/components/ComboBox.qml +++ b/declarativeimports/components/ComboBox.qml @@ -1,368 +1,378 @@ /* * Copyright 2016 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.7 import QtQuick.Window 2.2 import QtQuick.Templates 2.2 as T import QtQuick.Controls 2.2 as Controls import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.kirigami 2.5 as Kirigami import "private" as Private T.ComboBox { id: control implicitWidth: Math.max(background ? background.implicitWidth : 0, contentItem.implicitWidth + leftPadding + rightPadding) + indicator.implicitWidth + rightPadding implicitHeight: units.gridUnit * 1.6 baselineOffset: contentItem.y + contentItem.baselineOffset hoverEnabled: true topPadding: surfaceNormal.margins.top leftPadding: surfaceNormal.margins.left rightPadding: surfaceNormal.margins.right + units.gridUnit * 2 bottomPadding: surfaceNormal.margins.bottom wheelEnabled: false property bool blankSpaceForEmptyIcons: false property bool forcePressed: false property bool popUpAlignRight: true property int minimumPopUpWidth: 150 property int popUpRelativeX: 0 property string enabledRole property string iconRole property string iconToolTipRole property string iconOnlyWhenHoveredRole signal iconClicked(int index); delegate: ItemDelegate { width: control.popup.width enabled: control.enabledRole ? (Array.isArray(control.model) ? modelData[control.enabledRole] : model[control.enabledRole]) : true text: control.textRole ? (Array.isArray(control.model) ? modelData[control.textRole] : model[control.textRole]) : modelData icon: control.iconRole ? (Array.isArray(control.model) ? modelData[control.iconRole] : model[control.iconRole]) : '' iconToolTip: control.iconToolTipRole ? (Array.isArray(control.model) ? modelData[control.iconToolTipRole] : model[control.iconToolTipRole]) : '' iconOnlyWhenHovered: control.iconOnlyWhenHoveredRole ? (Array.isArray(control.model) ? modelData[control.iconOnlyWhenHoveredRole] : model[control.iconOnlyWhenHoveredRole]) : '' highlighted: mouseArea.pressed ? listView.currentIndex == index : control.currentIndex == index blankSpaceForEmptyIcons: control.blankSpaceForEmptyIcons property bool separatorVisible: false } indicator: PlasmaCore.SvgItem { implicitWidth: units.iconSizes.small implicitHeight: implicitWidth anchors { right: parent.right rightMargin: surfaceNormal.margins.right verticalCenter: parent.verticalCenter } svg: PlasmaCore.Svg { imagePath: "widgets/arrows" colorGroup: PlasmaCore.Theme.ButtonColorGroup } elementId: "down-arrow" } // contentItem: Label { // text: control.displayText // font: control.font // color: theme.buttonTextColor // horizontalAlignment: Text.AlignLeft // verticalAlignment: Text.AlignVCenter // elide: Text.ElideRight // } contentItem: MouseArea { id: mouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton preventStealing: true property int indexUnderMouse: -1 onWheel: { if (!control.wheelEnabled) { return; } if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) { control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1); } else { control.currentIndex = Math.max(control.currentIndex - 1, 0); } control.activated(control.currentIndex); } onPressed: { indexUnderMouse = -1; listView.currentIndex = control.highlightedIndex control.down = true; control.pressed = true; control.popup.visible = !control.popup.visible; } onReleased: { if (!containsMouse) { control.down = false; control.pressed = false; control.popup.visible = false; } if (indexUnderMouse > -1) { control.currentIndex = indexUnderMouse; } } onCanceled: { control.down = false; control.pressed = false; } onPositionChanged: { var pos = listView.mapFromItem(this, mouse.x, mouse.y); indexUnderMouse = listView.indexAt(pos.x, pos.y); listView.currentIndex = indexUnderMouse; control.activated(indexUnderMouse); } Connections { target: popup onClosed: { control.down = false; control.pressed = false; } } RowLayout { anchors.fill: parent PlasmaCore.IconItem { id: selectedIcon Layout.leftMargin: 2 width: textField.height height: textField.height colorGroup: PlasmaCore.Theme.ButtonColorGroup - source: control.iconRole === "icon" ? control.model.get(control.currentIndex).icon : '' + source: { + if (control && control.currentIndex>=0 && + control.iconRole && control.iconRole === "icon" + && control.model && control.model.get(control.currentIndex) + && control.model.get(control.currentIndex)) { + + return control.model.get(control.currentIndex).icon; + } + + return ""; + } visible: source !== '' } T.TextField { id: textField padding: 0 Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: selectedIcon.visible ? 0 : control.leftPadding Layout.rightMargin: control.rightPadding Layout.topMargin: control.topPadding Layout.bottomMargin: control.bottomPadding text: control.editable ? control.editText : control.displayText enabled: control.editable autoScroll: control.editable readOnly: control.down || !control.hasOwnProperty("editable") || !control.editable inputMethodHints: control.inputMethodHints validator: control.validator // Work around Qt bug where NativeRendering breaks for non-integer scale factors // https://bugreports.qt.io/browse/QTBUG-67007 renderType: Screen.devicePixelRatio % 1 !== 0 ? Text.QtRendering : Text.NativeRendering color: theme.buttonTextColor //control.enabled ? theme.textColor : theme.disabledTextColor selectionColor: Kirigami.Theme.highlightColor selectedTextColor: Kirigami.Theme.highlightedTextColor selectByMouse: !Kirigami.Settings.tabletMode cursorDelegate: Kirigami.Settings.tabletMode ? mobileCursor : undefinedCursor font: control.font horizontalAlignment: Text.AlignLeft verticalAlignment: Text.AlignVCenter opacity: control.enabled ? 1 : 0.6 onFocusChanged: { if (focus) { Private.MobileTextActionsToolBar.controlRoot = textField; } } onPressAndHold: { if (!Kirigami.Settings.tabletMode) { return; } forceActiveFocus(); cursorPosition = positionAt(event.x, event.y); selectWord(); } } } } Component { id: mobileCursor Private.MobileCursor { target: textField } } Component { id: undefinedCursor Item{} } Private.MobileCursor { target: textField selectionStartHandle: true property var rect: textField.positionToRectangle(textField.selectionStart) //FIXME: this magic values seem to be always valid, for every font,every dpi, every scaling x: rect.x + 5 y: rect.y + 6 } background: PlasmaCore.FrameSvgItem { id: surfaceNormal //retrocompatibility with old controls implicitWidth: units.gridUnit * 6 anchors.fill: parent readonly property bool editable: control.hasOwnProperty("editable") && control.editable imagePath: editable ? "widgets/lineedit" : "widgets/button" prefix: editable ? "base" : (control.pressed || control.forcePressed ? "pressed" : "normal") Private.TextFieldFocus { visible: parent.editable z: -1 state: control.activeFocus ? "focus" : (control.hovered ? "hover" : "hidden") anchors.fill: parent } Private.ButtonShadow { z: -1 visible: !parent.editable anchors.fill: parent state: { if (control.pressed) { return "hidden" } else if (control.hovered) { return "hover" } else if (control.activeFocus) { return "focus" } else { return "shadow" } } } MouseArea { anchors { fill: parent leftMargin: control.leftPadding rightMargin: control.rightPadding } acceptedButtons: Qt.NoButton onWheel: { if (!control.wheelEnabled) { return; } if (wheel.pixelDelta.y < 0 || wheel.angleDelta.y < 0) { control.currentIndex = Math.min(control.currentIndex + 1, delegateModel.count -1); } else { control.currentIndex = Math.max(control.currentIndex - 1, 0); } control.activated(control.currentIndex); } } } popup: T.Popup { x: { if (!control.mirrored) { if (popUpRelativeX !== 0) { var adjustedX = exceedsContent && control.popUpAlignRight ? -(width - control.width) : popUpRelativeX; return adjustedX; } else { return 0; } } else { //! mirrored case if (exceedsContent && control.popUpAlignRight) { var adjustedX = width - control.width - popUpRelativeX; return -adjustedX; } else { return 0; } } } y: control.height width: Math.max(control.width, control.minimumPopUpWidth) implicitHeight: contentItem.implicitHeight topMargin: 6 bottomMargin: 6 readonly property bool exceedsContent: control.width < width /*onVisibleChanged: { if (visible) { console.log(" mirrored:" + control.mirrored); console.log(" exceeds: " + exceedsContent); console.log(" popupAR: " + control.popUpAlignRight); console.log(" popupRX: " + popUpRelativeX); } }*/ contentItem: ListView { id: listView clip: true implicitHeight: contentHeight model: control.popup.visible ? control.delegateModel : null currentIndex: control.highlightedIndex highlightRangeMode: ListView.ApplyRange highlightMoveDuration: 0 // HACK: When the ComboBox is not inside a top-level Window, it's Popup does not inherit // the LayoutMirroring options. This is a workaround to fix this by enforcing // the LayoutMirroring options properly. // QTBUG: https://bugreports.qt.io/browse/QTBUG-66446 LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true T.ScrollBar.vertical: Controls.ScrollBar { } signal iconClicked(int index); onIconClicked: control.iconClicked(index); } background: Rectangle { anchors { fill: parent margins: -1 } radius: 2 color: theme.viewBackgroundColor border.color: Qt.rgba(theme.textColor.r, theme.textColor.g, theme.textColor.b, 0.3) layer.enabled: true layer.effect: DropShadow { transparentBorder: true radius: 4 samples: 8 horizontalOffset: 2 verticalOffset: 2 color: Qt.rgba(0, 0, 0, 0.3) } } } } diff --git a/shell/package/contents/configuration/pages/BehaviorConfig.qml b/shell/package/contents/configuration/pages/BehaviorConfig.qml index 8b7147fb..de2e6816 100644 --- a/shell/package/contents/configuration/pages/BehaviorConfig.qml +++ b/shell/package/contents/configuration/pages/BehaviorConfig.qml @@ -1,787 +1,792 @@ /* * Copyright 2016 Smith AR * Michail Vourlakos * * 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 . */ import QtQuick 2.0 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.components 3.0 as PlasmaComponents3 import org.kde.plasma.plasmoid 2.0 import org.kde.latte 0.2 as Latte import org.kde.latte.components 1.0 as LatteComponents import "../../controls" as LatteExtraControls PlasmaComponents.Page { Layout.maximumWidth: content.width + content.Layout.leftMargin * 2 Layout.maximumHeight: content.height + units.smallSpacing * 2 ColumnLayout { id: content width: (dialog.appliedWidth - units.smallSpacing * 2) - Layout.leftMargin * 2 spacing: dialog.subGroupSpacing anchors.horizontalCenter: parent.horizontalCenter Layout.leftMargin: units.smallSpacing * 2 //! BEGIN: Inline Dock/Panel Type, it is used only when the secondary window //! overlaps the main dock config window ColumnLayout { Layout.fillWidth: true spacing: units.smallSpacing Layout.topMargin: units.smallSpacing visible: dialog.highLevel && viewConfig.showInlineProperties LatteComponents.Header { text: i18n("Type") } LatteExtraControls.TypeSelection{ id: viewTypeSelection horizontal: true } } //! END: Inline Dock/Panel Type //! BEGIN: Location ColumnLayout { Layout.fillWidth: true spacing: units.smallSpacing Layout.topMargin: units.smallSpacing LatteComponents.Header { text: screenRow.visible ? i18n("Screen") : i18n("Location") } + Connections { + target: universalSettings + onScreensCountChanged: screenRow.updateScreens() + } + RowLayout { id: screenRow Layout.fillWidth: true Layout.leftMargin: units.smallSpacing * 2 Layout.rightMargin: units.smallSpacing * 3 spacing: 2 visible: true function updateScreens() { if (universalSettings.screens.length > 1) { screenRow.visible = true; } else { screenRow.visible = false; } screensModel.clear(); var primary = {name: i18n("On Primary"), icon: 'favorites'}; screensModel.append(primary); //check if the screen exists, it is used in cases Latte is moving //the view automatically to primaryScreen in order for the user //to has always a view with tasks shown var screenExists = false for (var i = 0; i < universalSettings.screens.length; i++) { if (universalSettings.screens[i].name === latteView.positioner.currentScreenName) { screenExists = true; } } if (!screenExists && !latteView.onPrimary) { var scr = {name: latteView.positioner.currentScreenName, icon: 'view-fullscreen'}; screensModel.append(scr); } for (var i = 0; i < universalSettings.screens.length; i++) { var scr = {name: universalSettings.screens[i].name, icon: 'view-fullscreen'}; screensModel.append(scr); } if (latteView.onPrimary) { screenCmb.currentIndex = 0; } else { screenCmb.currentIndex = screenCmb.findScreen(latteView.positioner.currentScreenName); } console.log(latteView.positioner.currentScreenName); } Connections{ target: viewConfig onShowSignal: screenRow.updateScreens(); } ListModel { id: screensModel } LatteComponents.ComboBox { id: screenCmb Layout.fillWidth: true model: screensModel textRole: "name" iconRole: "icon" Component.onCompleted: screenRow.updateScreens(); //they are used to restore the index when the screen edge //is occupied property bool acceptedIndex: true property int previousIndex: -1 onCurrentIndexChanged: { //it is used to restore the index when the screen edge //is occupied if (!acceptedIndex) { acceptedIndex = true; currentIndex = previousIndex; } } onActivated: { previousIndex = currentIndex; if (index === 0) { var succeed = latteView.positioner.setCurrentScreen("primary"); latteView.onPrimary = true; acceptedIndex = true; } else if (index>0 && (index !== findScreen(latteView.positioner.currentScreenName) || latteView.onPrimary)) { console.log("current index changed!!! :"+ index); console.log("screen must be changed..."); var succeed = latteView.positioner.setCurrentScreen(textAt(index)); if(succeed) { latteView.onPrimary = false; } else { console.log("the edge is already occupied!!!"); acceptedIndex = false; } } } function findScreen(scrName) { for(var i=0; i=0); topEdgeBtn.edgeIsFree = (edges.indexOf(topEdgeBtn.edge)>=0); leftEdgeBtn.edgeIsFree = (edges.indexOf(leftEdgeBtn.edge)>=0); rightEdgeBtn.edgeIsFree = (edges.indexOf(rightEdgeBtn.edge)>=0); } PlasmaComponents.Button { id: bottomEdgeBtn Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18nc("bottom location", "Bottom") iconSource: "arrow-down" checked: latteView.location === edge checkable: true enabled: checked || edgeIsFree exclusiveGroup: locationGroup property bool edgeIsFree: true readonly property int edge: PlasmaCore.Types.BottomEdge } PlasmaComponents.Button { id: leftEdgeBtn Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18nc("left location", "Left") iconSource: "arrow-left" checked: latteView.location === edge checkable: true enabled: checked || edgeIsFree exclusiveGroup: locationGroup property bool edgeIsFree: true readonly property int edge: PlasmaCore.Types.LeftEdge } PlasmaComponents.Button { id: topEdgeBtn Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18nc("top location", "Top") iconSource: "arrow-up" checked: latteView.location === edge checkable: true enabled: checked || edgeIsFree exclusiveGroup: locationGroup property bool edgeIsFree: true readonly property int edge: PlasmaCore.Types.TopEdge } PlasmaComponents.Button { id: rightEdgeBtn Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18nc("right location", "Right") iconSource: "arrow-right" checked: latteView.location === edge checkable: true enabled: checked || edgeIsFree exclusiveGroup: locationGroup property bool edgeIsFree: true readonly property int edge: PlasmaCore.Types.RightEdge } } } //! END: Location //! BEGIN: Alignment ColumnLayout { Layout.fillWidth: true spacing: units.smallSpacing LatteComponents.Header { text: i18n("Alignment") } RowLayout { id: alignmentRow Layout.fillWidth: true Layout.leftMargin: units.smallSpacing * 2 Layout.rightMargin: units.smallSpacing * 2 LayoutMirroring.enabled: false spacing: 2 readonly property int panelPosition: plasmoid.configuration.panelPosition readonly property int buttonSize: (dialog.optionsWidth - (spacing * 3)) / 4 ExclusiveGroup { id: alignmentGroup onCurrentChanged: { if (current.checked) plasmoid.configuration.panelPosition = current.position } } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: panelIsVertical ? i18nc("top alignment", "Top") : i18nc("left alignment", "Left") iconSource: panelIsVertical ? "format-align-vertical-top" : "format-justify-left" checked: parent.panelPosition === position checkable: true exclusiveGroup: alignmentGroup property int position: panelIsVertical ? Latte.Types.Top : Latte.Types.Left } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18nc("center alignment", "Center") iconSource: panelIsVertical ? "format-align-vertical-center" : "format-justify-center" checked: parent.panelPosition === position checkable: true exclusiveGroup: alignmentGroup property int position: Latte.Types.Center } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: panelIsVertical ? i18nc("bottom alignment", "Bottom") : i18nc("right alignment", "Right") iconSource: panelIsVertical ? "format-align-vertical-bottom" : "format-justify-right" checked: parent.panelPosition === position checkable: true exclusiveGroup: alignmentGroup property int position: panelIsVertical ? Latte.Types.Bottom : Latte.Types.Right } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18nc("justify alignment", "Justify") iconSource: "format-justify-fill" checked: parent.panelPosition === position checkable: true exclusiveGroup: alignmentGroup property int position: Latte.Types.Justify } } } //! END: Alignment //! BEGIN: Visibility ColumnLayout { Layout.fillWidth: true spacing: units.smallSpacing LatteComponents.Header { text: i18n("Visibility") } GridLayout { width: parent.width rowSpacing: 1 columnSpacing: 2 Layout.leftMargin: units.smallSpacing * 2 Layout.rightMargin: units.smallSpacing * 2 columns: 2 property int mode: latteView.visibility.mode readonly property int buttonSize: (dialog.optionsWidth - (columnSpacing)) / 2 ExclusiveGroup { id: visibilityGroup onCurrentChanged: { if (current.checked) latteView.visibility.mode = current.mode } } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18n("Always Visible") checked: parent.mode === mode checkable: true exclusiveGroup: visibilityGroup property int mode: Latte.Types.AlwaysVisible } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18n("Auto Hide") checked: parent.mode === mode checkable: true exclusiveGroup: visibilityGroup property int mode: Latte.Types.AutoHide } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18n("Dodge Active") checked: parent.mode === mode checkable: true exclusiveGroup: visibilityGroup property int mode: Latte.Types.DodgeActive } PlasmaComponents.Button { Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18n("Dodge Maximized") checked: parent.mode === mode checkable: true exclusiveGroup: visibilityGroup property int mode: Latte.Types.DodgeMaximized } PlasmaComponents.Button { id: dodgeAllWindowsBtn Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18n("Dodge All Windows") checked: parent.mode === mode checkable: true exclusiveGroup: visibilityGroup property int mode: Latte.Types.DodgeAllWindows } PlasmaComponents.Button { id: windowsGoBelowBtn Layout.minimumWidth: parent.buttonSize Layout.maximumWidth: Layout.minimumWidth text: i18n("Windows Go Below") checked: parent.mode === mode checkable: true exclusiveGroup: visibilityGroup property int mode: Latte.Types.WindowsGoBelow } } } //! END: Visibility //! BEGIN: Delay ColumnLayout { Layout.fillWidth: true spacing: units.smallSpacing enabled: !(latteView.visibility.mode === Latte.Types.AlwaysVisible || latteView.visibility.mode === Latte.Types.WindowsGoBelow) LatteComponents.Header { text: i18n("Delay") } Flow { width: dialog.optionsWidth Layout.minimumWidth: dialog.optionsWidth Layout.maximumWidth: dialog.optionsWidth Layout.leftMargin: units.smallSpacing * 2 Layout.rightMargin: units.smallSpacing * 2 Layout.topMargin: units.smallSpacing spacing: 2 readonly property bool overlap: showContainer.overlap || hideContainer.overlap Item { id: showContainer width: parent.overlap ? dialog.optionsWidth : oneLineWidth height: childrenRect.height implicitWidth: width implicitHeight: height readonly property bool overlap: oneLineWidth > dodgeAllWindowsBtn.width readonly property int oneLineWidth: Math.max(dodgeAllWindowsBtn.width, showTimerRow.width) RowLayout{ id: showTimerRow anchors.horizontalCenter: parent.horizontalCenter PlasmaComponents.Label { Layout.leftMargin: Qt.application.layoutDirection === Qt.RightToLeft ? units.smallSpacing : 0 Layout.rightMargin: Qt.application.layoutDirection === Qt.RightToLeft ? 0 : units.smallSpacing text: i18n("Show ") } LatteComponents.TextField { Layout.preferredWidth: width text: latteView.visibility.timerShow onValueChanged: { latteView.visibility.timerShow = value } } } } Item { id: hideContainer width: parent.overlap ? dialog.optionsWidth : oneLineWidth height: childrenRect.height implicitWidth: width implicitHeight: height readonly property bool overlap: oneLineWidth > windowsGoBelowBtn.width readonly property int oneLineWidth: Math.max(windowsGoBelowBtn.width, hideTimerRow.width) RowLayout { id: hideTimerRow anchors.horizontalCenter: parent.horizontalCenter PlasmaComponents.Label { Layout.leftMargin: Qt.application.layoutDirection === Qt.RightToLeft ? units.smallSpacing : 0 Layout.rightMargin: Qt.application.layoutDirection === Qt.RightToLeft ? 0 : units.smallSpacing text: i18n("Hide") } LatteComponents.TextField{ Layout.preferredWidth: width text: latteView.visibility.timerHide onValueChanged: { latteView.visibility.timerHide = value } } } } } } //! END: Delay //! BEGIN: Actions ColumnLayout { spacing: units.smallSpacing visible: dialog.expertLevel LatteComponents.Header { text: i18n("Actions") } ColumnLayout { Layout.leftMargin: units.smallSpacing * 2 Layout.rightMargin: units.smallSpacing * 2 spacing: 0 LatteComponents.SubHeader { text: i18n("Empty Area") } ColumnLayout { RowLayout { Layout.topMargin: units.smallSpacing PlasmaComponents.Label { id: mouseWheelLbl text: i18n("Mouse wheel") } LatteComponents.ComboBox { id: scrollAction Layout.fillWidth: true model: [i18nc("none scroll actions", "None Action"), i18n("Cycle Through Desktops"), i18n("Cycle Through Activities"), i18n("Cycle Through Tasks")] currentIndex: plasmoid.configuration.scrollAction onCurrentIndexChanged: { switch(currentIndex) { case Latte.Types.ScrollNone: plasmoid.configuration.scrollAction = Latte.Types.ScrollNone; break; case Latte.Types.ScrollDesktops: plasmoid.configuration.scrollAction = Latte.Types.ScrollDesktops; break; case Latte.Types.ScrollActivities: plasmoid.configuration.scrollAction = Latte.Types.ScrollActivities; break; case Latte.Types.ScrollTasks: plasmoid.configuration.scrollAction = Latte.Types.ScrollTasks; break; } } } } } LatteComponents.SubHeader { text: i18n("Active Window") } ColumnLayout { RowLayout { Layout.topMargin: units.smallSpacing PlasmaComponents.Label { Layout.minimumWidth: mouseWheelLbl.width Layout.maximumWidth: mouseWheelLbl.width text: i18n("Track From") } LatteComponents.ComboBox { id: activeWindowFilterCmb Layout.fillWidth: true model: [i18nc("track from current screen", "Current Screen"), i18nc("track from all screens", "All Screens")] currentIndex: plasmoid.configuration.activeWindowFilter onCurrentIndexChanged: { switch(currentIndex) { case Latte.Types.ActiveInCurrentScreen: plasmoid.configuration.activeWindowFilter = Latte.Types.ActiveInCurrentScreen; break; case Latte.Types.ActiveFromAllScreens: plasmoid.configuration.activeWindowFilter = Latte.Types.ActiveFromAllScreens; break; } } } } LatteComponents.CheckBox { Layout.maximumWidth: dialog.optionsWidth Layout.topMargin: units.smallSpacing text: i18n("Drag and maximize/restore active window") checked: plasmoid.configuration.dragActiveWindowEnabled tooltip: i18n("Drag/Maximize/Restore active window with double-click and dragging actions") visible: dialog.highLevel onClicked: { plasmoid.configuration.dragActiveWindowEnabled = !plasmoid.configuration.dragActiveWindowEnabled; } } } LatteComponents.SubHeader { text: i18n("Items") } LatteComponents.CheckBoxesColumn { LatteComponents.CheckBox { id: titleTooltipsChk Layout.maximumWidth: dialog.optionsWidth text: i18n("Show title tooltips on hovering") tooltip: i18n("Show thinner tooltips produced by Latte for items.\nThese tooltips are not drawn when applets zoom effect is disabled"); checked: plasmoid.configuration.titleTooltips enabled: plasmoid.configuration.zoomLevel > 0 onClicked: { plasmoid.configuration.titleTooltips = !plasmoid.configuration.titleTooltips; } } LatteComponents.CheckBox { id: mouseWheelChk Layout.maximumWidth: dialog.optionsWidth text: i18n("Activate through mouse wheel") checked: plasmoid.configuration.mouseWheelActions tooltip: i18n("Enable/Disable the mouse wheel action") visible: dialog.highLevel onClicked: { plasmoid.configuration.mouseWheelActions = checked } } LatteComponents.CheckBox { Layout.maximumWidth: dialog.optionsWidth // Layout.maximumHeight: mouseWheelChk.height text: i18n("🅰 Activate based on position through global shortcuts") checked: latteView.isPreferredForShortcuts || (!latteView.layout.preferredForShortcutsTouched && latteView.isHighestPriorityView()) tooltip: i18n("This view is used for based on position global shortcuts. Take note that only one view can have that option enabled for each layout") onClicked: { latteView.isPreferredForShortcuts = checked if (!latteView.layout.preferredForShortcutsTouched) { latteView.layout.preferredForShortcutsTouched = true } } } } } } //! END: Actions //! BEGIN: Adjust ColumnLayout { spacing: units.smallSpacing visible: dialog.expertLevel enabled: latteView.visibility.mode !== Latte.Types.AlwaysVisible && latteView.visibility.mode !== Latte.Types.WindowsGoBelow LatteComponents.Header { text: i18n("Environment") } LatteComponents.CheckBoxesColumn { Layout.leftMargin: units.smallSpacing * 2 Layout.rightMargin: units.smallSpacing * 2 LatteComponents.CheckBox { Layout.maximumWidth: dialog.optionsWidth text: i18n("Activate KWin edge after hiding") checked: latteView.visibility.enableKWinEdges tooltip: i18n("After the view becomes hidden, KWin is informed to track user feedback. For example an edge visual hint is shown whenever the mouse approaches the hidden view") onClicked: { latteView.visibility.enableKWinEdges = checked; } } LatteComponents.CheckBox { Layout.maximumWidth: dialog.optionsWidth text: i18n("Can be above fullscreen windows") checked: latteView.byPassWM tooltip: i18n("BypassWindowManagerHint flag for the window. The view will be above all windows even those set as 'Always On Top'") onCheckedChanged: { latteView.byPassWM = checked; } } LatteComponents.CheckBox { Layout.maximumWidth: dialog.optionsWidth text: i18n("Raise on desktop change") checked: latteView.visibility.raiseOnDesktop onClicked: { latteView.visibility.raiseOnDesktop = checked } } LatteComponents.CheckBox { Layout.maximumWidth: dialog.optionsWidth text: i18n("Raise on activity change") checked: latteView.visibility.raiseOnActivity onClicked: { latteView.visibility.raiseOnActivity = checked } } } } //! END: Adjust //! Bottom spacer PlasmaComponents.Label{ id: bottomMarginSpacer text:" " } } }