|  | @@ -36,7 +36,13 @@ Q_DECLARE_METATYPE(QuickTransition);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  static inline QString MakeQuickTransitionText(QuickTransition *qt)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  | -	QString name = QT_UTF8(obs_source_get_name(qt->source));
 | 
	
		
			
				|  |  | +	QString name;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (!qt->fadeToBlack)
 | 
	
		
			
				|  |  | +		name = QT_UTF8(obs_source_get_name(qt->source));
 | 
	
		
			
				|  |  | +	else
 | 
	
		
			
				|  |  | +		name = QTStr("FadeToBlack");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	if (!obs_transition_fixed(qt->source))
 | 
	
		
			
				|  |  |  		name += QString(" (%1ms)").arg(QString::number(qt->duration));
 | 
	
		
			
				|  |  |  	return name;
 | 
	
	
		
			
				|  | @@ -124,7 +130,7 @@ void OBSBasic::TriggerQuickTransition(int id)
 | 
	
		
			
				|  |  |  		if (GetCurrentTransition() != qt->source)
 | 
	
		
			
				|  |  |  			SetTransition(qt->source);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		TransitionToScene(source, false, false, true);
 | 
	
		
			
				|  |  | +		TransitionToScene(source, false, false, true, qt->fadeToBlack);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -169,6 +175,9 @@ void OBSBasic::CreateDefaultQuickTransitions()
 | 
	
		
			
				|  |  |  	quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
 | 
	
		
			
				|  |  |  							     1),
 | 
	
		
			
				|  |  |  				      300, quickTransitionIdCounter++);
 | 
	
		
			
				|  |  | +	quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
 | 
	
		
			
				|  |  | +							     1),
 | 
	
		
			
				|  |  | +				      300, quickTransitionIdCounter++, true);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
 | 
	
	
		
			
				|  | @@ -183,12 +192,13 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
 | 
	
		
			
				|  |  |  		const char *name = obs_data_get_string(data, "name");
 | 
	
		
			
				|  |  |  		int duration = obs_data_get_int(data, "duration");
 | 
	
		
			
				|  |  |  		int id = obs_data_get_int(data, "id");
 | 
	
		
			
				|  |  | +		bool toBlack = obs_data_get_bool(data, "fade_to_black");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		if (id) {
 | 
	
		
			
				|  |  |  			obs_source_t *source = FindTransition(name);
 | 
	
		
			
				|  |  |  			if (source) {
 | 
	
		
			
				|  |  |  				quickTransitions.emplace_back(source, duration,
 | 
	
		
			
				|  |  | -							      id);
 | 
	
		
			
				|  |  | +							      id, toBlack);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  				if (quickTransitionIdCounter <= id)
 | 
	
		
			
				|  |  |  					quickTransitionIdCounter = id + 1;
 | 
	
	
		
			
				|  | @@ -219,6 +229,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
 | 
	
		
			
				|  |  |  		obs_data_set_int(data, "duration", qt.duration);
 | 
	
		
			
				|  |  |  		obs_data_set_array(data, "hotkeys", hotkeys);
 | 
	
		
			
				|  |  |  		obs_data_set_int(data, "id", qt.id);
 | 
	
		
			
				|  |  | +		obs_data_set_bool(data, "fade_to_black", qt.fadeToBlack);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		obs_data_array_push_back(array, data);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -292,7 +303,7 @@ void OBSBasic::TransitionFullyStopped()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
 | 
	
		
			
				|  |  | -				 bool quickTransition)
 | 
	
		
			
				|  |  | +				 bool quickTransition, bool black)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	obs_scene_t *scene = obs_scene_from_source(source);
 | 
	
		
			
				|  |  |  	bool usingPreviewProgram = IsPreviewProgramMode();
 | 
	
	
		
			
				|  | @@ -305,7 +316,7 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
 | 
	
		
			
				|  |  |  		lastProgramScene = programScene;
 | 
	
		
			
				|  |  |  		programScene = OBSGetWeakRef(source);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		if (swapScenesMode && !force && !direct) {
 | 
	
		
			
				|  |  | +		if (swapScenesMode && !force && !direct && !black) {
 | 
	
		
			
				|  |  |  			OBSSource newScene = OBSGetStrongRef(lastProgramScene);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			if (!sceneDuplicationMode && newScene == source)
 | 
	
	
		
			
				|  | @@ -361,6 +372,18 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +		if (black && !prevFTBSource) {
 | 
	
		
			
				|  |  | +			source = nullptr;
 | 
	
		
			
				|  |  | +			prevFTBSource =
 | 
	
		
			
				|  |  | +				obs_transition_get_active_source(transition);
 | 
	
		
			
				|  |  | +			obs_source_release(prevFTBSource);
 | 
	
		
			
				|  |  | +		} else if (black && prevFTBSource) {
 | 
	
		
			
				|  |  | +			source = prevFTBSource;
 | 
	
		
			
				|  |  | +			prevFTBSource = nullptr;
 | 
	
		
			
				|  |  | +		} else if (!black) {
 | 
	
		
			
				|  |  | +			prevFTBSource = nullptr;
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  		bool success = obs_transition_start(
 | 
	
		
			
				|  |  |  			transition, OBS_TRANSITION_MODE_AUTO, duration, source);
 | 
	
		
			
				|  |  |  		if (!success)
 | 
	
	
		
			
				|  | @@ -940,6 +963,7 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	QMenu *menu = new QMenu(parent);
 | 
	
		
			
				|  |  |  	QAction *action;
 | 
	
		
			
				|  |  | +	OBSSource tr;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if (qt) {
 | 
	
		
			
				|  |  |  		action = menu->addAction(QTStr("Remove"));
 | 
	
	
		
			
				|  | @@ -965,8 +989,25 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
 | 
	
		
			
				|  |  |  			this, &OBSBasic::QuickTransitionChangeDuration);
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	tr = GetTransitionComboItem(ui->transitions, 1);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	action = menu->addAction(QTStr("FadeToBlack"));
 | 
	
		
			
				|  |  | +	action->setProperty("transition_index", 1);
 | 
	
		
			
				|  |  | +	action->setProperty("fadeToBlack", true);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if (qt) {
 | 
	
		
			
				|  |  | +		action->setProperty("id", qt->id);
 | 
	
		
			
				|  |  | +		connect(action, &QAction::triggered, this,
 | 
	
		
			
				|  |  | +			&OBSBasic::QuickTransitionChange);
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		action->setProperty("duration",
 | 
	
		
			
				|  |  | +				    QVariant::fromValue<QWidget *>(duration));
 | 
	
		
			
				|  |  | +		connect(action, &QAction::triggered, this,
 | 
	
		
			
				|  |  | +			&OBSBasic::AddQuickTransition);
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  	for (int i = 0; i < ui->transitions->count(); i++) {
 | 
	
		
			
				|  |  | -		OBSSource tr = GetTransitionComboItem(ui->transitions, i);
 | 
	
		
			
				|  |  | +		tr = GetTransitionComboItem(ui->transitions, i);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		action = menu->addAction(obs_source_get_name(tr));
 | 
	
		
			
				|  |  |  		action->setProperty("transition_index", i);
 | 
	
	
		
			
				|  | @@ -1037,10 +1078,12 @@ void OBSBasic::AddQuickTransition()
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |  	int trIdx = sender()->property("transition_index").toInt();
 | 
	
		
			
				|  |  |  	QSpinBox *duration = sender()->property("duration").value<QSpinBox *>();
 | 
	
		
			
				|  |  | +	bool toBlack = sender()->property("fadeToBlack").value<bool>();
 | 
	
		
			
				|  |  |  	OBSSource transition = GetTransitionComboItem(ui->transitions, trIdx);
 | 
	
		
			
				|  |  |  	int id = quickTransitionIdCounter++;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	quickTransitions.emplace_back(transition, duration->value(), id);
 | 
	
		
			
				|  |  | +	quickTransitions.emplace_back(transition, duration->value(), id,
 | 
	
		
			
				|  |  | +				      toBlack);
 | 
	
		
			
				|  |  |  	AddQuickTransitionId(id);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	int idx = (int)quickTransitions.size() - 1;
 |