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:
-rw-r--r--source/blender/blenloader/intern/writefile.c2
-rw-r--r--source/blender/makesdna/DNA_space_types.h5
-rw-r--r--source/blender/python/BPY_extern.h19
-rw-r--r--source/blender/python/api2_2x/Draw.c205
-rw-r--r--source/blender/python/api2_2x/Draw.h8
-rw-r--r--source/blender/src/drawscript.c8
-rw-r--r--source/blender/src/space.c15
7 files changed, 169 insertions, 93 deletions
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index ca63b860f6c..925233b4d77 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1582,6 +1582,8 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "SpaceText", 1, sl);
}
else if(sl->spacetype==SPACE_SCRIPT) {
+ SpaceScript *sc = (SpaceScript*)sl;
+ sc->but_refs = NULL;
writestruct(wd, DATA, "SpaceScript", 1, sl);
}
else if(sl->spacetype==SPACE_ACTION) {
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 65be09caf35..e7839f49cae 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -292,9 +292,10 @@ typedef struct SpaceScript {
struct ScrArea *area;
struct Script *script;
- int pad2;
short flags, menunr;
-
+ int pad1;
+
+ void *but_refs;
} SpaceScript;
typedef struct SpaceTime {
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index 0d466d5af7e..ee7afe7dcf6 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -51,6 +51,25 @@ struct bPythonConstraint; /* DNA_constraint_types.h */
extern "C" {
#endif
+ /*These two next functions are important for making sure the Draw module
+ works correctly. Before calling any gui callback using the Draw module,
+ the following code must be executed:
+
+ if (some_drawspace_pylist) {
+ BPy_Set_DrawButtonsList(some_drawspace_pylist->but_refs);
+ BPy_Free_DrawButtonsList();
+ }
+ some_drawspace_pylist = PyList_New(0);
+ BPy_Set_DrawButtonsList(some_drawspace_pylist);
+
+ Also, BPy_Free_DrawButtonsList() must be called as necassary when a drawspace
+ with python callbacks is destroyed.
+
+ This is necassary to avoid blender buttons storing invalid pointers to freed
+ python data.*/
+ void BPy_Set_DrawButtonsList(void *list);
+ void BPy_Free_DrawButtonsList(void);
+
void BPY_pyconstraint_eval(struct bPythonConstraint *con, float ownermat[][4], float targetmat[][4]);
void BPY_pyconstraint_settings(void *arg1, void *arg2);
int BPY_pyconstraint_targets(struct bPythonConstraint *con, float targetmat[][4]);
diff --git a/source/blender/python/api2_2x/Draw.c b/source/blender/python/api2_2x/Draw.c
index ea02fd57fe9..db8b6305dc7 100644
--- a/source/blender/python/api2_2x/Draw.c
+++ b/source/blender/python/api2_2x/Draw.c
@@ -134,19 +134,13 @@ static PyObject *Method_Image( PyObject * self, PyObject * args);
/* CLEVER NUMBUT */
static PyObject *Method_PupBlock( PyObject * self, PyObject * args );
-PyObject * pycallback_weakref_dealloc(PyObject *self, PyObject *weakref);
-/* python callable */
-PyObject * pycallback_weakref_dealloc__pyfunc;
-
static uiBlock *Get_uiBlock( void );
+
static void py_slider_update( void *butv, void *data2_unused );
/* hack to get 1 block for the UIBlock, only ever 1 at a time */
static uiBlock *uiblock=NULL;
-/* store weakref's to callbacks here */
-static PyObject *callback_list;
-
static char Draw_doc[] = "The Blender.Draw submodule";
static char Method_UIBlock_doc[] = "(drawfunc, x,y) - Popup dialog where buttons can be drawn (expemental)";
@@ -362,6 +356,12 @@ Warning: On cancel, the value objects are brought back to there previous values,
static char Method_Exit_doc[] = "() - Exit the windowing interface";
+/*This is needed for button callbacks. Any button that uses a callback gets added to this list.
+ On the C side of drawing begin, this list should be cleared.
+ Each entry is a tuple of the form (button, callback py object)
+*/
+PyObject *M_Button_List = NULL;
+
/*
* here we engage in some macro trickery to define the PyMethodDef table
*/
@@ -602,7 +602,13 @@ static PyObject *Button_richcmpr(PyObject *objectA, PyObject *objectB, int compa
static Button *newbutton( void )
{
- return ( Button * ) PyObject_NEW( Button, &Button_Type );
+ Button *but = NULL;
+
+ but = ( Button * ) PyObject_NEW( Button, &Button_Type );
+ but->tooltip[0] = 0; /*NULL-terminate tooltip string*/
+ but->tooltip[255] = 0; /*necassary to insure we always have a NULL-terminated string, as
+ according to the docs strncpy doesn't do this for us.*/
+ return but;
}
/* GUI interface routines */
@@ -623,6 +629,10 @@ static void exit_pydraw( SpaceScript * sc, short err )
scrarea_queue_redraw( sc->area );
}
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList(); /*clear all temp button references*/
+ sc->but_refs = NULL;
+
Py_XDECREF( ( PyObject * ) script->py_draw );
Py_XDECREF( ( PyObject * ) script->py_event );
Py_XDECREF( ( PyObject * ) script->py_button );
@@ -676,6 +686,13 @@ void BPY_spacescript_do_pywin_draw( SpaceScript * sc )
UI_HELV, curarea->win );
if( script->py_draw ) {
+ if (sc->but_refs) {
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList(); /*clear all temp button references*/
+ }
+ sc->but_refs = PyList_New(0);
+ BPy_Set_DrawButtonsList(sc->but_refs);
+
glPushAttrib( GL_ALL_ATTRIB_BITS );
exec_callback( sc, script->py_draw, Py_BuildValue( "()" ) );
glPopAttrib( );
@@ -717,10 +734,7 @@ void BPY_spacescript_do_pywin_event( SpaceScript * sc, unsigned short event,
if (event == UI_BUT_EVENT) {
/* check that event is in free range for script button events;
- * read the comment before check_button_event() below to understand
- *
- * This will never run from UIBlock so no need to check if uiblock==NULL
- * And only sub EXPP_BUTTON_EVENTS_OFFSET in that case */
+ * read the comment before check_button_event() below to understand */
if (val >= EXPP_BUTTON_EVENTS_OFFSET && val < 0x4000)
spacescript_do_pywin_buttons(sc, val - EXPP_BUTTON_EVENTS_OFFSET);
return;
@@ -758,14 +772,6 @@ static void exec_but_callback(void *pyobj, void *data)
if (callback==NULL || callback == Py_None)
return;
- if (callback) {
- if (!PySequence_Contains(callback_list, callback)) {
- printf("Error, the callback is out of scope.\n\tmake the callback global to resolve this.\n");
- return;
- }
- callback = PyWeakref_GetObject(callback);
- }
-
/* Button types support
case MENU:
case TEX:
@@ -832,31 +838,49 @@ static void exec_but_callback(void *pyobj, void *data)
Py_XDECREF( result );
}
-PyObject * pycallback_weakref_dealloc(PyObject *self, PyObject *weakref)
+/*note that this function populates the drawbutton ref lists.*/
+static void set_pycallback(uiBut *ubut, PyObject *callback, Button *but)
{
- int i = PySequence_Index(callback_list, weakref);
- if (i==-1) {
- printf("callback weakref internal error, weakref not in list\n\tthis should never happen.\n");
- return NULL;
+ PyObject *tuple;
+ if (!callback || !PyCallable_Check(callback)) {
+ if (M_Button_List && but) {
+ PyList_Append(M_Button_List, (PyObject*)but);
+ }
+ return;
}
- PySequence_DelItem(callback_list, i);
- Py_RETURN_NONE;
+
+ if (M_Button_List) {
+ if (but) tuple = PyTuple_New(2);
+ else tuple = PyTuple_New(1);
+
+ /*the tuple API mandates this*/
+ Py_XINCREF(callback);
+ Py_XINCREF(but); /*this checks for NULL*/
+
+ PyTuple_SET_ITEM(tuple, 0, callback);
+ if (but) PyTuple_SET_ITEM(tuple, 1, (PyObject*)but);
+
+ PyList_Append(M_Button_List, tuple);
+ Py_DECREF(tuple); /*we have to do this to aovid double references.*/
+
+ uiButSetFunc(ubut, exec_but_callback, callback, ubut);
+ }
+}
+
+void BPy_Set_DrawButtonsList(void *list)
+{
+ M_Button_List = list;
}
-static void set_pycallback(uiBut *ubut, PyObject *callback)
+
+/*this MUST be called after doing UI stuff.*/
+void BPy_Free_DrawButtonsList(void)
{
- PyObject *weakref;
- if (!callback || !PyCallable_Check(callback)) return;
-
- /* This works in most cases except where there are local functions
- * that are deallocated so we must use weakrefs, will complain rather then crashing */
- /*uiButSetFunc(ubut, exec_but_callback, callback, ubut);*/
-
- weakref = PyWeakref_NewRef(callback, pycallback_weakref_dealloc__pyfunc);
- PyList_Append(callback_list, weakref);
- Py_DECREF(weakref);
-
- /*printf("adding weakref, totlength %i\n", PyList_Size(callback_list));*/
- uiButSetFunc(ubut, exec_but_callback, weakref, ubut);
+ /*Clear the list.*/
+ if (M_Button_List) {
+ PyList_SetSlice(M_Button_List, 0, PyList_Size(M_Button_List), NULL);
+ Py_DECREF(M_Button_List);
+ M_Button_List = NULL;
+ }
}
static PyObject *Method_Exit( PyObject * self )
@@ -1047,6 +1071,7 @@ static PyObject *Method_Create( PyObject * self, PyObject * args )
return (PyObject*) but;
}
+
static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
{
PyObject *val = NULL;
@@ -1060,13 +1085,15 @@ static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
if (uiblock)
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"cannot run more then 1 UIBlock at a time" );
+
+ BPy_Set_DrawButtonsList(PyList_New(0));
mywinset(G.curscreen->mainwin);
uiblock= uiNewBlock(&listb, "numbuts", UI_EMBOSS, UI_HELV, G.curscreen->mainwin);
uiBlockSetFlag(uiblock, UI_BLOCK_LOOP|UI_BLOCK_REDRAW);
result = PyObject_CallObject( val, Py_BuildValue( "()" ) );
-
+
if (!result) {
PyErr_Print( );
error( "Python script error: check console" );
@@ -1076,11 +1103,17 @@ static PyObject *Method_UIBlock( PyObject * self, PyObject * args )
}
uiFreeBlocks(&listb);
uiblock = NULL;
+ BPy_Free_DrawButtonsList(); /*clear all temp button references*/
Py_XDECREF( result );
Py_RETURN_NONE;
}
+void Set_uiBlock(uiBlock *block)
+{
+ uiblock = block;
+}
+
static uiBlock *Get_uiBlock( void )
{
char butblock[32];
@@ -1149,7 +1182,7 @@ static PyObject *Method_Button( PyObject * self, PyObject * args )
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefBut( block, BUT, event, name, (short)x, (short)y, (short)w, (short)h, 0, 0, 0, 0, 0, tip );
- set_pycallback(ubut, callback);
+ set_pycallback(ubut, callback, NULL);
}
Py_RETURN_NONE;
}
@@ -1173,12 +1206,13 @@ static PyObject *Method_Menu( PyObject * self, PyObject * args )
but = newbutton( );
but->type = BINT_TYPE;
but->val.asint = def;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefButI( block, MENU, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, 0, 0, 0, 0, tip );
- set_pycallback(ubut, callback);
+ &but->val.asint, 0, 0, 0, 0, but->tooltip );
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
}
@@ -1202,12 +1236,13 @@ static PyObject *Method_Toggle( PyObject * self, PyObject * args )
but = newbutton( );
but->type = BINT_TYPE;
but->val.asint = def;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefButI( block, TOG, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, 0, 0, 0, 0, tip );
- set_pycallback(ubut, callback);
+ &but->val.asint, 0, 0, 0, 0, but->tooltip );
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
}
@@ -1235,12 +1270,12 @@ static void py_slider_update( void *butv, void *data2_unused )
disable_where_script( 1 );
spacescript_do_pywin_buttons( curarea->spacedata.first,
- (unsigned short)uiButGetRetVal( but ) - EXPP_BUTTON_EVENTS_OFFSET);
+ (unsigned short)uiButGetRetVal( but ) - EXPP_BUTTON_EVENTS_OFFSET );
/* XXX useless right now, investigate better before a bcon 5 */
ret = M_Window_Redraw( 0, ref );
- Py_DECREF(ref);
+ Py_XDECREF(ref);
Py_XDECREF(ret);
disable_where_script( 0 );
@@ -1265,10 +1300,10 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args )
"expected a string, five ints, three PyObjects\n\
and optionally int, string and callback arguments" );
- UI_METHOD_ERRORCHECK;
-
if(realtime && uiblock)
realtime = 0; /* realtime dosnt work with UIBlock */
+
+ UI_METHOD_ERRORCHECK;
but = newbutton( );
@@ -1281,17 +1316,18 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args )
but->type = BFLOAT_TYPE;
but->val.asfloat = ini;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
ubut = uiDefButF( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
(short)h, &but->val.asfloat, min, max, 0, 0,
- tip );
+ but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
else
- set_pycallback(ubut, callback);
+ set_pycallback(ubut, callback, but);
}
} else {
int ini, min, max;
@@ -1302,17 +1338,18 @@ static PyObject *Method_Slider( PyObject * self, PyObject * args )
but->type = BINT_TYPE;
but->val.asint = ini;
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
ubut = uiDefButI( block, NUMSLI, event, name, (short)x, (short)y, (short)w,
(short)h, &but->val.asint, (float)min, (float)max, 0, 0,
- tip );
+ but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
else
- set_pycallback(ubut, callback);
+ set_pycallback(ubut, callback, but);
}
}
return ( PyObject * ) but;
@@ -1345,7 +1382,8 @@ another int and string as arguments" );
"button event argument must be in the range [0, 16382]");
but = newbutton( );
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
if( PyFloat_Check( inio ) )
but->type = BFLOAT_TYPE;
else
@@ -1361,13 +1399,13 @@ another int and string as arguments" );
if( but->type == BFLOAT_TYPE ) {
but->val.asfloat = ini;
ubut = uiDefButF( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
- &but->val.asfloat, min, max, 0, 0, tip );
+ &but->val.asfloat, min, max, 0, 0, but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
} else {
but->val.asint = (int)ini;
ubut = uiDefButI( block, SCROLL, event, "", (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, min, max, 0, 0, tip );
+ &but->val.asint, min, max, 0, 0, but->tooltip );
if( realtime )
uiButSetFunc( ubut, py_slider_update, ubut, NULL );
}
@@ -1411,12 +1449,13 @@ static PyObject *Method_ColorPicker( PyObject * self, PyObject * args )
but->val.asvec[0] = col[0];
but->val.asvec[1] = col[1];
but->val.asvec[2] = col[2];
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
- ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, tip);
- set_pycallback(ubut, callback);
+ ubut = uiDefButF( block, COL, event, "", x, y, w, h, but->val.asvec, 0, 0, 0, 0, but->tooltip);
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
@@ -1450,7 +1489,8 @@ static PyObject *Method_Normal( PyObject * self, PyObject * args )
return EXPP_ReturnPyObjError( PyExc_ValueError, USAGE_ERROR);
but = newbutton();
-
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
+
but->type = BVECTOR_TYPE;
but->val.asvec[0] = nor[0];
but->val.asvec[1] = nor[1];
@@ -1459,8 +1499,8 @@ static PyObject *Method_Normal( PyObject * self, PyObject * args )
block = Get_uiBlock( );
if( block ) {
uiBut *ubut;
- ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, tip);
- set_pycallback(ubut, callback);
+ ubut = uiDefButF( block, BUT_NORMAL, event, "", x, y, w, h, but->val.asvec, 0.0f, 1.0f, 0, 0, but->tooltip);
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
@@ -1486,6 +1526,7 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
UI_METHOD_ERRORCHECK;
but = newbutton( );
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
block = Get_uiBlock( );
if( PyFloat_Check( inio ) ) {
@@ -1502,15 +1543,15 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
if (range>=1000.0f) precission=1.0f;
else if (range>=100.0f) precission=2.0f;
else if (range>=10.0f) precission=3.0f;
- else precission=4.0f;
-
+ else precission=4.0f;
+
but->type = BFLOAT_TYPE;
but->val.asfloat = ini;
if( block )
ubut= uiDefButF( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asfloat, min, max, 10*range, precission, tip );
+ &but->val.asfloat, min, max, 10*range, precission, but->tooltip );
} else {
int ini, min, max;
@@ -1523,10 +1564,10 @@ static PyObject *Method_Number( PyObject * self, PyObject * args )
if( block )
ubut= uiDefButI( block, NUM, event, name, (short)x, (short)y, (short)w, (short)h,
- &but->val.asint, (float)min, (float)max, 0, 0, tip );
+ &but->val.asint, (float)min, (float)max, 0, 0, but->tooltip );
}
- if (ubut) set_pycallback(ubut, callback);
+ if (ubut) set_pycallback(ubut, callback, but);
return ( PyObject * ) but;
}
@@ -1555,11 +1596,12 @@ static PyObject *Method_String( PyObject * self, PyObject * args )
real_len = strlen(newstr);
if (real_len > len) real_len = len;
-
+
but = newbutton( );
but->type = BSTRING_TYPE;
but->slen = len;
but->val.asstr = MEM_mallocN( len + 1, "pybutton str" );
+ if (tip) strncpy(but->tooltip, tip, BPY_MAX_TOOLTIP);
BLI_strncpy( but->val.asstr, newstr, len + 1); /* adds '\0' */
but->val.asstr[real_len] = '\0';
@@ -1570,8 +1612,8 @@ static PyObject *Method_String( PyObject * self, PyObject * args )
block = Get_uiBlock( );
if( block ) {
uiBut *ubut = uiDefBut( block, TEX, event, info_str, (short)x, (short)y, (short)w, (short)h,
- but->val.asstr, 0, (float)len, 0, 0, tip );
- set_pycallback(ubut, callback);
+ but->val.asstr, 0, (float)len, 0, 0, but->tooltip );
+ set_pycallback(ubut, callback, but);
}
return ( PyObject * ) but;
}
@@ -2004,26 +2046,17 @@ static PyObject *Method_Image( PyObject * self, PyObject * args )
}
-static PyMethodDef bpycallback_weakref_dealloc[] = {
- {"pycallback_weakref_dealloc", pycallback_weakref_dealloc, METH_O, ""}
-};
-
PyObject *Draw_Init( void )
{
PyObject *submodule, *dict;
-
- /* Weakref management - used for callbacks so we can
- * tell when a callback has been removed that a UI button referenced */
- callback_list = PyList_New(0);
- pycallback_weakref_dealloc__pyfunc = PyCFunction_New(bpycallback_weakref_dealloc, NULL);
-
+
if( PyType_Ready( &Button_Type) < 0)
Py_RETURN_NONE;
submodule = Py_InitModule3( "Blender.Draw", Draw_methods, Draw_doc );
dict = PyModule_GetDict( submodule );
-
+
#define EXPP_ADDCONST(x) \
EXPP_dict_set_item_str(dict, #x, PyInt_FromLong(x))
diff --git a/source/blender/python/api2_2x/Draw.h b/source/blender/python/api2_2x/Draw.h
index 31776500c80..12712713d1d 100644
--- a/source/blender/python/api2_2x/Draw.h
+++ b/source/blender/python/api2_2x/Draw.h
@@ -57,11 +57,13 @@ typedef struct _Button {
char *asstr;
float asvec[3];
} val;
- /*char *tooltip;*/
+ char tooltip[256];
} Button;
-#define BINT_TYPE 1
-#define BFLOAT_TYPE 2
+#define BPY_MAX_TOOLTIP 255
+
+#define BINT_TYPE 1
+#define BFLOAT_TYPE 2
#define BSTRING_TYPE 3
#define BVECTOR_TYPE 4
diff --git a/source/blender/src/drawscript.c b/source/blender/src/drawscript.c
index 024d83950ad..b009c3b8388 100644
--- a/source/blender/src/drawscript.c
+++ b/source/blender/src/drawscript.c
@@ -142,6 +142,12 @@ void winqreadscriptspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *
void free_scriptspace (SpaceScript *sc)
{
if (!sc) return;
-
+
+ /*free buttons references*/
+ if (sc->but_refs) {
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList();
+ sc->but_refs = NULL;
+ }
sc->script = NULL;
}
diff --git a/source/blender/src/space.c b/source/blender/src/space.c
index 8e006111ad9..8c74a0f4694 100644
--- a/source/blender/src/space.c
+++ b/source/blender/src/space.c
@@ -6222,13 +6222,26 @@ SpaceType *spacetext_get_type(void)
return st;
}
+
+static void spacescript_change(ScrArea *sa, void *spacedata)
+{
+ SpaceScript *sc = (SpaceScript*) spacedata;
+
+ /*clear all temp button references*/
+ if (sc->but_refs) {
+ BPy_Set_DrawButtonsList(sc->but_refs);
+ BPy_Free_DrawButtonsList();
+ sc->but_refs = NULL;
+ }
+}
+
SpaceType *spacescript_get_type(void)
{
static SpaceType *st = NULL;
if (!st) {
st = spacetype_new("Script");
- spacetype_set_winfuncs(st, drawscriptspace, NULL, winqreadscriptspace);
+ spacetype_set_winfuncs(st, drawscriptspace, spacescript_change, winqreadscriptspace);
}
return st;