Fixed Return and Enter being treated as different keys on Mac OS (#6729)
Co-authored-by: Chad Gorman <nevicar@Chads-Mini.localdomain> Reviewed-by: Mm2PL <mm2pl+gh@kotmisia.pl>
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
- Bugfix: Fixed <kbd>CMD</kbd> + <kbd>DELETE</kbd> 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)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "util/RapidJsonSerializeQString.hpp" // IWYU pragma: keep
|
||||
|
||||
#include <pajlada/settings.hpp>
|
||||
#include <QKeyCombination>
|
||||
#include <QMessageBox>
|
||||
#include <QShortcut>
|
||||
#include <QWidget>
|
||||
@@ -138,14 +139,27 @@ std::vector<QShortcut *> 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;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
#include "controllers/hotkeys/ActionNames.hpp"
|
||||
#include "controllers/hotkeys/HotkeyCategory.hpp"
|
||||
|
||||
#include <QKeyCombination>
|
||||
#include <QStringList>
|
||||
|
||||
#include <array>
|
||||
#include <optional>
|
||||
|
||||
namespace chatterino {
|
||||
@@ -52,4 +54,61 @@ std::optional<ActionDefinition> 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<QKeyCombination, 4> 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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "controllers/hotkeys/ActionNames.hpp"
|
||||
|
||||
#include <QKeySequence>
|
||||
#include <QString>
|
||||
|
||||
#include <optional>
|
||||
@@ -17,4 +18,7 @@ std::vector<QString> parseHotkeyArguments(QString argumentString);
|
||||
std::optional<ActionDefinition> 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
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#include "controllers/hotkeys/HotkeyHelpers.hpp"
|
||||
#include "ui_EditHotkeyDialog.h"
|
||||
|
||||
#include <QSignalBlocker>
|
||||
|
||||
namespace chatterino {
|
||||
|
||||
EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr<Hotkey> hotkey,
|
||||
@@ -21,6 +23,18 @@ EditHotkeyDialog::EditHotkeyDialog(const std::shared_ptr<Hotkey> 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;
|
||||
|
||||
@@ -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 <QKeySequenceEdit>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QSignalBlocker>
|
||||
#include <QTableView>
|
||||
|
||||
#include <array>
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user