29#include "RNA_prototypes.hh"
39 if (screen ==
nullptr) {
58 if (screen->
temp != 0) {
156 PyObject_GC_UnTrack(
self);
157 Py_CLEAR(
self->py_state_context_dict);
158 PyObject_GC_Del(
self);
165 Py_VISIT(
self->py_state_context_dict);
171 Py_CLEAR(
self->py_state_context_dict);
211 if (
self->ctx_temp.region_is_set && (region !=
nullptr)) {
212 if (screen ==
nullptr && area ==
nullptr) {
213 PyErr_SetString(PyExc_TypeError,
"Region set with screen & area set to None");
217 PyErr_SetString(PyExc_TypeError,
"Region not found in area or screen");
222 if (
self->ctx_temp.area_is_set && (area !=
nullptr)) {
223 if (win ==
nullptr && screen ==
nullptr) {
224 PyErr_SetString(PyExc_TypeError,
"Area set with window & screen set to None");
228 PyErr_SetString(PyExc_TypeError,
"Area not found in screen");
233 if (
self->ctx_temp.screen_is_set && (screen !=
nullptr)) {
234 if (win ==
nullptr) {
235 PyErr_SetString(PyExc_TypeError,
"Screen set with null window");
239 PyErr_SetString(PyExc_TypeError,
"Screen not found");
244 if (
self->ctx_init.screen_is_set) {
246 if ((
self->ctx_init.screen !=
nullptr) &&
249 PyErr_SetString(PyExc_TypeError,
250 "Overriding context with an active temporary screen isn't supported");
254 PyErr_SetString(PyExc_TypeError,
255 "Overriding context with temporary screen isn't supported");
259 PyErr_SetString(PyExc_TypeError,
"Screen has no workspace");
265 if (win_iter == win) {
269 PyErr_SetString(PyExc_TypeError,
"Screen is used by another window");
277 if (
self->ctx_temp.win_is_set && (win !=
nullptr)) {
279 PyErr_SetString(PyExc_TypeError,
"Window not found");
302 bScreen *screen =
self->ctx_temp.screen_is_set ?
self->ctx_temp.screen :
self->ctx_init.screen;
304 ARegion *region =
self->ctx_temp.region_is_set ?
self->ctx_temp.region :
self->ctx_init.region;
306 self->ctx_init.win_is_set = (
self->ctx_init.win != win);
307 self->ctx_init.screen_is_set = (
self->ctx_init.screen != screen);
308 self->ctx_init.area_is_set = (
self->ctx_init.area != area);
309 self->ctx_init.region_is_set = (
self->ctx_init.region != region);
314 if ((
self->ctx_temp.win_is_set ==
true) && (
self->ctx_temp.screen_is_set ==
false)) {
324 if (
self->ctx_temp.screen_is_set) {
339 if (
self->ctx_temp.win_is_set) {
342 if (
self->ctx_temp.screen_is_set) {
345 if (
self->ctx_temp.area_is_set) {
348 if (
self->ctx_temp.region_is_set) {
363 if (
self->ctx_temp.screen_is_set) {
381 bool do_restore =
true;
396 bool is_container_set =
false;
406 if (
self->ctx_init.win_is_set) {
408 is_container_set =
true;
410 else if (
self->ctx_temp.win_is_set) {
412 is_container_set =
true;
431 if (
self->ctx_init.screen_is_set || is_container_set) {
433 is_container_set =
true;
435 else if (
self->ctx_temp.screen_is_set) {
437 is_container_set =
true;
448 if (
self->ctx_init.area &&
456 if (
self->ctx_init.area_is_set || is_container_set) {
458 is_container_set =
true;
460 else if (
self->ctx_temp.area_is_set) {
462 is_container_set =
true;
473 if (
self->ctx_init.region &&
481 if (
self->ctx_init.region_is_set || is_container_set) {
483 is_container_set =
true;
486 else if (
false &&
self->ctx_temp.region_is_set) {
488 is_container_set =
true;
502 if (context_dict_test && (context_dict_test !=
self->py_state_context_dict)) {
503 Py_DECREF(context_dict_test);
512# pragma clang diagnostic push
513# pragma clang diagnostic ignored "-Wcast-function-type"
515# pragma GCC diagnostic push
516# pragma GCC diagnostic ignored "-Wcast-function-type"
528# pragma clang diagnostic pop
530# pragma GCC diagnostic pop
535 PyVarObject_HEAD_INIT(
nullptr, 0)
536 "ContextTempOverride",
554 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
595 PyObject *sentinel = Py_Ellipsis;
596 PyObject *kwds_parse = PyDict_New();
597 for (
int i = 0; kwds_static[
i];
i++) {
598 PyObject *key = PyUnicode_FromString(kwds_static[
i]);
599 PyObject *val = _PyDict_Pop(kwds, key, sentinel);
600 if (val != sentinel) {
601 if (PyDict_SetItem(kwds_parse, key, val) == -1) {
615 bpy_context_temp_override_doc,
616 ".. method:: temp_override(*, window=None, area=None, region=None, **keywords)\n"
618 " Context manager to temporarily override members in the context.\n"
620 " :arg window: Window override or None.\n"
621 " :type window: :class:`bpy.types.Window`\n"
622 " :arg screen: Screen override or None.\n"
624 " .. note:: Switching to or away from full-screen areas & temporary screens "
625 "isn't supported. Passing in these screens will raise an exception, "
626 "actions that leave the context such screens won't restore the prior screen.\n"
628 " .. note:: Changing the screen has wider implications "
629 "than other arguments as it will also change the works-space "
630 "and potentially the scene (when pinned).\n"
632 " :type screen: :class:`bpy.types.Screen`\n"
633 " :arg area: Area override or None.\n"
634 " :type area: :class:`bpy.types.Area`\n"
635 " :arg region: Region override or None.\n"
636 " :type region: :class:`bpy.types.Region`\n"
637 " :arg keywords: Additional keywords override context members.\n"
638 " :return: The context manager .\n"
639 " :rtype: ContextTempOverride\n");
643 if (context_ptr ==
nullptr) {
647 if (kwds ==
nullptr) {
654 if (!PyArg_ValidateKeywordArguments(kwds)) {
665 params.window.type = &RNA_Window;
666 params.screen.type = &RNA_Screen;
667 params.area.type = &RNA_Area;
668 params.region.type = &RNA_Region;
670 static const char *
const _keywords[] = {
677 static _PyArg_Parser _parser = {
689 kwds = kwds ? PyDict_Copy(kwds) : PyDict_New();
692 const int parse_result = _PyArg_ParseTupleAndKeywordsFast(args,
703 Py_DECREF(kwds_parse);
714 PyObject *context_dict_current =
static_cast<PyObject *
>(
CTX_py_dict_get(
C));
715 if (context_dict_current !=
nullptr) {
716 PyDict_Merge(kwds, context_dict_current, 0);
721 if (
params.window.ptr !=
nullptr) {
726 if (
params.screen.ptr !=
nullptr) {
731 if (
params.area.ptr !=
nullptr) {
736 if (
params.region.ptr !=
nullptr) {
744 ret->ctx_temp = ctx_temp;
745 memset(&
ret->ctx_init, 0,
sizeof(
ret->ctx_init));
747 ret->ctx_temp_orig.screen =
nullptr;
749 ret->py_state_context_dict = kwds;
751 PyObject_GC_Track(
ret);
753 return (PyObject *)
ret;
764# pragma clang diagnostic push
765# pragma clang diagnostic ignored "-Wcast-function-type"
767# pragma GCC diagnostic push
768# pragma GCC diagnostic ignored "-Wcast-function-type"
775 METH_VARARGS | METH_KEYWORDS,
776 bpy_context_temp_override_doc,
781# pragma clang diagnostic pop
783# pragma GCC diagnostic pop
void CTX_py_state_push(bContext *C, bContext_PyState *pystate, void *value)
bScreen * CTX_wm_screen(const bContext *C)
void CTX_py_state_pop(bContext *C, bContext_PyState *pystate)
ScrArea * CTX_wm_area(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
void CTX_wm_screen_set(bContext *C, bScreen *screen)
void CTX_wm_window_set(bContext *C, wmWindow *win)
Main * CTX_data_main(const bContext *C)
void CTX_wm_area_set(bContext *C, ScrArea *area)
void CTX_wm_region_set(bContext *C, ARegion *region)
ARegion * CTX_wm_region(const bContext *C)
void * CTX_py_dict_get(const bContext *C)
bool BKE_screen_is_fullscreen_area(const bScreen *screen) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
WorkSpaceLayout * BKE_workspace_layout_find_global(const Main *bmain, const bScreen *screen, WorkSpace **r_workspace) ATTR_NONNULL(1
#define BLI_assert_unreachable()
int BLI_findindex(const ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
#define LISTBASE_FOREACH(type, var, list)
const PointerRNA * pyrna_struct_as_ptr(PyObject *py_obj, const StructRNA *srna)
int pyrna_struct_as_ptr_or_null_parse(PyObject *o, void *p)
static PyObject * bpy_rna_context_temp_override_enter(BPyContextTempOverride *self)
static PyTypeObject BPyContextTempOverride_Type
static bool wm_check_area_exists(const wmWindow *win, const bScreen *screen, const ScrArea *area)
static PyObject * bpy_context_temp_override(PyObject *self, PyObject *args, PyObject *kwds)
static bool wm_check_region_exists(const bScreen *screen, const ScrArea *area, const ARegion *region)
static void bpy_rna_context_temp_override_dealloc(BPyContextTempOverride *self)
static bool wm_check_window_exists(const Main *bmain, const wmWindow *win)
static bool bpy_rna_context_temp_override_enter_ok_or_error(const BPyContextTempOverride *self, const Main *bmain, const wmWindow *win, const bScreen *screen, const ScrArea *area, const ARegion *region)
static PyObject * bpy_context_temp_override_extract_known_args(const char *const *kwds_static, PyObject *kwds)
static bool wm_check_screen_switch_supported(const bScreen *screen)
static bool wm_check_screen_exists(const Main *bmain, const bScreen *screen)
PyDoc_STRVAR(bpy_context_temp_override_doc, ".. method:: temp_override(*, window=None, area=None, region=None, **keywords)\n" "\n" " Context manager to temporarily override members in the context.\n" "\n" " :arg window: Window override or None.\n" " :type window: :class:`bpy.types.Window`\n" " :arg screen: Screen override or None.\n" "\n" " .. note:: Switching to or away from full-screen areas & temporary screens " "isn't supported. Passing in these screens will raise an exception, " "actions that leave the context such screens won't restore the prior screen.\n" "\n" " .. note:: Changing the screen has wider implications " "than other arguments as it will also change the works-space " "and potentially the scene (when pinned).\n" "\n" " :type screen: :class:`bpy.types.Screen`\n" " :arg area: Area override or None.\n" " :type area: :class:`bpy.types.Area`\n" " :arg region: Region override or None.\n" " :type region: :class:`bpy.types.Region`\n" " :arg keywords: Additional keywords override context members.\n" " :return: The context manager .\n" " :rtype: ContextTempOverride\n")
static PyObject * bpy_rna_context_temp_override_exit(BPyContextTempOverride *self, PyObject *)
void bpy_rna_context_types_init()
static int bpy_rna_context_temp_override_traverse(BPyContextTempOverride *self, visitproc visit, void *arg)
static PyMethodDef bpy_rna_context_temp_override_methods[]
static void bpy_rna_context_temp_set_screen_for_window(bContext *C, wmWindow *win, bScreen *screen)
PyMethodDef BPY_rna_context_temp_override_method_def
static int bpy_rna_context_temp_override_clear(BPyContextTempOverride *self)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
struct BPyContextTempOverride::@354233257271307345007214273262002220225061276230 ctx_temp_orig
PyObject_HEAD bContext * context
bContext_PyState py_state
PyObject * py_state_context_dict
void WM_window_set_active_workspace(bContext *C, wmWindow *win, WorkSpace *workspace)
void WM_window_set_active_screen(wmWindow *win, WorkSpace *workspace, bScreen *screen)
bScreen * WM_window_get_active_screen(const wmWindow *win)