mirror of
https://github.com/Mudlet/Mudlet
synced 2026-08-13 18:26:27 -04:00
add: keyboard shortcuts to switch between game tabs (#9460)
#### Brief overview of PR changes/additions - Ctrl+Tab / Ctrl+Shift+Tab cycle through open profile tabs (with wraparound); Ctrl+1-9 jump straight to a tab. On macOS: physical Ctrl+Tab and Cmd+1-9. - All 11 shortcuts are remappable per profile in Preferences > Shortcuts. - A one-time dismissible callout points out the new shortcuts when a second profile opens. - Replaces the old command-line-only Ctrl+Tab handling, which never worked on macOS and didn't move the tab bar highlight. The caret-mode Ctrl+Tab accessibility toggle still takes precedence when selected. #### Motivation for adding to Mudlet Switching between open games needed the mouse - the long-standing ask in #1160 - and macOS had no working way to do it at all (needs the QShortcut path due to QTBUG-12232, fixed for shortcuts in Qt 6.7.1+). #### Other info (issues closed, discussion etc) Closes #1160 Needs a test on macOS before merge (physical Ctrl+Tab / Cmd+1-9 delivery via Qt 6.8's performKeyEquivalent fix) - this was verified on Linux only. **Test case:** Open 3 profiles. Ctrl+Tab cycles forward and wraps, Ctrl+Shift+Tab cycles backward, Ctrl+2 jumps to the second tab - the tab bar highlight follows each switch. Remap "Next profile" in Preferences > Shortcuts and confirm the new key works. With Preferences > Accessibility caret shortcut set to Ctrl+Tab, Ctrl+Tab toggles caret mode instead of switching. https://github.com/user-attachments/assets/2f6a3ab7-1212-4d4a-9ad5-ed94dd0dc9b3
This commit is contained in:
parent
282d774956
commit
b649b60f0f
7 changed files with 173 additions and 29 deletions
21
src/Host.cpp
21
src/Host.cpp
|
|
@ -62,6 +62,7 @@
|
|||
#include <QtConcurrentRun>
|
||||
#include <QCoreApplication>
|
||||
#include <QDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QtUiTools>
|
||||
#include <QNetworkProxy>
|
||||
#include <QSettings>
|
||||
|
|
@ -4860,6 +4861,26 @@ void Host::setCaretEnabled(bool enabled)
|
|||
mpConsole->setCaretMode(enabled);
|
||||
}
|
||||
|
||||
// Whether this key press is the one selected in the accessibility preferences
|
||||
// to toggle caret mode - such a press must reach the caret-toggling key
|
||||
// handlers instead of being swallowed by an application-wide QShortcut,
|
||||
// which the user could have remapped onto any of these keys:
|
||||
bool Host::caretShortcutMatches(const QKeyEvent* ke) const
|
||||
{
|
||||
constexpr Qt::KeyboardModifiers allModifiers = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier;
|
||||
switch (mCaretShortcut) {
|
||||
case CaretShortcut::None:
|
||||
return false;
|
||||
case CaretShortcut::Tab:
|
||||
return ke->key() == Qt::Key_Tab && !(ke->modifiers() & Qt::ControlModifier);
|
||||
case CaretShortcut::CtrlTab:
|
||||
return ke->key() == Qt::Key_Tab && (ke->modifiers() & Qt::ControlModifier);
|
||||
case CaretShortcut::F6:
|
||||
return ke->key() == Qt::Key_F6 && (ke->modifiers() & allModifiers) == Qt::NoModifier;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Host::setFocusOnHostActiveCommandLine()
|
||||
{
|
||||
if (mFocusTimerRunning) {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
|
||||
class QDialog;
|
||||
class QDockWidget;
|
||||
class QKeyEvent;
|
||||
class QPushButton;
|
||||
class QListWidget;
|
||||
|
||||
|
|
@ -465,6 +466,7 @@ public:
|
|||
void setEditorShowBidi(const bool);
|
||||
bool caretEnabled() const;
|
||||
void setCaretEnabled(bool enabled);
|
||||
bool caretShortcutMatches(const QKeyEvent*) const;
|
||||
void setFocusOnHostActiveCommandLine();
|
||||
void recordActiveCommandLine(TCommandLine*);
|
||||
void forgetCommandLine(TCommandLine*);
|
||||
|
|
|
|||
|
|
@ -172,6 +172,19 @@ bool TCommandLine::event(QEvent* event)
|
|||
return QPlainTextEdit::event(event);
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::ShortcutOverride) {
|
||||
auto* ke = static_cast<QKeyEvent*>(event);
|
||||
// The accessibility caret-mode shortcut (Tab, Ctrl+Tab or F6) must
|
||||
// beat any application-wide QShortcut - the profile-switching ones
|
||||
// use Ctrl+Tab by default and all of them can be remapped onto these
|
||||
// keys - so claim it here to make it arrive as a KeyPress for the
|
||||
// caret-toggling code below:
|
||||
if (mpHost->caretShortcutMatches(ke)) {
|
||||
ke->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const Qt::KeyboardModifiers allModifiers = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier | Qt::GroupSwitchModifier;
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
auto* ke = dynamic_cast<QKeyEvent*>(event);
|
||||
|
|
@ -250,17 +263,6 @@ bool TCommandLine::event(QEvent* event)
|
|||
case Qt::Key_Backtab:
|
||||
// <BACKTAB> is usually internally generated by SHIFT used in
|
||||
// conjunction with TAB - so ignore just the SHIFT key:
|
||||
if ((ke->modifiers() & (allModifiers & ~(Qt::ShiftModifier))) == Qt::ControlModifier) {
|
||||
// Switch to PREVIOUS profile tab when used with <CTRL> (and
|
||||
// implicit <SHIFT>):
|
||||
const int currentIndex = mudlet::self()->mpTabBar->currentIndex();
|
||||
const int count = mudlet::self()->mpTabBar->count();
|
||||
const int newIndex = (currentIndex - 1 < 0) ? (count - 1) : (currentIndex - 1);
|
||||
mudlet::self()->slot_tabChanged(newIndex);
|
||||
ke->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((ke->modifiers() & (allModifiers & ~(Qt::ShiftModifier))) == Qt::NoModifier) {
|
||||
// Process as plain <BACKTAB> - (ignoring implicit <SHIFT>)
|
||||
handleTabCompletion(false);
|
||||
|
|
@ -271,29 +273,18 @@ bool TCommandLine::event(QEvent* event)
|
|||
|
||||
if (keybindingMatched(ke)) {
|
||||
// Process as a possible key binding if there are ANY modifiers
|
||||
// other than just the ignored <SHIFT> and the possible <CTRL>:
|
||||
// other than just the ignored <SHIFT>:
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Tab:
|
||||
if ((mpHost->mCaretShortcut == Host::CaretShortcut::Tab && !(ke->modifiers() & Qt::ControlModifier))
|
||||
|| (mpHost->mCaretShortcut == Host::CaretShortcut::CtrlTab && (ke->modifiers() & Qt::ControlModifier))) {
|
||||
if (mpHost->caretShortcutMatches(ke)) {
|
||||
mpHost->setCaretEnabled(true);
|
||||
ke->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((ke->modifiers() & allModifiers) == Qt::ControlModifier) {
|
||||
// Switch to NEXT profile tab
|
||||
const int currentIndex = mudlet::self()->mpTabBar->currentIndex();
|
||||
const int count = mudlet::self()->mpTabBar->count();
|
||||
const int newIndex = (currentIndex + 1 < count) ? (currentIndex + 1) : 0;
|
||||
mudlet::self()->slot_tabChanged(newIndex);
|
||||
ke->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((ke->modifiers() & allModifiers) == Qt::NoModifier) {
|
||||
handleTabCompletion(true);
|
||||
ke->accept();
|
||||
|
|
@ -301,7 +292,6 @@ bool TCommandLine::event(QEvent* event)
|
|||
}
|
||||
|
||||
// Process as a possible key binding if there are ANY modifiers
|
||||
// other than just the Ctrl one
|
||||
// CHECKME: What about system foreground application switching?
|
||||
if (keybindingMatched(ke)) {
|
||||
return true;
|
||||
|
|
@ -309,7 +299,7 @@ bool TCommandLine::event(QEvent* event)
|
|||
break;
|
||||
|
||||
case Qt::Key_F6:
|
||||
if ((mpHost->mCaretShortcut == Host::CaretShortcut::F6) && ((ke->modifiers() & allModifiers) == Qt::NoModifier)) {
|
||||
if (mpHost->caretShortcutMatches(ke)) {
|
||||
mpHost->setCaretEnabled(true);
|
||||
ke->accept();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -3706,6 +3706,23 @@ bool TTextEdit::focusNextPrevChild(bool next)
|
|||
return QWidget::focusNextPrevChild(next);
|
||||
}
|
||||
|
||||
bool TTextEdit::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::ShortcutOverride) {
|
||||
auto* ke = static_cast<QKeyEvent*>(event);
|
||||
// While caret mode is active its shortcut (Tab, Ctrl+Tab or F6) must
|
||||
// beat any application-wide QShortcut - the profile-switching ones
|
||||
// use Ctrl+Tab by default and all of them can be remapped onto these
|
||||
// keys - so claim it here to make it arrive as a KeyPress for the
|
||||
// caret-toggling code in keyPressEvent():
|
||||
if (mpHost && mpHost->caretEnabled() && mpHost->caretShortcutMatches(ke)) {
|
||||
ke->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QWidget::event(event);
|
||||
}
|
||||
|
||||
void TTextEdit::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (!mpHost || !mpHost->caretEnabled()) {
|
||||
|
|
@ -4003,8 +4020,7 @@ void TTextEdit::keyPressEvent(QKeyEvent* event)
|
|||
}
|
||||
break;
|
||||
case Qt::Key_Tab: {
|
||||
if ((mpHost->mCaretShortcut == Host::CaretShortcut::Tab && !(event->modifiers() & Qt::ControlModifier))
|
||||
|| (mpHost->mCaretShortcut == Host::CaretShortcut::CtrlTab && (event->modifiers() & Qt::ControlModifier))) {
|
||||
if (mpHost->caretShortcutMatches(event)) {
|
||||
mpHost->setCaretEnabled(false);
|
||||
break;
|
||||
}
|
||||
|
|
@ -4038,7 +4054,7 @@ void TTextEdit::keyPressEvent(QKeyEvent* event)
|
|||
}
|
||||
|
||||
case Qt::Key_F6: {
|
||||
if (mpHost->mCaretShortcut == Host::CaretShortcut::F6) {
|
||||
if (mpHost->caretShortcutMatches(event)) {
|
||||
mpHost->setCaretEnabled(false);
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -171,6 +171,7 @@ public slots:
|
|||
|
||||
protected:
|
||||
bool focusNextPrevChild(bool next) override;
|
||||
bool event(QEvent* event) override;
|
||||
void keyPressEvent(QKeyEvent* event) override;
|
||||
void focusOutEvent(QFocusEvent* event) override;
|
||||
|
||||
|
|
|
|||
104
src/mudlet.cpp
104
src/mudlet.cpp
|
|
@ -37,6 +37,7 @@
|
|||
#include "TDetachedWindow.h"
|
||||
#include "TDockWidget.h"
|
||||
#include "TEvent.h"
|
||||
#include "TFeatureCallout.h"
|
||||
#include "TMap.h"
|
||||
#include "TMedia.h"
|
||||
#include "TGameDetails.h"
|
||||
|
|
@ -667,6 +668,13 @@ void mudlet::init()
|
|||
mKeySequenceToggleReplay = QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_R);
|
||||
mKeySequenceToggleLogging = QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_L);
|
||||
mKeySequenceToggleEmergencyStop = QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_S);
|
||||
// Physical Ctrl+Tab (Qt::META is the Ctrl key on macOS), matching the
|
||||
// system-wide window-tab cycling convention there. Spelt with Key_Tab and
|
||||
// not Key_Backtab because QShortcutMap never generates a Shift+Backtab
|
||||
// candidate for a Shift+Tab press - the Shift is consumed producing the
|
||||
// Backtab keysym, so only "...+Shift+Tab" matches:
|
||||
mKeySequenceNextProfile = QKeySequence(Qt::META | Qt::Key_Tab);
|
||||
mKeySequencePreviousProfile = QKeySequence(Qt::META | Qt::SHIFT | Qt::Key_Tab);
|
||||
#else
|
||||
mKeySequenceTriggers = QKeySequence(Qt::ALT | Qt::Key_E);
|
||||
mKeySequenceShowMap = QKeySequence(Qt::ALT | Qt::Key_M);
|
||||
|
|
@ -685,7 +693,18 @@ void mudlet::init()
|
|||
mKeySequenceToggleReplay = QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_R);
|
||||
mKeySequenceToggleLogging = QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_L);
|
||||
mKeySequenceToggleEmergencyStop = QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_S);
|
||||
// Spelt with Key_Tab and not Key_Backtab because QShortcutMap never
|
||||
// generates a Shift+Backtab candidate for a Shift+Tab press - the Shift
|
||||
// is consumed producing the Backtab keysym, so only "Ctrl+Shift+Tab"
|
||||
// matches:
|
||||
mKeySequenceNextProfile = QKeySequence(Qt::CTRL | Qt::Key_Tab);
|
||||
mKeySequencePreviousProfile = QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Tab);
|
||||
#endif
|
||||
// Qt::CTRL is the Cmd key on macOS, so this gives the Cmd+1..9
|
||||
// (Safari/Chrome/iTerm2) convention there and Ctrl+1..9 elsewhere:
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
mKeySequencesSwitchToProfile[i] = QKeySequence(Qt::CTRL | static_cast<Qt::Key>(Qt::Key_1 + i));
|
||||
}
|
||||
connect(this, &mudlet::signal_menuBarVisibilityChanged, this, &mudlet::slot_updateShortcuts);
|
||||
connect(this, &mudlet::signal_hostCreated, this, &mudlet::slot_assignShortcutsFromProfile);
|
||||
connect(this, &mudlet::signal_profileActivated, this, &mudlet::slot_assignShortcutsFromProfile);
|
||||
|
|
@ -708,6 +727,12 @@ void mudlet::init()
|
|||
mpShortcutsManager->registerShortcut(qsl("Toggle Replay"), tr("Toggle Replay"), &mKeySequenceToggleReplay);
|
||||
mpShortcutsManager->registerShortcut(qsl("Toggle Logging"), tr("Toggle Logging"), &mKeySequenceToggleLogging);
|
||||
mpShortcutsManager->registerShortcut(qsl("Toggle Emergency Stop"), tr("Toggle Emergency Stop"), &mKeySequenceToggleEmergencyStop);
|
||||
mpShortcutsManager->registerShortcut(qsl("Next profile"), tr("Next profile"), &mKeySequenceNextProfile);
|
||||
mpShortcutsManager->registerShortcut(qsl("Previous profile"), tr("Previous profile"), &mKeySequencePreviousProfile);
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
//: Name of the keyboard shortcut that switches to the numbered profile tab, %1 is that number (1 to 9)
|
||||
mpShortcutsManager->registerShortcut(qsl("Switch to profile %1").arg(i + 1), tr("Switch to profile %1").arg(i + 1), &mKeySequencesSwitchToProfile[i]);
|
||||
}
|
||||
readLateSettings(*mpSettings);
|
||||
// The previous line will set an option used in the slot method:
|
||||
connect(mpMainToolBar, &QToolBar::visibilityChanged, this, &mudlet::slot_handleToolbarVisibilityChanged);
|
||||
|
|
@ -2061,6 +2086,29 @@ void mudlet::reshowRequiredMainConsoles()
|
|||
}
|
||||
}
|
||||
|
||||
void mudlet::slot_nextProfile()
|
||||
{
|
||||
const int count = mpTabBar->count();
|
||||
if (count > 1) {
|
||||
mpTabBar->setCurrentIndex((mpTabBar->currentIndex() + 1) % count);
|
||||
}
|
||||
}
|
||||
|
||||
void mudlet::slot_previousProfile()
|
||||
{
|
||||
const int count = mpTabBar->count();
|
||||
if (count > 1) {
|
||||
mpTabBar->setCurrentIndex((mpTabBar->currentIndex() + count - 1) % count);
|
||||
}
|
||||
}
|
||||
|
||||
void mudlet::switchToProfileTab(int index)
|
||||
{
|
||||
if (index >= 0 && index < mpTabBar->count()) {
|
||||
mpTabBar->setCurrentIndex(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Moved as much as possible to activateProfile()...
|
||||
void mudlet::slot_tabChanged(int tabID)
|
||||
{
|
||||
|
|
@ -2094,6 +2142,29 @@ void mudlet::slot_telnetConnectionStateChanged()
|
|||
updateDetachedWindowTabIndicators();
|
||||
}
|
||||
|
||||
// Renders a key sequence for use inside a sentence. NativeText produces the
|
||||
// macOS shortcut glyphs (like the tab glyph in "⌃⇥") which many users cannot
|
||||
// read, so on macOS spell the keys out the way Apple's docs do instead
|
||||
// ("Control-Tab", "Command-1"):
|
||||
static QString keySequenceForProse(const QKeySequence& sequence)
|
||||
{
|
||||
#if defined(Q_OS_MACOS)
|
||||
QStringList keys = sequence.toString(QKeySequence::PortableText).split(QLatin1Char('+'));
|
||||
for (auto& key : keys) {
|
||||
if (key == qsl("Meta")) {
|
||||
key = qsl("Control");
|
||||
} else if (key == qsl("Ctrl")) {
|
||||
key = qsl("Command");
|
||||
} else if (key == qsl("Alt")) {
|
||||
key = qsl("Option");
|
||||
}
|
||||
}
|
||||
return keys.join(QLatin1Char('-'));
|
||||
#else
|
||||
return sequence.toString(QKeySequence::NativeText);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mudlet::addConsoleForNewHost(Host* pH)
|
||||
{
|
||||
if (pH->mpConsole) {
|
||||
|
|
@ -2162,6 +2233,20 @@ void mudlet::addConsoleForNewHost(Host* pH)
|
|||
}
|
||||
mpTabBar->repaint();
|
||||
|
||||
// Tab switching only becomes relevant once a second profile is open; an
|
||||
// empty sequence means the player cleared the shortcut and already knows
|
||||
// about the feature:
|
||||
if (mpTabBar->count() == 2 && !mKeySequenceNextProfile.isEmpty()) {
|
||||
//: Title of a balloon pointing out the newly added profile tab switching shortcuts
|
||||
TFeatureCallout::maybeShow(
|
||||
qsl("profileTabShortcuts"),
|
||||
mpTabBar,
|
||||
tr("Switch games with the keyboard"),
|
||||
//: %1, %2 and %3 are keyboard shortcuts, e.g. Ctrl+Tab, Ctrl+1 and Ctrl+9 (Control-Tab, Command-1 and Command-9 on macOS)
|
||||
tr("Press %1 to cycle through your open games, or %2 to %3 to jump straight to one. You can change these keys in the preferences.")
|
||||
.arg(keySequenceForProse(mKeySequenceNextProfile), keySequenceForProse(mKeySequencesSwitchToProfile.front()), keySequenceForProse(mKeySequencesSwitchToProfile.back())));
|
||||
}
|
||||
|
||||
// update the window title for the currently selected profile
|
||||
updateMainWindowTitle();
|
||||
|
||||
|
|
@ -3770,6 +3855,25 @@ void mudlet::slot_updateShortcuts()
|
|||
void mudlet::assignKeySequences()
|
||||
{
|
||||
mMenuVisibleState = !(mMenuBarVisibility == enums::visibleNever || (mMenuBarVisibility == enums::visibleOnlyWithoutLoadedProfile && mHostManager.getHostCount()));
|
||||
|
||||
// The profile tab switching shortcuts have no menu-action counterparts so
|
||||
// they are always plain QShortcuts, whatever the menu visibility:
|
||||
delete mpShortcutNextProfile.data();
|
||||
mpShortcutNextProfile = new QShortcut(mKeySequenceNextProfile, this);
|
||||
connect(mpShortcutNextProfile.data(), &QShortcut::activated, this, &mudlet::slot_nextProfile);
|
||||
|
||||
delete mpShortcutPreviousProfile.data();
|
||||
mpShortcutPreviousProfile = new QShortcut(mKeySequencePreviousProfile, this);
|
||||
connect(mpShortcutPreviousProfile.data(), &QShortcut::activated, this, &mudlet::slot_previousProfile);
|
||||
|
||||
for (int i = 0; i < 9; ++i) {
|
||||
delete mpShortcutsSwitchToProfile[i].data();
|
||||
mpShortcutsSwitchToProfile[i] = new QShortcut(mKeySequencesSwitchToProfile[i], this);
|
||||
connect(mpShortcutsSwitchToProfile[i].data(), &QShortcut::activated, this, [this, i]() {
|
||||
switchToProfileTab(i);
|
||||
});
|
||||
}
|
||||
|
||||
if (!mMenuVisibleState.value()) {
|
||||
// The menu is hidden so wire the QKeySequences directly to the slots:
|
||||
|
||||
|
|
|
|||
10
src/mudlet.h
10
src/mudlet.h
|
|
@ -53,6 +53,7 @@
|
|||
#else
|
||||
#include <qt6keychain/keychain.h>
|
||||
#endif
|
||||
#include <array>
|
||||
#include <optional>
|
||||
#include <hunspell/hunspell.hxx>
|
||||
#include <hunspell/hunspell.h>
|
||||
|
|
@ -198,6 +199,7 @@ public:
|
|||
void init();
|
||||
void setupConfig();
|
||||
void activateProfile(Host*);
|
||||
void switchToProfileTab(int index);
|
||||
void takeOwnershipOfInstanceCoordinator(std::unique_ptr<MudletInstanceCoordinator>);
|
||||
MudletInstanceCoordinator* getInstanceCoordinator();
|
||||
void addConsoleForNewHost(Host*);
|
||||
|
|
@ -463,6 +465,8 @@ public slots:
|
|||
void slot_showHelpDialogForum();
|
||||
void slot_showHelpDialogIrc();
|
||||
void slot_showHelpDialogVideo();
|
||||
void slot_nextProfile();
|
||||
void slot_previousProfile();
|
||||
void slot_tabChanged(int);
|
||||
void slot_timerFires();
|
||||
void slot_toggleFullScreenView();
|
||||
|
|
@ -622,6 +626,9 @@ private:
|
|||
QKeySequence mKeySequenceToggleReplay;
|
||||
QKeySequence mKeySequenceToggleLogging;
|
||||
QKeySequence mKeySequenceToggleEmergencyStop;
|
||||
QKeySequence mKeySequenceNextProfile;
|
||||
QKeySequence mKeySequencePreviousProfile;
|
||||
std::array<QKeySequence, 9> mKeySequencesSwitchToProfile;
|
||||
bool mIsGoingDown = false;
|
||||
// Whether multi-view is in effect:
|
||||
enums::controlsVisibility mMenuBarVisibility = enums::visibleAlways;
|
||||
|
|
@ -704,6 +711,9 @@ private:
|
|||
QPointer<QShortcut> mpShortcutToggleReplay;
|
||||
QPointer<QShortcut> mpShortcutToggleLogging;
|
||||
QPointer<QShortcut> mpShortcutToggleEmergencyStop;
|
||||
QPointer<QShortcut> mpShortcutNextProfile;
|
||||
QPointer<QShortcut> mpShortcutPreviousProfile;
|
||||
std::array<QPointer<QShortcut>, 9> mpShortcutsSwitchToProfile;
|
||||
QPointer<QTimer> mpTimerReplay;
|
||||
QPointer<QTimer> mpBlinkTimer;
|
||||
QElapsedTimer mBlinkElapsedTimer;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue