Browse Source

frontend: Reorganize Preview/Source context menu

Warchamp7 11 months ago
parent
commit
69ecfcd9f6

+ 15 - 15
frontend/data/locale/en-US.ini

@@ -32,17 +32,17 @@ Browse="Browse"
 Mono="Mono"
 Stereo="Stereo"
 DroppedFrames="Dropped Frames %1 (%2%)"
-StudioProgramProjector="Fullscreen Projector (Program)"
-PreviewProjector="Fullscreen Projector (Preview)"
-SceneProjector="Fullscreen Projector (Scene)"
-SourceProjector="Fullscreen Projector (Source)"
-StudioProgramWindow="Windowed Projector (Program)"
-PreviewWindow="Windowed Projector (Preview)"
-SceneWindow="Windowed Projector (Scene)"
-SourceWindow="Windowed Projector (Source)"
-MultiviewProjector="Multiview (Fullscreen)"
-MultiviewWindowed="Multiview (Windowed)"
-ResizeProjectorWindowToContent="Fit window to content"
+Projector.Open.Program="Open Program Projector"
+Projector.Open.Preview="Open Preview Projector"
+Projector.Open.Scene="Open Scene Projector"
+Projector.Open.Source="Open Source Projector"
+Projector.Open.Multiview="Open Multiview"
+Projector.Display="Display: %1"
+Projector.Window="New window"
+Projector.Title="Projector"
+Projector.Title.Scene="Scene: %1"
+Projector.Title.Source="Source: %1"
+Projector.ResizeWindowToContent="Fit window to content"
 Clear="Clear"
 Revert="Revert"
 Show="Show"
@@ -1135,10 +1135,10 @@ Basic.Settings.Output.SplitFile.Size="Split Size"
 # Screenshot
 Screenshot="Screenshot Output"
 Screenshot.SourceHotkey="Screenshot Selected Source"
-Screenshot.StudioProgram="Screenshot (Program)"
-Screenshot.Preview="Screenshot (Preview)"
-Screenshot.Scene="Screenshot (Scene)"
-Screenshot.Source="Screenshot (Source)"
+Screenshot.StudioProgram="Save Program Screenshot"
+Screenshot.Preview="Save Preview Screenshot"
+Screenshot.Scene="Save Scene Screenshot"
+Screenshot.Source="Save Source Screenshot"
 
 # basic mode 'output' settings - advanced section - recording subsection - completer
 FilenameFormatting.completer="%CCYY-%MM-%DD %hh-%mm-%ss\n%YY-%MM-%DD %hh-%mm-%ss\n%Y-%m-%d %H-%M-%S\n%y-%m-%d %H-%M-%S\n%a %Y-%m-%d %H-%M-%S\n%A %Y-%m-%d %H-%M-%S\n%Y-%b-%d %H-%M-%S\n%Y-%B-%d %H-%M-%S\n%Y-%m-%d %I-%M-%S-%p\n%Y-%m-%d %H-%M-%S-%z\n%Y-%m-%d %H-%M-%S-%Z\n%FPS\n%CRES\n%ORES\n%VF"

+ 1 - 7
frontend/forms/OBSBasic.ui

@@ -901,7 +901,7 @@
     </widget>
     <widget class="QMenu" name="multiviewProjectorMenu">
      <property name="title">
-      <string>MultiviewProjector</string>
+      <string>Projector.Open.Multiview</string>
      </property>
     </widget>
     <action name="resetUI">
@@ -929,7 +929,6 @@
     <addaction name="stats"/>
     <addaction name="separator"/>
     <addaction name="multiviewProjectorMenu"/>
-    <addaction name="multiviewProjectorWindowed"/>
     <addaction name="separator"/>
     <addaction name="actionAlwaysOnTop"/>
    </widget>
@@ -2163,11 +2162,6 @@
     <string>Basic.Stats</string>
    </property>
   </action>
-  <action name="multiviewProjectorWindowed">
-   <property name="text">
-    <string>MultiviewWindowed</string>
-   </property>
-  </action>
   <action name="resetDocks">
    <property name="text">
     <string>Basic.MainMenu.Docks.ResetDocks</string>

+ 2 - 2
frontend/widgets/OBSBasic.cpp

@@ -1220,8 +1220,8 @@ void OBSBasic::OBSInit()
 
 	ui->viewMenu->addSeparator();
 
-	AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this, &OBSBasic::OpenMultiviewProjector);
-	connect(ui->viewMenu->menuAction(), &QAction::hovered, this, &OBSBasic::UpdateMultiviewProjectorMenu);
+	connect(ui->viewMenu->menuAction(), &QAction::hovered, this, &OBSBasic::updateMultiviewProjectorMenu);
+	OBSBasic::updateMultiviewProjectorMenu();
 
 	ui->sources->UpdateIcons();
 

+ 3 - 2
frontend/widgets/OBSBasic.hpp

@@ -919,7 +919,7 @@ private:
 	QPointer<QMenu> previewProjectorSource;
 	QPointer<QMenu> previewProjectorMain;
 
-	void UpdateMultiviewProjectorMenu();
+	void updateMultiviewProjectorMenu();
 	void ClearProjectors();
 	OBSProjector *OpenProjector(obs_source_t *source, int monitor, ProjectorType type);
 
@@ -928,7 +928,6 @@ private:
 
 private slots:
 	void OpenSavedProjector(SavedProjectorInfo *info);
-	void on_multiviewProjectorWindowed_triggered();
 
 	void OpenPreviewProjector();
 	void OpenSourceProjector();
@@ -938,6 +937,7 @@ private slots:
 	void OpenPreviewWindow();
 	void OpenSourceWindow();
 	void OpenSceneWindow();
+	void openMultiviewWindow();
 
 public:
 	void DeleteProjector(OBSProjector *projector);
@@ -1437,6 +1437,7 @@ private:
 	QPointer<QMenu> trayMenu;
 
 	bool sysTrayMinimizeToTray();
+	void updateSysTrayProjectorMenu();
 
 private slots:
 	void IconActivated(QSystemTrayIcon::ActivationReason reason);

+ 4 - 2
frontend/widgets/OBSBasic_Projectors.cpp

@@ -80,10 +80,12 @@ void OBSBasic::LoadSavedProjectors(obs_data_array_t *array)
 	}
 }
 
-void OBSBasic::UpdateMultiviewProjectorMenu()
+void OBSBasic::updateMultiviewProjectorMenu()
 {
 	ui->multiviewProjectorMenu->clear();
 	AddProjectorMenuMonitors(ui->multiviewProjectorMenu, this, &OBSBasic::OpenMultiviewProjector);
+	ui->multiviewProjectorMenu->addSeparator();
+	ui->multiviewProjectorMenu->addAction(QTStr("Projector.Window"), this, &OBSBasic::openMultiviewWindow);
 }
 
 void OBSBasic::ClearProjectors()
@@ -256,7 +258,7 @@ void OBSBasic::OpenSavedProjector(SavedProjectorInfo *info)
 	}
 }
 
-void OBSBasic::on_multiviewProjectorWindowed_triggered()
+void OBSBasic::openMultiviewWindow()
 {
 	OpenProjector(nullptr, -1, ProjectorType::Multiview);
 }

+ 108 - 72
frontend/widgets/OBSBasic_SceneItems.cpp

@@ -573,6 +573,32 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 	delete colorSelect;
 	delete deinterlaceMenu;
 
+	OBSSceneItem sceneItem;
+	obs_source_t *source;
+	uint32_t flags;
+	bool isAsyncVideo = false;
+	bool hasAudio = false;
+	bool hasVideo = false;
+
+	bool sourceSelected = idx != -1;
+
+	if (sourceSelected) {
+		sceneItem = ui->sources->Get(idx);
+		source = obs_sceneitem_get_source(sceneItem);
+		flags = obs_source_get_output_flags(source);
+		isAsyncVideo = (flags & OBS_SOURCE_ASYNC_VIDEO) == OBS_SOURCE_ASYNC_VIDEO;
+		hasAudio = (flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO;
+		hasVideo = (flags & OBS_SOURCE_VIDEO) == OBS_SOURCE_VIDEO;
+	}
+
+	// Add new source
+	QPointer<QMenu> addSourceMenu = CreateAddSourcePopupMenu();
+	if (addSourceMenu) {
+		popup.addMenu(addSourceMenu);
+		popup.addSeparator();
+	}
+
+	// Preview menu entries
 	if (preview) {
 		QAction *action =
 			popup.addAction(QTStr("Basic.Main.PreviewConextMenu.Enable"), this, &OBSBasic::TogglePreview);
@@ -584,79 +610,76 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 		popup.addAction(ui->actionLockPreview);
 		popup.addMenu(ui->scalingMenu);
 
-		previewProjectorSource = new QMenu(QTStr("PreviewProjector"));
+		popup.addSeparator();
+	}
+
+	// Projector menu entries
+	if (preview) {
+		previewProjectorSource = new QMenu(QTStr("Projector.Open.Preview"));
 		AddProjectorMenuMonitors(previewProjectorSource, this, &OBSBasic::OpenPreviewProjector);
+		previewProjectorSource->addSeparator();
+		previewProjectorSource->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenPreviewWindow);
 
 		popup.addMenu(previewProjectorSource);
+	}
 
