diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c3da492..66b8281b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ - Minor: Added a Send button in the input box so you can click to send a message. This is disabled by default and can be enabled with the "Show send message button" setting. (#4607) - Minor: Improved error messages when the updater fails a download. (#4594) - Minor: Added `/shield` and `/shieldoff` commands to toggle shield mode. (#4580) +- Minor: Allow for customizing the behavior of `Right Click`ing of usernames. (#4622) - Bugfix: Fixed the menu warping on macOS on Qt6. (#4595) - Bugfix: Fixed link tooltips not showing unless the thumbnail setting was enabled. (#4597) - Bugfix: Domains starting with `http` are now parsed as links again. (#4598) diff --git a/src/singletons/Settings.hpp b/src/singletons/Settings.hpp index 9440f8a97..3ef633f1e 100644 --- a/src/singletons/Settings.hpp +++ b/src/singletons/Settings.hpp @@ -83,6 +83,12 @@ enum ThumbnailPreviewMode : int { ShowOnShift = 2, }; +enum UsernameRightClickBehavior : int { + Reply = 0, + Mention = 1, + Ignore = 2, +}; + /// Settings which are availlable for reading and writing on the gui thread. // These settings are still accessed concurrently in the code but it is bad practice. class Settings : public ABSettings, public ConcurrentSettings @@ -194,6 +200,20 @@ public: BoolSetting autoCloseUserPopup = {"/behaviour/autoCloseUserPopup", true}; BoolSetting autoCloseThreadPopup = {"/behaviour/autoCloseThreadPopup", false}; + + EnumSetting usernameRightClickBehavior = { + "/behaviour/usernameRightClickBehavior", + UsernameRightClickBehavior::Mention, + }; + EnumSetting usernameRightClickModifierBehavior = + { + "/behaviour/usernameRightClickBehaviorWithModifier", + UsernameRightClickBehavior::Reply, + }; + EnumSetting usernameRightClickModifier = { + "/behaviour/usernameRightClickModifier", + Qt::KeyboardModifier::ShiftModifier}; + BoolSetting autoSubToParticipatedThreads = { "/behaviour/autoSubToParticipatedThreads", true, diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 6676c2734..94e372f65 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -2084,22 +2084,73 @@ void ChannelView::handleMouseClick(QMouseEvent *event, if (link.type == Link::UserInfo) { if (hoveredElement->getFlags().has( - MessageElementFlag::Username) && - event->modifiers() == Qt::ShiftModifier) + MessageElementFlag::Username)) { - // Start a new reply if Shift+Right-clicking the message username - this->setInputReply(layout->getMessagePtr()); - } - else - { - // Insert @username into split input - const bool commaMention = - getSettings()->mentionUsersWithComma; - const bool isFirstWord = - split && split->getInput().isEditFirstWord(); - auto userMention = formatUserMention( - link.value, isFirstWord, commaMention); - insertText("@" + userMention + " "); + Qt::KeyboardModifier userSpecifiedModifier = + getSettings()->usernameRightClickModifier; + + if (userSpecifiedModifier == + Qt::KeyboardModifier::NoModifier) + { + qCWarning(chatterinoCommon) + << "sanity check failed: " + "invalid settings detected " + "Settings::usernameRightClickModifier is " + "NoModifier, which should never happen"; + return; + } + + Qt::KeyboardModifiers modifiers{userSpecifiedModifier}; + auto isModifierHeld = event->modifiers() == modifiers; + + UsernameRightClickBehavior action{}; + if (isModifierHeld) + { + action = getSettings() + ->usernameRightClickModifierBehavior; + } + else + { + action = getSettings()->usernameRightClickBehavior; + } + + switch (action) + { + case UsernameRightClickBehavior::Mention: { + if (split == nullptr) + { + return; + } + + // Insert @username into split input + const bool commaMention = + getSettings()->mentionUsersWithComma; + const bool isFirstWord = + split->getInput().isEditFirstWord(); + auto userMention = formatUserMention( + link.value, isFirstWord, commaMention); + insertText("@" + userMention + " "); + } + break; + + case UsernameRightClickBehavior::Reply: { + // Start a new reply if matching user's settings + this->setInputReply(layout->getMessagePtr()); + } + break; + + case UsernameRightClickBehavior::Ignore: + break; + + default: { + qCWarning(chatterinoCommon) + << "unhandled or corrupted " + "UsernameRightClickBehavior value in " + "ChannelView::handleMouseClick:" + << action; + } + break; // unreachable + } } return; diff --git a/src/widgets/settingspages/GeneralPage.cpp b/src/widgets/settingspages/GeneralPage.cpp index 24d842d8a..d55dc1f4d 100644 --- a/src/widgets/settingspages/GeneralPage.cpp +++ b/src/widgets/settingspages/GeneralPage.cpp @@ -331,6 +331,74 @@ void GeneralPage::initLayout(GeneralPageView &layout) false, "Specify how Chatterino will handle messages that exceed Twitch " "message limits"); + layout.addDropdown::type>( + "Username right-click behavior", + { + "Reply", + "Mention", + "Ignore", + }, + s.usernameRightClickBehavior, + [](auto index) { + return index; + }, + [](auto args) { + return static_cast(args.index); + }, + false, + "Specify how Chatterino will handle right-clicking a username in " + "chat when not holding the modifier."); + layout.addDropdown::type>( + "Username right-click with modifier behavior", + { + "Reply", + "Mention", + "Ignore", + }, + s.usernameRightClickModifierBehavior, + [](auto index) { + return index; + }, + [](auto args) { + return static_cast(args.index); + }, + false, + "Specify how Chatterino will handle right-clicking a username in " + "chat when holding down the modifier."); + layout.addDropdown::type>( + "Modifier for alternate right-click action", + {"Shift", "Control", "Alt", META_KEY}, s.usernameRightClickModifier, + [](int index) { + switch (index) + { + case Qt::ShiftModifier: + return 0; + case Qt::ControlModifier: + return 1; + case Qt::AltModifier: + return 2; + case Qt::MetaModifier: + return 3; + default: + return 0; + } + }, + [](DropdownArgs args) { + switch (args.index) + { + case 0: + return Qt::ShiftModifier; + case 1: + return Qt::ControlModifier; + case 2: + return Qt::AltModifier; + case 3: + return Qt::MetaModifier; + default: + return Qt::NoModifier; + } + }, + false); layout.addTitle("Messages"); layout.addCheckbox(