forked from qt-creator/qt-creator
Terminal: lock/unlock keyboard
We copied QShortCutMap into Qtc to allow us tight control over which shortcuts are "enabled" while the focus is inside a terminal, and the keyboard is "locked" to the Terminal. Locked here means that except for a select few, all key presses are send directly to the terminal and cannot be used to activate other actions. Change-Id: I96cddf753033c0f4e7d806b20085bb4755853117 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -252,10 +252,37 @@ void TerminalWidget::setupColors()
|
||||
update();
|
||||
}
|
||||
|
||||
static RegisteredAction registerAction(Id commandId, const Context &context)
|
||||
static bool contextMatcher(QObject *, Qt::ShortcutContext)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void TerminalWidget::registerShortcut(Command *cmd)
|
||||
{
|
||||
QTC_ASSERT(cmd, return);
|
||||
auto addShortCut = [this, cmd] {
|
||||
for (const auto &keySequence : cmd->keySequences()) {
|
||||
m_shortcutMap.addShortcut(cmd->action(),
|
||||
keySequence,
|
||||
Qt::ShortcutContext::WindowShortcut,
|
||||
contextMatcher);
|
||||
}
|
||||
};
|
||||
auto removeShortCut = [this, cmd] { m_shortcutMap.removeShortcut(0, cmd->action()); };
|
||||
addShortCut();
|
||||
|
||||
connect(cmd, &Command::keySequenceChanged, this, [addShortCut, removeShortCut]() {
|
||||
removeShortCut();
|
||||
addShortCut();
|
||||
});
|
||||
}
|
||||
|
||||
RegisteredAction TerminalWidget::registerAction(Id commandId, const Context &context)
|
||||
{
|
||||
QAction *action = new QAction;
|
||||
ActionManager::registerAction(action, commandId, context);
|
||||
Command *cmd = ActionManager::registerAction(action, commandId, context);
|
||||
|
||||
registerShortcut(cmd);
|
||||
|
||||
return RegisteredAction(action, [commandId](QAction *a) {
|
||||
ActionManager::unregisterAction(a, commandId);
|
||||
@@ -287,10 +314,10 @@ void TerminalWidget::setupActions()
|
||||
this,
|
||||
&TerminalWidget::moveCursorWordRight);
|
||||
|
||||
m_exit = unlockGlobalAction(Core::Constants::EXIT, m_context);
|
||||
m_options = unlockGlobalAction(Core::Constants::OPTIONS, m_context);
|
||||
m_settings = unlockGlobalAction("Preferences.Terminal.General", m_context);
|
||||
m_findInDocument = unlockGlobalAction(Core::Constants::FIND_IN_DOCUMENT, m_context);
|
||||
unlockGlobalAction(Core::Constants::EXIT);
|
||||
unlockGlobalAction(Core::Constants::OPTIONS);
|
||||
unlockGlobalAction("Preferences.Terminal.General");
|
||||
unlockGlobalAction(Core::Constants::FIND_IN_DOCUMENT);
|
||||
}
|
||||
|
||||
void TerminalWidget::closeTerminal()
|
||||
@@ -1506,6 +1533,11 @@ void TerminalWidget::showEvent(QShowEvent *event)
|
||||
|
||||
bool TerminalWidget::event(QEvent *event)
|
||||
{
|
||||
if (TerminalSettings::instance().lockKeyboard() && event->type() == QEvent::ShortcutOverride) {
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::Paint) {
|
||||
QPainter p(this);
|
||||
p.fillRect(QRect(QPoint(0, 0), size()), m_currentColors[ColorIndex::Background]);
|
||||
@@ -1513,12 +1545,16 @@ bool TerminalWidget::event(QEvent *event)
|
||||
}
|
||||
|
||||
if (event->type() == QEvent::KeyPress) {
|
||||
QKeyEvent *k = (QKeyEvent *) event;
|
||||
auto k = static_cast<QKeyEvent *>(event);
|
||||
|
||||
if (TerminalSettings::instance().lockKeyboard() && m_shortcutMap.tryShortcut(k))
|
||||
return true;
|
||||
|
||||
keyPressEvent(k);
|
||||
return true;
|
||||
}
|
||||
if (event->type() == QEvent::KeyRelease) {
|
||||
QKeyEvent *k = (QKeyEvent *) event;
|
||||
auto k = static_cast<QKeyEvent *>(event);
|
||||
keyReleaseEvent(k);
|
||||
return true;
|
||||
}
|
||||
@@ -1565,21 +1601,11 @@ void TerminalWidget::initActions()
|
||||
ActionManager::registerAction(&clearTerminal, Constants::CLEAR_TERMINAL, context);
|
||||
}
|
||||
|
||||
UnlockedGlobalAction TerminalWidget::unlockGlobalAction(const Utils::Id &commandId,
|
||||
const Context &context)
|
||||
void TerminalWidget::unlockGlobalAction(const Utils::Id &commandId)
|
||||
{
|
||||
QAction *srcAction = ActionManager::command(commandId)->actionForContext(
|
||||
Core::Constants::C_GLOBAL);
|
||||
|
||||
ProxyAction *proxy = ProxyAction::proxyActionWithIcon(srcAction, srcAction->icon());
|
||||
ActionManager::registerAction(proxy, commandId, context);
|
||||
|
||||
UnlockedGlobalAction registeredAction(proxy, [commandId](QAction *a) {
|
||||
ActionManager::unregisterAction(a, commandId);
|
||||
delete a;
|
||||
});
|
||||
|
||||
return registeredAction;
|
||||
Command *cmd = ActionManager::command(commandId);
|
||||
QTC_ASSERT(cmd, return);
|
||||
registerShortcut(cmd);
|
||||
}
|
||||
|
||||
} // namespace Terminal
|
||||
|
||||
Reference in New Issue
Block a user