Changeset View
Changeset View
Standalone View
Standalone View
source/blender/windowmanager/intern/wm_files.c
| Show First 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_packedFile.h" | #include "BKE_packedFile.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BKE_sound.h" | #include "BKE_sound.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "BKE_screen.h" | #include "BKE_screen.h" | ||||
| #include "BKE_workspace.h" | |||||
| #include "BLO_readfile.h" | #include "BLO_readfile.h" | ||||
| #include "BLO_writefile.h" | #include "BLO_writefile.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "IMB_imbuf.h" | #include "IMB_imbuf.h" | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | for (wm = wmlist->first; wm; wm = wm->id.next) { | ||||
| WM_jobs_kill_all(wm); | WM_jobs_kill_all(wm); | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| CTX_wm_window_set(C, win); /* needed by operator close callbacks */ | CTX_wm_window_set(C, win); /* needed by operator close callbacks */ | ||||
| WM_event_remove_handlers(C, &win->handlers); | WM_event_remove_handlers(C, &win->handlers); | ||||
| WM_event_remove_handlers(C, &win->modalhandlers); | WM_event_remove_handlers(C, &win->modalhandlers); | ||||
| ED_screen_exit(C, win, win->screen); | ED_screen_exit(C, win, WM_window_get_active_screen(win)); | ||||
| } | } | ||||
| } | } | ||||
| /* reset active window */ | /* reset active window */ | ||||
| CTX_wm_window_set(C, active_win); | CTX_wm_window_set(C, active_win); | ||||
| /* XXX Hack! We have to clear context menu here, because removing all modalhandlers above frees the active menu | /* XXX Hack! We have to clear context menu here, because removing all modalhandlers above frees the active menu | ||||
| * (at least, in the 'startup splash' case), causing use-after-free error in later handling of the button | * (at least, in the 'startup splash' case), causing use-after-free error in later handling of the button | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (BLI_listbase_is_empty(&G.main->wm)) { | ||||
| /* when loading without UI, no matching needed */ | /* when loading without UI, no matching needed */ | ||||
| if (!(G.fileflags & G_FILE_NO_UI) && (screen = CTX_wm_screen(C))) { | if (!(G.fileflags & G_FILE_NO_UI) && (screen = CTX_wm_screen(C))) { | ||||
| /* match oldwm to new dbase, only old files */ | /* match oldwm to new dbase, only old files */ | ||||
| for (wm = oldwmlist->first; wm; wm = wm->id.next) { | for (wm = oldwmlist->first; wm; wm = wm->id.next) { | ||||
| for (win = wm->windows.first; win; win = win->next) { | for (win = wm->windows.first; win; win = win->next) { | ||||
| /* all windows get active screen from file */ | /* all windows get active screen from file */ | ||||
| if (screen->winid == 0) | if (screen->winid == 0) { | ||||
| win->screen = screen; | WM_window_set_active_screen(win, screen); | ||||
| else | } | ||||
| win->screen = ED_screen_duplicate(win, screen); | else { | ||||
| WorkSpace *workspace = WM_window_get_active_workspace(win); | |||||
| WorkSpaceLayout *layout_old = WM_window_get_active_layout(win); | |||||
| WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate(workspace, layout_old, win); | |||||
| WM_window_set_active_layout(win, layout_new); | |||||
| } | |||||
| BLI_strncpy(win->screenname, win->screen->id.name + 2, sizeof(win->screenname)); | bScreen *win_screen = WM_window_get_active_screen(win); | ||||
| win->screen->winid = win->winid; | BLI_strncpy(win->screenname, win_screen->id.name + 2, sizeof(win->screenname)); | ||||
| win_screen->winid = win->winid; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| G.main->wm = *oldwmlist; | G.main->wm = *oldwmlist; | ||||
| /* screens were read from file! */ | /* screens were read from file! */ | ||||
| ED_screens_initialize(G.main->wm.first); | ED_screens_initialize(G.main->wm.first); | ||||
| ▲ Show 20 Lines • Show All 300 Lines • ▼ Show 20 Lines | if (retval == BKE_READ_EXOTIC_OK_BLEND) { | ||||
| if (G.f != G_f) { | if (G.f != G_f) { | ||||
| const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); | const int flags_keep = (G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); | ||||
| G.f = (G.f & ~flags_keep) | (G_f & flags_keep); | G.f = (G.f & ~flags_keep) | (G_f & flags_keep); | ||||
| } | } | ||||
| /* match the read WM with current WM */ | /* match the read WM with current WM */ | ||||
| wm_window_match_do(C, &wmbase); | wm_window_match_do(C, &wmbase); | ||||
| WM_check(C); /* opens window(s), checks keymaps */ | WM_check(C); /* opens window(s), checks keymaps */ | ||||
campbellbarton: This is going to cause problems,
- `wm_init_userdef` versions preferences, initializes temp… | |||||
Not Done Inline ActionsThe issue I tried to fix with this re-ordering was a crash when loading startup.blend as regular .blend, see rB6bf890786305f. The important bits were the calls to CTX_wm_window_set in wm_file_read_post. IIRC calling CTX_wm_window_set once more in WM_file_read would've worked too, but I checked if reordering would be fine and it seemed so, so I decided to avoid the extra CTX_wm_window_set call. You're making good points however, will check the alternative(s) again. Severin: The issue I tried to fix with this re-ordering was a crash when loading startup.blend as… | |||||
| if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) { | if (retval == BKE_BLENDFILE_READ_OK_USERPREFS) { | ||||
| /* in case a userdef is read from regular .blend */ | /* in case a userdef is read from regular .blend */ | ||||
| wm_init_userdef(C, false); | wm_init_userdef(C, false); | ||||
| } | } | ||||
| if (retval != BKE_BLENDFILE_READ_FAIL) { | if (retval != BKE_BLENDFILE_READ_FAIL) { | ||||
| if (do_history) { | if (do_history) { | ||||
| wm_history_file_update(); | wm_history_file_update(); | ||||
| ▲ Show 20 Lines • Show All 676 Lines • ▼ Show 20 Lines | static int wm_homefile_write_exec(bContext *C, wmOperator *op) | ||||
| wmWindowManager *wm = CTX_wm_manager(C); | wmWindowManager *wm = CTX_wm_manager(C); | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| char filepath[FILE_MAX]; | char filepath[FILE_MAX]; | ||||
| int fileflags; | int fileflags; | ||||
| BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); | BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); | ||||
| /* check current window and close it if temp */ | /* check current window and close it if temp */ | ||||
| if (win && win->screen->temp) | if (win && WM_window_is_temp_screen(win)) | ||||
| wm_window_close(C, wm, win); | wm_window_close(C, wm, win); | ||||
| /* update keymaps in user preferences */ | /* update keymaps in user preferences */ | ||||
| WM_keyconfig_update(wm); | WM_keyconfig_update(wm); | ||||
| BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); | BLI_make_file_string("/", filepath, BKE_appdir_folder_id_create(BLENDER_USER_CONFIG, NULL), BLENDER_STARTUP_FILE); | ||||
| printf("trying to save homefile at %s ", filepath); | printf("trying to save homefile at %s ", filepath); | ||||
| ▲ Show 20 Lines • Show All 700 Lines • Show Last 20 Lines | |||||
This is going to cause problems,
This means addons may run before user preferences are properly versioned and initializes, which should be avoided since it could cause strange/undefined behavior.
Besides introducing problems (that can probably be worked around), the intended purpose of wm_file_read_post is to run last, so not really happy to move it before other operations.
What problems happen when the order is restored to the original state? - I think its better to try resolve that problem on it's own.