Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-03-11 16:34:23 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-03-11 16:40:52 +0300
commit2cc5af9c553cfc00b7d4616445ad954597a92d94 (patch)
treeccc0fa74bd5df7ed9d20867832997f1b8d6c82f3 /source/blender/windowmanager
parent2cdebf293d4cf925e1cdaf5c4a247b8886c1026e (diff)
Fix T86431: Keep memory location of the window manager on file load
Keep the pointer location from the initial window-manager between file load operations. This is needed as the Python API may hold references to keymaps for e.g. which are transferred to the newly loaded window manager, without their `PointerRNA.owner_id` fields being updated. Since there is only ever one window manager, keep the memory at the same location so the Python ID pointers stay valid. Reviewed By: mont29 Ref D10690
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r--source/blender/windowmanager/intern/wm_files.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 2d1342da2fb..bd220e2ff95 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -81,6 +81,7 @@
#include "BKE_idprop.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
+#include "BKE_lib_remap.h"
#include "BKE_main.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
@@ -296,6 +297,29 @@ static void wm_window_match_replace_by_file_wm(bContext *C,
{
wmWindowManager *oldwm = current_wm_list->first;
wmWindowManager *wm = readfile_wm_list->first; /* will become our new WM */
+
+ /* Support window-manager ID references being held between file load operations by keeping
+ * #Main.wm.first memory address in-place, while swapping all of it's contents.
+ *
+ * This is needed so items such as key-maps can be held by an add-on,
+ * without it pointing to invalid memory, see: T86431 */
+ {
+ /* Referencing the window-manager pointer from elsewhere in the file is highly unlikely
+ * however it's possible with ID-properties & animation-drivers.
+ * At some point we could check on disallowing this since it doesn't seem practical. */
+ Main *bmain = G_MAIN;
+ BLI_assert(bmain->relations == NULL);
+ BKE_libblock_remap(bmain, wm, oldwm, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_USER_CLEAR);
+
+ /* Simple pointer swapping step. */
+ BLI_remlink(current_wm_list, oldwm);
+ BLI_remlink(readfile_wm_list, wm);
+ SWAP(wmWindowManager, *oldwm, *wm);
+ SWAP(wmWindowManager *, oldwm, wm);
+ BLI_addhead(current_wm_list, oldwm);
+ BLI_addhead(readfile_wm_list, wm);
+ }
+
bool has_match = false;
/* this code could move to setup_appdata */