diff --git a/wled00/button.cpp b/wled00/button.cpp
index d544dd73ab..3022d25e1d 100644
--- a/wled00/button.cpp
+++ b/wled00/button.cpp
@@ -365,6 +365,16 @@ void handleIO()
{
handleButton();
+ // If in realtime mode and presets are explicitly allowed to override (e.g., via buttons),
+ // we process them here to avoid messing with the main loop.
+ if (realtimeMode && !realtimeOverride && !(realtimeMode && useMainSegmentOnly) && realtimeAllowPresets) {
+ handlePresets();
+ if (!presetNeedsSaving()) {
+ handlePlaylist();
+ }
+ handlePresets();
+ }
+
// if we want to control on-board LED (ESP8266) or relay we have to do it here as the final show() may not happen until
// next loop() cycle
handleOnOff();
diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp
index 2e458e7da9..7f777e5528 100644
--- a/wled00/cfg.cpp
+++ b/wled00/cfg.cpp
@@ -591,6 +591,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(receiveDirect, if_live["en"]); // UDP/Hyperion realtime
CJSON(useMainSegmentOnly, if_live[F("mso")]);
CJSON(realtimeRespectLedMaps, if_live[F("rlm")]);
+ CJSON(realtimeAllowPresets, if_live[F("rop")]);
CJSON(e131Port, if_live["port"]); // 5568
if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation
CJSON(e131Multicast, if_live[F("mc")]);
@@ -1126,6 +1127,7 @@ void serializeConfig(JsonObject root) {
if_live["en"] = receiveDirect; // UDP/Hyperion realtime
if_live[F("mso")] = useMainSegmentOnly;
if_live[F("rlm")] = realtimeRespectLedMaps;
+ if_live[F("rop")] = realtimeAllowPresets;
if_live["port"] = e131Port;
if_live[F("mc")] = e131Multicast;
diff --git a/wled00/data/settings_sync.htm b/wled00/data/settings_sync.htm
index 12eb3e8d07..b5d4a63ccd 100644
--- a/wled00/data/settings_sync.htm
+++ b/wled00/data/settings_sync.htm
@@ -156,7 +156,8 @@
Instance List
Realtime
Receive UDP realtime:
Use main segment only:
-Respect LED Maps:
+Respect LED Maps:
+Immediately force presets switching during realtime mode:
Network DMX input
Type: