diff --git a/pd/nw/dialog_canvas.html b/pd/nw/dialog_canvas.html
index d6d80cad1e6de989c9214adb2eeef304567e8e4b..0fdbf8dc2b536c62507acbfa40fa0f4573efd98a 100644
--- a/pd/nw/dialog_canvas.html
+++ b/pd/nw/dialog_canvas.html
@@ -13,12 +13,28 @@
         <legend data-i18n="canvas.prop.heading.gop"></legend> 
 
         <table class="pairs">
-          <tr class="display_flags prop hidden" data-i18n="[title]canvas.prop.gop_tt">
-            <td>
-              <input type="checkbox" name="gop" value="on">
+          <tr class="prop no_scroll hidden" data-i18n="[title]canvas.prop.no_scroll_tt">
+            <td colspan="2">
+              <label>
+                <input type="checkbox" name="no_scroll" value="off">
+                <span data-i18n="canvas.prop.no_scroll"></span>
+              </label>
             </td>
-            <td>
-              <span id="gop_label" data-i18n="canvas.prop.gop"></span>
+          </tr>
+          <tr class="prop no_menu hidden" data-i18n="[title]canvas.prop.no_menu_tt">
+            <td colspan="2">
+              <label>
+                <input type="checkbox" name="no_menu" value="off">
+                <span data-i18n="canvas.prop.no_menu"></span>
+              </label>
+            </td>
+          </tr>
+          <tr class="display_flags prop hidden" data-i18n="[title]canvas.prop.gop_tt">
+            <td colspan="2">
+              <label>
+                <input type="checkbox" name="gop" value="on">
+                <span data-i18n="canvas.prop.gop"></span>
+              </label>
             </td>
           </tr>
           <tr class="x_pix prop hidden">
@@ -443,11 +459,6 @@ arrays_select.addEventListener("change", function(evt) {
     array_choose(evt.target.value);
 });
 