-		QAction *previewWindow = popup.addAction(QTStr("PreviewWindow"), this, &OBSBasic::OpenPreviewWindow);
-
-		popup.addAction(previewWindow);
+	if (hasVideo) {
+		sourceProjector = new QMenu(QTStr("Projector.Open.Source"));
+		AddProjectorMenuMonitors(sourceProjector, this, &OBSBasic::OpenSourceProjector);
+		sourceProjector->addSeparator();
+		sourceProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenSourceWindow);
 
-		popup.addAction(QTStr("Screenshot.Preview"), this, &OBSBasic::ScreenshotScene);
-
-		popup.addSeparator();
+		popup.addMenu(sourceProjector);
 	}
 
-	QPointer<QMenu> addSourceMenu = CreateAddSourcePopupMenu();
-	if (addSourceMenu)
-		popup.addMenu(addSourceMenu);
-
-	if (ui->sources->MultipleBaseSelected()) {
-		popup.addSeparator();
-		popup.addAction(QTStr("Basic.Main.GroupItems"), ui->sources, &SourceTree::GroupSelectedItems);
+	popup.addSeparator();
 
-	} else if (ui->sources->GroupsSelected()) {
-		popup.addSeparator();
-		popup.addAction(QTStr("Basic.Main.Ungroup"), ui->sources, &SourceTree::UngroupSelectedGroups);
+	// Screenshot menu entries
+	if (preview) {
+		popup.addAction(QTStr("Screenshot.Preview"), this, &OBSBasic::ScreenshotScene);
 	}
 
-	popup.addSeparator();
-	popup.addAction(ui->actionCopySource);
-	popup.addAction(ui->actionPasteRef);
-	popup.addAction(ui->actionPasteDup);
-	popup.addSeparator();
+	if (hasVideo) {
+		popup.addAction(QTStr("Screenshot.Source"), this, &OBSBasic::ScreenshotSelectedSource);
+	}
 
-	popup.addSeparator();
-	popup.addAction(ui->actionCopyFilters);
-	popup.addAction(ui->actionPasteFilters);
 	popup.addSeparator();
 
-	if (idx != -1) {
-		if (addSourceMenu)
+	if (sourceSelected) {
+		// Sources list menu entries
+		if (!preview) {
+			colorMenu = new QMenu(QTStr("ChangeBG"));
+			colorWidgetAction = new QWidgetAction(colorMenu);
+			colorSelect = new ColorSelect(colorMenu);
+			popup.addMenu(AddBackgroundColorMenu(colorMenu, colorWidgetAction, colorSelect, sceneItem));
+
+			if (hasAudio) {
+				QAction *actionHideMixer =
+					popup.addAction(QTStr("HideMixer"), this, &OBSBasic::ToggleHideMixer);
+				actionHideMixer->setCheckable(true);
+				actionHideMixer->setChecked(SourceMixerHidden(source));
+			}
 			popup.addSeparator();
+		}
 
-		OBSSceneItem sceneItem = ui->sources->Get(idx);
-		obs_source_t *source = obs_sceneitem_get_source(sceneItem);
-		uint32_t flags = obs_source_get_output_flags(source);
-		bool isAsyncVideo = (flags & OBS_SOURCE_ASYNC_VIDEO) == OBS_SOURCE_ASYNC_VIDEO;
-		bool hasAudio = (flags & OBS_SOURCE_AUDIO) == OBS_SOURCE_AUDIO;
-		bool hasVideo = (flags & OBS_SOURCE_VIDEO) == OBS_SOURCE_VIDEO;
-
-		colorMenu = new QMenu(QTStr("ChangeBG"));
-		colorWidgetAction = new QWidgetAction(colorMenu);
-		colorSelect = new ColorSelect(colorMenu);
-		popup.addMenu(AddBackgroundColorMenu(colorMenu, colorWidgetAction, colorSelect, sceneItem));
-		popup.addAction(renameSource);
-		popup.addAction(ui->actionRemoveSource);
-		popup.addSeparator();
-
-		popup.addMenu(ui->orderMenu);
-
-		if (hasVideo)
-			popup.addMenu(ui->transformMenu);
+		// Scene item menu entries
+		if (hasVideo && source) {
+			scaleFilteringMenu = new QMenu(QTStr("ScaleFiltering"));
+			popup.addMenu(AddScaleFilteringMenu(scaleFilteringMenu, sceneItem));
+			blendingModeMenu = new QMenu(QTStr("BlendingMode"));
+			popup.addMenu(AddBlendingModeMenu(blendingModeMenu, sceneItem));
+			blendingMethodMenu = new QMenu(QTStr("BlendingMethod"));
+			popup.addMenu(AddBlendingMethodMenu(blendingMethodMenu, sceneItem));
+			if (isAsyncVideo) {
+				deinterlaceMenu = new QMenu(QTStr("Deinterlacing"));
+				popup.addMenu(AddDeinterlacingMenu(deinterlaceMenu, source));
+			}
 
-		popup.addSeparator();
+			popup.addMenu(CreateVisibilityTransitionMenu(true));
+			popup.addMenu(CreateVisibilityTransitionMenu(false));
 
-		if (hasAudio) {
-			QAction *actionHideMixer =
-				popup.addAction(QTStr("HideMixer"), this, &OBSBasic::ToggleHideMixer);
-			actionHideMixer->setCheckable(true);
-			actionHideMixer->setChecked(SourceMixerHidden(source));
 			popup.addSeparator();
-		}
 
-		if (hasVideo) {
 			QAction *resizeOutput = popup.addAction(QTStr("ResizeOutputSizeOfSource"), this,
 								&OBSBasic::ResizeOutputSizeOfSource);
 
@@ -667,41 +690,54 @@ void OBSBasic::CreateSourcePopupMenu(int idx, bool preview)
 
 			if (width < 32 || height < 32)
 				resizeOutput->setEnabled(false);
+		}
 
-			scaleFilteringMenu = new QMenu(QTStr("ScaleFiltering"));
-			popup.addMenu(AddScaleFilteringMenu(scaleFilteringMenu, sceneItem));
-			blendingModeMenu = new QMenu(QTStr("BlendingMode"));
-			popup.addMenu(AddBlendingModeMenu(blendingModeMenu, sceneItem));
-			blendingMethodMenu = new QMenu(QTStr("BlendingMethod"));
-			popup.addMenu(AddBlendingMethodMenu(blendingMethodMenu, sceneItem));
-			if (isAsyncVideo) {
-				deinterlaceMenu = new QMenu(QTStr("Deinterlacing"));
-				popup.addMenu(AddDeinterlacingMenu(deinterlaceMenu, source));
-			}
+		popup.addSeparator();
+
+		popup.addMenu(ui->orderMenu);
+
+		if (hasVideo) {
+			popup.addMenu(ui->transformMenu);
+		}
+
+		popup.addSeparator();
 
+		// Source grouping
+		if (ui->sources->MultipleBaseSelected()) {
 			popup.addSeparator();
+			popup.addAction(QTStr("Basic.Main.GroupItems"), ui->sources, &SourceTree::GroupSelectedItems);
 
-			popup.addMenu(CreateVisibilityTransitionMenu(true));
-			popup.addMenu(CreateVisibilityTransitionMenu(false));
+		} else if (ui->sources->GroupsSelected()) {
 			popup.addSeparator();
+			popup.addAction(QTStr("Basic.Main.Ungroup"), ui->sources, &SourceTree::UngroupSelectedGroups);
+		}
+		popup.addSeparator();
 
-			sourceProjector = new QMenu(QTStr("SourceProjector"));
-			AddProjectorMenuMonitors(sourceProjector, this, &OBSBasic::OpenSourceProjector);
-			popup.addMenu(sourceProjector);
-			popup.addAction(QTStr("SourceWindow"), this, &OBSBasic::OpenSourceWindow);
+		popup.addAction(ui->actionCopySource);
+		popup.addAction(ui->actionPasteRef);
+		popup.addAction(ui->actionPasteDup);
+		popup.addSeparator();
 
-			popup.addAction(QTStr("Screenshot.Source"), this, &OBSBasic::ScreenshotSelectedSource);
+		if (hasVideo || hasAudio) {
+			popup.addAction(ui->actionCopyFilters);
+			popup.addAction(ui->actionPasteFilters);
+			popup.addSeparator();
 		}
 
+		popup.addAction(ui->actionRemoveSource);
+		popup.addAction(renameSource);
 		popup.addSeparator();
 
-		if (flags & OBS_SOURCE_INTERACTION)
+		if (flags && flags & OBS_SOURCE_INTERACTION)
 			popup.addAction(QTStr("Interact"), this, &OBSBasic::on_actionInteract_triggered);
 
 		popup.addAction(QTStr("Filters"), this, [&]() { OpenFilters(); });
 		QAction *action =
 			popup.addAction(QTStr("Properties"), this, &OBSBasic::on_actionSourceProperties_triggered);
 		action->setEnabled(obs_source_configurable(source));
+	} else {
+		popup.addAction(ui->actionPasteRef);
+		popup.addAction(ui->actionPasteDup);
 	}
 
 	popup.exec(QCursor::pos());

+ 5 - 4
frontend/widgets/OBSBasic_Scenes.cpp

@@ -546,13 +546,14 @@ void OBSBasic::on_scenes_customContextMenuRequested(const QPoint &pos)
 		popup.addSeparator();
 
 		delete sceneProjectorMenu;
-		sceneProjectorMenu = new QMenu(QTStr("SceneProjector"));
+		sceneProjectorMenu = new QMenu(QTStr("Projector.Open.Scene"));
 		AddProjectorMenuMonitors(sceneProjectorMenu, this, &OBSBasic::OpenSceneProjector);
-		popup.addMenu(sceneProjectorMenu);
+		sceneProjectorMenu->addSeparator();
+		sceneProjectorMenu->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenSceneWindow);
 
-		QAction *sceneWindow = popup.addAction(QTStr("SceneWindow"), this, &OBSBasic::OpenSceneWindow);
+		popup.addMenu(sceneProjectorMenu);
+		popup.addSeparator();
 
-		popup.addAction(sceneWindow);
 		popup.addAction(QTStr("Screenshot.Scene"), this, &OBSBasic::ScreenshotScene);
 		popup.addSeparator();
 		popup.addAction(QTStr("Filters"), this, &OBSBasic::OpenSceneFilters);

+ 5 - 2
frontend/widgets/OBSBasic_StudioMode.cpp

@@ -363,11 +363,14 @@ void OBSBasic::ProgramViewContextMenuRequested()
 	QMenu popup(this);
 	QPointer<QMenu> studioProgramProjector;
 
-	studioProgramProjector = new QMenu(QTStr("StudioProgramProjector"));
+	studioProgramProjector = new QMenu(QTStr("Projector.Open.Program"));
 	AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector);
+	studioProgramProjector->addSeparator();
+	studioProgramProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenStudioProgramWindow);
 
 	popup.addMenu(studioProgramProjector);
