diff --git a/CHANGELOG.md b/CHANGELOG.md
index 26693087..bdca4601 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -44,6 +44,7 @@
- Bugfix: Fixed CMD + DELETE behavior in the user notes editing dialog for macOS. (#6676)
- Bugfix: Fixed a potential crash when closing Chatterino with a slow network connection. (#6645)
- Bugfix: Disable "Sort Tabs Alphabetically" action when notebook layout is locked. (#6710)
+- Bugfix: Fixed Return and Enter being treated as different keys on Mac OS. (#6726)
- Dev: Update release documentation. (#6498)
- Dev: Make code sanitizers opt in with the `CHATTERINO_SANITIZER_SUPPORT` CMake option. After that's enabled, use the `SANITIZE_*` flag to enable individual sanitizers. (#6493)
- Dev: Remove unused QTextCodec includes. (#6487)
diff --git a/src/controllers/hotkeys/HotkeyController.cpp b/src/controllers/hotkeys/HotkeyController.cpp
index cbb9951e..902ae08b 100644
--- a/src/controllers/hotkeys/HotkeyController.cpp
+++ b/src/controllers/hotkeys/HotkeyController.cpp
@@ -11,6 +11,7 @@
#include "util/RapidJsonSerializeQString.hpp" // IWYU pragma: keep
#include
+#include
#include
#include
#include
@@ -138,14 +139,27 @@ std::vector HotkeyController::shortcutsForCategory(
};
auto qs = QKeySequence(hotkey->keySequence());
- auto stringified = qs.toString(QKeySequence::NativeText);
- if (stringified.contains("Return"))
- {
- stringified.replace("Return", "Enter");
- auto copy = QKeySequence(stringified, QKeySequence::NativeText);
- createShortcutFromKeySeq(copy);
- }
+ // Create shortcut for the original key sequence
createShortcutFromKeySeq(qs);
+
+ // Qt treats Key_Return (main keyboard) and Key_Enter (numpad) as different keys, but they are expect to behave identically.
+ // Create a duplicate shortcut with the alternate key.
+ for (int i = 0; i < qs.count(); i++)
+ {
+ auto combo = qs[i];
+ if (combo.key() == Qt::Key_Return)
+ {
+ QKeyCombination enterCombo(combo.keyboardModifiers(),
+ Qt::Key_Enter);
+ createShortcutFromKeySeq(QKeySequence(enterCombo));
+ }
+ else if (combo.key() == Qt::Key_Enter)
+ {
+ QKeyCombination returnCombo(combo.keyboardModifiers(),
+ Qt::Key_Return);
+ createShortcutFromKeySeq(QKeySequence(returnCombo));
+ }
+ }
}
return output;
}
diff --git a/src/controllers/hotkeys/HotkeyHelpers.cpp b/src/controllers/hotkeys/HotkeyHelpers.cpp
index 0bd67d74..9337f0b4 100644
--- a/src/controllers/hotkeys/HotkeyHelpers.cpp
+++ b/src/controllers/hotkeys/HotkeyHelpers.cpp
@@ -7,8 +7,10 @@
#include "controllers/hotkeys/ActionNames.hpp"
#include "controllers/hotkeys/HotkeyCategory.hpp"
+#include
#include
+#include
#include
namespace chatterino {
@@ -52,4 +54,61 @@ std::optional findHotkeyActionDefinition(
return {};
}
+QKeySequence normalizeKeySequence(const QKeySequence &seq)
+{
+ if (seq.isEmpty())
+ {
+ return seq;
+ }
+
+ // First, check if any normalization is needed
+ bool needsNormalization = false;
+ for (int i = 0; i < seq.count(); i++)
+ {
+ if (seq[i].key() == Qt::Key_Enter)
+ {
+ needsNormalization = true;
+ break;
+ }
+ }
+
+ if (!needsNormalization)
+ {
+ return seq;
+ }
+
+ // Build normalized key combinations, preserving all keys in the sequence
+ // QKeySequence supports up to 4 key combinations
+ std::array combos{};
+ int count = seq.count();
+
+ for (int i = 0; i < count; i++)
+ {
+ auto combo = seq[i];
+ if (combo.key() == Qt::Key_Enter)
+ {
+ combos.at(i) =
+ QKeyCombination(combo.keyboardModifiers(), Qt::Key_Return);
+ }
+ else
+ {
+ combos.at(i) = combo;
+ }
+ }
+
+ // Construct QKeySequence with the appropriate number of keys
+ switch (count)
+ {
+ case 1:
+ return {combos.at(0)};
+ case 2:
+ return {combos.at(0), combos.at(1)};
+ case 3:
+ return {combos.at(0), combos.at(1), combos.at(2)};
+ case 4:
+ default:
+ return {combos.at(0), combos.at(1), combos.at(2), combos.at(3)};
+ }
+}
+
} // namespace chatterino
diff --git a/src/controllers/hotkeys/HotkeyHelpers.hpp b/src/controllers/hotkeys/HotkeyHelpers.hpp
index 53a19df9..fe0ed6fa 100644
--- a/src/controllers/hotkeys/HotkeyHelpers.hpp
+++ b/src/controllers/hotkeys/HotkeyHelpers.hpp
@@ -6,6 +6,7 @@
#include "controllers/hotkeys/ActionNames.hpp"
+#include
#include
#include
@@ -17,4 +18,7 @@ std::vector parseHotkeyArguments(QString argumentString);
std::optional findHotkeyActionDefinition(
HotkeyCategory category, const QString &action);
+// convert key_enter to key_return so that both keys function the same. preserves multi-key sequences and combinations.
+QKeySequence normalizeKeySequence(const QKeySequence &seq);
+
} // namespace chatterino
diff --git a/src/widgets/dialogs/EditHotkeyDialog.cpp b/src/widgets/dialogs/EditHotkeyDialog.cpp
index b8e8f106..40600b0d 100644
--- a/src/widgets/dialogs/EditHotkeyDialog.cpp
+++ b/src/widgets/dialogs/EditHotkeyDialog.cpp
@@ -12,6 +12,8 @@
#include "controllers/hotkeys/HotkeyHelpers.hpp"
#include "ui_EditHotkeyDialog.h"
+#include
+
namespace chatterino {
EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr hotkey,
@@ -21,6 +23,18 @@ EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr hotkey,
, data_(hotkey)
{
this->ui_->setupUi(this);
+ // normalize Key_Enter (numpad) to Key_Return so both Enter keys display and behave identically
+ QObject::connect(
+ this->ui_->keyComboEdit, &QKeySequenceEdit::keySequenceChanged, this,
+ [this](const QKeySequence &keySequence) {
+ auto normalized = normalizeKeySequence(keySequence);
+ if (normalized != keySequence)
+ {
+ // Block signals to prevent infinite loop
+ QSignalBlocker blocker(this->ui_->keyComboEdit);
+ this->ui_->keyComboEdit->setKeySequence(normalized);
+ }
+ });
this->setStyleSheet(R"(QToolTip {
padding: 2px;
background-color: #333333;
diff --git a/src/widgets/settingspages/KeyboardSettingsPage.cpp b/src/widgets/settingspages/KeyboardSettingsPage.cpp
index bfef14ac..0124795a 100644
--- a/src/widgets/settingspages/KeyboardSettingsPage.cpp
+++ b/src/widgets/settingspages/KeyboardSettingsPage.cpp
@@ -8,6 +8,7 @@
#include "common/QLogging.hpp"
#include "controllers/hotkeys/Hotkey.hpp"
#include "controllers/hotkeys/HotkeyController.hpp"
+#include "controllers/hotkeys/HotkeyHelpers.hpp"
#include "controllers/hotkeys/HotkeyModel.hpp"
#include "util/LayoutCreator.hpp"
#include "widgets/dialogs/EditHotkeyDialog.hpp"
@@ -18,6 +19,7 @@
#include
#include
#include
+#include
#include
#include
@@ -94,8 +96,16 @@ KeyboardSettingsPage::KeyboardSettingsPage()
auto *searchText = new QLabel("Search keybind:", this);
QObject::connect(keySequenceInput, &QKeySequenceEdit::keySequenceChanged,
- [view](const QKeySequence &keySequence) {
- view->filterSearchResultsHotkey(keySequence);
+ this,
+ [view, keySequenceInput](const QKeySequence &keySequence) {
+ // Normalize Key_Enter (numpad) to Key_Return for consistent search
+ auto normalized = normalizeKeySequence(keySequence);
+ if (normalized != keySequence)
+ {
+ QSignalBlocker blocker(keySequenceInput);
+ keySequenceInput->setKeySequence(normalized);
+ }
+ view->filterSearchResultsHotkey(normalized);
});
view->addCustomButton(searchText);
view->addCustomButton(keySequenceInput);