-var gop_label = document.getElementById("gop_label");
-gop_label.addEventListener("click", function() {
-    document.getElementsByName("gop")[0].click();
-});
-
 var gop_button = document.getElementsByName("gop")[0];
 gop_button.addEventListener("click", function(evt) {
     set_gop(this.checked);
@@ -510,8 +521,8 @@ function substitute_space(arg) {
 }
 
 function get_input(name) {
-    var val = document.getElementsByName(name)[0].value;
-    return val;
+    var elem = document.getElementsByName(name)[0];
+    return (elem.type === "checkbox") ? elem.checked : elem.value;
 }
 
 // get a value from the garray attr array
@@ -540,12 +551,12 @@ function get_array_slot_4(attrs) {
 
 function apply() {
     var gop, hide_name, slot_4;
-    // If this is a dialog to create a new array, we
+    // If this is a dialog to create a new array
     // skip the canvas dialog callback
     if (!new_array_dialog) {
         // Note: the "+" casts Boolean to Number
-        gop = +document.getElementsByName("gop")[0].checked;
-        hide_name = +document.getElementsByName("hide_name")[0].checked;
+        gop = +get_input("gop");
+        hide_name = +get_input("hide_name");
 
         pdgui.pdsend(pd_object_callback, "donecanvasdialog",
             +get_input("x_scale"),
@@ -558,7 +569,9 @@ function apply() {
             +get_input("x_pix"),
             +get_input("y_pix"),
             +get_input("x_margin"),
-            +get_input("y_margin")
+            +get_input("y_margin"),
+            +get_input("no_scroll"),
+            +get_input("no_menu")
         );
     }
 
@@ -760,6 +773,11 @@ function populate_form(attr_object) {
         // X/Y scaling-- garray is always in a gop so not needed
         document.getElementsByClassName("x_scale")[0]
             .classList.add("hidden");
+        // scrollbars and menu
+        document.getElementsByClassName("no_scroll")[0]
+            .classList.add("hidden");
+         document.getElementsByClassName("no_menu")[0]
+            .classList.add("hidden");
     }
 }
 
diff --git a/pd/nw/locales/en/translation.json b/pd/nw/locales/en/translation.json
index 62814d604e999a6cd6b29ab3bbeee948bd2d7e42..979a0dad38da431bba2b1dc46cdc6770a717f36b 100644
--- a/pd/nw/locales/en/translation.json
+++ b/pd/nw/locales/en/translation.json
@@ -306,6 +306,10 @@
         "viewbox_offsets": "viewbox offsets",
         "arrays": "array options"
       },
+      "no_scroll": "hide scrollbars",
+      "no_scroll_tt": "hide window scrollbars",
+      "no_menu": "hide menu",
+      "no_menu_tt": "hide window menu",
       "gop": "graph on parent",
       "gop_tt": "show the inner contents of this canvas in a rectangle on the containing canvas",
       "hide_name": "hide name and arguments",
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 277517292080a69f0968f771ebee453e4fe5a040..d4ed129192c2543d228700adc1034d3b7289db45 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -1366,7 +1366,7 @@ function create_window(cid, type, width, height, xpos, ypos, attr_array) {
 }
 
 // create a new canvas
-function gui_canvas_new(cid, width, height, geometry, zoom, editmode, name, dir, dirty_flag, cargs) {
+function gui_canvas_new(cid, width, height, geometry, zoom, editmode, name, dir, dirty_flag, hide_scroll, hide_menu, cargs) {
     // hack for buggy tcl popups... should go away for node-webkit
     //reset_ctrl_on_popup_window
 
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index fb50bb6c253d2585e58295a619cf219b8b14c013..14ad4af98b965b00e257abd8baa71948665f6b28 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -742,6 +742,18 @@ void canvas_scalar_event(t_canvas *x, t_symbol *s, int argc, t_atom *argv)
         draw_notify(x, s, argc, argv);
 }
 
+void canvas_show_scrollbars(t_canvas *x, t_floatarg f)
+{
+post("setting noscroll to %d", f);
+    x->gl_noscroll = (int)f;
+}
+
+void canvas_show_menu(t_canvas *x, t_floatarg f)
+{
+post("setting nomenu to %d", f);
+    x->gl_nomenu = (int)f;
+}
+
 extern void canvas_check_nlet_highlights(t_canvas *x);
 
 /*********** dpsaha@vt.edu resize move hooks ****************/
@@ -2579,6 +2591,10 @@ void g_canvas_setup(void)
 
     class_addmethod(canvas_class, (t_method)canvas_scalar_event,
         gensym("scalar_event"), A_GIMME, 0);
+    class_addmethod(canvas_class, (t_method)canvas_show_scrollbars,
+        gensym("scroll"), A_FLOAT, 0);
+    class_addmethod(canvas_class, (t_method)canvas_show_menu,
+        gensym("menu"), A_FLOAT, 0);
 
 /* ---------------------- list handling ------------------------ */
     class_addmethod(canvas_class, (t_method)glist_clear, gensym("clear"),
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index 231b84c47afbc876d8380be85a095dccd085cf64..1e58518892b925f04031bedcdfdb2d2a333185d4 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -217,6 +217,8 @@ struct _glist
     unsigned int gl_private:1;      /* private flag used in x_scalar.c */
     unsigned int gl_isclone:1;      /* exists as part of a clone object */
     unsigned int gl_gop_initialized:1;     /* used for tagged moving of gop-ed objects to avoid redundant reinit */
+    unsigned int gl_noscroll:1;     /* don't show window scrollbars */
+    unsigned int gl_nomenu:1;       /* don't show the window menu */
     //global preset array pointer
     t_preset_hub *gl_phub;
     //infinite undo goodies (have to stay here rather than the editor to prevent its obliteration when editor is deleted)
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index 6674690471e76b485bf3183acb01b0a696015ee2..61e9c6330196f26849b9c4b319fdf63e66460fe6 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -2471,7 +2471,7 @@ void canvas_vis(t_canvas *x, t_floatarg f)
             //fprintf(stderr,"new\n");
             canvas_create_editor(x);
             canvas_args_to_string(argsbuf, x);
-            gui_vmess("gui_canvas_new", "xiisiissis",
+            gui_vmess("gui_canvas_new", "xiisiissiiis",
                 x,
                 (int)(x->gl_screenx2 - x->gl_screenx1),
                 (int)(x->gl_screeny2 - x->gl_screeny1),
@@ -2481,6 +2481,8 @@ void canvas_vis(t_canvas *x, t_floatarg f)
                 x->gl_name->s_name,
                 canvas_getdir(x)->s_name,
                 x->gl_dirty,
+                x->gl_noscroll,
+                x->gl_nomenu,
                 argsbuf);
 
             /* It looks like this font size call is no longer needed,
@@ -2684,6 +2686,8 @@ void canvas_properties(t_glist *x)
         gui_s("y_pix");    gui_i((int)x->gl_pixheight);
         gui_s("x_margin"); gui_i((int)x->gl_xmargin);
         gui_s("y_margin"); gui_i((int)x->gl_ymargin);
+        gui_s("no_scroll");   gui_i(x->gl_noscroll);
+        gui_s("no_menu");     gui_i(x->gl_nomenu);
     }
     else
     {
@@ -2705,6 +2709,8 @@ void canvas_properties(t_glist *x)
         gui_s("y_pix");    gui_i((int)x->gl_pixheight);
         gui_s("x_margin"); gui_i((int)x->gl_xmargin);
         gui_s("y_margin"); gui_i((int)x->gl_ymargin);
+        gui_s("no_scroll");   gui_i(x->gl_noscroll);
+        gui_s("no_menu");     gui_i(x->gl_nomenu);
     }
     //gfxstub_new(&x->gl_pd, x, graphbuf);
 
@@ -2761,6 +2767,9 @@ static void canvas_donecanvasdialog(t_glist *x,
     xmargin = atom_getfloatarg(9, argc, argv);
     ymargin = atom_getfloatarg(10, argc, argv);
 
+    x->gl_noscroll = atom_getintarg(11, argc, argv);
+    x->gl_nomenu = atom_getintarg(12, argc, argv);
+
     /* parent windows are treated differently than applies to
        individual objects */
     if (glist_getcanvas(x) != x && !canvas_isabstraction(x))
diff --git a/pd/src/g_readwrite.c b/pd/src/g_readwrite.c
index ca888857e0a204e9d226633a555e206f7fe1187d..56b2e071d4ec497ac099632a07706c74fe5a7b3c 100644
--- a/pd/src/g_readwrite.c
+++ b/pd/src/g_readwrite.c
@@ -779,6 +779,13 @@ static void canvas_saveto(t_canvas *x, t_binbuf *b)
                 (t_float)x->gl_pixwidth, (t_float)x->gl_pixheight,
                 (t_float)x->gl_isgraph);
     }
+        /* save a message if scrollbars are disabled-- otherwise do nothing
+           for the sake of backwards compatibility. */
+    if (x->gl_noscroll)
+        binbuf_addv(b, "ssi;", gensym("#X"), gensym("scroll"), x->gl_noscroll);
+        /* same for menu */
+    if (x->gl_nomenu)
+        binbuf_addv(b, "ssi;", gensym("#X"), gensym("menu"), x->gl_nomenu);
 }
 
 /* yuck, wish I didn't have to do this... */