-	popup.addAction(QTStr("StudioProgramWindow"), this, &OBSBasic::OpenStudioProgramWindow);
+
+	popup.addSeparator();
 	popup.addAction(QTStr("Screenshot.StudioProgram"), this, &OBSBasic::ScreenshotProgram);
 
 	popup.exec(QCursor::pos());

+ 18 - 9
frontend/widgets/OBSBasic_SysTray.cpp

@@ -48,10 +48,11 @@ void OBSBasic::SystemTrayInit()
 	exit = new QAction(QTStr("Exit"), trayIcon.data());
 
 	trayMenu = new QMenu;
-	previewProjector = new QMenu(QTStr("PreviewProjector"));
-	studioProgramProjector = new QMenu(QTStr("StudioProgramProjector"));
-	AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector);
-	AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector);
+
+	previewProjector = new QMenu(QTStr("Projector.Open.Preview"));
+	studioProgramProjector = new QMenu(QTStr("Projector.Open.Program"));
+	OBSBasic::updateSysTrayProjectorMenu();
+
 	trayMenu->addAction(showHide);
 	trayMenu->addSeparator();
 	trayMenu->addMenu(previewProjector);
@@ -85,11 +86,7 @@ void OBSBasic::SystemTrayInit()
 
 void OBSBasic::IconActivated(QSystemTrayIcon::ActivationReason reason)
 {
-	// Refresh projector list
-	previewProjector->clear();
-	studioProgramProjector->clear();
-	AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector);
-	AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector);
+	OBSBasic::updateSysTrayProjectorMenu();
 
 #ifdef __APPLE__
 	UNUSED_PARAMETER(reason);
