fix: Throwing focus and hotkeys to QtCreator

This commit is contained in:
Petr Mironychev
2026-05-15 21:27:45 +02:00
parent cc2d42f6d7
commit b1ca6823b8
11 changed files with 129 additions and 26 deletions

View File

@@ -94,5 +94,5 @@ target_link_libraries(QodeAssistChatView
)
target_include_directories(QodeAssistChatView
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}
)

View File

@@ -6,12 +6,16 @@
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickItem>
#include <QSettings>
#include <QVariantMap>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <logger/Logger.hpp>
#include "QodeAssistConstants.hpp"
namespace {
constexpr Qt::WindowFlags baseFlags = Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint
| Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint
@@ -39,20 +43,31 @@ ChatView::ChatView(QQmlEngine* engine)
setMinimumSize({400, 300});
setFlags(baseFlags);
if (auto action = Core::ActionManager::command("QodeAssist.CloseChatView")) {
m_closeShortcut = new QShortcut(action->keySequence(), this);
connect(m_closeShortcut, &QShortcut::activated, this, &QQuickView::close);
connect(action, &Core::Command::keySequenceChanged, this, [action, this]() {
if (m_closeShortcut) {
m_closeShortcut->setKey(action->keySequence());
}
});
}
bindCommandShortcut("QodeAssist.CloseChatView", [this] { close(); });
bindCommandShortcut(Constants::QODE_ASSIST_CHAT_SEND_MESSAGE, [this] {
QMetaObject::invokeMethod(rootObject(), "sendChatMessage");
});
bindCommandShortcut(Constants::QODE_ASSIST_CHAT_CLEAR_SESSION, [this] {
QMetaObject::invokeMethod(rootObject(), "clearChat");
});
restoreSettings();
}
void ChatView::bindCommandShortcut(Utils::Id commandId,
const std::function<void()> &onActivated)
{
auto command = Core::ActionManager::command(commandId);
if (!command)
return;
auto shortcut = new QShortcut(command->keySequence(), this);
connect(shortcut, &QShortcut::activated, this, onActivated);
connect(command, &Core::Command::keySequenceChanged, shortcut, [command, shortcut]() {
shortcut->setKey(command->keySequence());
});
}
void ChatView::closeEvent(QCloseEvent *event)
{
saveSettings();

View File

@@ -3,6 +3,10 @@
#pragma once
#include <functional>
#include <utils/id.h>
#include <QQuickView>
#include <QShortcut>
@@ -27,9 +31,9 @@ protected:
private:
void saveSettings();
void restoreSettings();
void bindCommandShortcut(Utils::Id commandId, const std::function<void()> &onActivated);
bool m_isPin;
QShortcut *m_closeShortcut;
};
} // namespace QodeAssist::Chat

View File

@@ -3,8 +3,15 @@
#include "ChatWidget.hpp"
#include <QApplication>
#include <QQmlContext>
#include <QQmlEngine>
#include <QQuickItem>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
#include "QodeAssistConstants.hpp"
namespace QodeAssist::Chat {
@@ -20,6 +27,12 @@ ChatWidget::ChatWidget(QQmlEngine* engine, QWidget *parent)
setContent(component->url(), component, rootItem);
}
setResizeMode(QQuickWidget::SizeRootObjectToView);
setFocusPolicy(Qt::StrongFocus);
auto ideContext = new Core::IContext{this};
ideContext->setWidget(this);
ideContext->setContext(Core::Context{Constants::QODE_ASSIST_CHAT_CONTEXT});
Core::ICore::addContextObject(ideContext);
}
void ChatWidget::clear()
@@ -31,4 +44,35 @@ void ChatWidget::scrollToBottom()
{
QMetaObject::invokeMethod(rootObject(), "scrollToBottom");
}
void ChatWidget::focusInput()
{
setFocus(Qt::OtherFocusReason);
QMetaObject::invokeMethod(rootObject(), "focusInput");
}
bool ChatWidget::isChatFocused() const
{
return hasFocus() || (rootObject() && rootObject()->hasActiveFocus());
}
void ChatWidget::sendMessage()
{
QMetaObject::invokeMethod(rootObject(), "sendChatMessage");
}
void ChatWidget::clearSession()
{
QMetaObject::invokeMethod(rootObject(), "clearChat");
}
ChatWidget *ChatWidget::focusedInstance()
{
for (QWidget *widget = QApplication::focusWidget(); widget;
widget = widget->parentWidget()) {
if (auto chatWidget = qobject_cast<ChatWidget *>(widget))
return chatWidget;
}
return nullptr;
}
} // namespace QodeAssist::Chat

View File

@@ -17,6 +17,14 @@ public:
Q_INVOKABLE void clear();
Q_INVOKABLE void scrollToBottom();
Q_INVOKABLE void focusInput();
void sendMessage();
void clearSession();
bool isChatFocused() const;
static ChatWidget *focusedInstance();
signals:
void clearPressed();

View File

@@ -526,15 +526,6 @@ ChatRootView {
}
}
Shortcut {
id: sendMessageShortcut
sequences: ["Ctrl+Return", "Ctrl+Enter"]
context: Qt.WindowShortcut
enabled: messageInput.activeFocus && !Qt.inputMethod.visible && !fileMentionPopup.visible
onActivated: root.sendChatMessage()
}
function clearChat() {
root.clearMessages()
root.clearAttachmentFiles()
@@ -545,6 +536,10 @@ ChatRootView {
Qt.callLater(chatListView.positionViewAtEnd)
}
function focusInput() {
messageInput.forceActiveFocus()
}
function applyMentionSelection() {
var result = fileMentionPopup.applyCurrentSelection(
messageInput.text, messageInput.cursorPosition, root.useTools)
@@ -654,6 +649,6 @@ ChatRootView {
}
Component.onCompleted: {
messageInput.forceActiveFocus()
focusInput()
}
}