diff --git a/Marlin/Marlin_main.cpp b/Marlin/Marlin_main.cpp
index 48bf292248..708df4a6bf 100644
--- a/Marlin/Marlin_main.cpp
+++ b/Marlin/Marlin_main.cpp
@@ -1013,13 +1013,13 @@ void servo_init() {
       pixels.show(); // initialize to all off
 
       #if ENABLED(NEOPIXEL_STARTUP_TEST)
-        delay(2000);
+        safe_delay(1000);
         set_neopixel_color(pixels.Color(255, 0, 0, 0));  // red
-        delay(2000);
+        safe_delay(1000);
         set_neopixel_color(pixels.Color(0, 255, 0, 0));  // green
-        delay(2000);
+        safe_delay(1000);
         set_neopixel_color(pixels.Color(0, 0, 255, 0));  // blue
-        delay(2000);
+        safe_delay(1000);
       #endif
       set_neopixel_color(pixels.Color(NEO_WHITE));       // white
     }
@@ -3162,16 +3162,20 @@ static void homeaxis(const AxisEnum axis) {
     #endif
   ) {
 
-    static float hop_height,        // Remember where the Z height started
-                 hop_amount = 0.0;  // Total amount lifted, for use in recover
+    static float hop_amount = 0.0;  // Total amount lifted, for use in recover
 
-    // Simply never allow two retracts or recovers in a row
+    // Prevent two retracts or recovers in a row
     if (retracted[active_extruder] == retracting) return;
 
-    #if EXTRUDERS < 2
-      bool swapping = false;
+    // Prevent two swap-retract or recovers in a row
+    #if EXTRUDERS > 1
+      // Allow G10 S1 only after G10
+      if (swapping && retracted_swap[active_extruder] == retracting) return;
+      // G11 priority to recover the long retract if activated
+      if (!retracting) swapping = retracted_swap[active_extruder];
+    #else
+      const bool swapping = false;
     #endif
-    if (!retracting) swapping = retracted_swap[active_extruder];
 
     /* // debugging
       SERIAL_ECHOLNPAIR("retracting ", retracting);
@@ -3188,64 +3192,55 @@ static void homeaxis(const AxisEnum axis) {
     //*/
 
     const bool has_zhop = retract_zlift > 0.01;     // Is there a hop set?
-
     const float old_feedrate_mm_s = feedrate_mm_s;
-    const int16_t old_flow = flow_percentage[active_extruder];
-
-    // Don't apply flow multiplication to retract/recover
-    flow_percentage[active_extruder] = 100;
 
     // The current position will be the destination for E and Z moves
     set_destination_from_current();
+    stepper.synchronize();  // Wait for buffered moves to complete
 
-    stepper.synchronize(); // Wait for all moves to finish
+    const float renormalize = 100.0 / flow_percentage[active_extruder] / volumetric_multiplier[active_extruder];
 
     if (retracting) {
-      // Remember the Z height since G-code may include its own Z-hop
-      // For best results turn off Z hop if G-code already includes it
-      hop_height = destination[Z_AXIS];
-
       // Retract by moving from a faux E position back to the current E position
       feedrate_mm_s = retract_feedrate_mm_s;
-      current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) / volumetric_multiplier[active_extruder];
+      current_position[E_AXIS] += (swapping ? swap_retract_length : retract_length) * renormalize;
       sync_plan_position_e();
       prepare_move_to_destination();
 
       // Is a Z hop set, and has the hop not yet been done?
-      if (has_zhop) {
-        hop_amount += retract_zlift;                // Carriage is raised for retraction hop
-        current_position[Z_AXIS] -= retract_zlift;  // Pretend current pos is lower. Next move raises Z.
-        SYNC_PLAN_POSITION_KINEMATIC();             // Set the planner to the new position
-        prepare_move_to_destination();              // Raise up to the old current pos
+      if (has_zhop && !hop_amount) {
+        hop_amount += retract_zlift;                        // Carriage is raised for retraction hop
+        feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Z feedrate to max
+        current_position[Z_AXIS] -= retract_zlift;          // Pretend current pos is lower. Next move raises Z.
+        SYNC_PLAN_POSITION_KINEMATIC();                     // Set the planner to the new position
+        prepare_move_to_destination();                      // Raise up to the old current pos
+        feedrate_mm_s = retract_feedrate_mm_s;              // Restore feedrate
       }
     }
     else {
       // If a hop was done and Z hasn't changed, undo the Z hop
-      if (hop_amount && NEAR(hop_height, destination[Z_AXIS])) {
-        current_position[Z_AXIS] += hop_amount;     // Pretend current pos is higher. Next move lowers Z.
-        SYNC_PLAN_POSITION_KINEMATIC();             // Set the planner to the new position
-        prepare_move_to_destination();              // Lower to the old current pos
-        hop_amount = 0.0;
+      if (hop_amount) {
+        current_position[Z_AXIS] -= retract_zlift;          // Pretend current pos is lower. Next move raises Z.
+        SYNC_PLAN_POSITION_KINEMATIC();                     // Set the planner to the new position
+        feedrate_mm_s = planner.max_feedrate_mm_s[Z_AXIS];  // Z feedrate to max
+        prepare_move_to_destination();                      // Raise up to the old current pos
+        hop_amount = 0.0;                                   // Clear hop
       }
 
       // A retract multiplier has been added here to get faster swap recovery
       feedrate_mm_s = swapping ? swap_retract_recover_feedrate_mm_s : retract_recover_feedrate_mm_s;
 
       const float move_e = swapping ? swap_retract_length + swap_retract_recover_length : retract_length + retract_recover_length;
-      current_position[E_AXIS] -= move_e / volumetric_multiplier[active_extruder];
+      current_position[E_AXIS] -= move_e * renormalize;
       sync_plan_position_e();
-
-      prepare_move_to_destination();  // Recover E
+      prepare_move_to_destination();                        // Recover E
     }
 
-    // Restore flow and feedrate
-    flow_percentage[active_extruder] = old_flow;
-    feedrate_mm_s = old_feedrate_mm_s;
+    feedrate_mm_s = old_feedrate_mm_s;                      // Restore original feedrate
 
-    // The active extruder is now retracted or recovered
-    retracted[active_extruder] = retracting;
+    retracted[active_extruder] = retracting;                // Active extruder now retracted / recovered
 
-    // If swap retract/recover then update the retracted_swap flag too
+    // If swap retract/recover update the retracted_swap flag too
     #if EXTRUDERS > 1
       if (swapping) retracted_swap[active_extruder] = retracting;
     #endif
@@ -3264,7 +3259,7 @@ static void homeaxis(const AxisEnum axis) {
       SERIAL_ECHOLNPAIR("hop_amount ", hop_amount);
     //*/
 
-  } // retract()
+  }
 
 #endif // FWRETRACT
 
diff --git a/Marlin/language_en.h b/Marlin/language_en.h
index 3713433530..9c3b0b7711 100644
--- a/Marlin/language_en.h
+++ b/Marlin/language_en.h
@@ -615,7 +615,10 @@
   #define MSG_CONTROL_RETRACT_RECOVER_SWAP    _UxGT("S UnRet mm")
 #endif
 #ifndef MSG_CONTROL_RETRACT_RECOVERF
-  #define MSG_CONTROL_RETRACT_RECOVERF        _UxGT("UnRet  V")
+  #define MSG_CONTROL_RETRACT_RECOVERF        _UxGT("UnRet V")
+#endif
+#ifndef MSG_CONTROL_RETRACT_RECOVER_SWAPF
+  #define MSG_CONTROL_RETRACT_RECOVER_SWAPF   _UxGT("S UnRet V")
 #endif
 #ifndef MSG_AUTORETRACT
   #define MSG_AUTORETRACT                     _UxGT("AutoRetr.")
diff --git a/Marlin/language_fr.h b/Marlin/language_fr.h
index b98fc38643..f96426bd29 100644
--- a/Marlin/language_fr.h
+++ b/Marlin/language_fr.h
@@ -222,6 +222,7 @@
 #define MSG_CONTROL_RETRACT_RECOVER         _UxGT("UnRet mm")
 #define MSG_CONTROL_RETRACT_RECOVER_SWAP    _UxGT("Ech. UnRet mm")
 #define MSG_CONTROL_RETRACT_RECOVERF        _UxGT("UnRet V")
+#define MSG_CONTROL_RETRACT_RECOVER_SWAPF   _UxGT("Ech. UnRet V")
 #define MSG_AUTORETRACT                     _UxGT("Retract. Auto.")
 #define MSG_FILAMENTCHANGE                  _UxGT("Changer filament")
 #define MSG_INIT_SDCARD                     _UxGT("Init. la carte SD")
diff --git a/Marlin/language_pl-DOGM.h b/Marlin/language_pl-DOGM.h
index 5329536b4b..e712185c61 100644
--- a/Marlin/language_pl-DOGM.h
+++ b/Marlin/language_pl-DOGM.h
@@ -43,6 +43,7 @@
 #define MSG_LEVEL_BED_WAITING               _UxGT("Kliknij by rozp.")
 #define MSG_LEVEL_BED_NEXT_POINT            _UxGT("Następny punkt")
 #define MSG_LEVEL_BED_DONE                  _UxGT("Wypoziomowano!")
+#define MSG_USER_MENU                       _UxGT("Własne Polecenia")
 #define MSG_SET_HOME_OFFSETS                _UxGT("Ust. poz. zer.")
 #define MSG_HOME_OFFSETS_APPLIED            _UxGT("Poz. zerowa ust.")
 #define MSG_SET_ORIGIN                      _UxGT("Ustaw punkt zero")
diff --git a/Marlin/language_pl-HD44780.h b/Marlin/language_pl-HD44780.h
index aee679f8db..67ecaac6c0 100644
--- a/Marlin/language_pl-HD44780.h
+++ b/Marlin/language_pl-HD44780.h
@@ -43,6 +43,7 @@
 #define MSG_LEVEL_BED_WAITING               _UxGT("Kliknij by rozp.")
 #define MSG_LEVEL_BED_NEXT_POINT            _UxGT("Nastepny punkt")
 #define MSG_LEVEL_BED_DONE                  _UxGT("Wypoziomowano!")
+#define MSG_USER_MENU                       _UxGT("Wlasne Polecenia")
 #define MSG_SET_HOME_OFFSETS                _UxGT("Ust. poz. zer.")
 #define MSG_HOME_OFFSETS_APPLIED            _UxGT("Poz. zerowa ust.")
 #define MSG_SET_ORIGIN                      _UxGT("Ustaw punkt zero")
diff --git a/Marlin/planner.h b/Marlin/planner.h
index 3351697eac..619a3de67a 100644
--- a/Marlin/planner.h
+++ b/Marlin/planner.h
@@ -288,7 +288,7 @@ class Planner {
         return 1.0;
       }
 
-      FORCE_INLINE static bool leveling_active_at_z(const float &lz) { return true; }
+      FORCE_INLINE static bool leveling_active_at_z(const float &lz) { UNUSED(lz); return true; }
 
     #endif
 
diff --git a/Marlin/ultralcd.cpp b/Marlin/ultralcd.cpp
index eebd522b98..633db5fe3d 100644
--- a/Marlin/ultralcd.cpp
+++ b/Marlin/ultralcd.cpp
@@ -3726,6 +3726,9 @@ void kill_screen(const char* lcd_msg) {
         MENU_ITEM_EDIT(float52, MSG_CONTROL_RETRACT_RECOVER_SWAP, &swap_retract_recover_length, -100, 100);
       #endif
       MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVERF, &retract_recover_feedrate_mm_s, 1, 999);
+      #if EXTRUDERS > 1
+        MENU_ITEM_EDIT(float3, MSG_CONTROL_RETRACT_RECOVER_SWAPF, &swap_retract_recover_feedrate_mm_s, 1, 999);
+      #endif
       END_MENU();
     }