diff --git a/source/blender/editors/transform/transform.cc b/source/blender/editors/transform/transform.cc
index f2f40e6cec6..53864412d8f 100644
--- a/source/blender/editors/transform/transform.cc
+++ b/source/blender/editors/transform/transform.cc
@@ -1313,6 +1313,10 @@ int transformEvent(TransInfo *t, const wmEvent *event)
   /* Else do non-mapped events. */
   else if (event->val == KM_PRESS) {
     switch (event->type) {
+      case EVT_MKEY :
+        t->flag |= T_TRANSFORM_MULTIPLE;
+        handled = true;
+        break;
       case EVT_CKEY:
         if (event->flag & WM_EVENT_IS_REPEAT) {
           break;
@@ -1840,6 +1844,12 @@ void saveTransform(bContext *C, TransInfo *t, wmOperator *op)
     RNA_property_boolean_set(
         op->ptr, prop, (t->settings->uvcalc_flag & UVCALC_TRANSFORM_CORRECT_SLIDE) != 0);
   }
+
+  if ((prop = RNA_struct_find_property(op->ptr, "transform_multiple"))) {
+    RNA_boolean_set(op->ptr, "transform_multiple", (t->flag & T_TRANSFORM_MULTIPLE) != 0);
+    
+  }
+
 }
 
 static void initSnapSpatial(TransInfo *t, float r_snap[3], float *r_snap_precision)
@@ -1936,6 +1946,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
 
   initTransInfo(C, t, op, event);
 
+  if (prop = RNA_struct_find_property(op->ptr, "transform_multiple")) {
+    if (RNA_boolean_get(op->ptr, "transform_multiple")) {
+      t->flag |= T_TRANSFORM_MULTIPLE;
+    }
+  }
+
   if (t->spacetype == SPACE_VIEW3D) {
     t->draw_handle_view = ED_region_draw_cb_activate(
         t->region->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
@@ -2187,6 +2203,10 @@ int transformEnd(bContext *C, TransInfo *t)
       exit_code = OPERATOR_FINISHED;
     }
 
+    if (t->state == TRANS_CONFIRM && (t->flag & T_TRANSFORM_MULTIPLE)) {
+      exit_code |= OPERATOR_REPEAT;
+    }
+
     /* aftertrans does insert keyframes, and clears base flags; doesn't read transdata */
     special_aftertrans_update(C, t);
 
diff --git a/source/blender/editors/transform/transform_ops.cc b/source/blender/editors/transform/transform_ops.cc
index 27039700184..919abe19eca 100644
--- a/source/blender/editors/transform/transform_ops.cc
+++ b/source/blender/editors/transform/transform_ops.cc
@@ -815,6 +815,8 @@ void Transform_Properties(wmOperatorType *ot, int flags)
                            "Forces the use of Auto Merge and Split");
     RNA_def_property_flag(prop, PROP_HIDDEN);
   }
+
+  RNA_def_boolean(ot->srna, "transform_multiple", 0, "Multiple", "Apply Multiple times");
 }
 
 static void TRANSFORM_OT_translate(wmOperatorType *ot)
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 6439ccb884e..585d0824d41 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -646,10 +646,12 @@ enum {
    * \note this isn't great design (using operators to trigger UI) avoid where possible.
    */
   OPERATOR_INTERFACE = (1 << 5),
+  /* Create a new operator based on current */
+  OPERATOR_REPEAT = (1 << 6),
 };
 #define OPERATOR_FLAGS_ALL \
   (OPERATOR_RUNNING_MODAL | OPERATOR_CANCELLED | OPERATOR_FINISHED | OPERATOR_PASS_THROUGH | \
-   OPERATOR_HANDLED | OPERATOR_INTERFACE | 0)
+   OPERATOR_HANDLED | OPERATOR_INTERFACE | OPERATOR_REPEAT | 0)
 
 /* sanity checks for debug mode only */
 #define OPERATOR_RETVAL_CHECK(ret) \
diff --git a/source/blender/tornavis/patches/MB_0001.h b/source/blender/tornavis/patches/MB_0001.h
new file mode 100644
index 00000000000..c978e52a11c
--- /dev/null
+++ b/source/blender/tornavis/patches/MB_0001.h
@@ -0,0 +1 @@
+/* Empty File */
\ No newline at end of file
diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc
index b809a87e627..4b692e267d6 100644
--- a/source/blender/windowmanager/intern/wm_event_system.cc
+++ b/source/blender/windowmanager/intern/wm_event_system.cc
@@ -2524,6 +2524,9 @@ static eHandlerActionFlag wm_handler_operator_call(bContext *C,
           CTX_wm_area_set(C, area);
           CTX_wm_region_set(C, region);
         }
+        else if (retval & OPERATOR_REPEAT) {
+           wm_operator_invoke(C, ot, event, properties, NULL, false, true);
+        }
         else {
           /* This special cases is for areas and regions that get removed. */
           CTX_wm_area_set(C, nullptr);
