30#include "RNA_prototypes.hh"
40 if (screen ==
nullptr) {
59 if (screen->
temp != 0) {
168 PyObject_GC_UnTrack(
self);
169 Py_CLEAR(
self->py_state_context_dict);
170 PyObject_GC_Del(
self);
177 Py_VISIT(
self->py_state_context_dict);
183 Py_CLEAR(
self->py_state_context_dict);
223 if (
self->ctx_temp.region_is_set && (region !=
nullptr)) {
224 if (screen ==
nullptr && area ==
nullptr) {
225 PyErr_SetString(PyExc_TypeError,
"Region set with screen & area set to None");
229 PyErr_SetString(PyExc_TypeError,
"Region not found in area or screen");
234 if (
self->ctx_temp.area_is_set && (area !=
nullptr)) {
235 if (win ==
nullptr && screen ==
nullptr) {
236 PyErr_SetString(PyExc_TypeError,
"Area set with window & screen set to None");
240 PyErr_SetString(PyExc_TypeError,
"Area not found in screen");
245 if (
self->ctx_temp.screen_is_set && (screen !=
nullptr)) {
246 if (win ==
nullptr) {
247 PyErr_SetString(PyExc_TypeError,
"Screen set with null window");
251 PyErr_SetString(PyExc_TypeError,
"Screen not found");
256 if (
self->ctx_init.screen_is_set) {
258 if ((
self->ctx_init.screen !=
nullptr) &&
261 PyErr_SetString(PyExc_TypeError,
262 "Overriding context with an active temporary screen isn't supported");
266 PyErr_SetString(PyExc_TypeError,
267 "Overriding context with temporary screen isn't supported");
271 PyErr_SetString(PyExc_TypeError,
"Screen has no workspace");
277 if (win_iter == win) {
281 PyErr_SetString(PyExc_TypeError,
"Screen is used by another window");
289 if (
self->ctx_temp.win_is_set && (win !=
nullptr)) {
291 PyErr_SetString(PyExc_TypeError,
"Window not found");
305 if (
self->ctx_temp.use_logging) {
319 bScreen *screen =
self->ctx_temp.screen_is_set ?
self->ctx_temp.screen :
self->ctx_init.screen;
321 ARegion *region =
self->ctx_temp.region_is_set ?
self->ctx_temp.region :
self->ctx_init.region;
323 self->ctx_init.win_is_set = (
self->ctx_init.win != win);
324 self->ctx_init.screen_is_set = (
self->ctx_init.screen != screen);
325 self->ctx_init.area_is_set = (
self->ctx_init.area != area);
326 self->ctx_init.region_is_set = (
self->ctx_init.region != region);
331 if ((
self->ctx_temp.win_is_set ==
true) && (
self->ctx_temp.screen_is_set ==
false)) {
341 if (
self->ctx_temp.screen_is_set) {
356 if (
self->ctx_temp.win_is_set) {
359 if (
self->ctx_temp.screen_is_set) {
362 if (
self->ctx_temp.area_is_set) {
365 if (
self->ctx_temp.region_is_set) {
369 return Py_NewRef(
self);
380 if (
self->ctx_temp.screen_is_set) {
398 bool do_restore =
true;
413 bool is_container_set =
false;
423 if (
self->ctx_init.win_is_set) {
425 is_container_set =
true;
427 else if (
self->ctx_temp.win_is_set) {
429 is_container_set =
true;
448 if (
self->ctx_init.screen_is_set || is_container_set) {
450 is_container_set =
true;
452 else if (
self->ctx_temp.screen_is_set) {
454 is_container_set =
true;
465 if (
self->ctx_init.area &&
473 if (
self->ctx_init.area_is_set || is_container_set) {
475 is_container_set =
true;
477 else if (
self->ctx_temp.area_is_set) {
479 is_container_set =
true;
490 if (
self->ctx_init.region &&
498 if (
self->ctx_init.region_is_set || is_container_set) {
500 is_container_set =
true;
503 else if (
false &&
self->ctx_temp.region_is_set) {
505 is_container_set =
true;
519 if (context_dict_test && (context_dict_test !=
self->py_state_context_dict)) {
537 static const char *kwlist[] = {
"",
nullptr};
538 if (!PyArg_ParseTupleAndKeywords(args, kwds,
"O&", (
char **)kwlist,
PyC_ParseBool, &enable)) {
542 self->ctx_temp.use_logging = enable;
551# pragma clang diagnostic push
552# pragma clang diagnostic ignored "-Wcast-function-type"
554# pragma GCC diagnostic push
555# pragma GCC diagnostic ignored "-Wcast-function-type"
564 METH_VARARGS | METH_KEYWORDS},
570# pragma clang diagnostic pop
572# pragma GCC diagnostic pop
577 PyVarObject_HEAD_INIT(
nullptr, 0)
578 "ContextTempOverride",
596 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
637 PyObject *kwds_parse = PyDict_New();
638 for (
int i = 0; kwds_static[
i];
i++) {
639 PyObject *key = PyUnicode_FromString(kwds_static[
i]);
642#if PY_VERSION_HEX >= 0x030d0000
643 switch (PyDict_Pop(kwds, key, &val)) {
645 if (PyDict_SetItem(kwds_parse, key, val) == -1) {
659 PyObject *sentinel = Py_Ellipsis;
660 val = _PyDict_Pop(kwds, key, sentinel);
661 if (val != sentinel) {
662 if (PyDict_SetItem(kwds_parse, key, val) == -1) {
678 bpy_context_temp_override_doc,
679 ".. method:: temp_override(*, window=None, screen=None, area=None, region=None, **keywords)\n"
681 " Context manager to temporarily override members in the context.\n"
683 " :arg window: Window override or None.\n"
684 " :type window: :class:`bpy.types.Window`\n"
685 " :arg screen: Screen override or None.\n"
687 " .. note:: Switching to or away from full-screen areas & temporary screens "
688 "isn't supported. Passing in these screens will raise an exception, "
689 "actions that leave the context such screens won't restore the prior screen.\n"
691 " .. note:: Changing the screen has wider implications "
692 "than other arguments as it will also change the works-space "
693 "and potentially the scene (when pinned).\n"
695 " :type screen: :class:`bpy.types.Screen`\n"
696 " :arg area: Area override or None.\n"
697 " :type area: :class:`bpy.types.Area`\n"
698 " :arg region: Region override or None.\n"
699 " :type region: :class:`bpy.types.Region`\n"
700 " :arg keywords: Additional keywords override context members.\n"
701 " :return: The context manager .\n"
702 " :rtype: ContextTempOverride\n");
706 if (context_ptr ==
nullptr) {
710 if (kwds ==
nullptr) {
717 if (!PyArg_ValidateKeywordArguments(kwds)) {
728 params.window.type = &RNA_Window;
729 params.screen.type = &RNA_Screen;
730 params.area.type = &RNA_Area;
731 params.region.type = &RNA_Region;
733 static const char *
const _keywords[] = {
740 static _PyArg_Parser _parser = {
752 kwds = kwds ? PyDict_Copy(kwds) : PyDict_New();
755 const int parse_result = _PyArg_ParseTupleAndKeywordsFast(args,
777 PyObject *context_dict_current =
static_cast<PyObject *
>(
CTX_py_dict_get(
C));
778 if (context_dict_current !=
nullptr) {
779 PyDict_Merge(kwds, context_dict_current, 0);
784 if (
params.window.ptr !=
nullptr) {
789 if (
params.screen.ptr !=
nullptr) {
794 if (
params.area.ptr !=
nullptr) {
799 if (
params.region.ptr !=
nullptr) {
807 ret->ctx_temp = ctx_temp;
808 memset(&
ret->ctx_init, 0,
sizeof(
ret->ctx_init));
810 ret->ctx_temp_orig.screen =
nullptr;
812 ret->py_state_context_dict = kwds;
814 PyObject_GC_Track(
ret);
816 return (PyObject *)
ret;
827# pragma clang diagnostic push
828# pragma clang diagnostic ignored "-Wcast-function-type"
830# pragma GCC diagnostic push
831# pragma GCC diagnostic ignored "-Wcast-function-type"
838 METH_VARARGS | METH_KEYWORDS,
839 bpy_context_temp_override_doc,
844# pragma clang diagnostic pop
846# pragma GCC diagnostic pop
void CTX_member_logging_set(bContext *C, bool enable)
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)
PyDoc_STRVAR(bpy_context_temp_override_doc, ".. method:: temp_override(*, window=None, screen=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_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 PyObject * bpy_rna_context_temp_override_logging_set(BPyContextTempOverride *self, PyObject *args, PyObject *kwds)
static void bpy_rna_context_logging_set(bContext *C, bool enable)
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)
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)
int PyC_ParseBool(PyObject *o, void *p)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
PyObject_HEAD bContext * context
struct BPyContextTempOverride::@304241065162324270114022056126054014113033266215 ctx_temp_orig
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)