diff options
| -rw-r--r-- | src/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/dolphinmainwindow.cpp | 7 | ||||
| -rw-r--r-- | src/dolphintabwidget.cpp | 10 | ||||
| -rw-r--r-- | src/dolphintabwidget.h | 3 | ||||
| -rw-r--r-- | src/dolphinui.rc | 1 | ||||
| -rw-r--r-- | src/dolphinuiforphones.rc | 1 | ||||
| -rw-r--r-- | src/settings/dolphin_generalsettings.kcfg | 4 | ||||
| -rw-r--r-- | src/settings/dolphin_tab_key_shortcut_for_focus_other_view.py | 27 | ||||
| -rw-r--r-- | src/settings/dolphin_tab_key_shortcut_for_focus_other_view.upd | 8 | ||||
| -rw-r--r-- | src/settings/interface/folderstabssettingspage.cpp | 11 | ||||
| -rw-r--r-- | src/settings/interface/folderstabssettingspage.h | 1 | ||||
| -rw-r--r-- | src/tests/dolphinmainwindowtest.cpp | 39 | ||||
| -rw-r--r-- | src/views/dolphinview.cpp | 7 |
13 files changed, 98 insertions, 23 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a195747a..319c5512b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -642,6 +642,8 @@ install( FILES settings/dolphin_detailsmodesettings.upd settings/dolphin_statusandlocationbarssettings.upd settings/dolphin_replace_view_mode_with_view_settings_in_toolbar.upd settings/dolphin_replace_view_mode_with_view_settings_in_toolbar.py + settings/dolphin_tab_key_shortcut_for_focus_other_view.upd + settings/dolphin_tab_key_shortcut_for_focus_other_view.py DESTINATION ${KDE_INSTALL_KCONFUPDATEDIR} ) # install KF6 kconfig updater C++ scripts to kconf_update_bin diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index ed7215b5a..51fec8247 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -1897,6 +1897,13 @@ void DolphinMainWindow::setupActions() actionCollection()->setDefaultShortcut(moveToOtherViewAction, Qt::SHIFT | Qt::Key_F6); connect(moveToOtherViewAction, &QAction::triggered, this, &DolphinMainWindow::moveToInactiveSplitView); + QAction *focusOtherViewAction = actionCollection()->addAction(QStringLiteral("focus_inactive_split_view")); + focusOtherViewAction->setText(i18nc("@action:inmenu", "Focus Other View")); + focusOtherViewAction->setToolTip(i18nc("@info:tooltip", "Move keyboard focus to the inactive view.")); + focusOtherViewAction->setIcon(QIcon::fromTheme(QStringLiteral("swap-panels"))); + actionCollection()->setDefaultShortcut(focusOtherViewAction, Qt::CTRL | Qt::Key_F3); + connect(focusOtherViewAction, &QAction::triggered, m_tabWidget, &DolphinTabWidget::focusInactiveSplitView); + QAction *showFilterBar = actionCollection()->addAction(QStringLiteral("show_filter_bar")); showFilterBar->setText(i18nc("@action:inmenu Tools", "Filter…")); showFilterBar->setToolTip(i18nc("@info:tooltip", "Show Filter Bar")); diff --git a/src/dolphintabwidget.cpp b/src/dolphintabwidget.cpp index bbf80e4bf..7fbf10b19 100644 --- a/src/dolphintabwidget.cpp +++ b/src/dolphintabwidget.cpp @@ -383,6 +383,16 @@ void DolphinTabWidget::moveToInactiveSplitView() inactiveView->moveSelectedItems(selectedItems, inactiveView->url()); } +void DolphinTabWidget::focusInactiveSplitView() +{ + DolphinTabPage *const tabPage = currentTabPage(); + if (!tabPage->splitViewEnabled()) { + tabPage->setSplitViewEnabled(true, WithAnimation, tabPage->activeViewContainer()->url()); + } else { + activateViewContainerAt(ViewIndex{currentIndex(), !tabPage->primaryViewActive()}); + } +} + void DolphinTabWidget::detachTab(int index) { Q_ASSERT(index >= 0); diff --git a/src/dolphintabwidget.h b/src/dolphintabwidget.h index ca101e2db..5d3e84c0a 100644 --- a/src/dolphintabwidget.h +++ b/src/dolphintabwidget.h @@ -196,6 +196,9 @@ public Q_SLOTS: /** Moves all selected items to the inactive view. */ void moveToInactiveSplitView(); + /** Moves keyboard focus to the inactive view, making it the active view. */ + void focusInactiveSplitView(); + private Q_SLOTS: /** * Opens the tab with the index \a index in a new Dolphin instance and closes diff --git a/src/dolphinui.rc b/src/dolphinui.rc index c82e104f3..395436d74 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -53,6 +53,7 @@ <Separator/> <Action name="split_view_menu" /> <Action name="popout_split_view" /> + <Action name="focus_inactive_split_view" /> <Action name="split_stash" /> <Action name="redisplay" /> <Action name="stop" /> diff --git a/src/dolphinuiforphones.rc b/src/dolphinuiforphones.rc index eba2b970a..3a9e89c29 100644 --- a/src/dolphinuiforphones.rc +++ b/src/dolphinuiforphones.rc @@ -53,6 +53,7 @@ <Separator/> <Action name="split_view_menu" /> <Action name="popout_split_view" /> + <Action name="focus_inactive_split_view" /> <Action name="split_stash" /> <Action name="redisplay" /> <Action name="stop" /> diff --git a/src/settings/dolphin_generalsettings.kcfg b/src/settings/dolphin_generalsettings.kcfg index 48fecb2d0..b29526d64 100644 --- a/src/settings/dolphin_generalsettings.kcfg +++ b/src/settings/dolphin_generalsettings.kcfg @@ -115,10 +115,6 @@ <label>Show a bar for easy pasting after a cut or copy was done using the selection mode bottom bar.</label> <default>true</default> </entry> - <entry name="UseTabForSwitchingSplitView" type="Bool"> - <label>Use tab for switching between right and left view</label> - <default>false</default> - </entry> <entry name="CloseSplitViewChoice" type="Enum"> <choices> <choice name="ActiveView" /> diff --git a/src/settings/dolphin_tab_key_shortcut_for_focus_other_view.py b/src/settings/dolphin_tab_key_shortcut_for_focus_other_view.py new file mode 100644 index 000000000..4a18ad094 --- /dev/null +++ b/src/settings/dolphin_tab_key_shortcut_for_focus_other_view.py @@ -0,0 +1,27 @@ +#SPDX-FileCopyrightText: 2026 Felix Ernst <[email protected]> +#SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + +import os +import sys +from pathlib import Path +import xml.etree.ElementTree as ET + +use_tab_setting_detected = False + +XDG_CONFIG_HOME = Path(os.getenv("XDG_CONFIG_HOME") or (Path.home() / ".config")) +custom_settings_file = XDG_CONFIG_HOME / "dolphinrc" +print(custom_settings_file) +if custom_settings_file.exists(): + with open(custom_settings_file, "r+") as f: + lines = [line for line in f if line.find("UseTabForSwitchingSplitView=true") >= 0] + if len(lines) > 0: + use_tab_setting_detected = True + +XDG_DATA_HOME = Path(os.getenv("XDG_DATA_HOME") or (Path.home() / ".local/share")) +custom_ui_file = XDG_DATA_HOME / "kxmlgui5/dolphin/dolphinui.rc" +if use_tab_setting_detected and custom_ui_file.exists(): + tree = ET.parse(custom_ui_file) + root = tree.getroot() + for actionProperties in root.iter("ActionProperties"): + ET.SubElement(actionProperties, "Action", {"name":"focus_inactive_split_view", "shortcut":"Ctrl+F3; Tab"}) + tree.write(custom_ui_file, encoding="utf-8") diff --git a/src/settings/dolphin_tab_key_shortcut_for_focus_other_view.upd b/src/settings/dolphin_tab_key_shortcut_for_focus_other_view.upd new file mode 100644 index 000000000..579eb233a --- /dev/null +++ b/src/settings/dolphin_tab_key_shortcut_for_focus_other_view.upd @@ -0,0 +1,8 @@ +#SPDX-FileCopyrightText: 2026 Felix Ernst <[email protected]> +#SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL + +#Configuration update for Dolphin +Version=6 + +Id=tab_key_shortcut_for_focus_other_view +Script=dolphin_tab_key_shortcut_for_focus_other_view.py,python3 diff --git a/src/settings/interface/folderstabssettingspage.cpp b/src/settings/interface/folderstabssettingspage.cpp index 10303258c..fa1b1b80f 100644 --- a/src/settings/interface/folderstabssettingspage.cpp +++ b/src/settings/interface/folderstabssettingspage.cpp @@ -44,7 +44,6 @@ FoldersTabsSettingsPage::FoldersTabsSettingsPage(QWidget *parent) , m_filterBar(nullptr) , m_showFullPathInTitlebar(nullptr) , m_openExternallyCalledFolderInNewTab(nullptr) - , m_useTabForSplitViewSwitch(nullptr) , m_closeSplitComboBox(nullptr) { QFormLayout *topLayout = new QFormLayout(this); @@ -160,10 +159,6 @@ FoldersTabsSettingsPage::FoldersTabsSettingsPage(QWidget *parent) closeSplitViewHLayout->addWidget(m_closeSplitComboBox); topLayout->addRow(i18nc("@title:group", "Split view: "), closeSplitViewWidget); - // 'Switch between panes of split views with tab key' - m_useTabForSplitViewSwitch = new QCheckBox(i18nc("option:check split view panes", "Switch between views with Tab key")); - topLayout->addRow(QString(), m_useTabForSplitViewSwitch); - // 'Begin in split view mode' m_splitView = new QCheckBox(i18nc("@option:check Startup Settings", "Open new windows in split view mode")); topLayout->addRow(QString(), m_splitView); @@ -182,8 +177,6 @@ FoldersTabsSettingsPage::FoldersTabsSettingsPage(QWidget *parent) connect(m_openExternallyCalledFolderInNewTab, &QCheckBox::toggled, this, &FoldersTabsSettingsPage::slotSettingsChanged); connect(m_showFullPathInTitlebar, &QCheckBox::toggled, this, &FoldersTabsSettingsPage::slotSettingsChanged); - connect(m_useTabForSplitViewSwitch, &QCheckBox::toggled, this, &FoldersTabsSettingsPage::changed); - connect(m_closeSplitComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &FoldersTabsSettingsPage::changed); connect(m_alwaysShowTabBar, &QCheckBox::toggled, this, &FoldersTabsSettingsPage::changed); @@ -203,8 +196,6 @@ void FoldersTabsSettingsPage::applySettings() { GeneralSettings *settings = GeneralSettings::self(); - settings->setUseTabForSwitchingSplitView(m_useTabForSplitViewSwitch->isChecked()); - settings->setCloseSplitViewChoice(m_closeSplitComboBox->currentIndex()); const QUrl url(QUrl::fromUserInput(m_homeUrl->text(), QString(), QUrl::AssumeLocalFile)); @@ -322,8 +313,6 @@ void FoldersTabsSettingsPage::loadSettings() m_showFullPathInTitlebar->setChecked(GeneralSettings::showFullPathInTitlebar()); m_openExternallyCalledFolderInNewTab->setChecked(GeneralSettings::openExternallyCalledFolderInNewTab()); - m_useTabForSplitViewSwitch->setChecked(GeneralSettings::useTabForSwitchingSplitView()); - m_closeSplitComboBox->setCurrentIndex(GeneralSettings::closeSplitViewChoice()); m_alwaysShowTabBar->setChecked(GeneralSettings::alwaysShowTabBar()); diff --git a/src/settings/interface/folderstabssettingspage.h b/src/settings/interface/folderstabssettingspage.h index 690407b39..cf926e557 100644 --- a/src/settings/interface/folderstabssettingspage.h +++ b/src/settings/interface/folderstabssettingspage.h @@ -70,7 +70,6 @@ private: QCheckBox *m_filterBar; QCheckBox *m_showFullPathInTitlebar; QCheckBox *m_openExternallyCalledFolderInNewTab; - QCheckBox *m_useTabForSplitViewSwitch; QComboBox *m_closeSplitComboBox; }; diff --git a/src/tests/dolphinmainwindowtest.cpp b/src/tests/dolphinmainwindowtest.cpp index 534ac4654..a629268c1 100644 --- a/src/tests/dolphinmainwindowtest.cpp +++ b/src/tests/dolphinmainwindowtest.cpp @@ -65,6 +65,7 @@ private Q_SLOTS: void testWindowTitle(); void testFocusLocationBar(); void testFocusPlacesPanel(); + void testFocusOtherView(); void testPlacesPanelWidthResistance(); void testGoActions(); void testOpenFiles(); @@ -576,6 +577,44 @@ void DolphinMainWindowTest::testFocusPlacesPanel() "Activating a place should move focus to the view even if the view already has that place loaded."); } +void DolphinMainWindowTest::testFocusOtherView() +{ + m_mainWindow->openDirectories({QUrl::fromLocalFile(QDir::homePath())}, false); + m_mainWindow->show(); + QVERIFY(QTest::qWaitForWindowExposed(m_mainWindow.data())); + QVERIFY(m_mainWindow->isVisible()); + QTRY_VERIFY_WITH_TIMEOUT(QApplication::activeWindow() != nullptr, 100); + + QAction *const focusOtherViewAction = m_mainWindow->actionCollection()->action(QStringLiteral("focus_inactive_split_view")); + + /** Triggering the "Focus Other View" action when there is no other view should create such a view and focus it. */ + QVERIFY(!m_mainWindow->m_tabWidget->currentTabPage()->splitViewEnabled()); + const DolphinViewContainer *const previouslyActiveView = m_mainWindow->activeViewContainer(); + QVERIFY(previouslyActiveView->isAncestorOf(QApplication::focusWidget())); + focusOtherViewAction->trigger(); + QVERIFY(m_mainWindow->m_tabWidget->currentTabPage()->splitViewEnabled()); + QVERIFY(!previouslyActiveView->isAncestorOf(QApplication::focusWidget())); + + const DolphinViewContainer *const otherView = m_mainWindow->activeViewContainer(); + QVERIFY(previouslyActiveView != otherView); + QVERIFY(otherView->isAncestorOf(QApplication::focusWidget())); + + /** "Focus Other View" and "Split" have the same behaviour when there is only one view. Make sure their default keyboard shortcuts stay similar. */ + QVERIFY(focusOtherViewAction->shortcut().toString().contains(m_mainWindow->actionCollection()->action(QStringLiteral("split_view"))->shortcut().toString()) + || focusOtherViewAction->shortcut().toString().contains( + m_mainWindow->actionCollection()->action(QStringLiteral("split_view_menu"))->shortcut().toString())); + + /** Test the typical usage of "Focus Other View" */ + QVERIFY(previouslyActiveView != otherView); + QVERIFY(otherView->isAncestorOf(QApplication::focusWidget())); + focusOtherViewAction->trigger(); + QVERIFY(previouslyActiveView->isAncestorOf(QApplication::focusWidget())); + focusOtherViewAction->trigger(); + QVERIFY(otherView->isAncestorOf(QApplication::focusWidget())); + focusOtherViewAction->trigger(); + QVERIFY(previouslyActiveView->isAncestorOf(QApplication::focusWidget())); +} + /** * The places panel will resize itself if any of the other widgets requires too much horizontal space * but a user never wants the size of the places panel to change unless they resized it themselves explicitly. diff --git a/src/views/dolphinview.cpp b/src/views/dolphinview.cpp index 50c14ff77..78b8b9949 100644 --- a/src/views/dolphinview.cpp +++ b/src/views/dolphinview.cpp @@ -1093,13 +1093,6 @@ bool DolphinView::eventFilter(QObject *watched, QEvent *event) case QEvent::KeyPress: hideToolTip(ToolTipManager::HideBehavior::Instantly); - if (GeneralSettings::useTabForSwitchingSplitView()) { - QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); - if (keyEvent->key() == Qt::Key_Tab && keyEvent->modifiers() == Qt::NoModifier) { - Q_EMIT toggleActiveViewRequested(); - return true; - } - } break; case QEvent::KeyRelease: if (static_cast<QKeyEvent *>(event)->key() == Qt::Key_Control) { |
