Fix T98461: Crash running screenshot from the command-line

When launching Blender with a script creating a screenshot, the Outliner
tree wasn't initialized and built properly. That is because at this
stage, all visible regions were only tagged for a non-rebuild redraw,
not a full redraw. So ensure all regions are tagged for a full redraw
immediately after file reading. Usually the full redraw would be caused
by a file-read notifier, but the Python expression/script is executed
before notifiers are handled.

Note that even before this was crashing, the Outliner would be empty in
the created screenshot.

Additionally adds an assert to the Outliner to note assumptions
explicitly, rather than crashing later.
This commit is contained in:
Julian Eisel 2022-05-30 12:49:36 +02:00
parent a8471459fd
commit 1f85877263
Notes: blender-bot 2023-12-08 22:59:25 +01:00
Referenced by issue #98461, Regression: Crash running screenshot from the command-line
Referenced by issue #114838, Instant crash on Duplicate Area into new Window in fullscreen mode.
Referenced by pull request #115959, Fix #114838: Force Full Redraw When Duplicating Areas
2 changed files with 16 additions and 0 deletions

View File

@ -1682,6 +1682,9 @@ void outliner_build_tree(Main *mainvar,
space_outliner->storeflag &= ~SO_TREESTORE_REBUILD;
if (region->do_draw & RGN_DRAW_NO_REBUILD) {
BLI_assert_msg(space_outliner->runtime->tree_display != nullptr,
"Skipping rebuild before tree was built properly, a full redraw should be "
"triggered instead");
return;
}

View File

@ -41,6 +41,7 @@
#include "ED_mesh.h"
#include "ED_object.h"
#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_space_api.h"
#include "ED_util.h"
@ -187,6 +188,18 @@ void ED_editors_init(bContext *C)
ED_space_image_paint_update(bmain, wm, scene);
}
/* Enforce a full redraw for the first time areas/regions get drawn. Further region init/refresh
* just triggers non-rebuild redraws (#RGN_DRAW_NO_REBUILD). Usually a full redraw would be
* triggered by a `NC_WM | ND_FILEREAD` notifier, but if a startup script calls an operator that
* redraws the window, notifiers are not handled before the operator runs. See T98461. */
LISTBASE_FOREACH (wmWindow *, win, &wm->windows) {
const bScreen *screen = WM_window_get_active_screen(win);
ED_screen_areas_iter (win, screen, area) {
ED_area_tag_redraw(area);
}
}
ED_assetlist_storage_tag_main_data_dirty();
SWAP(int, reports->flag, reports_flag_prev);