[Bf-blender-cvs] [3ba72049270] topbar: Fix context issues when using operator repeat from top-bar
Julian Eisel
noreply at git.blender.org
Thu Nov 23 19:54:46 CET 2017
Commit: 3ba72049270cc7fbd36e5364de31491d2bdb66bf
Author: Julian Eisel
Date: Thu Nov 23 19:53:22 2017 +0100
Branches: topbar
https://developer.blender.org/rB3ba72049270cc7fbd36e5364de31491d2bdb66bf
Fix context issues when using operator repeat from top-bar
Use same fix for it as rB815eebbe17ab632.
===================================================================
M source/blender/editors/include/ED_util.h
M source/blender/editors/util/undo.c
M source/blender/windowmanager/intern/wm_event_system.c
===================================================================
diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h
index 60c4b3593aa..d8b92ffde41 100644
--- a/source/blender/editors/include/ED_util.h
+++ b/source/blender/editors/include/ED_util.h
@@ -31,11 +31,15 @@
#ifndef __ED_UTIL_H__
#define __ED_UTIL_H__
+#include "BLI_compiler_attrs.h"
+
struct bContext;
struct SpaceLink;
struct wmOperator;
struct wmOperatorType;
+typedef struct OperatorRepeatContextHandle OperatorRepeatContextHandle;
+
/* ed_util.c */
void ED_editors_init(struct bContext *C);
@@ -67,6 +71,11 @@ int ED_undo_operator_repeat(struct bContext *C, struct wmOperator *op);
/* convenience since UI callbacks use this mostly*/
void ED_undo_operator_repeat_cb(struct bContext *C, void *arg_op, void *arg_unused);
void ED_undo_operator_repeat_cb_evt(struct bContext *C, void *arg_op, int arg_unused);
+/* Context sanity helpers for operator repeat. */
+const OperatorRepeatContextHandle *ED_operator_repeat_prepare_context(
+ bContext *C, struct wmOperator *op) ATTR_WARN_UNUSED_RESULT;
+void ED_operator_repeat_reset_context(
+ bContext *C, const OperatorRepeatContextHandle *context_info);
bool ED_undo_is_valid(const struct bContext *C, const char *undoname);
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index dcc2ac41732..9570061a562 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -395,19 +395,47 @@ void ED_OT_undo_redo(wmOperatorType *ot)
ot->poll = ed_undo_redo_poll;
}
+struct OperatorRepeatContextHandle {
+ ScrArea *restore_area;
+ ARegion *restore_region;
+};
+
+/**
+ * Resets the context to the state \a op was executed in (or at least, was in when registering).
+ * #ED_operator_repeat_reset_context should be called when done repeating!
+ */
+const OperatorRepeatContextHandle *ED_operator_repeat_prepare_context(bContext *C, wmOperator *op)
+{
+ static OperatorRepeatContextHandle context_info;
+
+ context_info.restore_area = CTX_wm_area(C);
+ context_info.restore_region = CTX_wm_region(C);
+
+ CTX_wm_area_set(C, op->execution_area);
+ CTX_wm_region_set(C, op->execution_region);
+
+ return &context_info;
+}
+/**
+ * Resets context to the old state from before #ED_operator_repeat_prepare_context was called.
+ */
+void ED_operator_repeat_reset_context(bContext *C, const OperatorRepeatContextHandle *context_info)
+{
+ CTX_wm_area_set(C, context_info->restore_area);
+ CTX_wm_region_set(C, context_info->restore_region);
+}
+
/* ui callbacks should call this rather than calling WM_operator_repeat() themselves */
-int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
+int ED_undo_operator_repeat(bContext *C, wmOperator *op)
{
int ret = 0;
if (op) {
wmWindowManager *wm = CTX_wm_manager(C);
struct Scene *cur_scene = CTX_data_scene(C);
- ScrArea *cur_area = CTX_wm_area(C);
- ARegion *cur_region = CTX_wm_region(C);
+ const OperatorRepeatContextHandle *context_info;
- CTX_wm_area_set(C, op->execution_area);
- CTX_wm_region_set(C, op->execution_region);
+ context_info = ED_operator_repeat_prepare_context(C, op);
if ((WM_operator_repeat_check(C, op)) &&
(WM_operator_poll(C, op->type)) &&
@@ -455,8 +483,7 @@ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op)
}
}
- CTX_wm_area_set(C, cur_area);
- CTX_wm_region_set(C, cur_region);
+ ED_operator_repeat_reset_context(C, context_info);
}
else {
if (G.debug & G_DEBUG) {
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 71a89eb84fe..4902a4bd0bc 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -915,7 +915,14 @@ int WM_operator_call_notest(bContext *C, wmOperator *op)
*/
int WM_operator_repeat(bContext *C, wmOperator *op)
{
- return wm_operator_exec(C, op, true, true);
+ const OperatorRepeatContextHandle *context_info;
+ int retval;
+
+ context_info = ED_operator_repeat_prepare_context(C, op);
+ retval = wm_operator_exec(C, op, true, true);
+ ED_operator_repeat_reset_context(C, context_info);
+
+ return retval;
}
/**
* \return true if #WM_operator_repeat can run
More information about the Bf-blender-cvs
mailing list