Index: vdr-2.6.6_sik/timers.c
===================================================================
--- vdr-2.6.6_sik.orig/timers.c	2024-03-04 08:04:42.000000000 +0100
+++ vdr-2.6.6_sik/timers.c	2024-03-04 08:06:50.384676345 +0100
@@ -21,6 +21,8 @@
 // format characters in order to allow any number of blanks after a numeric
 // value!
 
+#define VPSGRACE 15  // seconds we still record after the running status of a VPS event has changed to "not running"
+
 // --- cTimer ----------------------------------------------------------------
 
 cTimer::cTimer(bool Instant, bool Pause, const cChannel *Channel)
@@ -47,6 +49,7 @@
   weekdays = 0;
   start = now->tm_hour * 100 + now->tm_min;
   stop = 0;
+  vpsNotRunning = 0;
   if (!Setup.InstantRecordTime && channel && (Instant || Pause)) {
      LOCK_SCHEDULES_READ;
      if (const cSchedule *Schedule = Schedules->GetSchedule(channel)) {
@@ -186,6 +189,7 @@
   aux = NULL;
   remote = NULL;
   event = NULL;
+  vpsNotRunning = 0;
   if (!PatternTimer || PatternTimer->HasFlags(tfVps)) {
      if (Event->Vps() && (PatternTimer || Setup.UseVps))
         SetFlags(tfVps);
@@ -255,6 +259,7 @@
      stop         = Timer.stop;
      priority     = Timer.priority;
      lifetime     = Timer.lifetime;
+     vpsNotRunning = 0;
      strncpy(pattern, Timer.pattern, sizeof(pattern));
      strncpy(file, Timer.file, sizeof(file));
      free(aux);
@@ -611,8 +616,16 @@
                  startTime = event->StartTime();
                  stopTime = event->EndTime();
                  if (!Margin) { // this is an actual check
-                    if (event->Schedule()->PresentSeenWithin(EITPRESENTFOLLOWINGRATE)) // VPS control can only work with up-to-date events...
-                       return event->IsRunning(true);
+                    if (event->Schedule()->PresentSeenWithin(EITPRESENTFOLLOWINGRATE)) { // VPS control can only work with up-to-date events...
+                       bool running = event->IsRunning(true);
+                       if (!running) {
+                          if (Recording() && vpsNotRunning == 0)
+                             vpsNotRunning = time(NULL);
+                          }
+                       else
+                          vpsNotRunning = 0;
+                       return running || time(NULL) < vpsNotRunning + VPSGRACE;
+                       }
                     // ...otherwise we fall back to normal timer handling below (note: Margin == 0!)
                     }
                  }
Index: vdr-2.6.6_sik/timers.h
===================================================================
--- vdr-2.6.6_sik.orig/timers.h	2024-03-04 08:04:42.000000000 +0100
+++ vdr-2.6.6_sik/timers.h	2024-03-04 08:06:50.388676297 +0100
@@ -37,6 +37,7 @@
   int scheduleStateSpawn;
   int scheduleStateAdjust;
   mutable time_t deferred; ///< Matches(time_t, ...) will return false if the current time is before this value
+  mutable time_t vpsNotRunning; ///< the time when a VPS event's running status changed to "not running"
   bool pending, inVpsMargin;
   uint flags;
   const cChannel *channel;
