From 7b6a67e520c04f56b4b05fa26b252177398df6df Mon Sep 17 00:00:00 2001 From: Eugene Popov Date: Tue, 25 Apr 2023 13:05:39 +0000 Subject: [PATCH] Fix activating the Selection Mode with a keyboard shortcut If a spacebar is used as a keyboard shortcut to activate the Selection Mode, then allow this shortcut to be triggered only if the view has a keyboard focus. BUG: 465489 --- src/dolphinmainwindow.cpp | 14 ++++++++++++++ src/dolphinmainwindow.h | 3 +++ src/kitemviews/kitemlistcontroller.cpp | 16 ++++++++++++---- src/kitemviews/kitemlistcontroller.h | 5 +++++ .../private/kitemlistkeyboardsearchmanager.cpp | 10 +++++----- .../private/kitemlistkeyboardsearchmanager.h | 11 +++++------ src/views/dolphinview.cpp | 5 +++++ src/views/dolphinview.h | 14 +++++++++++--- 8 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 7931bab58..0094bc2e7 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -547,6 +547,19 @@ void DolphinMainWindow::showTarget() }); } +bool DolphinMainWindow::event(QEvent *event) +{ + if (event->type() == QEvent::ShortcutOverride) { + const QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Space && m_activeViewContainer->view()->handleSpaceAsNormalKey()) { + event->accept(); + return true; + } + } + + return KXmlGuiWindow::event(event); +} + void DolphinMainWindow::showEvent(QShowEvent *event) { KXmlGuiWindow::showEvent(event); @@ -1722,6 +1735,7 @@ void DolphinMainWindow::setupActions() "")); toggleSelectionModeAction->setIcon(QIcon::fromTheme(QStringLiteral("quickwizard"))); toggleSelectionModeAction->setCheckable(true); + actionCollection()->setDefaultShortcut(toggleSelectionModeAction, Qt::Key_Space ); connect(toggleSelectionModeAction, &QAction::triggered, this, &DolphinMainWindow::toggleSelectionMode); // A special version of the toggleSelectionModeAction for the toolbar that also contains a menu diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index fe07cbc17..92ddb24c3 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -238,6 +238,9 @@ Q_SIGNALS: void settingsChanged(); protected: + /** @see QObject::event() */ + bool event(QEvent *event) override; + /** @see QWidget::showEvent() */ void showEvent(QShowEvent *event) override; diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index 0c9f19f55..2e7d2f057 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -228,6 +228,11 @@ bool KItemListController::selectionMode() const return m_selectionMode; } +bool KItemListController::isSearchAsYouTypeActive() const +{ + return m_keyboardManager->isSearchAsYouTypeActive(); +} + bool KItemListController::keyPressEvent(QKeyEvent *event) { int index = m_selectionManager->currentItem(); @@ -439,10 +444,13 @@ bool KItemListController::keyPressEvent(QKeyEvent *event) m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); m_selectionManager->beginAnchoredSelection(index); break; - } else if (m_keyboardManager->addKeyBeginsNewSearch()) { // File names shouldn't start with a space, - // so we can use this press as a keyboard shortcut instead. - Q_EMIT selectionModeChangeRequested(!m_selectionMode); - break; + } else { + // Select the current item if it is not selected yet. + const int current = m_selectionManager->currentItem(); + if (!m_selectionManager->isSelected(current)) { + m_selectionManager->setSelected(current); + break; + } } } Q_FALLTHROUGH(); // fall through to the default case and add the Space to the current search string. diff --git a/src/kitemviews/kitemlistcontroller.h b/src/kitemviews/kitemlistcontroller.h index d75a8a22d..0969ed21a 100644 --- a/src/kitemviews/kitemlistcontroller.h +++ b/src/kitemviews/kitemlistcontroller.h @@ -123,6 +123,11 @@ public: void setSelectionModeEnabled(bool enabled); bool selectionMode() const; + /** + * @return \c true if search as you type is active, or \c false otherwise. + */ + bool isSearchAsYouTypeActive() const; + bool processEvent(QEvent *event, const QTransform &transform); Q_SIGNALS: diff --git a/src/kitemviews/private/kitemlistkeyboardsearchmanager.cpp b/src/kitemviews/private/kitemlistkeyboardsearchmanager.cpp index b7318b344..c74ef1638 100644 --- a/src/kitemviews/private/kitemlistkeyboardsearchmanager.cpp +++ b/src/kitemviews/private/kitemlistkeyboardsearchmanager.cpp @@ -27,6 +27,11 @@ bool KItemListKeyboardSearchManager::shouldClearSearchIfInputTimeReached() return (keyboardInputTimeElapsed > m_timeout) || !keyboardTimeWasValid; } +bool KItemListKeyboardSearchManager::isSearchAsYouTypeActive() const +{ + return !m_searchedString.isEmpty() && !m_keyboardInputTime.hasExpired(m_timeout); +} + void KItemListKeyboardSearchManager::addKeys(const QString &keys) { if (shouldClearSearchIfInputTimeReached()) { @@ -63,11 +68,6 @@ void KItemListKeyboardSearchManager::addKeys(const QString &keys) m_keyboardInputTime.start(); } -bool KItemListKeyboardSearchManager::addKeyBeginsNewSearch() const -{ - return m_keyboardInputTime.hasExpired(m_timeout) || m_searchedString.isEmpty(); -} - void KItemListKeyboardSearchManager::setTimeout(qint64 milliseconds) { m_timeout = milliseconds; diff --git a/src/kitemviews/private/kitemlistkeyboardsearchmanager.h b/src/kitemviews/private/kitemlistkeyboardsearchmanager.h index d370bc9ba..981d98cd3 100644 --- a/src/kitemviews/private/kitemlistkeyboardsearchmanager.h +++ b/src/kitemviews/private/kitemlistkeyboardsearchmanager.h @@ -34,11 +34,6 @@ public: * Add \a keys to the text buffer used for searching. */ void addKeys(const QString &keys); - /** - * @returns true if the next call to addKeys() will trigger a new search. - * Returns false if the next added key char will be added to the search string that was used previously. - */ - bool addKeyBeginsNewSearch() const; /** * Sets the delay after which the search is cancelled to \a milliseconds. @@ -51,6 +46,11 @@ public: void cancelSearch(); + /** + * @return \c true if search as you type is active, or \c false otherwise. + */ + bool isSearchAsYouTypeActive() const; + public Q_SLOTS: void slotCurrentChanged(int current, int previous); @@ -71,7 +71,6 @@ Q_SIGNALS: private: bool shouldClearSearchIfInputTimeReached(); -private: QString m_searchedString; bool m_isSearchRestarted; /** Measures the time since the last key press. */ diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index b33353e3a..186de4fcc 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1828,6 +1828,11 @@ void DolphinView::hideToolTip(const ToolTipManager::HideBehavior behavior) } } +bool DolphinView::handleSpaceAsNormalKey() const +{ + return !m_container->hasFocus() || m_container->controller()->isSearchAsYouTypeActive(); +} + void DolphinView::slotTwoClicksRenamingTimerTimeout() { const KItemListSelectionManager *selectionManager = m_container->controller()->selectionManager(); diff --git a/src/views/dolphinview.h b/src/views/dolphinview.h index 3486ee9b4..705272308 100644 --- a/src/views/dolphinview.h +++ b/src/views/dolphinview.h @@ -335,6 +335,17 @@ public: */ void hideToolTip(const ToolTipManager::HideBehavior behavior = ToolTipManager::HideBehavior::Later); + /** + * Check if the space key should be handled as a normal key, even if it's + * used as a keyboard shortcut. + * + * See BUG 465489 + */ + bool handleSpaceAsNormalKey() const; + + /** Activates the view if the item list container gets focus. */ + bool eventFilter(QObject *watched, QEvent *event) override; + public Q_SLOTS: /** * Changes the directory to \a url. If the current directory is equal to @@ -426,9 +437,6 @@ public Q_SLOTS: */ void updateViewState(); - /** Activates the view if the item list container gets focus. */ - bool eventFilter(QObject *watched, QEvent *event) override; - Q_SIGNALS: /** * Is emitted if the view has been activated by e. g. a mouse click.