WorkSpace: fix mode exiting w/ multi-window
authorCampbell Barton <ideasman42@gmail.com>
Thu, 1 Mar 2018 10:07:09 +0000 (21:07 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 1 Mar 2018 10:33:06 +0000 (21:33 +1100)
Activating an object exited modes for all other objects in the layer.
Now check these objects aren't active in other windows first.

source/blender/editors/include/ED_object.h
source/blender/editors/object/object_edit.c
source/blender/editors/object/object_select.c
source/blender/editors/screen/workspace_edit.c

index ddbf3325a87aca4d971e29c3bda7a9ca716c0598..3e04c8ccc8ee42726e9cf92cb90b18630579b562 100644 (file)
@@ -160,6 +160,9 @@ bool ED_object_mode_generic_enter(
 void ED_object_mode_generic_exit(
         const struct EvaluationContext *eval_ctx,
         struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
+bool ED_object_mode_generic_has_data(
+        const struct EvaluationContext *eval_ctx,
+        struct Object *ob);
 
 void ED_object_location_from_view(struct bContext *C, float loc[3]);
 void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis);
index e975ee40c3cd07f059ddc74bc8b9cd9c491a90bf..320aadf22496d7e5bdf5e0b769d0d9645370ed8b 100644 (file)
@@ -2096,33 +2096,65 @@ bool ED_object_mode_generic_enter(
  * Use for changing works-paces or changing active object.
  * Caller can check #OB_MODE_ALL_MODE_DATA to test if this needs to be run.
  */
-void ED_object_mode_generic_exit(
+static bool ed_object_mode_generic_exit_ex(
         const struct EvaluationContext *eval_ctx,
-        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob)
+        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob,
+        bool only_test)
 {
        if (eval_ctx->object_mode & OB_MODE_EDIT) {
                if (BKE_object_is_in_editmode(ob)) {
+                       if (only_test) {
+                               return true;
+                       }
                        ED_object_editmode_exit_ex(NULL, workspace, scene, ob, EM_FREEDATA);
                }
        }
        else if (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) {
                if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) {
+                       if (only_test) {
+                               return true;
+                       }
                        ED_object_vpaintmode_exit_ex(workspace, ob);
                }
        }
        else if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
                if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) {
+                       if (only_test) {
+                               return true;
+                       }
                        ED_object_wpaintmode_exit_ex(workspace, ob);
                }
        }
        else if (eval_ctx->object_mode & OB_MODE_SCULPT) {
                if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) {
+                       if (only_test) {
+                               return true;
+                       }
                        ED_object_sculptmode_exit_ex(eval_ctx, workspace, scene, ob);
                }
        }
        else {
+               if (only_test) {
+                       return false;
+               }
                BLI_assert((eval_ctx->object_mode & OB_MODE_ALL_MODE_DATA) == 0);
        }
+
+       return false;
+}
+
+void ED_object_mode_generic_exit(
+        const struct EvaluationContext *eval_ctx,
+        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob)
+{
+       ed_object_mode_generic_exit_ex(eval_ctx, workspace, scene, ob, false);
+}
+
+bool ED_object_mode_generic_has_data(
+        const struct EvaluationContext *eval_ctx,
+        struct Object *ob)
+{
+       return ed_object_mode_generic_exit_ex(eval_ctx, NULL, NULL, ob, true);
 }
 
 bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_only, float r_center[3])
index 5cf04ddc7355576a0301f2c6e27a7393476f8355..9875fb84b56b4f26c7f0490a3437a9e76efe611e 100644 (file)
@@ -157,11 +157,16 @@ void ED_object_base_activate(bContext *C, Base *base)
                 * Not correct because it's possible other work-spaces use these.
                 * although that's a corner case. */
                if (workspace->object_mode & OB_MODE_ALL_MODE_DATA) {
+                       wmWindowManager *wm = CTX_wm_manager(C);
                        EvaluationContext eval_ctx;
                        CTX_data_eval_ctx(C, &eval_ctx);
                        FOREACH_OBJECT_BEGIN(view_layer, ob) {
                                if (ob != obact) {
-                                       ED_object_mode_generic_exit(&eval_ctx, workspace, scene, ob);
+                                       if (ED_object_mode_generic_has_data(&eval_ctx, ob) &&
+                                           ED_workspace_object_mode_in_other_window(wm, workspace, ob, NULL) == false)
+                                       {
+                                               ED_object_mode_generic_exit(&eval_ctx, workspace, scene, ob);
+                                       }
                                }
                        }
                        FOREACH_OBJECT_END;
index 839b7468d4b16a436dd8a4ed6adbc537c84f75e2..59e2463289215c3bcf4bdc0a2fdf36042eafd4ee 100644 (file)
@@ -352,7 +352,9 @@ bool ED_workspace_object_mode_in_other_window(
                        ViewLayer *view_layer_iter = BKE_view_layer_from_workspace_get(scene_iter, workspace_iter);
                        Object *obact_iter = OBACT(view_layer_iter);
                        if (obact == obact_iter) {
-                               *r_object_mode = workspace_iter->object_mode;
+                               if (r_object_mode) {
+                                       *r_object_mode = workspace_iter->object_mode;
+                               }
                                return true;
                        }
                }