Commit 7f41a383 authored by Georg Gadinger's avatar Georg Gadinger 🐾 Committed by Kurt Hindenburg
Browse files

Improve usability on macOS including altering shortcuts

This change removes some application attributes that are not necessary anymore (like disabling the global menu bar) or make Konsole behave slightly different when used from a KPart (e.g. inside Kate), and changes some keyboard shortcuts around (mainly using Command instead of Ctrl+Shift now.)

Unfortunately this does not resolve the requirement for the special keytab file for macOS; it looks like Qt does something funny with the QKeyEvents here: on Linux these have a `text` attribute set to e.g. `\u0003` for `^C`, that attribute is empty on macOS.

Note this could impact shortcut changes on non-macOS systems.
parent ed39d279
Pipeline #193506 passed with stage
in 2 minutes and 11 seconds
......@@ -513,7 +513,7 @@ void Application::startBackgroundMode(MainWindow *window)
QAction *action = collection->addAction(QStringLiteral("toggle-background-window"));
action->setObjectName(QStringLiteral("Konsole Background Mode"));
action->setText(i18nc("@item", "Toggle Background Window"));
KGlobalAccel::self()->setGlobalShortcut(action, QKeySequence(Konsole::ACCEL | Qt::SHIFT | Qt::Key_F12));
KGlobalAccel::self()->setGlobalShortcut(action, QKeySequence(Konsole::ACCEL | Qt::Key_F12));
connect(action, &QAction::triggered, this, &Application::toggleBackgroundInstance);
_backgroundInstance = window;
......
......@@ -36,12 +36,14 @@ BookmarkMenu::BookmarkMenu(KBookmarkManager *mgr, KBookmarkOwner *owner, QMenu *
disconnect(bookmarkAction, nullptr, this, nullptr);
connect(bookmarkAction, &QAction::triggered, this, &BookmarkMenu::maybeAddBookmark);
#ifndef Q_OS_MACOS // not needed on this platform, Cmd+B (shortcut) is different to Ctrl+B (^B in terminal)
// replace Ctrl+B shortcut for bookmarks only if user hasn't already
// changed the shortcut; however, if the user changed it to Ctrl+B
// this will still get changed to Ctrl+Shift+B
if (bookmarkAction->shortcut() == QKeySequence(Konsole::ACCEL | Qt::Key_B)) {
collection->setDefaultShortcut(bookmarkAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_B);
if (bookmarkAction->shortcut() == QKeySequence(Qt::CTRL | Qt::Key_B)) {
collection->setDefaultShortcut(bookmarkAction, Qt::CTRL | Qt::SHIFT | Qt::Key_B);
}
#endif
}
void BookmarkMenu::maybeAddBookmark()
......
......@@ -305,7 +305,7 @@ void MainWindow::setupActions()
// File Menu
_newTabMenuAction = new KActionMenu(QIcon::fromTheme(QStringLiteral("tab-new")), i18nc("@action:inmenu", "&New Tab"), collection);
collection->setDefaultShortcut(_newTabMenuAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_T);
collection->setDefaultShortcut(_newTabMenuAction, Konsole::ACCEL | Qt::Key_T);
collection->setShortcutsConfigurable(_newTabMenuAction, true);
_newTabMenuAction->setAutoRepeat(false);
connect(_newTabMenuAction, &KActionMenu::triggered, this, &MainWindow::newTab);
......@@ -322,14 +322,14 @@ void MainWindow::setupActions()
menuAction = collection->addAction(QStringLiteral("new-window"));
menuAction->setIcon(QIcon::fromTheme(QStringLiteral("window-new")));
menuAction->setText(i18nc("@action:inmenu", "New &Window"));
collection->setDefaultShortcut(menuAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_N);
collection->setDefaultShortcut(menuAction, Konsole::ACCEL | Qt::Key_N);
menuAction->setAutoRepeat(false);
connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::newWindow);
menuAction = collection->addAction(QStringLiteral("close-window"));
menuAction->setIcon(QIcon::fromTheme(QStringLiteral("window-close")));
menuAction->setText(i18nc("@action:inmenu", "Close Window"));
collection->setDefaultShortcut(menuAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_Q);
collection->setDefaultShortcut(menuAction, Konsole::ACCEL | Qt::Key_Q);
connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::close);
// Bookmark Menu
......@@ -341,7 +341,7 @@ void MainWindow::setupActions()
// Settings Menu
_toggleMenuBarAction = KStandardAction::showMenubar(menuBar(), &QMenuBar::setVisible, collection);
collection->setDefaultShortcut(_toggleMenuBarAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_M);
collection->setDefaultShortcut(_toggleMenuBarAction, Konsole::ACCEL | Qt::Key_M);
// Set up themes
actionCollection()->addAction(QStringLiteral("window-colorscheme-menu"), new AppColorSchemeChooser(actionCollection()));
......@@ -361,7 +361,7 @@ void MainWindow::setupActions()
// Set up an shortcut-only action for activating menu bar.
menuAction = collection->addAction(QStringLiteral("activate-menu"));
menuAction->setText(i18nc("@item", "Activate Menu"));
collection->setDefaultShortcut(menuAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_F10);
collection->setDefaultShortcut(menuAction, Konsole::ACCEL | Qt::Key_F10);
connect(menuAction, &QAction::triggered, this, &Konsole::MainWindow::activateMenuBar);
auto action = collection->addAction(QStringLiteral("save-layout"));
......
......@@ -16,13 +16,11 @@ namespace Konsole
*/
enum Modifier {
#ifdef Q_OS_MACOS
ACCEL = Qt::META,
LEFT = Qt::Key_BracketLeft,
RIGHT = Qt::Key_BracketRight
#else
// Use plain Command key for shortcuts
ACCEL = Qt::CTRL,
LEFT = Qt::Key_Left,
RIGHT = Qt::Key_Right,
#else
// Use Ctrl+Shift for shortcuts
ACCEL = Qt::CTRL | Qt::SHIFT,
#endif
};
}
......
......@@ -157,13 +157,13 @@ void ViewManager::setupActions()
action->setText(i18nc("@action:inmenu", "Expand View"));
action->setEnabled(false);
connect(action, &QAction::triggered, this, &ViewManager::expandActiveContainer);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_BracketRight);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_BracketRight);
collection->addAction(QStringLiteral("expand-active-view"), action);
_multiSplitterOnlyActions << action;
action = new QAction(this);
action->setText(i18nc("@action:inmenu", "Shrink View"));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_BracketLeft);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_BracketLeft);
action->setEnabled(false);
collection->addAction(QStringLiteral("shrink-active-view"), action);
connect(action, &QAction::triggered, this, &ViewManager::shrinkActiveContainer);
......@@ -179,7 +179,7 @@ void ViewManager::setupActions()
// Ctrl+Shift+D is not used as a shortcut by default because it is too close
// to Ctrl+D - which will terminate the session in many cases
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_H);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_H);
action = collection->addAction(QStringLiteral("detach-tab"));
action->setEnabled(true);
......@@ -208,25 +208,25 @@ void ViewManager::setupActions()
action = new QAction(i18nc("@action Shortcut entry", "Focus Above Terminal"), this);
connect(action, &QAction::triggered, this, &ViewManager::focusUp);
collection->addAction(QStringLiteral("focus-view-above"), action);
collection->setDefaultShortcut(action, Qt::SHIFT | Qt::CTRL | Qt::Key_Up);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::SHIFT | Qt::Key_Up);
_viewContainer->addAction(action);
_multiSplitterOnlyActions << action;
action = new QAction(i18nc("@action Shortcut entry", "Focus Below Terminal"), this);
collection->setDefaultShortcut(action, Qt::SHIFT | Qt::CTRL | Qt::Key_Down);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::SHIFT | Qt::Key_Down);
collection->addAction(QStringLiteral("focus-view-below"), action);
connect(action, &QAction::triggered, this, &ViewManager::focusDown);
_multiSplitterOnlyActions << action;
_viewContainer->addAction(action);
action = new QAction(i18nc("@action Shortcut entry", "Focus Left Terminal"), this);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Konsole::LEFT);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::SHIFT | Qt::Key_Left);
connect(action, &QAction::triggered, this, &ViewManager::focusLeft);
collection->addAction(QStringLiteral("focus-view-left"), action);
_multiSplitterOnlyActions << action;
action = new QAction(i18nc("@action Shortcut entry", "Focus Right Terminal"), this);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Konsole::RIGHT);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::SHIFT | Qt::Key_Right);
connect(action, &QAction::triggered, this, &ViewManager::focusRight);
collection->addAction(QStringLiteral("focus-view-right"), action);
_multiSplitterOnlyActions << action;
......
......@@ -147,17 +147,6 @@ int main(int argc, char *argv[])
migrateRenamedConfigKeys();
#if defined(Q_OS_MACOS)
// this ensures that Ctrl and Meta are not swapped, so CTRL-C and friends
// will work correctly in the terminal
app->setAttribute(Qt::AA_MacDontSwapCtrlAndMeta);
// KDE's menuBar()->isTopLevel() hasn't worked in a while.
// For now, put menus inside Konsole window; this also make
// the keyboard shortcut to show menus look reasonable.
app->setAttribute(Qt::AA_DontUseNativeMenuBar);
#endif
app->setWindowIcon(QIcon::fromTheme(QStringLiteral("utilities-terminal")));
KLocalizedString::setApplicationDomain("konsole");
......
......@@ -618,7 +618,7 @@ void SessionController::setupCommonActions()
action->setText(i18n("&Close Session"));
action->setIcon(QIcon::fromTheme(QStringLiteral("tab-close")));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_W);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_W);
// Open Browser
action = collection->addAction(QStringLiteral("open-browser"), this, &SessionController::openBrowser);
......@@ -627,13 +627,7 @@ void SessionController::setupCommonActions()
// Copy and Paste
action = KStandardAction::copy(this, &SessionController::copy, collection);
#ifdef Q_OS_MACOS
// Don't use the Konsole::ACCEL const here, we really want the Command key (Qt::META)
// TODO: check what happens if we leave it to Qt to assign the default?
collection->setDefaultShortcut(action, Qt::META | Qt::Key_C);
#else
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_C);
#endif
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_C);
// disabled at first, since nothing has been selected now
action->setEnabled(false);
......@@ -647,11 +641,9 @@ void SessionController::setupCommonActions()
action = KStandardAction::paste(this, &SessionController::paste, collection);
QList<QKeySequence> pasteShortcut;
#ifdef Q_OS_MACOS
pasteShortcut.append(QKeySequence(Qt::META | Qt::Key_V));
pasteShortcut.append(QKeySequence(Konsole::ACCEL | Qt::Key_V));
#ifndef Q_OS_MACOS
// No Insert key on Mac keyboards
#else
pasteShortcut.append(QKeySequence(Konsole::ACCEL | Qt::SHIFT | Qt::Key_V));
pasteShortcut.append(QKeySequence(Qt::SHIFT | Qt::Key_Insert));
#endif
collection->setDefaultShortcuts(action, pasteShortcut);
......@@ -659,9 +651,9 @@ void SessionController::setupCommonActions()
action = collection->addAction(QStringLiteral("paste-selection"), this, &SessionController::pasteFromX11Selection);
action->setText(i18n("Paste Selection"));
#ifdef Q_OS_MACOS
collection->setDefaultShortcut(action, Qt::META | Qt::SHIFT | Qt::Key_V);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::SHIFT | Qt::Key_V);
#else
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_Insert);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::SHIFT | Qt::Key_Insert);
#endif
_webSearchMenu = new KActionMenu(i18n("Web Search"), this);
......@@ -679,12 +671,12 @@ void SessionController::setupCommonActions()
action = KStandardAction::saveAs(this, &SessionController::saveHistory, collection);
action->setText(i18n("Save Output &As..."));
#ifdef Q_OS_MACOS
action->setShortcut(QKeySequence(Qt::META | Qt::Key_S));
action->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
#endif
action = KStandardAction::print(this, &SessionController::requestPrint, collection);
action->setText(i18n("&Print Screen..."));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_P);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_P);
action = collection->addAction(QStringLiteral("adjust-history"), this, &SessionController::showHistoryOptions);
action->setText(i18n("Adjust Scrollback..."));
......@@ -697,7 +689,7 @@ void SessionController::setupCommonActions()
action = collection->addAction(QStringLiteral("clear-history-and-reset"), this, &SessionController::clearHistoryAndReset);
action->setText(i18n("Clear Scrollback and Reset"));
action->setIcon(QIcon::fromTheme(QStringLiteral("edit-clear-history")));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::SHIFT | Qt::Key_K);
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_K);
// Profile Options
action = collection->addAction(QStringLiteral("edit-current-profile"), this, &SessionController::editCurrentProfile);
......@@ -723,11 +715,11 @@ void SessionController::setupCommonActions()
_findPreviousAction->setEnabled(false);
#ifdef Q_OS_MACOS
collection->setDefaultShortcut(_findAction, Qt::META | Qt::Key_F);
collection->setDefaultShortcut(_findNextAction, Qt::META | Qt::Key_G);
collection->setDefaultShortcut(_findPreviousAction, Qt::META | Qt::SHIFT | Qt::Key_G);
collection->setDefaultShortcut(_findAction, Qt::CTRL | Qt::Key_F);
collection->setDefaultShortcut(_findNextAction, Qt::CTRL | Qt::Key_G);
collection->setDefaultShortcut(_findPreviousAction, Qt::CTRL | Qt::SHIFT | Qt::Key_G);
#else
collection->setDefaultShortcut(_findAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_F);
collection->setDefaultShortcut(_findAction, Qt::CTRL | Qt::SHIFT | Qt::Key_F);
collection->setDefaultShortcut(_findNextAction, Qt::Key_F3);
collection->setDefaultShortcut(_findPreviousAction, QKeySequence{Qt::SHIFT | Qt::Key_F3});
#endif
......@@ -774,7 +766,7 @@ void SessionController::setupExtraActions()
QAction *action = collection->addAction(QStringLiteral("rename-session"), this, &SessionController::renameSession);
action->setText(i18n("&Configure or Rename Tab..."));
action->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::ALT | Qt::Key_S);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::ALT | Qt::Key_S);
// Copy input to ==> all tabs
auto *copyInputToAllTabsAction = collection->add<KToggleAction>(QStringLiteral("copy-input-to-all-tabs"));
......@@ -786,13 +778,13 @@ void SessionController::setupExtraActions()
// Copy input to ==> selected tabs
auto *copyInputToSelectedTabsAction = collection->add<KToggleAction>(QStringLiteral("copy-input-to-selected-tabs"));
copyInputToSelectedTabsAction->setText(i18n("&Select Tabs..."));
collection->setDefaultShortcut(copyInputToSelectedTabsAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_Period);
collection->setDefaultShortcut(copyInputToSelectedTabsAction, Konsole::ACCEL | Qt::Key_Period);
copyInputToSelectedTabsAction->setData(CopyInputToSelectedTabsMode);
// Copy input to ==> none
auto *copyInputToNoneAction = collection->add<KToggleAction>(QStringLiteral("copy-input-to-none"));
copyInputToNoneAction->setText(i18nc("@action:inmenu Do not select any tabs", "&None"));
collection->setDefaultShortcut(copyInputToNoneAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_Slash);
collection->setDefaultShortcut(copyInputToNoneAction, Konsole::ACCEL | Qt::Key_Slash);
copyInputToNoneAction->setData(CopyInputToNoneMode);
copyInputToNoneAction->setChecked(true); // the default state
......@@ -808,17 +800,17 @@ void SessionController::setupExtraActions()
action = collection->addAction(QStringLiteral("zmodem-upload"), this, &SessionController::zmodemUpload);
action->setText(i18n("&ZModem Upload..."));
action->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::ALT | Qt::Key_U);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::ALT | Qt::Key_U);
// Monitor
KToggleAction *toggleAction = new KToggleAction(i18n("Monitor for &Activity"), this);
collection->setDefaultShortcut(toggleAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_A);
collection->setDefaultShortcut(toggleAction, Konsole::ACCEL | Qt::Key_A);
action = collection->addAction(QStringLiteral("monitor-activity"), toggleAction);
connect(action, &QAction::toggled, this, &Konsole::SessionController::monitorActivity);
action->setIcon(QIcon::fromTheme(QStringLiteral("tools-media-optical-burn")));
toggleAction = new KToggleAction(i18n("Monitor for &Silence"), this);
collection->setDefaultShortcut(toggleAction, Konsole::ACCEL | Qt::SHIFT | Qt::Key_I);
collection->setDefaultShortcut(toggleAction, Konsole::ACCEL | Qt::Key_I);
action = collection->addAction(QStringLiteral("monitor-silence"), toggleAction);
connect(action, &QAction::toggled, this, &Konsole::SessionController::monitorSilence);
action->setIcon(QIcon::fromTheme(QStringLiteral("tools-media-optical-copy")));
......@@ -833,18 +825,18 @@ void SessionController::setupExtraActions()
action->setText(i18n("Enlarge Font"));
action->setIcon(QIcon::fromTheme(QStringLiteral("format-font-size-more")));
QList<QKeySequence> enlargeFontShortcut;
enlargeFontShortcut.append(QKeySequence(Konsole::ACCEL | Qt::Key_Plus));
enlargeFontShortcut.append(QKeySequence(Konsole::ACCEL | Qt::Key_Equal));
enlargeFontShortcut.append(QKeySequence(Qt::CTRL | Qt::Key_Plus));
enlargeFontShortcut.append(QKeySequence(Qt::CTRL | Qt::Key_Equal));
collection->setDefaultShortcuts(action, enlargeFontShortcut);
action = collection->addAction(QStringLiteral("shrink-font"), this, &SessionController::decreaseFontSize);
action->setText(i18n("Shrink Font"));
action->setIcon(QIcon::fromTheme(QStringLiteral("format-font-size-less")));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::Key_Minus);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::Key_Minus);
action = collection->addAction(QStringLiteral("reset-font-size"), this, &SessionController::resetFontSize);
action->setText(i18n("Reset Font Size"));
collection->setDefaultShortcut(action, Konsole::ACCEL | Qt::ALT | Qt::Key_0);
collection->setDefaultShortcut(action, Qt::CTRL | Qt::ALT | Qt::Key_0);
// Send signal
auto *sendSignalActions = collection->add<KSelectAction>(QStringLiteral("send-signal"));
......@@ -1845,11 +1837,7 @@ void SessionController::showDisplayContextMenu(const QPoint &position)
// We don't actually use this shortcut, but we need to display it for consistency :/
QAction *copy = actionCollection()->action(QStringLiteral("edit_copy_contextmenu"));
#ifdef Q_OS_MACOS
copy->setShortcut(Qt::META | Qt::Key_C);
#else
copy->setShortcut(Konsole::ACCEL | Qt::SHIFT | Qt::Key_C);
#endif
copy->setShortcut(Konsole::ACCEL | Qt::Key_C);
// Adds a "Open Folder With" action
const QUrl currentUrl = url().isLocalFile() ? url() : QUrl::fromLocalFile(QDir::homePath());
......
......@@ -2540,6 +2540,14 @@ void TerminalDisplay::keyPressEvent(QKeyEvent *event)
peekPrimaryRequested(true);
}
#ifdef Q_OS_MACOS // swap Ctrl and Meta
if (event->modifiers() & Qt::MetaModifier) {
event->setModifiers((event->modifiers() & ~Qt::MetaModifier) | Qt::ControlModifier);
} else if (event->modifiers() & Qt::ControlModifier) {
event->setModifiers((event->modifiers() & ~Qt::ControlModifier) | Qt::MetaModifier);
}
#endif
if (!_readOnly) {
_actSel = 0; // Key stroke implies a screen update, so TerminalDisplay won't
// know where the current selection is.
......
......@@ -51,7 +51,7 @@ void PartManualTest::testShortcutOverride()
auto mainWindow = new KMainWindow();
QMenu *fileMenu = mainWindow->menuBar()->addMenu(QStringLiteral("File"));
QAction *testAction = fileMenu->addAction(QStringLiteral("Test"));
testAction->setShortcut(QKeySequence(Konsole::ACCEL | Qt::Key_S));
testAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_S));
connect(testAction, &QAction::triggered, this, &Konsole::PartManualTest::shortcutTriggered);
// Create terminal part and embed in into the main window
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment