29#include "RNA_prototypes.hh"
39 if (screen ==
nullptr) {
58 if (screen->temp != 0) {
90 if (screen && (
BLI_findindex(&screen->areabase, area) != -1)) {
100 if (screen && (
BLI_findindex(&screen->regionbase, region) != -1)) {
103 if (area && (
BLI_findindex(&area->regionbase, region) != -1)) {
173 bScreen *screen =
self->ctx_temp.screen_is_set ?
self->ctx_temp.screen :
self->ctx_init.screen;
175 ARegion *region =
self->ctx_temp.region_is_set ?
self->ctx_temp.region :
self->ctx_init.region;
177 self->ctx_init.win_is_set = (
self->ctx_init.win != win);
178 self->ctx_init.screen_is_set = (
self->ctx_init.screen != screen);
179 self->ctx_init.area_is_set = (
self->ctx_init.area != area);
180 self->ctx_init.region_is_set = (
self->ctx_init.region != region);
185 if ((
self->ctx_temp.win_is_set ==
true) && (
self->ctx_temp.screen_is_set ==
false)) {
217 if (
self->ctx_temp.region_is_set && (region !=
nullptr)) {
218 if (screen ==
nullptr && area ==
nullptr) {
219 PyErr_SetString(PyExc_TypeError,
"Region set with screen & area set to None");
223 PyErr_SetString(PyExc_TypeError,
"Region not found in area or screen");
228 if (
self->ctx_temp.area_is_set && (area !=
nullptr)) {
229 if (win ==
nullptr && screen ==
nullptr) {
230 PyErr_SetString(PyExc_TypeError,
"Area set with window & screen set to None");
234 PyErr_SetString(PyExc_TypeError,
"Area not found in screen");
239 if (
self->ctx_temp.screen_is_set && (screen !=
nullptr)) {
240 if (win ==
nullptr) {
241 PyErr_SetString(PyExc_TypeError,
"Screen set with null window");
245 PyErr_SetString(PyExc_TypeError,
"Screen not found");
250 if (
self->ctx_init.screen_is_set) {
252 if ((
self->ctx_init.screen !=
nullptr) &&
255 PyErr_SetString(PyExc_TypeError,
256 "Overriding context with an active temporary screen isn't supported");
260 PyErr_SetString(PyExc_TypeError,
261 "Overriding context with temporary screen isn't supported");
265 PyErr_SetString(PyExc_TypeError,
"Screen has no workspace");
271 if (win_iter == win) {
275 PyErr_SetString(PyExc_TypeError,
"Screen is used by another window");
283 if (
self->ctx_temp.win_is_set && (win !=
nullptr)) {
285 PyErr_SetString(PyExc_TypeError,
"Window not found");
291 if (
self->ctx_temp.screen_is_set) {
306 if (
self->ctx_temp.win_is_set) {
309 if (
self->ctx_temp.screen_is_set) {
312 if (
self->ctx_temp.area_is_set) {
315 if (
self->ctx_temp.region_is_set) {
330 if (
self->ctx_temp.screen_is_set) {
348 bool do_restore =
true;
363 bool is_container_set =
false;
373 if (
self->ctx_init.win_is_set) {
375 is_container_set =
true;
377 else if (
self->ctx_temp.win_is_set) {
379 is_container_set =
true;
398 if (
self->ctx_init.screen_is_set || is_container_set) {
400 is_container_set =
true;
402 else if (
self->ctx_temp.screen_is_set) {
404 is_container_set =
true;
415 if (
self->ctx_init.area &&
423 if (
self->ctx_init.area_is_set || is_container_set) {
425 is_container_set =
true;
427 else if (
self->ctx_temp.area_is_set) {
429 is_container_set =
true;
440 if (
self->ctx_init.region &&
448 if (
self->ctx_init.region_is_set || is_container_set) {
450 is_container_set =
true;
453 else if (
false &&
self->ctx_temp.region_is_set) {
455 is_container_set =
true;
468 PyObject *context_dict_test =
static_cast<PyObject *
>(
CTX_py_dict_get(C));
469 if (context_dict_test && (context_dict_test !=
self->py_state_context_dict)) {
470 Py_DECREF(context_dict_test);
473 Py_CLEAR(
self->py_state_context_dict);
478#if (defined(__GNUC__) && !defined(__clang__))
479# pragma GCC diagnostic push
480# pragma GCC diagnostic ignored "-Wcast-function-type"
489#if (defined(__GNUC__) && !defined(__clang__))
490# pragma GCC diagnostic pop
494 PyVarObject_HEAD_INIT(
nullptr, 0)
495 "ContextTempOverride",
554 PyObject *sentinel = Py_Ellipsis;
555 PyObject *kwds_parse = PyDict_New();
556 for (
int i = 0; kwds_static[i]; i++) {
557 PyObject *key = PyUnicode_FromString(kwds_static[i]);
558 PyObject *val = _PyDict_Pop(kwds, key, sentinel);
559 if (val != sentinel) {
560 if (PyDict_SetItem(kwds_parse, key, val) == -1) {
574 bpy_context_temp_override_doc,
575 ".. method:: temp_override(*, window=None, area=None, region=None, **keywords)\n"
577 " Context manager to temporarily override members in the context.\n"
579 " :arg window: Window override or None.\n"
580 " :type window: :class:`bpy.types.Window`\n"
581 " :arg screen: Screen override or None.\n"
583 " .. note:: Switching to or away from full-screen areas & temporary screens "
584 "isn't supported. Passing in these screens will raise an exception, "
585 "actions that leave the context such screens won't restore the prior screen.\n"
587 " .. note:: Changing the screen has wider implications "
588 "than other arguments as it will also change the works-space "
589 "and potentially the scene (when pinned).\n"
591 " :type screen: :class:`bpy.types.Screen`\n"
592 " :arg area: Area override or None.\n"
593 " :type area: :class:`bpy.types.Area`\n"
594 " :arg region: Region override or None.\n"
595 " :type region: :class:`bpy.types.Region`\n"
596 " :arg keywords: Additional keywords override context members.\n"
597 " :return: The context manager .\n"
598 " :rtype: ContextTempOverride\n");
602 if (context_ptr ==
nullptr) {
606 if (kwds ==
nullptr) {
613 if (!PyArg_ValidateKeywordArguments(kwds)) {
624 params.window.type = &RNA_Window;
625 params.screen.type = &RNA_Screen;
626 params.area.type = &RNA_Area;
627 params.region.type = &RNA_Region;
629 static const char *
const _keywords[] = {
636 static _PyArg_Parser _parser = {
648 kwds = kwds ? PyDict_Copy(kwds) : PyDict_New();
651 const int parse_result = _PyArg_ParseTupleAndKeywordsFast(args,
662 Py_DECREF(kwds_parse);
673 PyObject *context_dict_current =
static_cast<PyObject *
>(
CTX_py_dict_get(C));
674 if (context_dict_current !=
nullptr) {
675 PyDict_Merge(kwds, context_dict_current, 0);
680 if (
params.window.ptr !=
nullptr) {
685 if (
params.screen.ptr !=
nullptr) {
690 if (
params.area.ptr !=
nullptr) {
695 if (
params.region.ptr !=
nullptr) {
702 ret->ctx_temp = ctx_temp;
703 memset(&
ret->ctx_init, 0,
sizeof(
ret->ctx_init));
705 ret->ctx_temp_orig.screen =
nullptr;
707 ret->py_state_context_dict = kwds;
709 return (PyObject *)
ret;
718#if (defined(__GNUC__) && !defined(__clang__))
719# pragma GCC diagnostic push
720# pragma GCC diagnostic ignored "-Wcast-function-type"
726 METH_VARARGS | METH_KEYWORDS,
727 bpy_context_temp_override_doc,
730#if (defined(__GNUC__) && !defined(__clang__))
731# 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()
#define LISTBASE_FOREACH(type, var, list)
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
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 bool wm_check_window_exists(const Main *bmain, const wmWindow *win)
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 PyMethodDef bpy_rna_context_temp_override__tp_methods[]
static PyObject * bpy_rna_context_temp_override_exit(BPyContextTempOverride *self, PyObject *)
void bpy_rna_context_types_init()
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 void bpy_rna_context_temp_override__tp_dealloc(BPyContextTempOverride *self)
header-only compatibility defines.
#define PY_ARG_PARSER_HEAD_COMPAT()
struct BPyContextTempOverride::@1355 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)