diff --git a/Telegram/SourceFiles/core/application.cpp b/Telegram/SourceFiles/core/application.cpp index 14714e1e4..ea8102f0f 100644 --- a/Telegram/SourceFiles/core/application.cpp +++ b/Telegram/SourceFiles/core/application.cpp @@ -183,9 +183,6 @@ Application::~Application() { Local::writeSettings(); } - // Depend on primaryWindow() for now :( - Shortcuts::Finish(); - _closingAsyncWindows.clear(); _secondaryWindows.clear(); _primaryWindows.clear(); @@ -261,6 +258,7 @@ void Application::run() { Ui::StartCachedCorners(); Ui::Emoji::Init(); Ui::PreloadTextSpoilerMask(); + startShortcuts(); startEmojiImageLoader(); startSystemDarkModeViewer(); Media::Player::start(_audio.get()); @@ -329,10 +327,7 @@ void Application::run() { DEBUG_LOG(("Application Info: window created...")); - // Depend on primaryWindow() for now :( - startShortcuts(); startDomain(); - startTray(); _lastActivePrimaryWindow->widget()->show(); @@ -567,7 +562,7 @@ bool Application::eventFilter(QObject *object, QEvent *e) { const auto event = static_cast(e); DEBUG_LOG(("Shortcut event caught: %1" ).arg(event->key().toString())); - if (Shortcuts::HandleEvent(event)) { + if (Shortcuts::HandleEvent(object, event)) { return true; } } break; diff --git a/Telegram/SourceFiles/core/shortcuts.cpp b/Telegram/SourceFiles/core/shortcuts.cpp index 06b59760a..ef566e64a 100644 --- a/Telegram/SourceFiles/core/shortcuts.cpp +++ b/Telegram/SourceFiles/core/shortcuts.cpp @@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "platform/platform_specific.h" #include "base/parse_helper.h" +#include #include #include #include @@ -143,11 +144,13 @@ public: void fill(); void clear(); - [[nodiscard]] std::vector lookup(int shortcutId) const; + [[nodiscard]] std::vector lookup( + not_null object) const; void toggleMedia(bool toggled); void toggleSupport(bool toggled); + void listen(not_null widget); - const QStringList &errors() const; + [[nodiscard]] const QStringList &errors() const; private: void fillDefaults(); @@ -156,15 +159,15 @@ private: void set(const QString &keys, Command command, bool replace = false); void remove(const QString &keys); - void unregister(base::unique_qptr shortcut); + void unregister(base::unique_qptr shortcut); QStringList _errors; - base::flat_map> _shortcuts; - base::flat_multi_map _commandByShortcutId; + base::flat_map> _shortcuts; + base::flat_multi_map, Command> _commandByObject; - base::flat_set _mediaShortcuts; - base::flat_set _supportShortcuts; + base::flat_set _mediaShortcuts; + base::flat_set _supportShortcuts; }; @@ -227,7 +230,7 @@ void Manager::fill() { void Manager::clear() { _errors.clear(); _shortcuts.clear(); - _commandByShortcutId.clear(); + _commandByObject.clear(); _mediaShortcuts.clear(); _supportShortcuts.clear(); } @@ -236,11 +239,11 @@ const QStringList &Manager::errors() const { return _errors; } -std::vector Manager::lookup(int shortcutId) const { +std::vector Manager::lookup(not_null object) const { auto result = std::vector(); - auto i = _commandByShortcutId.findFirst(shortcutId); - const auto end = _commandByShortcutId.end(); - for (; i != end && (i->first == shortcutId); ++i) { + auto i = _commandByObject.findFirst(object); + const auto end = _commandByObject.end(); + for (; i != end && (i->first == object); ++i) { result.push_back(i->second); } return result; @@ -258,6 +261,12 @@ void Manager::toggleSupport(bool toggled) { } } +void Manager::listen(not_null widget) { + for (const auto &[keys, shortcut] : _shortcuts) { + widget->addAction(shortcut.get()); + } +} + bool Manager::readCustomFile() { // read custom shortcuts from file if it exists or write an empty custom shortcuts file QFile file(CustomFilePath()); @@ -412,10 +421,10 @@ void Manager::writeDefaultFile() { shortcuts.push_back(version); for (const auto &[sequence, shortcut] : _shortcuts) { - const auto shortcutId = shortcut->id(); - auto i = _commandByShortcutId.findFirst(shortcutId); - const auto end = _commandByShortcutId.end(); - for (; i != end && i->first == shortcutId; ++i) { + const auto object = shortcut.get(); + auto i = _commandByObject.findFirst(object); + const auto end = _commandByObject.end(); + for (; i != end && i->first == object; ++i) { const auto j = CommandNames.find(i->second); if (j != CommandNames.end()) { QJsonObject entry; @@ -441,12 +450,9 @@ void Manager::set(const QString &keys, Command command, bool replace) { _errors.push_back(u"Could not derive key sequence '%1'!"_q.arg(keys)); return; } - auto shortcut = base::make_unique_q( - result, - Core::App().activePrimaryWindow()->widget().get(), // #TODO windows - nullptr, - nullptr, - Qt::ApplicationShortcut); + auto shortcut = base::make_unique_q(); + shortcut->setShortcut(result); + shortcut->setShortcutContext(Qt::ApplicationShortcut); if (!AutoRepeatCommands.contains(command)) { shortcut->setAutoRepeat(false); } @@ -455,20 +461,16 @@ void Manager::set(const QString &keys, Command command, bool replace) { if (isMediaShortcut || isSupportShortcut) { shortcut->setEnabled(false); } - auto id = shortcut->id(); + auto object = shortcut.get(); auto i = _shortcuts.find(result); if (i == end(_shortcuts)) { i = _shortcuts.emplace(result, std::move(shortcut)).first; } else if (replace) { unregister(std::exchange(i->second, std::move(shortcut))); } else { - id = i->second->id(); + object = i->second.get(); } - if (!id) { - _errors.push_back(u"Could not create shortcut '%1'!"_q.arg(keys)); - return; - } - _commandByShortcutId.emplace(id, command); + _commandByObject.emplace(object, command); if (!shortcut && isMediaShortcut) { _mediaShortcuts.emplace(i->second.get()); } @@ -494,9 +496,9 @@ void Manager::remove(const QString &keys) { } } -void Manager::unregister(base::unique_qptr shortcut) { +void Manager::unregister(base::unique_qptr shortcut) { if (shortcut) { - _commandByShortcutId.erase(shortcut->id()); + _commandByObject.erase(shortcut.get()); _mediaShortcuts.erase(shortcut.get()); _supportShortcuts.erase(shortcut.get()); } @@ -560,8 +562,10 @@ const QStringList &Errors() { return Data.errors(); } -bool HandleEvent(not_null event) { - return Launch(Data.lookup(event->shortcutId())); +bool HandleEvent( + not_null object, + not_null event) { + return Launch(Data.lookup(object)); } void ToggleMediaShortcuts(bool toggled) { @@ -576,4 +580,8 @@ void Finish() { Data.clear(); } +void Listen(not_null widget) { + Data.listen(widget); +} + } // namespace Shortcuts diff --git a/Telegram/SourceFiles/core/shortcuts.h b/Telegram/SourceFiles/core/shortcuts.h index 94448a093..6e1904c68 100644 --- a/Telegram/SourceFiles/core/shortcuts.h +++ b/Telegram/SourceFiles/core/shortcuts.h @@ -100,8 +100,10 @@ rpl::producer> Requests(); void Start(); void Finish(); +void Listen(not_null widget); + bool Launch(Command command); -bool HandleEvent(not_null event); +bool HandleEvent(not_null object, not_null event); const QStringList &Errors(); diff --git a/Telegram/SourceFiles/window/main_window.cpp b/Telegram/SourceFiles/window/main_window.cpp index d8b9fe617..192eac847 100644 --- a/Telegram/SourceFiles/window/main_window.cpp +++ b/Telegram/SourceFiles/window/main_window.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "main/main_account.h" // Account::sessionValue. #include "core/application.h" #include "core/sandbox.h" +#include "core/shortcuts.h" #include "lang/lang_keys.h" #include "data/data_session.h" #include "data/data_forum_topic.h" @@ -352,6 +353,8 @@ MainWindow::MainWindow(not_null controller) updateControlsGeometry(); }, _outdated->lifetime()); } + + Shortcuts::Listen(this); } Main::Account &MainWindow::account() const {