diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 5be087848d076ed88e4adaa3f88b9769c2ceef43..16f09fd3307a6e1d59cd1628eb81c310293682ee 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -2376,9 +2376,12 @@ function gui_text_set (cid, tag, text) {
 }
 
 function gui_text_redraw_border(cid, tag, x1, y1, x2, y2) {
-    var g = get_gobj(cid, tag),
-        b = g.querySelectorAll(".border"),
-        i;
+    var g, b, i;
+    if (!patchwin[cid]) {
+        return;
+    }
+    g = get_gobj(cid, tag);
+    b = g.querySelectorAll(".border");
     for (i = 0; i < b.length; b++) {
         configure_item(b[i], {
             width: x2 - x1,
@@ -4039,23 +4042,31 @@ function gui_grid_point(cid, tag, x, y) {
 
 // mknob from moonlib
 function gui_mknob_new(cid, tag, x, y, is_toplevel, show_in, show_out) {
-    var g = gui_gobj_new(cid, tag, "obj", x, y, is_toplevel),
+    var g, border, circle, line;
+    if (!patchwin[cid]) {
+        return;
+    }
+    g = gui_gobj_new(cid, tag, "obj", x, y, is_toplevel),
         border = create_item(cid, "path", {
             class: "border" // now we can inherit the css border styles
-        }),
-        circle = create_item(cid, "circle", {
-            class: "circle"
-        }),
-        line = create_item(cid, "line", {
-            class: "dial"
-        });
+    });
+    circle = create_item(cid, "circle", {
+       class: "circle"
+    });
+    line = create_item(cid, "line", {
+        class: "dial"
+    });
     g.appendChild(border);
     g.appendChild(circle);
     g.appendChild(line);
 }
 
 function gui_configure_mknob(cid, tag, size, bg_color, fg_color) {
-    var g = get_gobj(cid, tag);
+    var g;
+    if (!patchwin[cid]) {
+        return;
+    }
+    g = get_gobj(cid, tag);
     configure_item(g.querySelector(".border"), {
         d: ["M", 0, 0, size, 0,
             "M", 0, size, size, size,
diff --git a/pd/src/g_all_guis.c b/pd/src/g_all_guis.c
index 84748f1d840e1117d563ae93816de0f3d599488c..4c0c6591b97c9bd00a98c0bf7c064edbcebda05b 100644
--- a/pd/src/g_all_guis.c
+++ b/pd/src/g_all_guis.c
@@ -231,19 +231,15 @@ void iemgui_receive(t_iemgui *x, t_symbol *s)
 
 void iemgui_label(t_iemgui *x, t_symbol *s)
 {
+    t_symbol *old;
     if (s == &s_) s = s_empty; //tb: fix for empty label
+    old = x->x_lab;
     t_symbol *lab = iemgui_raute2dollar(s);
     x->x_lab_unexpanded = lab;
     x->x_lab = lab = canvas_realizedollar(x->x_glist, lab);
 
-    if(glist_isvisible(x->x_glist))
-    {
-        gui_vmess("gui_iemgui_label_set", "xxs",
-            glist_getcanvas(x->x_glist),
-            x,
-            s != s_empty ? x->x_lab->s_name : "");
+    if (glist_isvisible(x->x_glist) && lab != old)
         iemgui_shouldvis(x, IEM_GUI_DRAW_MODE_CONFIG);
-    }
 }
 
 void iemgui_label_pos(t_iemgui *x, t_symbol *s, int ac, t_atom *av)
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index 736a9dbd9e460f746515548b285c1fee1ea94dde..1e5d057b6c7839c3837e39de8e62cedd7be2e190 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -745,12 +745,12 @@ void canvas_scalar_event(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
 void canvas_show_scrollbars(t_canvas *x, t_floatarg f)
 {
     x->gl_noscroll = (int)f;
-    gui_vmess("gui_canvas_set_scrollbars", "xi", x, (int)f);
+    if (x->gl_mapped)
+        gui_vmess("gui_canvas_set_scrollbars", "xi", x, (int)f);
 }
 
 void canvas_show_menu(t_canvas *x, t_floatarg f)
 {
-post("setting nomenu to %d", f);
     x->gl_nomenu = (int)f;
 }
 
@@ -826,28 +826,29 @@ void canvas_map(t_canvas *x, t_floatarg f)
     t_gobj *y;
     if (flag)
     {
-        t_selection *sel;
-        if (!x->gl_havewindow)
-        {
-            bug("canvas_map");
-            canvas_vis(x, 1);
-        }
-
-        if (!x->gl_list) {
-            //if there are no objects on the canvas
-            canvas_create_editor(x);
-        }
-        else for (y = x->gl_list; y; y = y->g_next) {
-            gobj_vis(y, x, 1);
+        if (!glist_isvisible(x)) {
+            t_selection *sel;
+            if (!x->gl_havewindow)
+            {
+                bug("canvas_map");
+                canvas_vis(x, 1);
+            }
+            if (!x->gl_list) {
+                //if there are no objects on the canvas
+                canvas_create_editor(x);
+            }
+            else for (y = x->gl_list; y; y = y->g_next) {
+                gobj_vis(y, x, 1);
+            }
+            if (x->gl_editor && x->gl_editor->e_selection)
+                for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
+                    gobj_select(sel->sel_what, x, 1);
+            x->gl_mapped = 1;
+            canvas_drawlines(x);
+            if (x->gl_isgraph && x->gl_goprect)
+                canvas_drawredrect(x, 1);
+            scrollbar_update(x);
         }
-        if (x->gl_editor && x->gl_editor->e_selection)
-            for (sel = x->gl_editor->e_selection; sel; sel = sel->sel_next)
-                gobj_select(sel->sel_what, x, 1);
-        x->gl_mapped = 1;
-        canvas_drawlines(x);
-        if (x->gl_isgraph && x->gl_goprect)
-            canvas_drawredrect(x, 1);
-        scrollbar_update(x);
     }
     else
     {
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index abea628172d14a05e7690a1065069106540dd0da..2817d1774700e3e04691c88ec96338c07d8cfe83 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -220,6 +220,13 @@ int gobj_shouldvis(t_gobj *x, struct _glist *glist)
     //fprintf(stderr,"shouldvis %d %d %d %d\n",
     //    glist->gl_havewindow, glist->gl_isgraph,
     //    glist->gl_goprect, glist->gl_owner != NULL);
+        /* if our parent is a graph, and if that graph itself isn't
+        visible, then we aren't either. */
+    if (!glist->gl_havewindow && glist->gl_isgraph && glist->gl_owner
+        && !gobj_shouldvis(&glist->gl_gobj, glist->gl_owner))
+            return (0);
+        /* if we're graphing-on-parent and the object falls outside the
+        graph rectangle, don't draw it. */
     if (!glist->gl_havewindow && glist->gl_isgraph && glist->gl_goprect &&
         glist->gl_owner && (pd_class(&x->g_pd) != scalar_class) &&
         (pd_class(&x->g_pd) != garray_class))
@@ -1329,6 +1336,14 @@ static void glist_doreload(t_glist *gl, t_symbol *name, t_symbol *dir,
                 do g = g->g_next in this case. */
             //int j = glist_getindex(gl, g);
             //fprintf(stderr, "rebuildlicious %d\n", j);
+
+            // Bugfix for cases where canvas_vis doesn't actually create a
+            // new editor. We need to fix canvas_vis so that the bug doesn't
+            // get triggered. But since we know this fixes a regression we'll
+            // keep this as a point in the history as we fix canvas_vis. Once
+            // that's done we can remove this call.
+            canvas_create_editor(gl);
+
             if (!gl->gl_havewindow)
             {
                 canvas_vis(glist_getcanvas(gl), 1);
@@ -1380,7 +1395,7 @@ static void glist_doreload(t_glist *gl, t_symbol *name, t_symbol *dir,
     them to reload an abstraction; also suppress window list update */
 int glist_amreloadingabstractions = 0;
 
-    /* call canvas_doreload on everyone */
+    /* call glist_doreload on everyone */
 void canvas_reload(t_symbol *name, t_symbol *dir, t_gobj *except)
 {
     t_canvas *x;
@@ -2880,7 +2895,7 @@ static void canvas_donecanvasdialog(t_glist *x,
     {
         glist_noselect(x);
         gobj_vis(&x->gl_gobj, x->gl_owner, 0);
-        if (gobj_shouldvis(&x->gl_obj, x->gl_owner))
+        if (gobj_shouldvis(&x->gl_gobj, x->gl_owner))
         {
             gobj_vis(&x->gl_gobj, x->gl_owner, 1);
             //fprintf(stderr,"yes\n");
diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c
index 0f39f37d07543925858fd9ce498b3940a319ff70..24d2a2714221374129481b9820135f5cf0e67e78 100644
--- a/pd/src/g_graph.c
+++ b/pd/src/g_graph.c
@@ -311,11 +311,11 @@ void glist_grab(t_glist *x, t_gobj *y, t_glistmotionfn motionfn,
 t_canvas *glist_getcanvas(t_glist *x)
 {
     //fprintf(stderr,"glist_getcanvas\n");
-    while (x->gl_owner && !x->gl_havewindow && x->gl_isgraph &&
-        gobj_shouldvis(&x->gl_gobj, x->gl_owner))
+    while (x->gl_owner && !x->gl_havewindow && x->gl_isgraph)
     {
-            //fprintf(stderr,"x=%lx x->gl_owner=%d x->gl_havewindow=%d x->gl_isgraph=%d gobj_shouldvis=%d\n", 
-            //    x, (x->gl_owner ? 1:0), x->gl_havewindow, x->gl_isgraph, 
+            //fprintf(stderr,"x=%lx x->gl_owner=%d x->gl_havewindow=%d "
+            //               "x->gl_isgraph=%d gobj_shouldvis=%d\n", 
+            //    x, (x->gl_owner ? 1:0), x->gl_havewindow, x->gl_isgraph,
             //    gobj_shouldvis(&x->gl_gobj, x->gl_owner));
             x = x->gl_owner;
             //fprintf(stderr,"+\n");
@@ -1244,7 +1244,6 @@ static void graph_getrect(t_gobj *z, t_glist *glist,
         int hadwindow;
         t_gobj *g;
         int x21, y21, x22, y22;
-
         graph_graphrect(z, glist, &x1, &y1, &x2, &y2);
         //fprintf(stderr,"%d %d %d %d\n", x1, y1, x2, y2);
 
@@ -1435,7 +1434,7 @@ static void graph_select(t_gobj *z, t_glist *glist, int state)
         }
         if (glist_isvisible(glist) &&
                 (glist_istoplevel(glist) ||
-                 gobj_shouldvis(x, glist)))
+                 gobj_shouldvis(z, glist)))
         {
             if (state)
                 gui_vmess("gui_gobj_select", "xs",
diff --git a/pd/src/g_mycanvas.c b/pd/src/g_mycanvas.c
index fc5ee264a3fd8be5777121d395666f78b86c68d7..a5977ada5ff1c3f175370cb5b3c45a427084ae7a 100644
--- a/pd/src/g_mycanvas.c
+++ b/pd/src/g_mycanvas.c
@@ -28,7 +28,7 @@ void my_canvas_draw_new(t_my_canvas *x, t_glist *glist)
     sprintf(cbuf, "#%6.6x", x->x_gui.x_bcol);
 
     gui_vmess("gui_gobj_new", "xxsiii", canvas,
-        x, "iemgui", x1, y1, glist_istoplevel(canvas));
+        x, "iemgui", x1, y1, glist_istoplevel(glist));
     gui_vmess("gui_mycanvas_new", "xxsiiiiii", canvas,
         x, cbuf, x1, y1, x1+x->x_vis_w, y1+x->x_vis_h,
         x1+x->x_gui.x_w, y1+x->x_gui.x_h);
diff --git a/pd/src/g_readwrite.c b/pd/src/g_readwrite.c
index 92b5bd7d5cb669d382a0ca847b86257b1976f1a0..a3affb88f8ac10b4cd97e6e523a18e420c7387e3 100644
--- a/pd/src/g_readwrite.c
+++ b/pd/src/g_readwrite.c
@@ -402,6 +402,8 @@ void canvas_doaddtemplate(t_symbol *templatesym,
 
 static void glist_writelist(t_gobj *y, t_binbuf *b);
 
+void binbuf_savetext(t_binbuf *bfrom, t_binbuf *bto);
+
 void canvas_writescalar(t_symbol *templatesym, t_word *w, t_binbuf *b,
     int amarrayelement)
 {
diff --git a/pd/src/s_loader.c b/pd/src/s_loader.c
index a3b7fa4540d98e429a5b92fb66b234709279afd0..7039aa4b9a5f8509f3ac8e2fd4cf647dbe9b87aa 100644
--- a/pd/src/s_loader.c
+++ b/pd/src/s_loader.c
@@ -462,7 +462,7 @@ static t_pd *do_create_abstraction(t_symbol*s, int argc, t_atom *argv)
         const char *objectname = s->s_name;
         char dirbuf[MAXPDSTRING], classslashclass[MAXPDSTRING], *nameptr;
         t_glist *glist = (t_glist *)canvas_getcurrent();
-        t_canvas *canvas = (t_canvas*)glist_getcanvas(glist);
+        t_canvas *canvas = (t_canvas*)canvas_getrootfor(glist);
         int fd = -1;
 
         t_pd *was = s__X.s_thing;