diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index 458bbc8400cc017b0946dd9f484971e07c31c253..a391881b3b69374f5af744abe94b547bd2d889f3 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -187,6 +187,7 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
 {
 	//fprintf(stderr,"scalar_getrect %d\n", array_joc);
     t_scalar *x = (t_scalar *)z;
+
     t_template *template = template_findbyname(x->sc_template);
     t_canvas *templatecanvas = template_findcanvas(template);
     int x1 = 0x7fffffff, x2 = -0x7fffffff, y1 = 0x7fffffff, y2 = -0x7fffffff;
@@ -214,6 +215,15 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
         }
         else
         {
+            /* todo: bad flow with internal return here. make it cleaner */
+            if (x->sc_bboxcache)
+            {
+                *xp1 = x->sc_x1;
+                *yp1 = x->sc_y1;
+                *xp2 = x->sc_x2;
+                *yp2 = x->sc_y2;
+                return;
+            }
             x1 = y1 = 0x7fffffff;
             x2 = y2 = -0x7fffffff;
             for (y = templatecanvas->gl_list; y; y = y->g_next)
@@ -235,10 +245,11 @@ static void scalar_getrect(t_gobj *z, t_glist *owner,
         }
     }
     //fprintf(stderr,"FINAL scalar_getrect x1 %d y1 %d x2 %d y2 %d\n", x1, y1, x2, y2);
-    *xp1 = x1;
-    *yp1 = y1;
-    *xp2 = x2;
-    *yp2 = y2; 
+    *xp1 = x->sc_x1 = x1;
+    *yp1 = x->sc_y1 = y1;
+    *xp2 = x->sc_x2 = x2;
+    *yp2 = x->sc_y2 = y2; 
+    x->sc_bboxcache = 1;
 }
 
 void scalar_drawselectrect(t_scalar *x, t_glist *glist, int state)
@@ -416,11 +427,19 @@ static void scalar_displace_withtag(t_gobj *z, t_glist *glist, int dx, int dy)
     if ((goty && (ytype != DT_FLOAT)) || select_owner != glist)
         goty = 0;
     if (gotx)
+    {
         *(t_float *)(((char *)(x->sc_vec)) + xonset) +=
             dx * (glist_pixelstox(glist, 1) - glist_pixelstox(glist, 0));
+        x->sc_x1 += dx;
+        x->sc_x2 += dx;
+    }
     if (goty)
+    {
         *(t_float *)(((char *)(x->sc_vec)) + yonset) +=
             dy * (glist_pixelstoy(glist, 1) - glist_pixelstoy(glist, 0));
+        x->sc_y1 += dy;
+        x->sc_y2 += dy;
+    }
     scalar_getbasexy(x, &basex, &basey);
     gpointer_init(&gp);
     gpointer_setglist(&gp, glist, x);
@@ -473,6 +492,9 @@ static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
 {
 	//fprintf(stderr,"scalar_vis %d\n", vis);
     t_scalar *x = (t_scalar *)z;
+
+    x->sc_bboxcache = 0;
+
     t_template *template = template_findbyname(x->sc_template);
     t_canvas *templatecanvas = template_findcanvas(template);
     t_gobj *y;
@@ -517,6 +539,7 @@ static void scalar_vis(t_gobj *z, t_glist *owner, int vis)
     if (!vis)
         sys_vgui(".x%lx.c delete .scalar%lx\n", glist_getcanvas(owner), x->sc_vec);
 
+
     sys_unqueuegui(x);
     if (glist_isselected(owner, &x->sc_gobj))
     {
diff --git a/pd/src/g_template.c b/pd/src/g_template.c
index 9766ce71e1e8b0f7edad2c2b9fa62b495a5d611a..cb5388b9fb3ed832b39f46113bfa10754c98d8d2 100644
--- a/pd/src/g_template.c
+++ b/pd/src/g_template.c
@@ -1735,22 +1735,26 @@ void draw_doupdatetransform(t_draw *x, t_canvas *c)
             t_float m1, m2, m3, m4, m5, m6;
             draw_parsetransform(x, template, ((t_scalar *)g)->sc_vec,
                 &m1, &m2, &m3, &m4, &m5, &m6);
-        t_canvas *visible = c;
-        while(visible->gl_isgraph && visible->gl_owner)
-            visible = visible->gl_owner;
-        if (x->x_drawtype == gensym("group"))
-            sys_vgui(".x%lx.c itemconfigure .dgroup%lx -matrix { {%g %g} {%g %g} {%g %g} }\n",
-                visible, ((t_scalar *)g)->sc_vec, m1, m2, m3, m4, m5, m6);
-        else
-            sys_vgui(".x%lx.c itemconfigure .draw%lx.%lx -matrix { {%g %g} {%g %g} {%g %g} }\n",
-                visible, x, ((t_scalar*)g)->sc_vec,
-                m1, m2, m3, m4, m5, m6);
-        }
-        if (glist_isselected(c, &((t_scalar *)g)->sc_gobj))
-        {
-            scalar_select(g, c, 1);
-            scalar_drawselectrect((t_scalar *)g, c, 0);
-            scalar_drawselectrect((t_scalar *)g, c, 1);
+            t_canvas *visible = c;
+            while(visible->gl_isgraph && visible->gl_owner)
+                visible = visible->gl_owner;
+            if (x->x_drawtype == gensym("group"))
+                sys_vgui(".x%lx.c itemconfigure .dgroup%lx -matrix "
+                    "{ {%g %g} {%g %g} {%g %g} }\n",
+                    visible, ((t_scalar *)g)->sc_vec, m1, m2, m3, m4, m5, m6);
+            else
+                sys_vgui(".x%lx.c itemconfigure .draw%lx.%lx -matrix "
+                    "{ {%g %g} {%g %g} {%g %g} }\n",
+                    visible, x, ((t_scalar*)g)->sc_vec,
+                    m1, m2, m3, m4, m5, m6);
+            /* uncache the scalar's bbox */
+            ((t_scalar *)g)->sc_bboxcache = 0;
+            if (glist_isselected(c, &((t_scalar *)g)->sc_gobj))
+            {
+                scalar_select(g, c, 1);
+                scalar_drawselectrect((t_scalar *)g, c, 0);
+                scalar_drawselectrect((t_scalar *)g, c, 1);
+            }
         }
         if (g->g_pd == canvas_class)
             draw_doupdatetransform(x, (t_glist *)g);
diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h
index c6131db151b7109695b2b484f24cadb409a80ee7..ed4c9e0049158bf541736531176dafa0b760b9c3 100644
--- a/pd/src/m_pd.h
+++ b/pd/src/m_pd.h
@@ -190,6 +190,11 @@ typedef struct _scalar      /* a graphical object holding data */
 {
     t_gobj sc_gobj;         /* header for graphical object */
     t_symbol *sc_template;  /* template name (LATER replace with pointer) */
+    int sc_x1;
+    int sc_x2;
+    int sc_y1;
+    int sc_y2;
+    int sc_bboxcache;
     t_word sc_vec[1];       /* indeterminate-length array of words */
 } t_scalar;