diff --git a/src/frontend-common/fullscreen_ui.cpp b/src/frontend-common/fullscreen_ui.cpp
index d23f861cb..c78db52d8 100644
--- a/src/frontend-common/fullscreen_ui.cpp
+++ b/src/frontend-common/fullscreen_ui.cpp
@@ -3793,11 +3793,23 @@ void FullscreenUI::SavePostProcessingChain()
   if (bsi->GetBoolValue("Display", "PostProcessing", false))
     g_host_display->SetPostProcessingChain(config);
   if (IsEditingGameSettings(bsi))
+  {
     s_game_settings_interface->Save();
+  }
   else
-    Host::CommitBaseSettingChanges();
+  {
+    s_settings_changed.store(true, std::memory_order_release);
+  }
 }
 
+enum
+{
+  POSTPROCESSING_ACTION_NONE = 0,
+  POSTPROCESSING_ACTION_REMOVE,
+  POSTPROCESSING_ACTION_MOVE_UP,
+  POSTPROCESSING_ACTION_MOVE_DOWN,
+};
+
 void FullscreenUI::DrawPostProcessingSettingsPage()
 {
   SettingsInterface* bsi = GetEditingSettingsInterface();
@@ -3861,36 +3873,40 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
 
         s_postprocessing_chain.ClearStages();
         ShowToast(std::string(), "Post-processing chain cleared.");
+        SavePostProcessingChain();
       });
   }
 
+  u32 postprocessing_action = POSTPROCESSING_ACTION_NONE;
+  u32 postprocessing_action_index;
+
   SmallString str;
   SmallString tstr;
-  for (u32 stage_index = 0; stage_index < s_postprocessing_chain.GetStageCount();)
+  for (u32 stage_index = 0; stage_index < s_postprocessing_chain.GetStageCount(); stage_index++)
   {
+    ImGui::PushID(stage_index);
     FrontendCommon::PostProcessingShader& stage = s_postprocessing_chain.GetShaderStage(stage_index);
     str.Fmt("Stage {}: {}", stage_index + 1, stage.GetName());
     MenuHeading(str);
 
     if (MenuButton(ICON_FA_TIMES " Remove From Chain", "Removes this shader from the chain."))
     {
-      ShowToast(std::string(), fmt::format("Removed stage {} ({}).", stage_index + 1, stage.GetName()));
-      s_postprocessing_chain.RemoveStage(stage_index);
-      continue;
+      postprocessing_action = POSTPROCESSING_ACTION_REMOVE;
+      postprocessing_action_index = stage_index;
     }
 
     if (MenuButton(ICON_FA_ARROW_UP " Move Up", "Moves this shader higher in the chain, applying it earlier.",
                    (stage_index > 0)))
     {
-      s_postprocessing_chain.MoveStageUp(stage_index);
-      continue;
+      postprocessing_action = POSTPROCESSING_ACTION_MOVE_UP;
+      postprocessing_action_index = stage_index;
     }
 
     if (MenuButton(ICON_FA_ARROW_DOWN " Move Down", "Moves this shader lower in the chain, applying it later.",
                    (stage_index != (s_postprocessing_chain.GetStageCount() - 1))))
     {
-      s_postprocessing_chain.MoveStageDown(stage_index);
-      continue;
+      postprocessing_action = POSTPROCESSING_ACTION_MOVE_DOWN;
+      postprocessing_action_index = stage_index;
     }
 
     for (FrontendCommon::PostProcessingShader::Option& opt : stage.GetOptions())
@@ -4118,7 +4134,33 @@ void FullscreenUI::DrawPostProcessingSettingsPage()
       }
     }
 
-    stage_index++;
+    ImGui::PopID();
+  }
+
+  switch (postprocessing_action)
+  {
+    case POSTPROCESSING_ACTION_REMOVE:
+    {
+      FrontendCommon::PostProcessingShader& stage = s_postprocessing_chain.GetShaderStage(postprocessing_action_index);
+      ShowToast(std::string(), fmt::format("Removed stage {} ({}).", postprocessing_action_index + 1, stage.GetName()));
+      s_postprocessing_chain.RemoveStage(postprocessing_action_index);
+      SavePostProcessingChain();
+    }
+    break;
+    case POSTPROCESSING_ACTION_MOVE_UP:
+    {
+      s_postprocessing_chain.MoveStageUp(postprocessing_action_index);
+      SavePostProcessingChain();
+    }
+    break;
+    case POSTPROCESSING_ACTION_MOVE_DOWN:
+    {
+      s_postprocessing_chain.MoveStageDown(postprocessing_action_index);
+      SavePostProcessingChain();
+    }
+    break;
+    default:
+      break;
   }
 
   EndMenuButtons();