diff --git a/krunner/CMakeLists.txt b/krunner/CMakeLists.txt --- a/krunner/CMakeLists.txt +++ b/krunner/CMakeLists.txt @@ -23,6 +23,7 @@ KF5::Crash KF5::WaylandClient KF5::QuickAddons + KF5::XmlGui PW::KWorkspace ) target_compile_definitions(krunner PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") diff --git a/krunner/view.h b/krunner/view.h --- a/krunner/view.h +++ b/krunner/view.h @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -93,7 +94,8 @@ void writeHistory(); QPoint m_customPos; KDeclarative::QmlObject *m_qmlObj; - KConfigGroup m_config; + KConfig m_config; + KActionCollection *m_shortcuts; qreal m_offset; bool m_floating : 1; QStringList m_history; diff --git a/krunner/view.cpp b/krunner/view.cpp --- a/krunner/view.cpp +++ b/krunner/view.cpp @@ -35,7 +35,7 @@ #include #include #include - +#include #include #include @@ -50,6 +50,7 @@ View::View(QWindow *) : PlasmaQuick::Dialog(), + m_config("krunnerrc"), m_offset(.5), m_floating(false) { @@ -61,10 +62,8 @@ //used only by screen readers setTitle(i18n("KRunner")); - m_config = KConfigGroup(KSharedConfig::openConfig(QStringLiteral("krunnerrc")), "General"); - setFreeFloating(m_config.readEntry("FreeFloating", false)); - reloadConfig(); + setFreeFloating(m_config.group("General").readEntry("FreeFloating", false)); new AppAdaptor(this); QDBusConnection::sessionBus().registerObject(QStringLiteral("/App"), this); @@ -100,6 +99,69 @@ m_qmlObj->engine()->rootContext()->setContextProperty(QStringLiteral("runnerWindow"), this); m_qmlObj->completeInitialization(); + m_shortcuts = new KActionCollection(this); + QAction *moveToStartOfLine = new QAction(nullptr); + moveToStartOfLine->setText(QStringLiteral("Start of Line")); + m_shortcuts->setDefaultShortcut(moveToStartOfLine, QKeySequence::MoveToStartOfLine); + m_shortcuts->addAction(moveToStartOfLine->text(), moveToStartOfLine); + + QAction *moveToEndOfLine = new QAction(nullptr); + moveToEndOfLine->setText(QStringLiteral("End of Line")); + m_shortcuts->setDefaultShortcut(moveToEndOfLine, QKeySequence::MoveToEndOfLine); + m_shortcuts->addAction(moveToEndOfLine->text(), moveToEndOfLine); + + QAction *previousItem = new QAction(nullptr); + previousItem->setText(QStringLiteral("Previous Item in List")); + m_shortcuts->setDefaultShortcuts(previousItem, QList() << QKeySequence::MoveToPreviousLine << QKeySequence(Qt::CTRL + Qt::Key_K)); + m_shortcuts->addAction(previousItem->text(), previousItem); + + QAction *nextItem = new QAction(nullptr); + nextItem->setText(QStringLiteral("Next Item in List")); + m_shortcuts->setDefaultShortcuts(nextItem, QList() << QKeySequence::MoveToNextLine << QKeySequence(Qt::CTRL + Qt::Key_J)); + m_shortcuts->addAction(nextItem->text(), nextItem); + + QAction *runItem = new QAction(nullptr); + runItem->setText(QStringLiteral("Run Selected Item")); + m_shortcuts->setDefaultShortcuts(runItem, QList() << Qt::Key_Return << Qt::Key_Enter); + m_shortcuts->addAction(runItem->text(), runItem); + + QAction *hideRunnerWindow = new QAction(nullptr); + hideRunnerWindow->setText(QStringLiteral("Hide Runner Window")); + m_shortcuts->setDefaultShortcut(hideRunnerWindow, Qt::Key_Escape); + m_shortcuts->addAction(hideRunnerWindow->text(), hideRunnerWindow); + + QAction *cutSelected = new QAction(nullptr); + cutSelected->setText(i18n("Cut")); + m_shortcuts->setDefaultShortcut(cutSelected, QKeySequence::Cut); + m_shortcuts->addAction(cutSelected->text(), cutSelected); + + QAction *copySelected = new QAction(nullptr); + copySelected->setText(i18n("Copy")); + m_shortcuts->setDefaultShortcut(copySelected, QKeySequence::Copy); + m_shortcuts->addAction(copySelected->text(), copySelected); + + QAction *pasteSelected = new QAction(nullptr); + pasteSelected->setText(i18n("Paste")); + m_shortcuts->setDefaultShortcut(pasteSelected, QKeySequence::Paste); + m_shortcuts->addAction(pasteSelected->text(), pasteSelected); + + QAction *clearAll = new QAction(nullptr); + clearAll->setText(i18n("Clear")); + m_shortcuts->setDefaultShortcut(clearAll, QKeySequence(Qt::CTRL + Qt::Key_U)); + m_shortcuts->addAction(clearAll->text(), clearAll); + + QAction *selectAll = new QAction(nullptr); + selectAll->setText(i18n("Select All")); + m_shortcuts->setDefaultShortcut(selectAll, QKeySequence::SelectAll); + m_shortcuts->addAction(selectAll->text(), selectAll); + + QAction *deselectSelected = new QAction(nullptr); + deselectSelected->setText(i18n("Deselect")); + m_shortcuts->setDefaultShortcut(deselectSelected, QKeySequence::Deselect); + m_shortcuts->addAction(deselectSelected->text(), deselectSelected); + + reloadConfig(); + auto screenRemoved = [this](QScreen* screen) { if (screen == this->screen()) { setScreen(qGuiApp->primaryScreen()); @@ -176,14 +238,27 @@ void View::reloadConfig() { - m_config.config()->reparseConfiguration(); - setFreeFloating(m_config.readEntry("FreeFloating", false)); + m_config.reparseConfiguration(); + setFreeFloating(m_config.group("General").readEntry("FreeFloating", false)); - const QStringList history = m_config.readEntry("history", QStringList()); + const QStringList history = m_config.group("General").readEntry("history", QStringList()); if (m_history != history) { m_history = history; emit historyChanged(); } + + KConfigGroup group = m_config.group("Shortcuts"); + m_shortcuts->readSettings(&group); + for (const QAction *action : m_shortcuts->actions()) { + QObject *qmlShortcut = m_qmlObj->rootObject()->findChild(action->text()); + if (qmlShortcut) { + QVariantList shortcuts; + for (const QKeySequence &keySequence: action->shortcuts()) { + shortcuts << keySequence.toString(); + } + qmlShortcut->setProperty("sequences", shortcuts); + } + } } bool View::event(QEvent *event) @@ -384,7 +459,7 @@ emit historyChanged(); writeHistory(); - m_config.sync(); + m_config.group("General").sync(); } void View::removeFromHistory(int index) @@ -401,5 +476,5 @@ void View::writeHistory() { - m_config.writeEntry("history", m_history); + m_config.group("General").writeEntry("history", m_history); } diff --git a/lookandfeel/contents/runcommand/RunCommand.qml b/lookandfeel/contents/runcommand/RunCommand.qml --- a/lookandfeel/contents/runcommand/RunCommand.qml +++ b/lookandfeel/contents/runcommand/RunCommand.qml @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -import QtQuick 2.6 +import QtQuick 2.11 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 import org.kde.plasma.core 2.0 as PlasmaCore @@ -32,6 +32,118 @@ LayoutMirroring.enabled: Qt.application.layoutDirection === Qt.RightToLeft LayoutMirroring.childrenInherit: true + Shortcut { + objectName: "Start of Line" + onActivated: queryField.cursorPosition = 0; + } + + Shortcut { + objectName: "End of Line" + onActivated: queryField.cursorPosition = queryField.length; + } + + Shortcut { + objectName: "Next Item in List" + onActivated: { + if (queryField.activeFocus) { + if (queryField.lenth === 0) { + root.showHistory = true; + listView.forceActiveFocus(); + } else if (results.count > 0) { + results.forceActiveFocus(); + results.incrementCurrentIndex(); + } + } else if (results.activeFocus) { + results.incrementCurrentIndex(); + } else if (listView.activeFocus) { + listView.incrementCurrentIndex(); + } + } + } + + Shortcut { + objectName: "Previous Item in List" + onActivated: { + if (queryField.activeFocus) { + if (queryField.length === 0) { + root.showHistory = true; + listView.forceActiveFocus(); + } else if (results.count > 0) { + results.forceActiveFocus(); + results.decrementCurrentIndex(); + } + } else if (results.activeFocus) { + results.decrementCurrentIndex(); + } else if (listView.activeFocus) { + listView.decrementCurrentIndex(); + } + } + } + + Shortcut { + objectName: "Run Selected Item" + onActivated: { + if (listView.activeFocus) { + listView.runCurrentIndex(); + } else { + results.runCurrentIndex(root.event); + } + } + } + + Shortcut { + objectName: "Hide Runner Window" + onActivated: { + if (queryField.activeFocus) { + runnerWindow.visible = false; + } else { + queryField.forceActiveFocus(); + } + } + } + + Shortcut { + objectName: "Cut" + onActivated: { + queryField.cut(); + } + } + + Shortcut { + objectName: "Copy" + onActivated: { + queryField.copy(); + } + } + + Shortcut { + objectName: "Paste" + onActivated: { + queryField.paste(); + } + } + + Shortcut { + objectName: "Clear" + onActivated: { + queryField.remove(0, queryField.length); + } + } + + Shortcut { + objectName: "Select All" + onActivated: { + queryField.selectAll(); + } + } + + Shortcut { + objectName: "Deselect" + onActivated: { + queryField.deselect(); + } + } + onQueryChanged: { queryField.text = query; } @@ -77,26 +189,6 @@ : i18ndc("plasma_lookandfeel_org.kde.lookandfeel", "Textfield placeholder text", "Search...") - function move_up() { - if (length === 0) { - root.showHistory = true; - listView.forceActiveFocus(); - } else if (results.count > 0) { - results.forceActiveFocus(); - results.decrementCurrentIndex(); - } - } - - function move_down() { - if (length === 0) { - root.showHistory = true; - listView.forceActiveFocus(); - } else if (results.count > 0) { - results.forceActiveFocus(); - results.incrementCurrentIndex(); - } - } - onTextChanged: { root.query = queryField.text if (allowCompletion && length > 0) { @@ -118,24 +210,6 @@ } Keys.onPressed: { allowCompletion = (event.key !== Qt.Key_Backspace && event.key !== Qt.Key_Delete) - - if (event.modifiers & Qt.ControlModifier) { - if (event.key === Qt.Key_J) { - move_down() - event.accepted = true; - } else if (event.key === Qt.Key_K) { - move_up() - event.accepted = true; - } - } - } - Keys.onUpPressed: move_up() - Keys.onDownPressed: move_down() - Keys.onEnterPressed: results.runCurrentIndex(event) - Keys.onReturnPressed: results.runCurrentIndex(event) - - Keys.onEscapePressed: { - runnerWindow.visible = false } PlasmaCore.SvgItem { @@ -189,12 +263,7 @@ runner: root.runner Keys.onPressed: { - var ctrl = event.modifiers & Qt.ControlModifier; - if (ctrl && event.key === Qt.Key_J) { - incrementCurrentIndex() - } else if (ctrl && event.key === Qt.Key_K) { - decrementCurrentIndex() - } else if (event.text !== "") { + if (event.text != "") { queryField.text += event.text; queryField.focus = true; } @@ -244,9 +313,7 @@ currentIndex = 0; } } - Keys.onReturnPressed: runCurrentIndex() - Keys.onEnterPressed: runCurrentIndex() - + Keys.onTabPressed: { if (currentIndex == listView.count-1) { listView.nextItemInFocusChain(true).forceActiveFocus(); @@ -261,20 +328,13 @@ decrementCurrentIndex() } } + Keys.onPressed: { - var ctrl = event.modifiers & Qt.ControlModifier; - if (ctrl && event.key === Qt.Key_J) { - incrementCurrentIndex() - } else if (ctrl && event.key === Qt.Key_K) { - decrementCurrentIndex() - } else if (event.text !== "") { + if (event.text != "") { queryField.text += event.text; queryField.focus = true; } } - - Keys.onUpPressed: decrementCurrentIndex() - Keys.onDownPressed: incrementCurrentIndex() function runCurrentIndex() { var entry = runnerWindow.history[currentIndex]