@@ -145,3 +142,15 @@ bool OBSBasic::sysTrayMinimizeToTray()
 {
 	return config_get_bool(App()->GetUserConfig(), "BasicWindow", "SysTrayMinimizeToTray");
 }
+
+void OBSBasic::updateSysTrayProjectorMenu()
+{
+	previewProjector->clear();
+	studioProgramProjector->clear();
+	AddProjectorMenuMonitors(previewProjector, this, &OBSBasic::OpenPreviewProjector);
+	previewProjector->addSeparator();
+	previewProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenPreviewWindow);
+	AddProjectorMenuMonitors(studioProgramProjector, this, &OBSBasic::OpenStudioProgramProjector);
+	studioProgramProjector->addSeparator();
+	studioProgramProjector->addAction(QTStr("Projector.Window"), this, &OBSBasic::OpenStudioProgramWindow);
+}

+ 6 - 23
frontend/widgets/OBSProjector.cpp

@@ -263,7 +263,7 @@ void OBSProjector::mousePressEvent(QMouseEvent *event)
 			popup.addAction(QTStr("Windowed"), this, &OBSProjector::OpenWindowedProjector);
 
 		} else if (!this->isMaximized()) {
-			popup.addAction(QTStr("ResizeProjectorWindowToContent"), this, &OBSProjector::ResizeToContent);
+			popup.addAction(QTStr("Projector.ResizeWindowToContent"), this, &OBSProjector::ResizeToContent);
 		}
 
 		QAction *alwaysOnTopButton = new QAction(QTStr("Basic.MainMenu.View.AlwaysOnTop"), this);
