UI: Prevent automatic mode switching in certain scenarios

This commit effectively reverts 8d9bf47ba6
and reimplements the check at a more generic / higher level.

After the above commit, Sculpt Mode was unique compared to the other
modes in how visibility is handled, leading to inconsistencies in
behavior in Blender as a whole.

In general, we do not prevent visibility changes of objects no matter
the mode, from the outliner or otherwise, so preventing entry at the API
level solves the problem highlighted in the original commit at an
incorrect level.

While the above may be changed in the future, for now, keeping this
behavior consistent across different object modes is better than the
alternative, and preventing specialized workspaces from being entered
based on the visibility solves the original issue in a more coherent
way.

Pull Request: https://projects.blender.org/blender/blender/pulls/142284
This commit is contained in:
Sean Kim
2025-08-13 22:06:30 +02:00
committed by Sean Kim
parent 08a38e8439
commit 8b1f2dfc45
2 changed files with 20 additions and 11 deletions

View File

@@ -20,6 +20,7 @@
#include "BKE_appdir.hh"
#include "BKE_blendfile.hh"
#include "BKE_context.hh"
#include "BKE_layer.hh"
#include "BKE_lib_id.hh"
#include "BKE_main.hh"
#include "BKE_screen.hh"
@@ -212,7 +213,25 @@ bool ED_workspace_change(WorkSpace *workspace_new, bContext *C, wmWindowManager
/* Automatic mode switching. */
if (workspace_new->object_mode != workspace_old->object_mode) {
blender::ed::object::mode_set(C, eObjectMode(workspace_new->object_mode));
const Base *base = CTX_data_active_base(C);
const Object *object = base->object;
if (object) {
/* Behavior that depends on the active area is not expected in the context of workspace
* switching, ignore the view-port even if it's available. */
const View3D *v3d = nullptr;
const bool base_visible = BKE_base_is_visible(v3d, base);
if (!base_visible && object->mode == OB_MODE_OBJECT) {
/* Set this to nullptr to indicate that the mode should not be switched. This matches
* CTX_data_active_object behavior in the 3D Viewport. See `view3d_context` for more
* details. */
object = nullptr;
}
}
if (object) {
blender::ed::object::mode_set(C, eObjectMode(workspace_new->object_mode));
}
}
return true;

View File

@@ -553,16 +553,6 @@ static wmOperatorStatus sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
const bool is_mode_set = (ob.mode & mode_flag) != 0;
if (!is_mode_set) {
/* Being in sculpt mode on an invisible object is a confusing state; while switching the
* visibility of the current object shouldn't inherently change the mode, we prevent entering
* sculpt mode on an object that is already invisible to better align with how the mode toggle
* works currently. */
const View3D *v3d = CTX_wm_view3d(C);
const Base *base = BKE_view_layer_base_find(&view_layer, &ob);
if (!BKE_base_is_visible(v3d, base)) {
return OPERATOR_CANCELLED;
}
if (!object::mode_compat_set(C, &ob, eObjectMode(mode_flag), op->reports)) {
return OPERATOR_CANCELLED;
}