void WM_window_open_temp(bContext *C, rcti *position, int type) { wmWindow *win; ScrArea *sa; /* changes rect to fit within desktop */ wm_window_check_position(position); /* test if we have a temp screen already */ for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) if (win->screen->temp) break; /* add new window? */ if (win == NULL) { win = wm_window_new(C); win->posx = position->xmin; win->posy = position->ymin; } win->sizex = position->xmax - position->xmin; win->sizey = position->ymax - position->ymin; if (win->ghostwin) { wm_window_set_size(win, win->sizex, win->sizey); wm_window_raise(win); } /* add new screen? */ if (win->screen == NULL) win->screen = ED_screen_add(win, CTX_data_scene(C), "temp"); win->screen->temp = 1; /* make window active, and validate/resize */ CTX_wm_window_set(C, win); WM_check(C); /* ensure it shows the right spacetype editor */ sa = win->screen->areabase.first; CTX_wm_area_set(C, sa); if (type == WM_WINDOW_RENDER) { ED_area_newspace(C, sa, SPACE_IMAGE); } else { ED_area_newspace(C, sa, SPACE_USERPREF); } ED_screen_set(C, win->screen); if (sa->spacetype == SPACE_IMAGE) GHOST_SetTitle(win->ghostwin, IFACE_("Blender Render")); else if (ELEM(sa->spacetype, SPACE_OUTLINER, SPACE_USERPREF)) GHOST_SetTitle(win->ghostwin, IFACE_("Blender User Preferences")); else if (sa->spacetype == SPACE_FILE) GHOST_SetTitle(win->ghostwin, IFACE_("Blender File View")); else GHOST_SetTitle(win->ghostwin, "Blender"); }
/* operator callback */ int wm_window_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { wm_window_copy(C, CTX_wm_window(C)); WM_check(C); WM_event_add_notifier(C, NC_WINDOW | NA_ADDED, NULL); return OPERATOR_FINISHED; }
/* area-rip calls this */ wmWindow *WM_window_open(bContext *C, const rcti *rect) { wmWindow *win = wm_window_new(C); win->posx = rect->xmin; win->posy = rect->ymin; win->sizex = BLI_rcti_size_x(rect); win->sizey = BLI_rcti_size_y(rect); win->drawmethod = U.wmdrawmethod; WM_check(C); return win; }
/* area-rip calls this */ wmWindow *WM_window_open(bContext *C, rcti *rect) { wmWindow *win = wm_window_new(C); win->posx = rect->xmin; win->posy = rect->ymin; win->sizex = rect->xmax - rect->xmin; win->sizey = rect->ymax - rect->ymin; win->drawmethod = -1; win->drawdata = NULL; WM_check(C); return win; }
/** * A higher level version of copy that tests the new window can be added. * (called from the operator directly) */ wmWindow *wm_window_copy_test(bContext *C, wmWindow *win_src) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win_dst; win_dst = wm_window_copy(C, win_src); WM_check(C); if (win_dst->ghostwin) { WM_event_add_notifier(C, NC_WINDOW | NA_ADDED, NULL); return win_dst; } else { wm_window_close(C, wm, win_dst); return NULL; } }
/** * new window, no screen yet, but we open ghostwindow for it, * also gets the window level handlers * \note area-rip calls this. * \return the window or NULL. */ wmWindow *WM_window_open(bContext *C, const rcti *rect) { wmWindow *win_prev = CTX_wm_window(C); wmWindow *win = wm_window_new(C); win->posx = rect->xmin; win->posy = rect->ymin; win->sizex = BLI_rcti_size_x(rect); win->sizey = BLI_rcti_size_y(rect); win->drawmethod = U.wmdrawmethod; WM_check(C); if (win->ghostwin) { return win; } else { wm_window_close(C, CTX_wm_manager(C), win); CTX_wm_window_set(C, win_prev); return NULL; } }
/** * called on startup, (context entirely filled with NULLs) * or called for 'New File' * both startup.blend and userpref.blend are checked * the optional parameter custom_file points to an alternative startup page * custom_file can be NULL */ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const char *custom_file) { ListBase wmbase; char startstr[FILE_MAX]; char prefstr[FILE_MAX]; int success = 0; /* Indicates whether user preferences were really load from memory. * * This is used for versioning code, and for this we can not rely on from_memory * passed via argument. This is because there might be configuration folder * exists but it might not have userpref.blend and in this case we fallback to * reading home file from memory. * * And in this case versioning code is to be run. */ bool read_userdef_from_memory = true; /* options exclude eachother */ BLI_assert((from_memory && custom_file) == 0); if ((G.f & G_SCRIPT_OVERRIDE_PREF) == 0) { BKE_BIT_TEST_SET(G.f, (U.flag & USER_SCRIPT_AUTOEXEC_DISABLE) == 0, G_SCRIPT_AUTOEXEC); } BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); UI_view2d_zoom_cache_reset(); G.relbase_valid = 0; if (!from_memory) { const char * const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL); if (custom_file) { BLI_strncpy(startstr, custom_file, FILE_MAX); if (cfgdir) { BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { prefstr[0] = '\0'; } } else if (cfgdir) { BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { startstr[0] = '\0'; prefstr[0] = '\0'; from_memory = 1; } } /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory) { if (BLI_access(startstr, R_OK) == 0) { success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); } if (BLI_listbase_is_empty(&U.themes)) { if (G.debug & G_DEBUG) printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr); success = 0; } } if (success == 0 && custom_file && reports) { BKE_reportf(reports, RPT_ERROR, "Could not read '%s'", custom_file); /*We can not return from here because wm is already reset*/ } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, true); if (BLI_listbase_is_empty(&wmbase)) { wm_clear_default_size(C); } BKE_tempdir_init(U.tempdir); #ifdef WITH_PYTHON_SECURITY /* use alternative setting for security nuts * otherwise we'd need to patch the binary blob - startup.blend.c */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; #endif } /* check new prefs only after startup.blend was finished */ if (!from_memory && BLI_exists(prefstr)) { int done = BKE_read_file_userdef(prefstr, NULL); if (done != BKE_READ_FILE_FAIL) { read_userdef_from_memory = false; printf("Read new prefs: %s\n", prefstr); } } /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; /* check userdef before open window, keymaps etc */ wm_init_userdef(C, read_userdef_from_memory); /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ G.main->name[0] = '\0'; /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ if (!G.background) GPU_default_lights(); /* XXX */ G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ wm_file_read_post(C, true); return true; }
bool WM_file_read(bContext *C, const char *filepath, ReportList *reports) { /* assume automated tasks with background, don't write recent file list */ const bool do_history = (G.background == false) && (CTX_wm_manager(C)->op_undo_depth == 0); bool success = false; int retval; /* so we can get the error message */ errno = 0; WM_cursor_wait(1); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); UI_view2d_zoom_cache_reset(); /* first try to append data from exotic file formats... */ /* it throws error box when file doesn't exist and returns -1 */ /* note; it should set some error message somewhere... (ton) */ retval = wm_read_exotic(filepath); /* we didn't succeed, now try to read Blender file */ if (retval == BKE_READ_EXOTIC_OK_BLEND) { int G_f = G.f; ListBase wmbase; /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); /* confusing this global... */ G.relbase_valid = 1; retval = BKE_read_file(C, filepath, reports); /* when loading startup.blend's, we can be left with a blank path */ if (G.main->name[0]) { G.save_over = 1; } else { G.save_over = 0; G.relbase_valid = 0; } /* this flag is initialized by the operator but overwritten on read. * need to re-enable it here else drivers + registered scripts wont work. */ if (G.f != G_f) { const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); G.f = (G.f & ~flags_keep) | (G_f & flags_keep); } /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ if (retval == BKE_READ_FILE_OK_USERPREFS) { /* in case a userdef is read from regular .blend */ wm_init_userdef(C, false); } if (retval != BKE_READ_FILE_FAIL) { if (do_history) { wm_history_file_update(); } } wm_file_read_post(C, false); success = true; } #if 0 else if (retval == BKE_READ_EXOTIC_OK_OTHER) BKE_undo_write(C, "Import file"); #endif else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) { BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath, errno ? strerror(errno) : TIP_("unable to open the file")); } else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) { BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath); } else if (retval == BKE_READ_EXOTIC_FAIL_PATH) { BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath); } else { BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath); BLI_assert(!"invalid 'retval'"); } if (success == false) { /* remove from recent files list */ if (do_history) { RecentFile *recent = wm_file_history_find(filepath); if (recent) { wm_history_file_free(recent); wm_history_file_write(); } } } WM_cursor_wait(0); return success; }
static int load_file(int UNUSED(argc), const char **argv, void *data) { bContext *C = data; /* Make the path absolute because its needed for relative linked blends to be found */ char filename[FILE_MAX]; /* note, we could skip these, but so far we always tried to load these files */ if (argv[0][0] == '-') { fprintf(stderr, "unknown argument, loading as file: %s\n", argv[0]); } BLI_strncpy(filename, argv[0], sizeof(filename)); BLI_path_cwd(filename); if (G.background) { int retval = BKE_read_file(C, filename, NULL); /* we successfully loaded a blend file, get sure that * pointcache works */ if (retval != BKE_READ_FILE_FAIL) { wmWindowManager *wm = CTX_wm_manager(C); /* special case, 2.4x files */ if (wm == NULL && CTX_data_main(C)->wm.first == NULL) { extern void wm_add_default(bContext *C); /* wm_add_default() needs the screen to be set. */ CTX_wm_screen_set(C, CTX_data_main(C)->screen.first); wm_add_default(C); } CTX_wm_manager_set(C, NULL); /* remove wm to force check */ WM_check(C); G.relbase_valid = 1; if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */ DAG_on_visible_update(CTX_data_main(C), TRUE); } else { /* failed to load file, stop processing arguments */ return -1; } /* WM_file_read() runs normally but since we're in background mode do here */ #ifdef WITH_PYTHON /* run any texts that were loaded in and flagged as modules */ BPY_python_reset(C); #endif /* happens for the UI on file reading too (huh? (ton))*/ // XXX BKE_reset_undo(); // BKE_write_undo("original"); /* save current state */ } else { /* we are not running in background mode here, but start blender in UI mode with * a file - this should do everything a 'load file' does */ ReportList reports; BKE_reports_init(&reports, RPT_PRINT); WM_file_autoexec_init(filename); WM_file_read(C, filename, &reports); BKE_reports_clear(&reports); } G.file_loaded = 1; return 0; }
/* custom_file can be NULL */ int wm_homefile_read(bContext *C, ReportList *reports, bool from_memory, const char *custom_file) { ListBase wmbase; char startstr[FILE_MAX]; char prefstr[FILE_MAX]; int success = 0; /* Indicates whether user prefereneces were really load from memory. * * This is used for versioning code, and for this we can not rely on from_memory * passed via argument. This is because there might be configuration folder * exists but it might not have userpref.blend and in this case we fallback to * reading home file from memory. * * And in this case versioning code is to be run. */ bool read_userdef_from_memory = true; /* options exclude eachother */ BLI_assert((from_memory && custom_file) == 0); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); G.relbase_valid = 0; if (!from_memory) { const char * const cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (custom_file) { BLI_strncpy(startstr, custom_file, FILE_MAX); if (cfgdir) { BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { prefstr[0] = '\0'; } } else if (cfgdir) { BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { startstr[0] = '\0'; prefstr[0] = '\0'; from_memory = 1; } } /* prevent loading no UI */ G.fileflags &= ~G_FILE_NO_UI; /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory) { if (BLI_access(startstr, R_OK) == 0) { success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); } if (U.themes.first == NULL) { if (G.debug & G_DEBUG) printf("\nNote: No (valid) '%s' found, fall back to built-in default.\n\n", startstr); success = 0; } } if (success == 0 && custom_file && reports) { BKE_reportf(reports, RPT_ERROR, "Could not read '%s'", custom_file); /*We can not return from here because wm is already reset*/ } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL, true); if (wmbase.first == NULL) wm_clear_default_size(C); BLI_init_temporary_dir(U.tempdir); #ifdef WITH_PYTHON_SECURITY /* use alternative setting for security nuts * otherwise we'd need to patch the binary blob - startup.blend.c */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; #endif } /* check new prefs only after startup.blend was finished */ if (!from_memory && BLI_exists(prefstr)) { int done = BKE_read_file_userdef(prefstr, NULL); if (done) { read_userdef_from_memory = false; printf("Read new prefs: %s\n", prefstr); } } /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; /* check userdef before open window, keymaps etc */ wm_init_userdef(C, read_userdef_from_memory); /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ G.main->name[0] = '\0'; /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ if (!G.background) GPU_default_lights(); /* XXX */ G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ // refresh_interface_font(); // undo_editmode_clear(); BKE_reset_undo(); BKE_write_undo(C, "original"); /* save current state */ ED_editors_init(C); DAG_on_visible_update(CTX_data_main(C), TRUE); #ifdef WITH_PYTHON if (CTX_py_init_get(C)) { /* sync addons, these may have changed from the defaults */ BPY_string_exec(C, "__import__('addon_utils').reset_all()"); BPY_python_reset(C); } #endif /* important to do before NULL'ing the context */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); /* in background mode the scene will stay NULL */ if (!G.background) { CTX_wm_window_set(C, NULL); /* exits queues */ } return TRUE; }
void WM_file_read(bContext *C, const char *filepath, ReportList *reports) { int retval; /* so we can get the error message */ errno = 0; WM_cursor_wait(1); BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); /* first try to append data from exotic file formats... */ /* it throws error box when file doesn't exist and returns -1 */ /* note; it should set some error message somewhere... (ton) */ retval = wm_read_exotic(CTX_data_scene(C), filepath); /* we didn't succeed, now try to read Blender file */ if (retval == BKE_READ_EXOTIC_OK_BLEND) { int G_f = G.f; ListBase wmbase; /* assume automated tasks with background, don't write recent file list */ const int do_history = (G.background == FALSE) && (CTX_wm_manager(C)->op_undo_depth == 0); /* put aside screens to match with persistent windows later */ /* also exit screens and editors */ wm_window_match_init(C, &wmbase); /* confusing this global... */ G.relbase_valid = 1; retval = BKE_read_file(C, filepath, reports); /* when loading startup.blend's, we can be left with a blank path */ if (G.main->name[0]) { G.save_over = 1; } else { G.save_over = 0; G.relbase_valid = 0; } /* this flag is initialized by the operator but overwritten on read. * need to re-enable it here else drivers + registered scripts wont work. */ if (G.f != G_f) { const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); G.f = (G.f & ~flags_keep) | (G_f & flags_keep); } /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ if (retval == BKE_READ_FILE_OK_USERPREFS) { /* in case a userdef is read from regular .blend */ wm_init_userdef(C, false); } if (retval != BKE_READ_FILE_FAIL) { if (do_history) { write_history(); } } WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); // refresh_interface_font(); CTX_wm_window_set(C, CTX_wm_manager(C)->windows.first); ED_editors_init(C); DAG_on_visible_update(CTX_data_main(C), TRUE); #ifdef WITH_PYTHON /* run any texts that were loaded in and flagged as modules */ BPY_python_reset(C); #endif /* important to do before NULL'ing the context */ BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); if (!G.background) { /* in background mode this makes it hard to load * a blend file and do anything since the screen * won't be set to a valid value again */ CTX_wm_window_set(C, NULL); /* exits queues */ } #if 0 /* gives popups on windows but not linux, bug in report API * but disable for now to stop users getting annoyed */ /* TODO, make this show in header info window */ { Scene *sce; for (sce = G.main->scene.first; sce; sce = sce->id.next) { if (sce->r.engine[0] && BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) { BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' " "(an addon may need to be installed or enabled)", sce->r.engine, sce->id.name + 2); } } } #endif BKE_reset_undo(); BKE_write_undo(C, "original"); /* save current state */ } else if (retval == BKE_READ_EXOTIC_OK_OTHER) BKE_write_undo(C, "Import file"); else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) { BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath, errno ? strerror(errno) : TIP_("unable to open the file")); } else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) { BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath); } else if (retval == BKE_READ_EXOTIC_FAIL_PATH) { BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath); } else { BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath); BLI_assert(!"invalid 'retval'"); } WM_cursor_wait(0); }
/* op can be NULL */ int WM_read_homefile(bContext *C, ReportList *UNUSED(reports), short from_memory) { ListBase wmbase; char tstr[FILE_MAX]; int success = 0; free_ttfont(); /* still weird... what does it here? */ G.relbase_valid = 0; if (!from_memory) { char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (cfgdir) { BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE); } else { tstr[0] = '\0'; from_memory = 1; } } /* prevent loading no UI */ G.fileflags &= ~G_FILE_NO_UI; /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); if (!from_memory && BLI_exists(tstr)) { success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL); if (U.themes.first == NULL) { printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); success = 0; } } if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL); if (wmbase.first == NULL) wm_clear_default_size(C); #ifdef WITH_PYTHON_SECURITY /* not default */ /* use alternative setting for security nuts * otherwise we'd need to patch the binary blob - startup.blend.c */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; #endif } /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; /* check userdef before open window, keymaps etc */ wm_init_userdef(C); /* match the read WM with current WM */ wm_window_match_do(C, &wmbase); WM_check(C); /* opens window(s), checks keymaps */ G.main->name[0] = '\0'; /* When loading factory settings, the reset solid OpenGL lights need to be applied. */ if (!G.background) GPU_default_lights(); /* XXX */ G.save_over = 0; // start with save preference untitled.blend G.fileflags &= ~G_FILE_AUTOPLAY; /* disable autoplay in startup.blend... */ // mainwindow_set_filename_to_title(""); // empty string re-initializes title to "Blender" // refresh_interface_font(); // undo_editmode_clear(); BKE_reset_undo(); BKE_write_undo(C, "original"); /* save current state */ ED_editors_init(C); DAG_on_visible_update(CTX_data_main(C), TRUE); #ifdef WITH_PYTHON if (CTX_py_init_get(C)) { /* sync addons, these may have changed from the defaults */ BPY_string_exec(C, "__import__('addon_utils').reset_all()"); BPY_driver_reset(); BPY_app_handlers_reset(FALSE); BPY_modules_load_user(C); } #endif WM_event_add_notifier(C, NC_WM | ND_FILEREAD, NULL); /* in background mode the scene will stay NULL */ if (!G.background) { CTX_wm_window_set(C, NULL); /* exits queues */ } return TRUE; }
/** * Uses `screen->temp` tag to define what to do, currently it limits * to only one "temp" window for render out, preferences, filewindow, etc... * * \param type: WM_WINDOW_RENDER, WM_WINDOW_USERPREFS... * \return the window or NULL. */ wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type) { wmWindow *win_prev = CTX_wm_window(C); wmWindow *win; ScrArea *sa; Scene *scene = CTX_data_scene(C); const char *title; rcti rect = *rect_init; const short px_virtual = (short)wm_window_get_virtual_pixelsize(); /* changes rect to fit within desktop */ wm_window_check_position(&rect); /* test if we have a temp screen already */ for (win = CTX_wm_manager(C)->windows.first; win; win = win->next) if (win->screen->temp) break; /* add new window? */ if (win == NULL) { win = wm_window_new(C); win->posx = rect.xmin; win->posy = rect.ymin; } /* multiply with virtual pixelsize, ghost handles native one (e.g. for retina) */ win->sizex = BLI_rcti_size_x(&rect) * px_virtual; win->sizey = BLI_rcti_size_y(&rect) * px_virtual; if (win->ghostwin) { wm_window_set_size(win, win->sizex, win->sizey); wm_window_raise(win); } if (win->screen == NULL) { /* add new screen */ win->screen = ED_screen_add(win, scene, "temp"); } else { /* switch scene for rendering */ if (win->screen->scene != scene) ED_screen_set_scene(C, win->screen, scene); } win->screen->temp = 1; /* make window active, and validate/resize */ CTX_wm_window_set(C, win); WM_check(C); /* It's possible `win->ghostwin == NULL`. * instead of attempting to cleanup here (in a half finished state), * finish setting up the screen, then free it at the end of the function, * to avoid having to take into account a partially-created window. */ /* ensure it shows the right spacetype editor */ sa = win->screen->areabase.first; CTX_wm_area_set(C, sa); if (type == WM_WINDOW_RENDER) { ED_area_newspace(C, sa, SPACE_IMAGE); } else { ED_area_newspace(C, sa, SPACE_USERPREF); } ED_screen_set(C, win->screen); ED_screen_refresh(CTX_wm_manager(C), win); /* test scale */ if (sa->spacetype == SPACE_IMAGE) title = IFACE_("Blender Render"); else if (ELEM(sa->spacetype, SPACE_OUTLINER, SPACE_USERPREF)) title = IFACE_("Blender User Preferences"); else if (sa->spacetype == SPACE_FILE) title = IFACE_("Blender File View"); else title = "Blender"; if (win->ghostwin) { GHOST_SetTitle(win->ghostwin, title); return win; } else { /* very unlikely! but opening a new window can fail */ wm_window_close(C, CTX_wm_manager(C), win); CTX_wm_window_set(C, win_prev); return NULL; } }