@@ -319,39 +319,22 @@ void OBSProjector::UpdateMultiview()
 
 void OBSProjector::UpdateProjectorTitle(QString name)
 {
-	bool window = (GetMonitor() == -1);
-
 	QString title = nullptr;
 	switch (type) {
 	case ProjectorType::Scene:
-		if (!window)
-			title = QTStr("SceneProjector") + " - " + name;
-		else
-			title = QTStr("SceneWindow") + " - " + name;
+		title = QTStr("Projector.Title") + " - " + QTStr("Projector.Title.Scene").arg(name);
 		break;
 	case ProjectorType::Source:
-		if (!window)
-			title = QTStr("SourceProjector") + " - " + name;
-		else
-			title = QTStr("SourceWindow") + " - " + name;
+		title = QTStr("Projector.Title") + " - " + QTStr("Projector.Title.Source").arg(name);
 		break;
 	case ProjectorType::Preview:
-		if (!window)
-			title = QTStr("PreviewProjector");
-		else
-			title = QTStr("PreviewWindow");
+		title = QTStr("Projector.Title") + " - " + QTStr("StudioMode.Preview");
 		break;
 	case ProjectorType::StudioProgram:
-		if (!window)
-			title = QTStr("StudioProgramProjector");
-		else
-			title = QTStr("StudioProgramWindow");
+		title = QTStr("Projector.Title") + " - " + QTStr("StudioMode.Program");
 		break;
 	case ProjectorType::Multiview:
-		if (!window)
-			title = QTStr("MultiviewProjector");
-		else
-			title = QTStr("MultiviewWindowed");
+		title = QTStr("Projector.Title") + " - " + QTStr("Multiview");
 		break;
 	default:
 		title = name;