Undo: Add explicit filtering for IDs and RNA structs marked as skippable
In the past, around the time that 2.80 was released, 4a08b974f4
introduced the idea of filtering out certain editor changes inside
the paint modes and edit mode (e.g. changing brush sizes in the editor).
This commit is the first in a series to attempt to refine this behavior
so that only certain editor settings are filtered out from the undo
stack.
In total, it does the following:
* Adds the Brush datablock to the list of IDs that do not have undo
pushes.
* Adds support to filter out RNA structs that do not have the
`STRUCT_UNDO` property applied (currently, just the 3D Cursor).
This has the following effects:
* Changing brush settings inside the Image Editor no longer causes
undo pushes, becoming consistent with the other paint modes.
* Changing brush settings while in object mode in the outliner data
block view no longer causes undo pushes.
Co-authored-by: Campbell Barton <campbell@blender.org>
This commit is contained in:
@@ -15,6 +15,7 @@ struct Base;
|
||||
struct CLG_LogRef;
|
||||
struct ID;
|
||||
struct MemFile;
|
||||
struct PointerRNA;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
struct UndoStack;
|
||||
@@ -72,7 +73,7 @@ bool ED_undo_is_memfile_compatible(const bContext *C);
|
||||
* For example, changing a brush property isn't stored by sculpt-mode undo steps.
|
||||
* This workaround is needed until the limitation is removed, see: #61948.
|
||||
*/
|
||||
bool ED_undo_is_legacy_compatible_for_property(bContext *C, ID *id);
|
||||
bool ED_undo_is_legacy_compatible_for_property(bContext *C, ID *id, PointerRNA &ptr);
|
||||
|
||||
/**
|
||||
* This function addresses the problem of restoring undo steps when multiple windows are used.
|
||||
|
||||
@@ -1012,8 +1012,8 @@ static void ui_apply_but_undo(uiBut *but)
|
||||
}
|
||||
else {
|
||||
ID *id = but->rnapoin.owner_id;
|
||||
if (!ED_undo_is_legacy_compatible_for_property(static_cast<bContext *>(but->block->evil_C),
|
||||
id))
|
||||
if (!ED_undo_is_legacy_compatible_for_property(
|
||||
static_cast<bContext *>(but->block->evil_C), id, but->rnapoin))
|
||||
{
|
||||
skip_undo = true;
|
||||
}
|
||||
|
||||
@@ -419,8 +419,16 @@ bool ED_undo_is_memfile_compatible(const bContext *C)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_undo_is_legacy_compatible_for_property(bContext *C, ID *id)
|
||||
bool ED_undo_is_legacy_compatible_for_property(bContext *C, ID *id, PointerRNA &ptr)
|
||||
{
|
||||
if (!RNA_struct_undo_check(ptr.type)) {
|
||||
return false;
|
||||
}
|
||||
/* If the whole ID type doesn't support undo there is no need to check the current context. */
|
||||
if (id && !ID_CHECK_UNDO(id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
if (view_layer != nullptr) {
|
||||
|
||||
@@ -605,7 +605,8 @@ typedef struct PreviewImage {
|
||||
#define ID_REFCOUNTING_USERS(id) (ID_REAL_USERS(id) - ID_EXTRA_REAL_USERS(id))
|
||||
|
||||
#define ID_CHECK_UNDO(id) \
|
||||
((GS((id)->name) != ID_SCR) && (GS((id)->name) != ID_WM) && (GS((id)->name) != ID_WS))
|
||||
((GS((id)->name) != ID_SCR) && (GS((id)->name) != ID_WM) && (GS((id)->name) != ID_WS)) && \
|
||||
(GS((id)->name) != ID_BR)
|
||||
|
||||
#define ID_BLEND_PATH(_bmain, _id) \
|
||||
((_id)->lib ? (_id)->lib->runtime->filepath_abs : BKE_main_blendfile_path((_bmain)))
|
||||
|
||||
@@ -3441,7 +3441,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
if (wm->op_undo_depth == 0) {
|
||||
ID *id = rc->ptr.owner_id;
|
||||
if (ED_undo_is_legacy_compatible_for_property(C, id)) {
|
||||
if (ED_undo_is_legacy_compatible_for_property(C, id, rc->ptr)) {
|
||||
ED_undo_push(C, op->type->name);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user