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
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c28
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c5
-rw-r--r--source/blender/windowmanager/wm.h3
3 files changed, 33 insertions, 3 deletions
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 7608b015f49..4fcbff6bf98 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -434,6 +434,30 @@ static void wait_for_console_key(void)
}
#endif
+static int wm_exit_handler(bContext *C, const wmEvent *event, void *userdata)
+{
+ WM_exit(C);
+
+ UNUSED_VARS(event, userdata);
+ return WM_UI_HANDLER_BREAK;
+}
+
+/**
+ * Cause a delayed WM_exit() call to avoid leaking memory when trying to exit from within operators.
+ */
+void wm_exit_schedule_delayed(const bContext *C)
+{
+ /* What we do here is a little bit hacky, but quite simple and doesn't require bigger
+ * changes: Add a handler wrapping WM_exit() to cause a delayed call of it. */
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ /* Doesn't matter which window we use. */
+ wmWindow *win = wm->windows.first;
+
+ /* Use modal UI handler for now. Could add separate WM handlers or so, but probably not worth it. */
+ WM_event_add_ui_handler(C, &win->modalhandlers, wm_exit_handler, NULL, NULL, 0);
+}
+
/**
* \note doesn't run exit() call #WM_exit() for that.
*/
@@ -604,6 +628,10 @@ void WM_exit_ext(bContext *C, const bool do_python)
BKE_tempdir_session_purge();
}
+/**
+ * \brief Main exit function to close Blender ordinarily.
+ * \note Use #wm_exit_schedule_delayed() to close Blender from an operator. Might leak memory otherwise.
+ */
void WM_exit(bContext *C)
{
WM_exit_ext(C, 1);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index 363b8e61763..bf2f00e9460 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -2160,7 +2160,7 @@ static void WM_OT_window_fullscreen_toggle(wmOperatorType *ot)
ot->poll = WM_operator_winactive;
}
-static int wm_exit_blender_exec(bContext *C, wmOperator *op)
+static int wm_exit_blender_exec(bContext *C, wmOperator *UNUSED(op))
{
wmWindowManager *wm = CTX_wm_manager(C);
@@ -2168,8 +2168,7 @@ static int wm_exit_blender_exec(bContext *C, wmOperator *op)
wm_confirm_quit(C);
}
else {
- WM_operator_free(op);
- WM_exit(C);
+ wm_exit_schedule_delayed(C);
}
return OPERATOR_FINISHED;
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index a417a719b8d..5ced36a104f 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -43,6 +43,9 @@ typedef struct wmPaintCursor {
void (*draw)(bContext *C, int, int, void *customdata);
} wmPaintCursor;
+
+void wm_exit_schedule_delayed(const bContext *C);
+
extern void wm_close_and_free(bContext *C, wmWindowManager *);
extern void wm_close_and_free_all(bContext *C, ListBase *);