Skip to content

Commit 0a41ebd

Browse files
committed
frontend: Escape "&" in non-hardcoded menu items
"&" is used to make shortcuts for menu items, so we need to escape non-hardcoded items with "&&". Applies escaping for these menus: - profiles menu - scene collections menu - projector names - transitions menu (for plugins) - filters menu (for plugins)
1 parent d97e5ad commit 0a41ebd

File tree

7 files changed

+14
-7
lines changed

7 files changed

+14
-7
lines changed

frontend/dialogs/OBSBasicFilters.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
484484
if (!filter_compatible(async, sourceFlags, filterFlags))
485485
continue;
486486

487-
QAction *popupItem = new QAction(QT_UTF8(type.name.c_str()), this);
487+
QAction *popupItem = new QAction(escapeMenuItem(QT_UTF8(type.name.c_str())), this);
488488
popupItem->setData(QT_UTF8(type.type.c_str()));
489489
connect(popupItem, &QAction::triggered, [this, type]() { AddNewFilter(type.type.c_str()); });
490490
popup->addAction(popupItem);

frontend/widgets/OBSBasic.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -957,7 +957,7 @@ private slots:
957957
auto projectors = GetProjectorMenuMonitorsFormatted();
958958
for (int i = 0; i < projectors.size(); i++) {
959959
QString str = projectors[i];
960-
QAction *action = parent->addAction(str, target, slot);
960+
QAction *action = parent->addAction(escapeMenuItem(str), target, slot);
961961
action->setProperty("monitor", i);
962962
}
963963
}

frontend/widgets/OBSBasic_Profiles.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ void OBSBasic::RefreshProfiles(bool refreshCache)
309309
const OBSProfile &profile = profiles.at(profileName);
310310
const QString qProfileName = QString().fromStdString(profileName);
311311

312-
QAction *action = new QAction(qProfileName, this);
312+
QAction *action = new QAction(escapeMenuItem(qProfileName), this);
313313
action->setProperty("profile_name", qProfileName);
314314
action->setProperty("file_name", QString().fromStdString(profile.directoryName));
315315
connect(action, &QAction::triggered, this, &OBSBasic::ChangeProfile);

frontend/widgets/OBSBasic_SceneCollections.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ void OBSBasic::RefreshSceneCollections(bool refreshCache)
398398
const SceneCollection &collection = collections.at(collectionName);
399399
const QString qCollectionName = QString().fromStdString(collectionName);
400400

401-
QAction *action = new QAction(qCollectionName, this);
401+
QAction *action = new QAction(escapeMenuItem(qCollectionName), this);
402402
action->setProperty("collection_name", qCollectionName);
403403
action->setProperty("file_name", QString().fromStdString(collection.getFileName()));
404404
connect(action, &QAction::triggered, this, &OBSBasic::ChangeSceneCollection);

frontend/widgets/OBSBasic_Transitions.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ void OBSBasic::on_transitionAdd_clicked()
483483
while (obs_enum_transition_types(idx++, &id)) {
484484
if (obs_is_source_configurable(id)) {
485485
const char *name = obs_source_get_display_name(id);
486-
QAction *action = new QAction(name, this);
486+
QAction *action = new QAction(escapeMenuItem(name), this);
487487

488488
connect(action, &QAction::triggered, [this, id]() { AddTransition(id); });
489489

@@ -840,7 +840,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
840840
if (!name || !*name)
841841
name = Str("None");
842842

843-
action = menu->addAction(QT_UTF8(name));
843+
action = menu->addAction(escapeMenuItem(QT_UTF8(name)));
844844
action->setProperty("transition_uuid", QString::fromStdString(uuid));
845845
action->setCheckable(true);
846846
action->setChecked(match);
@@ -999,7 +999,7 @@ QMenu *OBSBasic::CreateVisibilityTransitionMenu(bool visible)
999999
while (obs_enum_transition_types(idx++, &id)) {
10001000
const char *name = obs_source_get_display_name(id);
10011001
const bool match = id && curId && strcmp(id, curId) == 0;
1002-
action = menu->addAction(QT_UTF8(name));
1002+
action = menu->addAction(escapeMenuItem(QT_UTF8(name)));
10031003
action->setProperty("transition_id", QT_UTF8(id));
10041004
action->setCheckable(true);
10051005
action->setChecked(match);

shared/qt/wrappers/qt-wrappers.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,8 @@ void RefreshToolBarStyling(QToolBar *toolBar)
373373
widget->style()->polish(widget);
374374
}
375375
}
376+
377+
QString escapeMenuItem(QString name)
378+
{
379+
return name.replace("&", "&&");
380+
}

shared/qt/wrappers/qt-wrappers.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,5 @@ QStringList OpenFiles(QWidget *parent, QString title, QString path, QString exte
9999
void TruncateLabel(QLabel *label, QString newText, int length = MAX_LABEL_LENGTH);
100100

101101
void RefreshToolBarStyling(QToolBar *toolBar);
102+
103+
QString escapeMenuItem(QString name);

0 commit comments

Comments
 (0)