diff --git a/pd/nw/pd_canvas.html b/pd/nw/pd_canvas.html
index e239da5b2090983fd89d28cb18d60c2bd2c567f6..ea60a7f48403c8cf04bfb3afaefb1d654e5316be 100644
--- a/pd/nw/pd_canvas.html
+++ b/pd/nw/pd_canvas.html
@@ -10,7 +10,7 @@
   <input style="display:none;" id="openpanel_dialog" type="file" />
   <input style="display:none;" id="savepanel_dialog" type="file" nwsaveas nwworkingdir />
 
-  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="patchsvg" height="1000" width="1000" class="noselect">
+  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="patchsvg" height="1000" width="1000" overflow="visible" class="noselect">
   </svg>
   <script>
 'use strict';
@@ -54,6 +54,7 @@ function text_to_fudi(text) {
 var canvas_events = (function() {
     var name,
         state,
+        svg_view = document.getElementById('patchsvg').viewBox.baseVal,
         textbox = function () {
             return document.getElementById('new_object_textentry');
         },
@@ -62,8 +63,9 @@ var canvas_events = (function() {
                 //pdgui.gui_post("x: " + evt.pageX + " y: " + evt.pageY +
                 //    " modifier: " + (evt.shiftKey + (evt.ctrlKey << 1)));
                 pdgui.pdsend(name +
-                    " motion " + evt.pageX + " " + evt.pageY + " " +
-                    (evt.shiftKey + (evt.ctrlKey << 1)));
+                    " motion " + (evt.pageX + svg_view.x) + " " +
+                                 (evt.pageY + svg_view.y) + " " +
+                                 (evt.shiftKey + (evt.ctrlKey << 1)));
                 evt.stopPropagation();
                 evt.preventDefault();
                 return false;
@@ -81,8 +83,9 @@ var canvas_events = (function() {
                     mod = (evt.shiftKey + (evt.ctrlKey << 1)); 
                 }
                 pdgui.pdsend(name +
-                    " mouse " + evt.pageX + " " + evt.pageY + " " +
-                    b + " " + mod);
+                    " mouse " + (evt.pageX + svg_view.x) + " " +
+                                (evt.pageY + svg_view.y) + " " +
+                                 b + " " + mod);
                 //evt.stopPropagation();
                 evt.preventDefault();
             },
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index eef8cfce546198f8950a1265eb576015c339a8f6..38ae126e578a2cbc8c5e8b28bb67d92b58eadb67 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -1886,15 +1886,12 @@ function add_gobj_to_svg(svg, gobj) {
 function gui_text_create_gobj(cid, tag, type, xpos, ypos, is_toplevel) {
     gui_post("creating a gobj");
     var svg = get_item(cid, "patchsvg"); // "patchsvg" is id for the svg element
-    // Put objects on half-pixels to make them crisp (look in to the
-    // difference between this and the object-rendering 'crispEdges' attribute)
-    xpos += 0.5;
-    ypos += 0.5;
     var transform_string = 'matrix(1,0,0,1,' + xpos + ',' + ypos + ')';
     var g = create_item(cid, 'g', {
             id: tag + 'gobj',
             transform: transform_string,
-            class: type + (is_toplevel !== 0 ? '' : ' gop')
+            class: type + (is_toplevel !== 0 ? '' : ' gop'),
+            //'shape-rendering': 'crispEdges'
     });
     add_gobj_to_svg(svg, g);
 //    var bluh = svg.getBBox();
@@ -1919,7 +1916,7 @@ function gui_text_drawborder(cid, tag, bgcolor, isbroken, x1, y1, x2, y2) {
         height: y2 - y1,
         stroke: 'black',
         fill: 'none',
-        'shape-rendering': 'optimizeSpeed',
+        'shape-rendering': 'crispEdges',
         class: 'border'
     });
     if (isbroken === 1) {
@@ -1952,6 +1949,7 @@ function gui_canvas_drawio(cid, parenttag, tag, x1, y1, x2, y2, basex, basey, ty
         y: y1 - basey,
         id: xlet_id,
         class: xlet_class,
+        'shape-rendering': 'crispEdges'
     });
     g.appendChild(rect);
     gui_post("the tag for this XLET is " + tag);
@@ -3529,3 +3527,20 @@ function gui_undo_menu(cid, undo_text, redo_text) {
         patchwin[cid].window.nw_undo_menu(undo_text, redo_text);
     }
 }
+
+function gui_canvas_getscroll(cid) {
+    var svg = get_item(cid, 'patchsvg');
+    var bbox = svg.getBBox();
+    configure_item(svg, {
+        viewBox: [bbox.x > 0 ? 0 : bbox.x,
+                  bbox.y > 0 ? 0 : bbox.y,
+                  bbox.x > 0 ? bbox.x + bbox.width : bbox.width,
+                  bbox.y > 0 ? bbox.y + bbox.height: bbox.height].join(" ")
+    });
+    svg.width.baseVal.valueAsString = bbox.x > 0 ? bbox.x + bbox.width : bbox.width;
+    svg.height.baseVal.valueAsString = bbox.y > 0 ? bbox.y + bbox.height : bbox.height;
+    console.log("x is " + bbox.x);
+    console.log("y is " + bbox.x);
+    console.log("width is " + bbox.width);
+    console.log("height is " + bbox.height);
+}
diff --git a/pd/nw/todo.txt b/pd/nw/todo.txt
index 42274a4cdc2607b2cce20dc5cf42615f83761bd2..15cb68d559526e13f6b1d43f9c78ab3f5d7c7d23 100644
--- a/pd/nw/todo.txt
+++ b/pd/nw/todo.txt
@@ -185,6 +185,7 @@ Everything else: (A [x] means we've fixed it)
 [ ] abstract out multi-line text loop, use for text_new and text_set
 [ ] think about translating the undo/redo actions as they appear in the menu.
     (Might be tricky to do)
+[ ] set svg viewBox/width/height to the window size when window gets created
 
 Crashers
 --------
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index 66f8682b4e5359ee1f0fb987a6d029ec0d236aac..210931415aa5ced06c2c0db73866169718eb3375 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -173,7 +173,8 @@ static void canvas_nlet_conf (t_canvas *x, int type) {
 }*/
 
 void canvas_getscroll (t_canvas *x) {
-    sys_vgui("pdtk_canvas_getscroll .x%lx.c\n",(long)x);
+    //sys_vgui("pdtk_canvas_getscroll .x%lx.c\n",(long)x);
+    gui_vmess("gui_canvas_getscroll", "x", x);
 }
 
 /* ---------------- generic widget behavior ------------------------- */