[Bf-blender-cvs] [f68e50a263b] master: WM: operators that add their own undo pushes now clears the redo panel

Campbell Barton noreply at git.blender.org
Tue Dec 6 04:02:52 CET 2022


Commit: f68e50a263b8a970075c8fd540a985f2798e1d13
Author: Campbell Barton
Date:   Tue Dec 6 13:53:53 2022 +1100
Branches: master
https://developer.blender.org/rBf68e50a263b8a970075c8fd540a985f2798e1d13

WM: operators that add their own undo pushes now clears the redo panel

Detect when the operator adds its own undo step and clear the panel.

An alternative fix for [0] which caused T101743.

Needed to prevent changing values in the last operator panel from
destructively undoing brush steps.

[0]: 11bdc321a274712e5c5ae83ff2c199690f66ecf7.

Reviewed By: mont29, joeedh

Ref D16523

===================================================================

M	source/blender/windowmanager/intern/wm_event_system.cc

===================================================================

diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc
index 90f162ac76a..f4cd3959475 100644
--- a/source/blender/windowmanager/intern/wm_event_system.cc
+++ b/source/blender/windowmanager/intern/wm_event_system.cc
@@ -43,6 +43,7 @@
 #include "BKE_report.h"
 #include "BKE_scene.h"
 #include "BKE_screen.h"
+#include "BKE_undo_system.h"
 #include "BKE_workspace.h"
 
 #include "BKE_sound.h"
@@ -928,6 +929,17 @@ void WM_reportf(eReportType type, const char *format, ...)
 /** \name Operator Logic
  * \{ */
 
+/**
+ * Return the active undo step as an identifier for the purpose of comparison only.
+ */
+static intptr_t wm_operator_undo_active_id(const wmWindowManager *wm)
+{
+  if (wm->undo_stack) {
+    return intptr_t(wm->undo_stack->step_active);
+  }
+  return -1;
+}
+
 bool WM_operator_poll(bContext *C, wmOperatorType *ot)
 {
 
@@ -1059,7 +1071,12 @@ static bool wm_operator_register_check(wmWindowManager *wm, wmOperatorType *ot)
   return wm && (wm->op_undo_depth == 0) && (ot->flag & (OPTYPE_REGISTER | OPTYPE_UNDO));
 }
 
-static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat, const bool store)
+/**
+ * \param has_undo_step: True when an undo step was added,
+ * needed when the operator doesn't use #OPTYPE_UNDO, #OPTYPE_UNDO_GROUPED but adds an undo step.
+ */
+static void wm_operator_finished(
+    bContext *C, wmOperator *op, const bool repeat, const bool store, const bool has_undo_step)
 {
   wmWindowManager *wm = CTX_wm_manager(C);
   enum {
@@ -1090,6 +1107,11 @@ static void wm_operator_finished(bContext *C, wmOperator *op, const bool repeat,
         hud_status = CLEAR;
       }
     }
+    else if (has_undo_step) {
+      if (repeat == 0) {
+        hud_status = CLEAR;
+      }
+    }
   }
 
   if (repeat == 0) {
@@ -1150,6 +1172,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
     return retval;
   }
 
+  const intptr_t undo_id_prev = wm_operator_undo_active_id(wm);
   if (op->type->exec) {
     if (op->type->flag & OPTYPE_UNDO) {
       wm->op_undo_depth++;
@@ -1171,7 +1194,9 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons
   }
 
   if (retval & OPERATOR_FINISHED) {
-    wm_operator_finished(C, op, repeat, store && wm->op_undo_depth == 0);
+    const bool has_undo_step = (undo_id_prev != wm_operator_undo_active_id(wm));
+
+    wm_operator_finished(C, op, repeat, store && wm->op_undo_depth == 0, has_undo_step);
   }
   else if (repeat == 0) {
     /* WARNING: modal from exec is bad practice, but avoid crashing. */
@@ -1412,6 +1437,7 @@ static int wm_operator_invoke(bContext *C,
 
   if (WM_operator_poll(C, ot)) {
     wmWindowManager *wm = CTX_wm_manager(C);
+    const intptr_t undo_id_prev = wm_operator_undo_active_id(wm);
 
     /* If `reports == nullptr`, they'll be initialized. */
     wmOperator *op = wm_operator_create(wm, ot, properties, reports);
@@ -1480,8 +1506,9 @@ static int wm_operator_invoke(bContext *C,
       /* Do nothing, #wm_operator_exec() has been called somewhere. */
     }
     else if (retval & OPERATOR_FINISHED) {
+      const bool has_undo_step = (undo_id_prev != wm_operator_undo_active_id(wm));
       const bool store = !is_nested_call && use_last_properties;
-      wm_operator_finished(C, op, false, store);
+      wm_operator_finished(C, op, false, store, has_undo_step);
     }
     else if (retval & OPERATOR_RUNNING_MODAL) {
       /* Take ownership of reports (in case python provided own). */
@@ -2378,6 +2405,7 @@ static int wm_handler_operator_call(bContext *C,
       wmEvent_ModalMapStore event_backup;
       wm_event_modalkeymap_begin(C, op, event, &event_backup);
 
+      const intptr_t undo_id_prev = wm_operator_undo_active_id(wm);
       if (ot->flag & OPTYPE_UNDO) {
         wm->op_undo_depth++;
       }
@@ -2413,7 +2441,9 @@ static int wm_handler_operator_call(bContext *C,
 
         /* Important to run 'wm_operator_finished' before setting the context members to null. */
         if (retval & OPERATOR_FINISHED) {
-          wm_operator_finished(C, op, false, true);
+          const bool has_undo_step = (undo_id_prev != wm_operator_undo_active_id(wm));
+
+          wm_operator_finished(C, op, false, true, has_undo_step);
           handler->op = nullptr;
         }
         else if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) {



More information about the Bf-blender-cvs mailing list