diff --git a/pd/nw/css/default.css b/pd/nw/css/default.css
index b58290b90e7d76f6f8dc1d771f21e7c3182b807b..a29812f32c6e38daa73038a5b33d465d30baed14 100644
--- a/pd/nw/css/default.css
+++ b/pd/nw/css/default.css
@@ -27,6 +27,17 @@ body {
     background: transparent;
 }
 
+#hscroll:hover, #vscroll:hover {
+    background-color: rgba(0, 0, 0, 0.39) !important;
+}
+#hscroll, #vscroll {
+  background-color: rgba(0, 0, 0, 0.267);
+}
+
+#hscroll, #vscroll {
+    cursor: -webkit-grabbing;
+}
+
 .noselect {
     -webkit-touch-callout: none;
     -webkit-user-select: none;
@@ -279,7 +290,7 @@ mark.console_find_highlighted {
     min-width: 3ch;
     position: absolute;
     display: table-cell;
-    padding: 3px 1.5px 3px 1.5px;
+    padding: 1px 0px 3px 1.5px;
     margin-left: 1px;
     /* box-shadow: inset 1px 0px 0px 1px #000; */
     color: black; /* text color */
@@ -513,7 +524,7 @@ text {
     stroke: #e87216;
     fill: #e87216;
     stroke-width: 5;
-    -webkit-animation: fizzle 0.2s ease-in 1;
+    -webkit-animation: fizzle 0.1s ease-in 1;
 }
 
 .xlet_disabled {
@@ -525,8 +536,8 @@ text {
     width: 100%;
     height: 1em;
     padding-top: 2px;
-    padding-left: 2px;
-    padding-bottom: 8px;
+    padding-left: 3px;
+    padding-bottom: 9px;
     background: silver;
     position: fixed;
     bottom: 0;
@@ -537,8 +548,8 @@ text {
     width: 100%;
     height: 1em;
     padding-top: 2px;
-    padding-left: 2px;
-    padding-bottom: 8px;
+    padding-left: 3px;
+    padding-bottom: 9px;
     background: silver;
     position: fixed;
     bottom: 0;
@@ -554,7 +565,7 @@ text {
     /*box-shadow: 7px 7px 5px grey;*/
     left: 50%;
     top: 50%;
-    width: 40%;
+    width: 70%;
     transform: translate(-50%, -50%);
 }
 
@@ -575,7 +586,7 @@ dialog::backdrop {
 .dialog_body {
     font-family: "DejaVu Sans", sans-serif;
     font-size: 10pt;
-    background-color: #f3f3f3;
+    background: rgba(243, 243, 243, 0.941); /* #f3f3f3f0; */
 }
 
 .submit_buttons {
@@ -583,9 +594,14 @@ dialog::backdrop {
     padding: 8px;
 }
 
+form {
+    margin-left: 4px;
+    margin-right: 4px;
+}
+
 fieldset {
 /*    font-family:Georgia; */
-    background-color:#f3f3f3;
+    background-color: rgba(243, 243, 243, 0.627); /* #f3f3f3a0; */
     border-radius:3px;
     border:1px solid #ddd;
     margin-left:auto;
@@ -651,7 +667,7 @@ input[name="receive_symbol"] {
 }
 
 input[name="label"] {
-    width: 8em;
+    width: 9em;
 }
 
 input[name="font_size"] {
@@ -662,6 +678,18 @@ input[name="startup_flags"] {
     width: 16em;
 }
 
+/* All radios */
+input[type="radio"] {
+    position: relative;
+    top: 2px;
+}
+
+/* All checkboxes */
+input[type=checkbox] {
+    position: relative;
+    top: 2px;
+}
+
 /* Canvas dialog */
 
 div.x-scale {
@@ -731,13 +759,13 @@ div.y2 {
    without becoming an order of magnitude more complex, do feel free... */
 .prefs_tab_group {
     display: table;
-    width: 90%;
+    width: 96%;
 }
 
 /* Configure the radio buttons to hide off-screen */
 .prefs_tab {
     position: absolute;
-    left:-100px;
+    left:-500px;
     top:-100px;
 }
 
@@ -792,6 +820,13 @@ div.y2 {
     height: 78vh;
 }
 
+#midi_in1, #midi_in2, #midi_in3, #midi_in4, #midi_in5, 
+    #midi_in6, #midi_in7, #midi_in8, #midi_in9, #midi_in10,
+    #midi_out1, #midi_out2, #midi_out3, #midi_out4, #midi_out5, 
+    #midi_out6, #midi_out7, #midi_out8, #midi_out9, #midi_out10 {
+    width: 205px;
+}
+
 .tab_settings {
     padding-top: 8px;
 }
@@ -810,3 +845,68 @@ input[name="rate"] {
     margin-bottom: -10px;
     padding: 30px;
 }
+
+/* used for the custom dialog titlebar */
+#titlebar {
+    width: 100%;
+    height: 20px;
+    margin-bottom: 4px;
+    -webkit-app-region: drag;
+    background-color: gray;
+    cursor: grab;
+}
+
+#titlebar_buttons {
+    top: 2px;
+    right: 2px;
+    text-align: right;
+    background-color: gray;
+}
+
+#titlebar_title {
+    color: white;
+    position: relative;
+    left: 1px;
+    top: 1px;
+    background-color: gray;
+}
+
+#titlebar_close_button {
+    width: 16px;
+    height: 16px;
+    background: #a2a2a2;
+    -webkit-app-region: no-drag;
+    color: #FFF;
+    font-size: 18px;
+    text-align: center;
+    line-height: 16px;
+    cursor: default;
+}
+
+/*#titlebar_close_button:after {
+    position: absolute;
+    right: 6px;
+    top: 1px;
+    content: "\d7";
+    font-size: 20px;
+    color: #FFF;
+}*/
+
+#titlebar_close_button:hover {
+    background: #b2b2b2;
+}
+
+#titlebar_close_button:active {
+    background: #e2e2e2;
+}
+
+input[type="color"] {
+    margin-bottom: 2px;
+}
+
+.foreground_color span, 
+.background_color span,
+.label_color span {
+    position: relative;
+    bottom: 2px;
+}
\ No newline at end of file
diff --git a/pd/nw/dialog_canvas.html b/pd/nw/dialog_canvas.html
index ed9a8b1068975b4e0e72cca6ef1017828b3168da..fdc41dfb0924005d8385aa5f71e97ff7c2e6f14c 100644
--- a/pd/nw/dialog_canvas.html
+++ b/pd/nw/dialog_canvas.html
@@ -5,10 +5,21 @@
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
     <title>Canvas Dialog</title>
   </head>
-  <body class="dialog_body">
+  <body class="dialog_body" style="overflow: hidden;">
     <div class="container noselect">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Canvas Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
     <form> 
-
       <fieldset class="canvas"> 
         <legend data-i18n="canvas.prop.heading.gop"></legend> 
 
@@ -96,7 +107,7 @@
 
       <fieldset class="canvas"> 
         <legend data-i18n="canvas.prop.heading.data_scaling"></legend> 
-<div style="display: inline-block; align: left;">
+<div style="display: inline-block; margin-right: -5px; width: 100%;">
           <div class="x_scale prop hidden">
             <nobr>
             <label class="no_gop_opt" data-i18n="[title]canvas.prop.x_scale_tt">
@@ -140,7 +151,6 @@
          </label>
        </div>
     </div>
-</div>
       </fieldset> 
 
 
@@ -151,7 +161,7 @@
           <select id="arrays_select" class="hidden"></select>
         </label>
 
-          <div class="array-name prop">
+          <div class="array-name prop" style="margin-right: -5px;">
             <label class="array-name"
                    data-i18n="[title]canvas.prop.array_name_tt">
               <span data-i18n="canvas.prop.array_name"></span>
@@ -187,7 +197,7 @@
             </label>
             <br/>
 
-            <span data-i18n="canvas.prop.array_style"></span>
+            <span style="position: relative; top: 4px;" data-i18n="canvas.prop.array_style"></span>
             <br/>
             <table class="array_style">
               <tr>
@@ -245,7 +255,7 @@
             </table>
           </div>
 
-      <div class="array-fill">
+      <div class="array-fill" style="margin-top: 2px;">
         <label data-i18n="[title]canvas.prop.array_fill_tt">
           <input onchange="update_array_attr(this);"
                  type="color"
@@ -289,6 +299,7 @@
         </label>
       </div>
       </fieldset> 
+</div>
 
     <div class="submit_buttons">
       <button type="button" id="ok_button" onClick="ok()" data-i18n="[title]iem.prop.ok_tt">
@@ -620,9 +631,11 @@ function populate_array_form(objects) {
         a_field = document.getElementById("arrays"),
         opt, i;
     a_field.classList.remove("hidden");
+    a_field.style.setProperty("height", "240px");
     if (objects.length > 1) {
         // show the select element if there's more than one array
         arrays_select.classList.remove("hidden");
+        arrays_select.style.setProperty("margin", "0px 0px 5px 0px");
     }
     for (i = 0; i < objects.length; i++) {
         opt = document.createElement("option");
@@ -669,6 +682,7 @@ function register_window_id(gfxstub, attr_objects) {
     // attr_objects[0]: canvas properties
     // attr_objects[1...n-1]: array properties
     add_events(gfxstub);
+    pdgui.gui_check_for_dialog_appearance_inconsistencies(gfxstub);
     // not sure that we need this for properties windows...
     // pdgui.canvas_map(gfxstub);
     translate_form();
@@ -690,7 +704,7 @@ function register_window_id(gfxstub, attr_objects) {
         new_array_dialog = false; // this is a canvas/array props dialog
         populate_form(attr_objects[0]);
     }
-        init_arrays(pd_garray_attrs);
+    init_arrays(pd_garray_attrs);
 
     // Disabling the menus does not yet work, so we hide that button for
     // the moment
diff --git a/pd/nw/dialog_data.html b/pd/nw/dialog_data.html
index 15f09ae4bbe482adfbed32182e3951dcdce5ecba..aa39420aff0ac23715e18b95e3a30f9f8fc54786 100644
--- a/pd/nw/dialog_data.html
+++ b/pd/nw/dialog_data.html
@@ -3,14 +3,67 @@
   <head>
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body">
+  <style>
+/* width */
+::-webkit-scrollbar {
+  width: 5px;
+}
+
+/* Track */
+::-webkit-scrollbar-track {
+  background: rgba(0,0,0,0); 
+}
+
+/* Handle */
+::-webkit-scrollbar-thumb {
+  background: rgba(0, 0, 0, 0.267); 
+}
+
+/* Handle on hover */
+::-webkit-scrollbar-thumb:hover {
+  background: #888;
+}
+
+input[type=checkbox] {
+    margin: 2px 0px 8px 0px;
+}
+
+input[type="text"] {
+    margin-bottom: 3px;
+}
+
+label {
+	margin-left: 0px;
+    margin-bottom: 1px;
+
+}
+  </style>
+  <body class="dialog_body" style="overflow: hidden;">
     <div class="container">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Data Object Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
     <form> 
-      <fieldset id="data_container"> 
-        <legend id="legend"></legend> 
+      <fieldset id="data_container" style="height: 267px;"> 
+        <legend id="legend"></legend>
+      	  <div id="scrollable_data" style="overflow: auto; height: 250px;">
+      	  	<table id="pairs" style="margin-right: 5px;">
+      	  	</table>
       </fieldset> 
 
-    <div class="submit_buttons">
+    <div class="submit_buttons" style="
+   		text-align: center;
+    	padding: 8px 0px 8px 0px;"
+    >
       <button type="button" onClick="ok()" data-i18n="[title]iem.prop.ok_tt">
         <span data-i18n="iem.prop.ok"></span>
       </button>
@@ -27,6 +80,8 @@
 var gui = require("nw.gui");
 var pdgui = require("./pdgui.js");
 
+//gui.Window.get().setResizable(false);
+
 // For translations
 var l = pdgui.get_local_string;
 
@@ -146,12 +201,15 @@ function add_textarea_input(first_row) {
         textarea = document.createElement("textarea"),
         check_label = document.createElement("label"),
         check = document.createElement("input"),
-        outer_container = document.getElementById("data_container"),
+        outer_container = document.getElementById("pairs"),
         inner_container = document.createElement("div"),
         br = document.createElement("br");
 
     label.textContent = "vector fields";
 
+    inner_container.style.setProperty("display", "inline-block");
+    inner_container.style.setProperty("width", "100%");
+
     label.style.setProperty("display", "block");
     label.style.setProperty("text-align", "left");
     textarea.style.setProperty("display", "block");
@@ -159,7 +217,8 @@ function add_textarea_input(first_row) {
     textarea.setAttribute("id", "vector_textarea");
     textarea.setAttribute("rows", "4");
     textarea.setAttribute("col", "5");
-    textarea.style.setProperty("width", "11.3em");
+    textarea.style.setProperty("width", "97.5%");
+    textarea.style.setProperty("resize", "none");
     textarea.disabled = true;
 
     check.type = "checkbox";
@@ -181,7 +240,7 @@ function add_textarea_input(first_row) {
 function add_text_input(field, left_column, first_row) {
     var label = document.createElement("label"),
         text_input = document.createElement("input"),
-        outer_container = document.getElementById("data_container"),
+        outer_container = document.getElementById("pairs"),
         inner_container = document.createElement("div"),
         br;
     inner_container.style.setProperty("float", "left");
@@ -190,6 +249,9 @@ function add_text_input(field, left_column, first_row) {
     if (left_column && field.type !== "symbol") {
         inner_container.style.setProperty("margin-right", "1em");
     }
+    if (!left_column) {
+        inner_container.style.setProperty("float", "right");
+    }
     label.textContent = field["var"];
     text_input.type = "text";
     text_input.classList.add("scalar_value");
@@ -204,7 +266,7 @@ function add_text_input(field, left_column, first_row) {
     text_input.style.setProperty("display", "block");
     // Also in opposition to iemgui dialogs
     text_input.style.setProperty("width",
-        field.type === "float" ? "5em" : "11.3em");
+        field.type === "float" ? "5em" : "97.5%");
     // Some bottom margin
     inner_container.style.setProperty("margin-bottom", "8px");
 
@@ -301,6 +363,7 @@ function register_window_id(gfxstub, data_string) {
     var head, tail, templates, data, data_separator;
     pd_object_callback = gfxstub;
     add_events(gfxstub);
+    pdgui.gui_check_for_dialog_appearance_inconsistencies(gfxstub);
     // slice off the head of the message. This is where the templates
     // for the data-- plus any templates for (nested) arrays-- are kept.
     // We will keep the head intact for sending back to Pd since the user
diff --git a/pd/nw/dialog_dropdown.html b/pd/nw/dialog_dropdown.html
new file mode 100644
index 0000000000000000000000000000000000000000..a06e7da2c9e80adf07d6d256b8b5a96c54c8d436
--- /dev/null
+++ b/pd/nw/dialog_dropdown.html
@@ -0,0 +1,403 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
+  </head>
+  <body class="dialog_body">
+    <div class="container noselect">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Dropdown Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
+    <form> 
+      <fieldset> 
+        <legend id="dialog_header"></legend>
+
+        <table class="pairs">
+          <tr class="width prop">
+            <td>
+              <label data-i18n="[title]gatom.prop.width_tt"> 
+                <span data-i18n="gatom.prop.width"></span>
+              </label>
+            </td>
+            <td data-i18n="[title]gatom.prop.width_tt">
+              <input type="text" id="width" name="width"
+                     onchange="update_attr(this)">
+            </td>
+            <td>
+            </td>
+            <td>
+            </td>
+          </tr>
+          <tr class="draglo prop pair">
+            <td>
+              <label data-i18n="[title]iem.prop.minimum_tt">
+                <span data-i18n="iem.prop.minimum"></span>
+              </label>
+            </td>
+            <td data-i18n="[title]iem.prop.minimum_tt">
+              <input type="text" id="draglo" name="draglo"
+                     onchange="update_attr(this)">
+            </td>
+            <td>
+              <label data-i18n="[title]iem.prop.maximum_tt">
+                <span data-i18n="iem.prop.maximum"></span>
+              </label>
+            </td>
+            <td data-i18n="[title]iem.prop.maximum_tt">
+              <input type="text" id="draghi" name="draghi"
+                     onchange="update_attr(this)">
+            </td>
+          </tr>
+
+          <tr class="outtype prop">
+            <td>
+              <label data-i18n="[title]gatom.prop.dropdown_outtype_tt">
+                <span data-i18n="gatom.prop.dropdown_outtype"></span>
+              </label>
+            </td>
+            <td colspan="3"
+                data-i18n="[title]gatom.prop.dropdown_outtype_tt">
+              <select id="outtype_select"
+                      onchange="update_dropdown_outtype(this);">
+                <option>index</option>
+                <option>value</option>
+              </select>
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <label data-i18n="[title]iem.prop.send_tt">
+                <span data-i18n="iem.prop.send"></span>
+              </label>
+            </td>
+            <td colspan="3"
+                data-i18n="[title]iem.prop.send_tt">
+              <input type="text" id="send_symbol" name="send_symbol"
+                     onchange="update_attr(this);">
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <label data-i18n="[title]iem.prop.receive_tt">
+                <span data-i18n="iem.prop.receive"></span>
+              </label>
+            </td>
+            <td colspan="3"
+                data-i18n="[title]iem.prop.receive_tt">
+            <input type="text" id="receive_symbol" name="receive_symbol"
+                   onchange="update_attr(this);">
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <label data-i18n="[title]gatom.prop.label_tt">
+                <span data-i18n="gatom.prop.label"></span>
+              </label>
+            </td>
+            <td colspan="3"
+                data-i18n="[title]gatom.prop.label_tt">
+              <input type="text" id="label" name="label"
+                     onchange="update_attr(this)">
+            </td>
+          </tr>
+          <tr>
+            <td>
+              <label data-i18n="[title]gatom.prop.labelpos_tt">
+                <span data-i18n="gatom.prop.labelpos"></span>
+              </label> 
+            </td>
+            <td colspan="3">
+              <label class="points"
+                     data-i18n="[title]gatom.prop.labelpos_tt">
+
+                <input class="label-pos"
+                       type="radio"
+                       id="labelpos_top"
+                       value="2"
+                       name="labelpos"
+                       style="margin-left: 27px;"
+                       onchange="update_attr(this)">
+                <span data-i18n="gatom.prop.label_top"></span>
+
+                <br/>
+
+                <input class="label-pos"
+                       type="radio"
+                       id="labelpos_left"
+                       value="0"
+                       name="labelpos"
+                       onchange="update_attr(this)">
+                <span data-i18n="gatom.prop.label_left"></span>
+
+                <input class="label-pos"
+                       type="radio"
+                       id="labelpos_right"
+                       value="1"
+                       name="labelpos"
+                       onchange="update_attr(this)">
+                <span data-i18n="gatom.prop.label_right"></span>
+
+                <br/>
+
+                <input class="label-pos"
+                       type="radio"
+                       id="labelpos_bottom"
+                       value="3"
+                       name="labelpos"
+                       style="margin-left: 27px;"
+                       onchange="update_attr(this)">
+                <span data-i18n="gatom.prop.label_bottom"></span>
+
+              </label>
+
+        </table>
+
+      </fieldset> 
+
+    <div class="submit_buttons">
+      <button type="button" onClick="ok()" data-i18n="[title]iem.prop.ok_tt">
+        <span data-i18n="iem.prop.ok"></span>
+      </button>
+      <button type="button" onClick="apply()" data-i18n="[title]iem.prop.apply_tt">
+        <span data-i18n="iem.prop.apply"></span>
+      </button>
+      <button type="button" onClick="cancel(true)" data-i18n="[title]iem.prop.cancel_tt">
+        <span data-i18n="iem.prop.cancel"></span>
+      </button>
+    </div>
+
+  </form> 
+  </div>      
+
+  <script>
+"use strict";
+var gui = require("nw.gui");
+var pdgui = require("./pdgui.js");
+
+// For translations
+var l = pdgui.get_local_string;
+
+pdgui.skin.apply(window);
+
+var pd_object_callback,
+    old_attrs = {}, // original state. Used if we cancel the dialog
+    new_attrs = {}; // changed state. Used if we apply or click "Ok"
+
+function substitute_space(arg) {
+    var fake_space = String.fromCharCode(11);
+    return arg.split(" ").join(fake_space);
+}
+
+function strip_problem_chars(arg) {
+    var problem_chars = [";", ",", "\\"];
+    var ret = arg;
+    for(var i = 0; i < problem_chars.length; i++) {
+        ret = ret.split(problem_chars[i]).join("");
+    }
+    return ret;
+}
+
+function gatom_escape(str) {
+    var ret;
+    if (str.length === 0) {
+        ret = "-";
+    } else if (str.slice(0,1) === "-") {
+        ret = "-" + str;
+    } else {
+        var arr = str.split("");
+        for (var i = 0; i < arr.length; i++) {
+            if (arr[i] === "$" && i+1 < arr.length &&
+                arr[i+1] >= "0" && arr[i+1] <= "9") {
+                arr[i] = "#";
+            }
+        }
+        ret = arr.join("");
+    }
+    return strip_problem_chars(ret);
+}
+
+function gatom_unescape(str) {
+    if (str.slice(0,1) === "-") {
+        str = str.slice(1);
+    } else {
+        var arr = str.split("");
+        for (var i = 0; i < arr.length; i++) {
+            if (arr[i] === "#" && i+1 < arr.length &&
+                arr[i+1] >= "0" && arr[i+1] <= "9") {
+                arr[i] = "$";
+            }
+        }
+        str = arr.join("");
+    }
+    return str;
+}
+
+function update_attr(elem) {
+    new_attrs[elem.name] = elem.value;
+}
+
+function update_dropdown_outtype(elem) {
+    new_attrs.outtype = elem.selectedIndex;
+}
+
+function send_params(attrs, create_undo_point) {
+    //pdgui.post("we're applying gatom changes!");
+    var gatom = attrs.name === "atom";
+    pdgui.pdsend(pd_object_callback, "param",
+        +attrs.width,
+        gatom ? +attrs.draglo : +attrs.outtype,
+        gatom ? +attrs.draghi : 0,
+        gatom_escape(attrs.label),
+        +attrs.labelpos,
+        gatom_escape(attrs.receive_symbol),
+        gatom_escape(attrs.send_symbol),
+        create_undo_point ? 1 : 0
+    );
+}
+
+function cancel(revert_changes) {
+    var dirty = false, attr;
+    //window.close(true);
+    if (revert_changes) {
+        for (attr in old_attrs) {
+            if (old_attrs[attr] !== new_attrs[attr]) {
+                dirty = true;
+            }
+        }
+        if (dirty) {
+            send_params(old_attrs, false);
+        }
+    }
+    pdgui.pdsend(pd_object_callback, "cancel");
+}
+
+function apply() {
+    send_params(new_attrs, false);
+}
+
+function ok() {
+    // Steal focus from any active input to make sure it triggers an
+    // onchange event
+    document.querySelector("button").focus();
+    // send the old attrs first so we can set an undo point on them
+    send_params(old_attrs, false);
+    send_params(new_attrs, true);
+    cancel(false);
+}
+
+// This gets called from the nw_create_window function in index.html
+// It provides us with our window id from the C side.  Once we have it
+// we can create the menu and register event callbacks
+function register_window_id(gfxstub, attributes) {
+    var attr;
+    pd_object_callback = gfxstub;
+    add_events(gfxstub);
+
+    // before translating, set the header based on class name:
+    document.querySelector("#dialog_header")
+        .setAttribute("data-i18n", "gatom.prop." +
+            (attributes.name === "dropdown" ? "dropdown" : "gatom"));
+
+    translate_form();
+    populate_form(attributes);
+
+    // hide outtype select for "dropdown", or draglo/hi for "gatom"
+    document.querySelector(attributes.name === "atom" ? ".outtype" : ".draglo")
+        .style.setProperty("display", "none");
+
+
+    // Hack... change incoming "-" to empty string
+    if (attributes.label === "-") { attributes.label = ""; }
+    if (attributes.send_symbol === "-") { attributes.send_symbol= ""; }
+    if (attributes.receive_symbol === "-") { attributes.receive_symbol = ""; }
+
+    // Initialize the new_attrs to the current ones
+    for (attr in attributes) {
+        if (attributes.hasOwnProperty(attr)) {
+            new_attrs[attr] = attributes[attr];
+        }
+    }
+
+    old_attrs = attributes;
+    // We don't turn on rendering of the "container" div until
+    // We've finished displaying all the spans and populating the
+    // labels and form elements.  That makes it more efficient and
+    // snappier, at least on older machines.
+    document.getElementsByClassName("container")[0]
+        .style.setProperty("display", "inline");
+    pdgui.resize_window(pd_object_callback);
+}
+
+function tr_text(id) {
+    var elem = document.getElementById("iem.prop." + id);
+    elem.textContent = l("iem.prop." + id);
+}
+
+// Stop-gap translator
+function translate_form() {
+    var i
+    var elements = document.querySelectorAll("[data-i18n]");
+    for (i = 0; i < elements.length; i++) {
+        var data = elements[i].dataset.i18n;
+        if (data.slice(0,7) === "[title]") {
+            elements[i].title = l(data.slice(7));
+        } else {
+            elements[i].textContent = l(data);
+        }
+    }
+}
+
+function get_attr(name, attrs) {
+    return attrs[attrs.indexOf(name)+1];
+}
+
+function get_elem(name) {
+    return document.getElementById(name);
+}
+
+function populate_form(attributes) {
+    var label, snd, rcv, labelpos, i, radios;
+    get_elem("width").value = attributes.width;
+    if (attributes.name === "atom") {
+        get_elem("draglo").value = attributes.draglo;
+        get_elem("draghi").value = attributes.draghi;
+    } else {
+        get_elem("outtype_select").selectedIndex = attributes.outtype;
+    }
+    label = attributes.label;
+    get_elem("label").value = gatom_unescape(label);
+    snd = attributes.send_symbol;
+    get_elem("send_symbol").value = gatom_unescape(snd);
+    rcv = attributes.receive_symbol;
+    get_elem("receive_symbol").value = gatom_unescape(rcv);
+
+    labelpos = attributes.labelpos;
+    radios = document.getElementsByName("labelpos");
+    for (i = 0; i < radios.length; i++) {
+        if (+radios[i].value === labelpos) {
+            radios[i].checked = true;
+        }
+    }
+}
+
+function add_events(name) {
+    // closing the Window
+    gui.Window.get().on("close", function() {
+        // this needs to do whatever the "cancel" button does
+        cancel(false);
+    });
+    pdgui.dialog_bindings(name);
+}
+
+  </script>
+  </body>
+</html>
diff --git a/pd/nw/dialog_external.html b/pd/nw/dialog_external.html
index 63b31d643d8e713b56802b9a5f53548e48f4c92c..a2c73209e580af27df4470b6774cb6c448b0308c 100644
--- a/pd/nw/dialog_external.html
+++ b/pd/nw/dialog_external.html
@@ -3,13 +3,66 @@
   <head>
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body">
+  <style>
+/* width */
+::-webkit-scrollbar {
+  width: 5px;
+}
+
+/* Track */
+::-webkit-scrollbar-track {
+  background: rgba(0,0,0,0); 
+}
+
+/* Handle */
+::-webkit-scrollbar-thumb {
+  background: rgba(0, 0, 0, 0.267); 
+}
+
+/* Handle on hover */
+::-webkit-scrollbar-thumb:hover {
+  background: #888;
+}
+
+input[type=checkbox] {
+    margin: 2px 0px 8px 0px;
+}
+
+input[type="text"] {
+    margin-bottom: 3px;
+}
+
+label {
+	margin-left: 5px;
+}
+  </style>
+  <body class="dialog_body" style="overflow: hidden;">
     <div class="container">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%; margin: 7px;">
+            <div id="titlebar_title">External Object Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
+
     <form> 
-      <fieldset> 
-        <legend></legend> 
+      <fieldset id="data_container" style="height: 267px;"> 
+        <legend></legend>
+      	  <div id="scrollable_data" style="overflow: auto; height: 250px;">
+      	  	<table id="pairs">
+      	  	</table>
+      	  </div>
       </fieldset> 
-    <div class="submit_buttons">
+    <div class="submit_buttons" style="
+   		text-align: center;
+    	padding: 8px 0px 8px 0px;"
+    >
       <button type="button"
               onClick="ok();"
               id="ok_button"
@@ -35,6 +88,8 @@
 var gui = require("nw.gui");
 var pdgui = require("./pdgui.js");
 
+//gui.Window.get().setResizable(false);
+
 // For translations
 var l = pdgui.get_local_string;
 
@@ -122,6 +177,7 @@ function register_window_id(gfxstub, args) {
     var external_name = args.name,
         array_of_objects;
     pd_object_callback = gfxstub;
+    pdgui.gui_check_for_dialog_appearance_inconsistencies(gfxstub);
     array_of_objects = parse_attrs(args.attributes);
     // Store our array for later use
     new_properties = array_of_objects;
@@ -166,7 +222,7 @@ function get_input_type(t) {
 }
 
 function build_form(external_name, array_of_objects) {
-    var fieldset = document.querySelector("fieldset");
+    var fieldset = document.getElementById("pairs");
     document.querySelector("legend").textContent = external_name;
     array_of_objects.forEach(function(elem) {
         var input_elem = document.createElement("input"),
@@ -184,11 +240,15 @@ function build_form(external_name, array_of_objects) {
             }
         }
         label.textContent = elem.label;
-        label.appendChild(input_elem);
-        fieldset.appendChild(label);
+        fieldset.appendChild(input_elem);       
+        fieldset.appendChild(label); 
         // stop-gap until we make this prettier through css: insert a break
         fieldset.appendChild(document.createElement("br"));
     });
+    // update scrollbars
+    var parent_fieldset = document.getElementById("data_container");
+    fieldset.style.setProperty("height", (parseInt(parent_fieldset.style.getPropertyValue("height")) - 10) + "px");
+
 }
 
 function add_events(name) {
diff --git a/pd/nw/dialog_font.html b/pd/nw/dialog_font.html
index 2b162ced19386b58393531b64a8c00983da0aa57..ae3de3ce19cd8d0d6d11dd9cca7b0e14c1fdb53b 100644
--- a/pd/nw/dialog_font.html
+++ b/pd/nw/dialog_font.html
@@ -3,8 +3,20 @@
   <head>
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body">
+  <body class="dialog_body" style="overflow: hidden;">
     <div class="container">
+   	  <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Font Size</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
     <form> 
       <fieldset> 
         <legend data-i18n="font.prop.size"></legend> 
diff --git a/pd/nw/dialog_gatom.html b/pd/nw/dialog_gatom.html
index 5d0e9fba4c197f45f6fd282d1e4ae39fb2a54e2c..f02bfb3b7d4a9a1cf8c1783e7c025458a5988cf1 100644
--- a/pd/nw/dialog_gatom.html
+++ b/pd/nw/dialog_gatom.html
@@ -3,13 +3,25 @@
   <head>
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body">
-    <div class="container">
+  <body class="dialog_body" style="overflow: hidden;">
+    <div class="container noselect">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Atom Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
     <form> 
-      <fieldset> 
+      <fieldset style="display: inline-block; margin-right: 4px;"> 
         <legend id="dialog_header"></legend>
 
-        <table class="pairs">
+        <table class="pairs" style="display: inline-block; width: 232px;">
           <tr class="width prop">
             <td>
               <label data-i18n="[title]gatom.prop.width_tt"> 
@@ -109,15 +121,16 @@
 
                 <input class="label-pos"
                        type="radio"
-                       id="labelpos_left"
+                       id="labelpos_top"
                        value="2"
                        name="labelpos"
+                       style="margin-left: 27px;"
                        onchange="update_attr(this)">
                 <span data-i18n="gatom.prop.label_top"></span>
 
                 <br/>
 
-                <input class="array-style"
+                <input class="label-pos"
                        type="radio"
                        id="labelpos_left"
                        value="0"
@@ -125,7 +138,7 @@
                        onchange="update_attr(this)">
                 <span data-i18n="gatom.prop.label_left"></span>
 
-                <input class="array-style"
+                <input class="label-pos"
                        type="radio"
                        id="labelpos_right"
                        value="1"
@@ -135,11 +148,12 @@
 
                 <br/>
 
-                <input class="array-style"
+                <input class="label-pos"
                        type="radio"
                        id="labelpos_bottom"
                        value="3"
                        name="labelpos"
+                       style="margin-left: 27px;"
                        onchange="update_attr(this)">
                 <span data-i18n="gatom.prop.label_bottom"></span>
 
@@ -287,6 +301,7 @@ function register_window_id(gfxstub, attributes) {
     var attr;
     pd_object_callback = gfxstub;
     add_events(gfxstub);
+    pdgui.gui_check_for_dialog_appearance_inconsistencies(gfxstub);
 
     // before translating, set the header based on class name:
     document.querySelector("#dialog_header")
diff --git a/pd/nw/dialog_iemgui.html b/pd/nw/dialog_iemgui.html
index cd39e492a573f96af0cc09bfca8e87ee0b73e7b3..c176b772200649a4dae064287a3ed96c489e79ac 100644
--- a/pd/nw/dialog_iemgui.html
+++ b/pd/nw/dialog_iemgui.html
@@ -4,8 +4,20 @@
     <link id="page_style" rel="stylesheet"
           type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body">
+  <body class="dialog_body" style="overflow: hidden;">
     <div class="container">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Iemgui Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
     <form> 
       <fieldset> 
         <legend data-i18n="iem.prop.heading.size"></legend> 
@@ -24,7 +36,7 @@
           </tr>
           <tr class="selection_size prop hidden">
             <td>
-              <label data-i18n="[title]iem.select_size_tt">
+              <label data-i18n="[title]iem.prop.select_size_tt">
                 <span data-i18n="iem.prop.select_size"></span>
               </label>
             </td>
@@ -86,7 +98,7 @@
                      onchange="update_attr(this);">
             </td>
             <td>
-              <label data-i18n="iem.prop.visible_height">
+              <label data-i18n="[title]iem.prop.visible_height_tt">
                 <span data-i18n="iem.prop.visible_height"></span>
               </label>
             </td>
@@ -198,7 +210,8 @@
             </td>
             <td data-i18n="[title]iem.prop.send_tt">
               <input type="text" name="send_symbol"
-                     onchange="update_attr(this, true);">
+                     onchange="update_attr(this, true);"
+                     style="width: 12em;">
             </td>
             <td>
           <tr class="receive_symbol prop hidden">
@@ -209,7 +222,8 @@
             </td>
             <td data-i18n="[title]iem.prop.receive_tt">
               <input type="text" name="receive_symbol"
-                     onchange="update_attr(this, true);">
+                     onchange="update_attr(this, true);"
+                     style="width: 12em;">
             </td>
             <td>
           </tr>
@@ -228,7 +242,8 @@
             </td>
             <td data-i18n="[title]iem.prop.label_tt">
               <input type="text" name="label"
-                     onchange="update_attr(this, true);">
+                     onchange="update_attr(this, true);"
+                     style="width: 131px;">
             </td>
             <td>
               <label data-i18n="[title]iem.prop.xoffset_tt">
@@ -577,8 +592,10 @@ function register_window_id(gfxstub, attr_object) {
             new_attrs[attr] = old_attrs[attr];
         }
     }
-    console.log("attr object is " + attr_object.toString());
+    console.log("attr object is " + attr_object.toString() +
+        " and its type is " + attr_object.type);
     add_events(gfxstub);
+    pdgui.gui_check_for_dialog_appearance_inconsistencies(gfxstub);
 
     // Special case for [moonlib/mknob] which leverages the iemgui dialog--
     // change the label for "height" to "steps"
@@ -586,6 +603,11 @@ function register_window_id(gfxstub, attr_object) {
         change_width_and_height_labels();
     }
 
+    // ico@vt.edu TODO: translate the window title
+    // for the timebeing we just give it english version
+    document.getElementById("titlebar_title").textContent = "[" + 
+        attr_object.type + "] Iemgui Properties";
+
     translate_form();
     populate_form(attr_object);
     // We don't turn on rendering of the "container" div until
diff --git a/pd/nw/dialog_prefs.html b/pd/nw/dialog_prefs.html
index 63b18f48859fe1e8cecccd50d62ce24b1ce859e8..d92a02242c4f7e899911f19b5529897130f2fe74 100644
--- a/pd/nw/dialog_prefs.html
+++ b/pd/nw/dialog_prefs.html
@@ -3,8 +3,25 @@
   <head>
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body prefs_body">
+  <style>
+td {
+  padding-right: 0px;
+}
+  </style>
+  <body class="dialog_body prefs_body" style="overflow: hidden;">
     <div class="container noselect prefs_container">
+      <table id="titlebar">
+        <tr>
+          <td style="width: 100%;">
+            <div id="titlebar_title">Pd-L2Ork Properties</div>
+          </td>
+          <td>
+            <div class="titlebar_buttons">
+              <div id="titlebar_close_button" onclick="cancel(false);">&#215</div>
+            </div>
+          </td>
+        </tr>
+      </table>
       <div class="prefs_tab_group">
         <input type="radio"
                name="prefs_radio_group"
@@ -259,7 +276,7 @@
             <span data-i18n="[title]prefs.midi.input_title_tt">
               <span data-i18n="prefs.midi.input_title"></span>
             </span>
-            <table class="tab_settings">
+            <table class="tab_settings" style="width: 100%;">
               <tr>
                 <td>1</td><td>
                   <select id="midi_in1" onchange="dev_change(this);"></select>
@@ -421,7 +438,8 @@
             <label data-i18n="[title]prefs.startup.paths_tt">
               <span data-i18n="prefs.startup.paths"></span>
             </label>
-            <div style="height:24vh; width:89vw; background:white; border: 1px solid #bbb; overflow-y:auto; overflow-x:auto; padding:0px;">
+            <div style="height:24vh; background:white; border: 1px solid #bbb;
+                margin-right: -4px; overflow-y:auto; overflow-x:auto; padding:0px;">
               <table id="startup_paths" style="width:100%; background:white;">
               </table>
             </div>
@@ -439,7 +457,8 @@
             <label data-i18n="[title]prefs.startup.libs_tt">
               <span data-i18n="prefs.startup.libs"></span>
             </label>
-            <div style="height:24vh; width:89vw; background:white; border: 1px solid #bbb; overflow-y:auto; overflow-x:auto; padding:0px;">
+            <div style="height:24vh; background:white; border: 1px solid #bbb;
+                margin-right: -4px; overflow-y:auto; overflow-x:auto; padding:0px;">
               <table id="startup_libs" style="width:100%; background:white;">
               </table>
             </div>
@@ -460,7 +479,7 @@
               <input type="text"
                      id="startup_flags"
                      name="startup_flags"
-                     style="width:89vw">
+                     style="width:100%">
             </label>
           </div>
         </div>
@@ -1240,6 +1259,7 @@ function startup_path_delete() {
 function register_window_id(gfxstub, attr_arrays) {
     pd_object_callback = gfxstub;
     add_events(gfxstub);
+    pdgui.gui_check_for_dialog_appearance_inconsistencies(gfxstub);
     translate_form();
 
     // We don't turn on rendering of the "container" div until
diff --git a/pd/nw/dialog_search.html b/pd/nw/dialog_search.html
index 282bb2610dae14910b0d97b1e65b0ac9139b63fc..6727ce498cfce3e7b2d64eaf6b3a77e6833bcd35 100644
--- a/pd/nw/dialog_search.html
+++ b/pd/nw/dialog_search.html
@@ -383,14 +383,22 @@ function find_bar_shortcut(evt) {
     return (evt.keyCode === 70 && evt[modifier]) // <ctrl-f>
 }
 
+function window_close_shortcut(evt) {
+    var osx = process.platform === "darwin",
+    modifier = osx ? "metaKey" : "ctrlKey";
+    return (evt.keyCode === 87 && evt[modifier]) // <ctrl-w>
+}
+
 function toggle_find_bar() {
     // this is copied from index.js m.edit.find...
     var find_div = document.getElementById("console_find"),
         find_bar_text = document.getElementById("console_find_text"),
         state = find_div.style.getPropertyValue("display");
     if (state !== "inline") {
-        find_div.style.setProperty("height", "1.4em");
+        find_div.style.setProperty("height", "1.2em");
         find_div.style.setProperty("display", "inline");
+        find_div.style.setProperty("padding-left", "3px");
+        find_div.style.setProperty("padding-bottom", "9px");
         window.setTimeout(function() {
                 find_bar_text.focus();
                 find_bar_text.select();
@@ -419,6 +427,10 @@ function add_events() {
             if (find_bar_shortcut(evt)) {
                 toggle_find_bar();
                 evt.stopPropagation();
+            } else if (window_close_shortcut(evt)) {
+                evt.stopPropagation();
+                pdgui.remove_dialogwin("search");
+                nw.Window.get().close(true);
             } else {
                 evt.stopPropagation();
                 return console_find_keydown(this, evt);
@@ -448,10 +460,15 @@ function add_events() {
                    evt.keyCode === 10 || evt.keyCode === 13) {
         } else if (evt.target !== input_elem) {
             input_elem.focus();
+        } else if (window_close_shortcut(evt)) {
+                evt.stopPropagation();
+                pdgui.remove_dialogwin("search");
+                nw.Window.get().close(true);
         } else {
             // If we want to trigger a search on each keystroke we can do it
             // here.
         }
+
     });
     document.getElementById("search_text").addEventListener("search",
         function() {
@@ -571,11 +588,12 @@ function doc_search() {
                       defaultValue="Search in Console"
                       style="width:10em;"/>
         </label>
-        <label>Highlight All
+        <label style="margin-left: 7px;">Highlight All
                <input type="checkbox"
                       id="console_find_highlight"
                       name="console_find_highlight"
-                      onchange="console_find_highlight_all(this);"/>
+                      onchange="console_find_highlight_all(this);"
+                      style="left: -3px;"/>
         </label>
       </div>
     </div>
diff --git a/pd/nw/dialog_text.html b/pd/nw/dialog_text.html
index 500e76badbcc685fea650d7f68ecf63eafda3aee..71e5feaa70c1716e153ea48702bf984f92fd3724 100644
--- a/pd/nw/dialog_text.html
+++ b/pd/nw/dialog_text.html
@@ -3,12 +3,13 @@
   <head>
     <link id="page_style" rel="stylesheet" type="text/css" href="css/default.css">
   </head>
-  <body class="dialog_body">
+  <body class="dialog_body" onload="resize_textarea();" onresize="resize_textarea();"
+  		style="overflow: hidden;">
     <div class="container">
-      <textarea id="text" style="width: 100%; box-sizing: border-box; height: 85vh; resize: none;"> 
+      <textarea id="text" style="margin: 5px 5px 4px 5px; box-sizing: border-box; resize: none;">
       </textarea>
     </div>
-    <div class="submit_buttons">
+    <div class="submit_buttons" style="padding: 0px;">
       <button type="button" onClick="ok()" data-i18n="[title]iem.prop.ok_tt">
         <span data-i18n="iem.prop.ok"></span>
       </button>
@@ -54,6 +55,8 @@ pdgui.skin.apply(window);
 var pd_object_callback;
 var dirty = false;
 
+gui.Window.get().setMinimumSize(260, 70);
+
 function apply() {
     var text_array = document.getElementById("text").value.split("\n");
     // clear out Pd's binbuf for our text object
@@ -132,7 +135,7 @@ function register_window_id(gfxstub, attr) {
     // nwjs window, so you'll see a flicker to the title set here if it's
     // not "text". We need to change this so that the title can be different
     // from the dialog type in nw_create_window.
-    document.title = attr.title;
+    document.title = "[" + attr.title + "] Text Editor";
 }
 
 // Stop-gap translator
@@ -185,6 +188,14 @@ function add_events(name) {
     // We leave off those bindings since Enter starts a new line in the textarea
     //pdgui.dialog_bindings(name);
 }
+
+function resize_textarea() {
+	var text = document.getElementById("text");
+	var textwidth = (window.innerWidth - 10 > 200 ? (window.innerWidth - 10) : 200);
+	var textheight = (window.innerHeight - 40 > 21 ? (window.innerHeight - 40) : 21);
+	text.style.setProperty("width", textwidth + "px");
+	text.style.setProperty("height", textheight + "px");
+}
   </script>
   </body>
 </html>
diff --git a/pd/nw/index.html b/pd/nw/index.html
index d96e25ef000800b9d94428955fe8ec156131db85..7b8b9c7b14947f688236d817340e4828389505f3 100644
--- a/pd/nw/index.html
+++ b/pd/nw/index.html
@@ -36,12 +36,12 @@
                     defaultValue="Search in Console"
                     style="width:10em"/>
       </label>
-      <label style="margin-left: 7px;  margin-right: -3px;">Highlight All
+      <label style="margin-left: 7px;">Highlight All
           <input type="checkbox"
                id="console_find_highlight"
                name="console_find_highlight"
                onchange="console_find_highlight_all(this);"
-               style="position: relative; top: 2px; margin-right: 5px;"/> 
+               style="position: relative; top: 2px; margin-right: 5px; left: -3px;"/> 
       </label>
     </div>
     <script src="./console_search.js"></script>
diff --git a/pd/nw/index.js b/pd/nw/index.js
index b71105f1a1be88a948fc4db1f310a17269dd2ec7..30ee7736150d91b633dbe567dcf766c3f7c14e6b 100644
--- a/pd/nw/index.js
+++ b/pd/nw/index.js
@@ -386,16 +386,29 @@ function nw_close_window(window) {
 var null_pos = pdgui.check_nw_version("0.46") ? "null" : "center";
 
 function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
-        // todo: make a separate way to format the title for OSX
+    // todo: make a separate way to format the title for OSX
     var my_title;
+    var win_frame = true;
+    var win_transparent = false;
     if (type === "pd_canvas") {
         my_title = pdgui.format_window_title(
             attr_array.name,
             attr_array.dirty,
             attr_array.args,
             attr_array.dir);
+
+	    // ico@vt.edu 2020-08-13:
+	    // why does Windows have different innerWidth and innerHeight from other OSs?
+	    // See pdgui.js' canvas_params for the explanation...
+	    // ico@vt.edu 2020-08-21: this should only apply to patch windows
+	    width -= 16 * pdgui.nw_os_is_windows;
+	    height -= 8 * pdgui.nw_os_is_windows;
     } else {
         my_title = type;
+        if (type !== "search" && type !== "text") {
+            win_frame = false;
+            win_transparent = true;
+        }
     }
     var my_file =
         type === "pd_canvas" ? "pd_canvas.html" : "dialog_" + type + ".html";
@@ -417,12 +430,24 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
 
     //pdgui.post("nw_create_window w=" + width + " h=" + height);
 
-    // ico@vt.edu 2020-08-13:
-    // why does Windows have different innerWidth and innerHeight from other OSs?
-    // See pdgui.js' canvas_params for the explanation...
-    width -= 16 * pdgui.nw_os_is_windows;
-    height -= 8 * pdgui.nw_os_is_windows;
-
+    /*
+    // ico@vt.edu: instantiate default options for the window behavior
+    // the first two vars (transparent is currently disabled) are options
+    // to be passed to the window at creation time, while second two are
+    // activated via a function call after the window has been created
+    var frame_val = true,
+        //transparent_val = true,
+        resize_val = true,
+        topmost_val = false,
+        menu_val = true;
+
+    if (frame_option !== undefined) {
+        pdgui.post("window_options have content");
+        process_window_options(window_options,
+            frame_val, transparent_val,
+            resize_val, topmost_val);
+        // TODO: do stuff here
+    }*/
     gui.Window.open(my_file, {
         title: my_title,
         // ico@vt.edu: position in 0.46.2 overrides x and y below
@@ -436,7 +461,9 @@ function nw_create_window(cid, type, width, height, xpos, ypos, attr_array) {
         // ico@vt.edu: on 0.46.2 this is now 25, go figure...
         height: height + (pdgui.nw_menu_offset * !pdgui.nw_os_is_osx),
         x: xpos,
-        y: ypos
+        y: ypos,
+        frame: win_frame,
+        transparent: win_transparent
     }, function (new_win) {
         if (type === "pd_canvas") {
             pdgui.set_patchwin(cid, new_win);
diff --git a/pd/nw/locales/en/translation.json b/pd/nw/locales/en/translation.json
index 1427ac9040be5410da688473fc989e3673a1ea08..213156285b68f039f8e56b0db848b872e7b94139 100644
--- a/pd/nw/locales/en/translation.json
+++ b/pd/nw/locales/en/translation.json
@@ -3,7 +3,7 @@
     "prop": {
       "heading": {
           "size":    "size and behavior",
-          "messages": "messages",
+          "messages": "messaging",
           "label":   "label",
           "colors":  "colors"
       },
@@ -154,8 +154,8 @@
     "tofront_tt": "Bring the selected object visually in front of all other objects",
     "toback": "Send to Back",
     "toback_tt": "Send the selected object visually behind all other objects",
-    "font": "Font",
-    "font_tt": "Font settings for this patch",
+    "font": "Font Size",
+    "font_tt": "Font size settings for this patch",
     "cordinspector": "Cord Inspector",
     "cordinspector_tt": "Move the mouse over cords to inspect the data moving between objects",
     "find": "Find",
@@ -319,9 +319,9 @@
         "viewbox_offsets": "viewbox offsets",
         "arrays": "array options"
       },
-      "no_scroll": "hide scrollbars (experimental)",
+      "no_scroll": "hide scrollbars",
       "no_scroll_tt": "hide window scrollbars",
-      "no_menu": "hide menu (experimental)",
+      "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",
diff --git a/pd/nw/pd_canvas.html b/pd/nw/pd_canvas.html
index cfd6665b715e65ee5b85d1e226082ad3ad2f4e46..7ba063a2740a95b6116765e9385176ee7b61b4ac 100644
--- a/pd/nw/pd_canvas.html
+++ b/pd/nw/pd_canvas.html
@@ -102,8 +102,8 @@
         </button>
       </div>
     </dialog>
-	<div id="hscroll" style="background-color: rgba(0, 0, 0, 0.267); position: fixed; left: 0px; bottom: 0px; border-radius: 0px; width: 10px; height: 5px; visibility: hidden;"></div>
-	<div id="vscroll" style="background-color: rgba(0, 0, 0, 0.267); position: fixed; right: 0px; top: 0px; border-radius: 0px; width: 5px; height: 10px; visibility: hidden;"></div>
+	<div id="hscroll" style="position: fixed; left: 0px; bottom: 0px; border-radius: 0px; width: 10px; height: 5px; visibility: hidden;"></div>
+	<div id="vscroll" style="position: fixed; right: 0px; top: 0px; border-radius: 0px; width: 5px; height: 10px; visibility: hidden;"></div>
     <script type="text/javascript" src="./pd_canvas.js"></script>
   </body>
 </html>
diff --git a/pd/nw/pd_canvas.js b/pd/nw/pd_canvas.js
index a0490f56a90498686d65059df14b562e8f305e2f..55c3c8ada412d4f70b7be14b8e0a6f4a9237978c 100644
--- a/pd/nw/pd_canvas.js
+++ b/pd/nw/pd_canvas.js
@@ -614,6 +614,8 @@ var canvas_events = (function() {
                 canvas_events[canvas_events.get_previous_state()]();
             },
             hscroll_mouseup: function(evt) {
+                document.getElementById("hscroll").style.setProperty("background-color", "rgba(0, 0, 0, 0.267)");
+                document.getElementById("patchsvg").style.cursor = "default";
                 canvas_events[canvas_events.get_previous_state()]();
             },
             hscroll_mousemove: function(evt) {
@@ -643,6 +645,8 @@ var canvas_events = (function() {
                 }
             },
             vscroll_mouseup: function(evt) {
+                document.getElementById("vscroll").style.setProperty("background-color", "rgba(0, 0, 0, 0.267)");
+                document.getElementById("patchsvg").style.cursor = "default";
                 canvas_events[canvas_events.get_previous_state()]();
             },
             vscroll_mousemove: function(evt) {
@@ -915,11 +919,15 @@ var canvas_events = (function() {
         },
         hscroll_drag: function() {
             canvas_events.none();
+            document.getElementById("hscroll").style.cssText += "background-color: rgba(0, 0, 0, 0.5) !important";
+            document.getElementById("patchsvg").style.cursor = "-webkit-grabbing";
             document.addEventListener("mouseup", events.hscroll_mouseup, false);
             document.addEventListener("mousemove", events.hscroll_mousemove, false);
         },
         vscroll_drag: function() {
             canvas_events.none();
+            document.getElementById("vscroll").style.cssText += "background-color: rgba(0, 0, 0, 0.5) !important";
+            document.getElementById("patchsvg").style.cursor = "-webkit-grabbing";
             document.addEventListener("mouseup", events.vscroll_mouseup, false);
             document.addEventListener("mousemove", events.vscroll_mousemove, false);
         },
@@ -1337,6 +1345,7 @@ function register_window_id(cid, attr_array) {
         nw.Window.get().title = kludge_title;
     }
     pdgui.free_title_queue(cid);
+    document.body.addEventListener("load", update_menu_items(cid), false);
 }
 
 function create_popup_menu(name) {
@@ -1443,6 +1452,7 @@ function set_edit_menu_modals(state) {
     canvas_menu.edit.copy.enabled = state;
     canvas_menu.edit.paste.enabled = state;
     canvas_menu.edit.selectall.enabled = state;
+    canvas_menu.edit.font.enabled = state;
 }
 
 function set_editmode_checkbox(state) {
@@ -1477,9 +1487,12 @@ function minit(menu_item, options) {
     }
 }
 
+// used, so that we can reference menu later
+var m  = null;
+
 function nw_create_patch_window_menus(gui, w, name) {
     // if we're on GNU/Linux or Windows, create the menus:
-    var m = canvas_menu = pd_menus.create_menu(gui);
+    m = canvas_menu = pd_menus.create_menu(gui);
 
     // File sub-entries
     // We explicitly enable these menu items because on OSX
@@ -1641,7 +1654,79 @@ function nw_create_patch_window_menus(gui, w, name) {
     });
     minit(m.edit.font, {
         enabled: true,
-        click: function () { pdgui.pdsend(name, "menufont"); }
+        /*click: function () { pdgui.pdsend(name, "menufont"); } */
+    });
+    minit(m.font.s8, {
+        enabled: true,
+        click: function () {
+            m.font.s8.checked = true;
+            m.font.s10.checked = false;
+            m.font.s12.checked = false;
+            m.font.s16.checked = false;
+            m.font.s24.checked = false;
+            m.font.s36.checked = false;
+            pdgui.gui_menu_font_change_size(name, 8);
+        }
+    });
+    minit(m.font.s10, {
+        enabled: true,
+        click: function () {
+            m.font.s8.checked = false;
+            m.font.s10.checked = true;
+            m.font.s12.checked = false;
+            m.font.s16.checked = false;
+            m.font.s24.checked = false;
+            m.font.s36.checked = false;
+            pdgui.gui_menu_font_change_size(name, 10);
+        }
+    });
+    minit(m.font.s12, {
+        enabled: true,
+        click: function () {
+            m.font.s8.checked = false;
+            m.font.s10.checked = false;
+            m.font.s12.checked = true;
+            m.font.s16.checked = false;
+            m.font.s24.checked = false;
+            m.font.s36.checked = false;
+            pdgui.gui_menu_font_change_size(name, 12);
+        }
+    });
+    minit(m.font.s16, {
+        enabled: true,
+        click: function () {
+            m.font.s8.checked = false;
+            m.font.s10.checked = false;
+            m.font.s12.checked = false;
+            m.font.s16.checked = true;
+            m.font.s24.checked = false;
+            m.font.s36.checked = false;
+            pdgui.gui_menu_font_change_size(name, 16);
+        }
+    });
+    minit(m.font.s24, {
+        enabled: true,
+        click: function () {
+            m.font.s8.checked = false;
+            m.font.s10.checked = false;
+            m.font.s12.checked = false;
+            m.font.s16.checked = false;
+            m.font.s24.checked = false;
+            m.font.s36.checked = false;
+            pdgui.gui_menu_font_change_size(name, 24);
+        }
+    });
+    minit(m.font.s36, {
+        enabled: true,
+        click: function () {
+            m.font.s8.checked = false;
+            m.font.s10.checked = false;
+            m.font.s12.checked = false;
+            m.font.s16.checked = false;
+            m.font.s24.checked = false;
+            m.font.s36.checked = true;
+            pdgui.gui_menu_font_change_size(name, 36);
+        }
     });
     minit(m.edit.cordinspector, {
         enabled: true,
@@ -1984,3 +2069,42 @@ function nw_create_patch_window_menus(gui, w, name) {
         }
     });
 }
+
+function init_menu_font_size(size) {
+    //pdgui.post("init_menu_font_size " + size);
+    m.font.s8.checked = false;
+    m.font.s10.checked = false;
+    m.font.s12.checked = false;
+    m.font.s16.checked = false;
+    m.font.s24.checked = false;
+    m.font.s36.checked = false;
+
+    switch(size)
+    {
+        case 8:
+            m.font.s8.checked = true;
+            break;
+        case 10:
+            m.font.s10.checked = true;
+            break;
+        case 12:
+            m.font.s12.checked = true;
+            break;
+        case 16:
+            m.font.s16.checked = true;
+            break;
+        case 24:
+            m.font.s24.checked = true;
+            break;
+        case 36:
+            m.font.s36.checked = true;
+            break;
+    } 
+}
+
+// ico@vt.edu 2020-08-24: this is called when the window is finally
+// loaded and then asks libpd to tell us what is the font state
+// LATER: we can use this to also update the undo state appropriately
+function update_menu_items(cid) {
+    pdgui.pdsend(cid, "updatemenu");
+}
\ No newline at end of file
diff --git a/pd/nw/pd_menus.js b/pd/nw/pd_menus.js
index 79e031410c527e0e21d64c1247574ad8dc01f15a..a9dd9e69d189c98ec4f18a408af1a1c9f66b4489 100644
--- a/pd/nw/pd_menus.js
+++ b/pd/nw/pd_menus.js
@@ -25,7 +25,8 @@ function create_menu(gui, type) {
         put_menu,
         winman_menu,
         media_menu,
-        help_menu;
+        help_menu,
+        font_submenu;
 
     // We only maintain a single instance of the recent files submenu which
     // gets updated in pdgui.js via a callback from the engine.
@@ -37,6 +38,41 @@ function create_menu(gui, type) {
         pdgui.populate_recent_files(recent_files_submenu);
     }
 
+    // File sub-entries
+    m.font = {};
+    font_submenu = new gui.Menu();
+
+    font_submenu.append(m.font.s8 = new gui.MenuItem({
+        label: 8,
+        tooltip: 8,
+        type: "checkbox"
+    }));
+    font_submenu.append(m.font.s10 = new gui.MenuItem({
+        label: 10,
+        tooltip: 10,
+        type: "checkbox"
+    }));
+    font_submenu.append(m.font.s12 = new gui.MenuItem({
+        label: 12,
+        tooltip: 12,
+        type: "checkbox"
+    }));
+    font_submenu.append(m.font.s16 = new gui.MenuItem({
+        label: 16,
+        tooltip: 16,
+        type: "checkbox"
+    }));
+    font_submenu.append(m.font.s24 = new gui.MenuItem({
+        label: 24,
+        tooltip: 24,
+        type: "checkbox"
+    }));
+    font_submenu.append(m.font.s36 = new gui.MenuItem({
+        label: 36,
+        tooltip: 36,
+        type: "checkbox"
+    }));
+
     // OSX just spawns a single canvas menu and then enables/disables
     // the various menu items as needed.
     canvas_menu = osx || (type !== "console");
@@ -290,10 +326,14 @@ function create_menu(gui, type) {
             modifiers: shortcuts.menu.tidyup.modifiers,
             tooltip: l("menu.tidyup_tt")
         }));
+
         edit_menu.append(m.edit.font = new gui.MenuItem({
             label: l("menu.font"),
-            tooltip: l("menu.font_tt")
+            tooltip: l("menu.font_tt"),
+            submenu: font_submenu
         }));
+
+
         edit_menu.append(m.edit.cordinspector = new gui.MenuItem({
             type: "checkbox",
             label: l("menu.cordinspector"),
diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js
index 6f4f9f38f5939da9898b618598172bccb98ef7be..e62f16b4b7289bf155945b1cda8e8c471ba3015d 100644
--- a/pd/nw/pdgui.js
+++ b/pd/nw/pdgui.js
@@ -1628,6 +1628,8 @@ function gui_canvas_cursor(cid, pd_event_type) {
 function canvas_sendkey(cid, state, evt, char_code, repeat) {
     var shift = evt.shiftKey ? 1 : 0,
         repeat_number = repeat ? 1 : 0;
+    //post("canvas_sendkey state=" + state + " evt=" + evt +
+    //	" char_code=<" + char_code + "> repeat=" + repeat);
     pdsend(cid, "key", state, char_code, shift, 1, repeat_number);
 }
 
@@ -1732,6 +1734,8 @@ function gui_canvas_new(cid, width, height, geometry, zoom, editmode, name, dir,
     last_loaded = cid;
     // Not sure why resize and topmost are here-- but we'll pass them on for
     // the time being...
+    // ico@vt.edu 2020-08-24: this is because in 1.x we can change these window
+    // properties via scripting. We should add this to 2.x soon...
     create_window(cid, "pd_canvas", width, height,
         xpos, ypos, {
             menu_flag: menu_flag,
@@ -2466,7 +2470,9 @@ function gui_atom_redraw_border(cid, tag, type, width, height) {
 }
 
 // draw a patch cord
-function gui_canvas_line(cid,tag,type,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) {
+// ico@vt.edu: p11 added to provide different color for when the cord is
+// being created vs when it is being finished
+function gui_canvas_line(cid,tag,type,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11) {
     gui(cid).get_elem("patchsvg")
     .append(function(frag) {
         var svg = get_item(cid, "patchsvg"),
@@ -2484,8 +2490,8 @@ function gui_canvas_line(cid,tag,type,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10) {
             d: d_array.join(" "),
             fill: "none",
             //"shape-rendering": "optimizeSpeed",
-            id: tag,
-            "class": "cord " + type
+            id: tag, 
+            "class": "cord " + type + (p11 == 1 ? " new" : "")
         });
         frag.appendChild(path);
         return frag;
@@ -3010,6 +3016,8 @@ function gui_numbox_draw_text(cid,tag,text,font_size,color,xpos,ypos,basex,basey
     // below. But it works for most font sizes.
     gui(cid).get_gobj(tag)
     .append(function(frag, w) {
+    	//post("ypos=" + ypos + " int=" + Math.floor(ypos));
+    	//ypos = Math.floor(ypos);
         var svg_text = create_item(cid, "text", {
             transform: "translate(" +
                         (xpos - basex) + "," +
@@ -3679,7 +3687,7 @@ function gui_scalar_new(cid, tag, isselected, t1, t2, t3, t4, t5, t6,
                     //matrix = [t1,t2,t3,t4+1,t5+0.5,t6+0.5];
                     matrix = 0;
                     transform_string = "translate(" + (t5+(t1 < 1 ? 0.5 : 1.5)) +
-                        "," + (t6+1) + ") scale(" + t1 + "," + t4 + ")";
+                        "," + (t6+1.5) + ") scale(" + t1 + "," + t4 + ")";
                     //post("transform_string = " + transform_string);
                     break;
                 default:
@@ -4083,9 +4091,11 @@ function img_size_setter(cid, svg_image_tag, type, data, tk_anchor) {
     img.onload = function() {
         w = this.width,
         h = this.height;
+        // ico@vt.edu here we subtract one from the svg interpretation
+        // of the anchor to keep it 1.x and K12 mode compatible
         configure_item(get_item(cid, svg_image_tag), {
-            width: w,
-            height: h,
+            width: w + 1,
+            height: h + 1,
             x: tk_anchor === "center" ? 0 - w/2 : 0,
             y: tk_anchor === "center" ? 0 - h/2 : 0
         });
@@ -4233,31 +4243,38 @@ function gui_image_size_callback(cid, key, callback) {
         ";base64," + pd_cache.get(key).data;
 }
 
-function gui_image_draw_border(cid, tag, x, y, w, h) {
-    gui(cid).get_gobj(tag)
-    .append(function(frag) {
-        var b = create_item(cid, "path", {
-            "stroke-width": "1",
-            fill: "none",
-            d: ["m", x, y, w, 0,
-                "m", 0, 0, 0, h,
-                "m", 0, 0, -w, 0,
-                "m", 0, 0, 0, -h
-               ].join(" "),
-            visibility: "hidden",
-            class: "border"
+function gui_image_toggle_border(cid, tag, x, y, w, h, onoff) {
+    if (onoff == 0) {
+        gui(cid).get_gobj(tag)
+        .q("path", function(border) {
+            border.parentNode.removeChild(border);
         });
-        frag.appendChild(b);
-        return frag;
-    });
+    } else {
+        gui(cid).get_gobj(tag)
+        .append(function(frag) {
+            var b = create_item(cid, "path", {
+                "stroke-width": "1",
+                fill: "none",
+                d: ["m", x, y, w, 0,
+                    "m", 0, 0, 0, h,
+                    "m", 0, 0, -w, 0,
+                    "m", 0, 0, 0, -h
+                   ].join(" "),
+                visibility: "visible",
+                class: "border"
+            });
+            frag.appendChild(b);
+            return frag;
+        });
+    }
 }
 
-function gui_image_toggle_border(cid, tag, state) {
+/*function gui_image_toggle_border(cid, tag, state) {
     gui(cid).get_gobj(tag)
     .q(".border", {
         visibility: state === 0 ? "hidden" : "visible"
     });
-}
+}*/
 
 // Switch the data for an existing svg image
 function gui_image_configure(cid, tag, image_key, tk_anchor) {
@@ -5410,7 +5427,7 @@ function attr_array_to_object(attr_array) {
 }
 
 function gui_gatom_dialog(did, attr_array) {
-    dialogwin[did] = create_window(did, "gatom", 265, 300,
+    dialogwin[did] = create_window(did, "gatom", 259, 278-5,
         popup_coords[2], popup_coords[3],
         attr_array_to_object(attr_array));
 }
@@ -5426,10 +5443,14 @@ function gui_gatom_activate(cid, tag, state) {
 }
 
 function gui_dropdown_dialog(did, attr_array) {
-    // Just reuse the "gatom" dialog
-    dialogwin[did] = create_window(did, "gatom", 265, 300,
+    // Just reuse the "gatom" dialog (this is not true anymore, see below)
+    // ico@vt.edu 2020-08-21: made this into a separate dialog due to inability to easily retitle
+    // the window
+    dialogwin[did] = create_window(did, "dropdown", 222, 268-5,
         popup_coords[2], popup_coords[3],
         attr_array_to_object(attr_array));
+    // ico@vt.edu 2020-08-21: the following does not work because the window is not created yet?
+    //dialogwin[did].window.document.getElementById("titlebar_title").innerHTML = "dropdown properties";
 }
 
 function dropdown_populate(w, label_array, current_index) {
@@ -5522,8 +5543,12 @@ function gui_iemgui_dialog(did, attr_array) {
     //for (var i = 0; i < attr_array.length; i++) {
     //    attr_array[i] = '"' + attr_array[i] + '"';
     //}
-    create_window(did, "iemgui", 265, 450,
-        popup_coords[2], popup_coords[3],
+    // ico@vt.edu: updated window size to match actual, thereby minimizing the flicker
+    // We are subtracting 25 for the menu
+    // ico@vt.edu: since adding frameless window, we use top 20px for draggable titlebar,
+    // so now we subtract only 5 (25-20)
+    create_window(did, "iemgui", 298, 414-5,
+        popup_coords[2] + 10, popup_coords[3] + 60,
         attr_array_to_object(attr_array));
 }
 
@@ -5544,6 +5569,28 @@ function gui_font_dialog_change_size(did, font_size) {
     }
 }
 
+function gui_menu_font_change_size(canvas, newsize) {
+    pdsend(canvas, "menufont", newsize);
+    	// ico@vt.edu 2020-08-24: changed to use submenu
+    	// this was the following
+        /*+document.querySelector('input[name="font_size"]:checked').value,
+        current_size,
+        100,
+        0 // "$noundo" from pd.tk-- not sure what it does*/
+}
+
+exports.gui_menu_font_change_size = gui_menu_font_change_size;
+
+function gui_menu_font_set_initial_size(cid, size) {
+	//post("gui_menu_font_set_initial_size " + cid + " " + size);
+	gui(cid).get_nw_window(function(nw_win) {
+		if (cid !== "nobody") {
+    		nw_win.window.init_menu_font_size(size);
+    		//post("this should work");
+    	}
+    });
+}
+
 function gui_array_new(did, count) {
     var attr_array = [{
         array_gfxstub: did,
@@ -5554,11 +5601,13 @@ function gui_array_new(did, count) {
         array_outline: "black",
         array_in_existing_graph: 0
     }];
-    dialogwin[did] = create_window(did, "canvas", 265, 340, 20, 20,
+    dialogwin[did] = create_window(did, "canvas",
+        240 + (5 * nw_os_is_linux) - (30 * nw_os_is_osx), 268-25, 20, 20,
         attr_array);
 }
 
 function gui_canvas_dialog(did, attr_arrays) {
+	//post("gui_canvas_dialog");
     var i, j, inner_array, prop;
     // Convert array of arrays to an array of objects
     for (i = 0; i < attr_arrays.length; i++) {
@@ -5569,13 +5618,26 @@ function gui_canvas_dialog(did, attr_arrays) {
             }
         }
     }
-    dialogwin[did] = create_window(did, "canvas", 300, 100,
+    var has_array = (attr_arrays.length > 1 ? 1 : 0);
+    /*
+    post("array.length=" + attr_arrays.length + " has_array=" + has_array +" width=" +
+    	(230 - (8 * has_array)) + " height=" +
+    	(attr_arrays.length > 1 ? 494-25+(attr_arrays.length > 2 ? 38 : 0) : 392-25));
+    */
+    dialogwin[did] = create_window(did, "canvas",
+        // ico@vt.edu: property dialog size is larger when one has
+        // arrays inside the canvas.
+        // 1 for regular canvas and 2 for a canvas with 1 array,
+        // 3 for canvas with 2 arrays, etc.
+        // We also substract here 5 for the smaller top bar...
+        238 + (8 * has_array),
+        (attr_arrays.length > 1 ? 535-25 : 392-25),
         popup_coords[2], popup_coords[3],
         attr_arrays);
 }
 
 function gui_data_dialog(did, data_string) {
-    dialogwin[did] = create_window(did, "data", 250, 300,
+    dialogwin[did] = create_window(did, "data", 195, 323 + (22 * nw_os_is_osx),
         popup_coords[2], popup_coords[3],
         data_string);
 }
@@ -5631,14 +5693,16 @@ function gui_remove_gfxstub(did) {
     }
 }
 
-function gui_font_dialog(cid, gfxstub, font_size) {
-    var attrs = { canvas: cid, font_size: font_size };
-    dialogwin[gfxstub] = create_window(gfxstub, "font", 265, 200, 0, 0,
-        attrs);
+function gui_font_dialog(cid, font_size) {
+    //var attrs = { canvas: cid, font_size: font_size };
+    //dialogwin[gfxstub] = create_window(gfxstub, "font", 136, 187, 0, 0,
+    //    attrs);
+    // ico@vt.edu: 2020-08-24: we don't need this anymore since everything
+    // is now inside the menu
 }
 
 function gui_external_dialog(did, external_name, attr_array) {
-    create_window(did, "external", 265, 450,
+    create_window(did, "external", 202, 323 + (22 * nw_os_is_osx),
         popup_coords[2], popup_coords[3],
         {
             name: external_name,
@@ -5656,7 +5720,7 @@ function gui_pd_dsp(state) {
 
 function open_prefs() {
     if (!dialogwin["prefs"]) {
-        create_window("prefs", "prefs", 370, 470, 0, 0, null);
+        create_window("prefs", "prefs", 486, 532, 0, 0, null);
     } else {
         dialog_raise("prefs");
     }
@@ -5672,7 +5736,7 @@ function open_search() {
     }
 }
 
-exports.open_search= open_search;
+exports.open_search = open_search;
 
 // This is the same for all windows (initialization is in pd_menus.js).
 var recent_files_submenu = null;
@@ -5881,8 +5945,12 @@ exports.get_style_by_selector = get_style_by_selector;
 // the user clicks a box in edit mode. One set of points for
 // the "head", or main box, and the other for the "tail", or
 // message flag at the right.
-function generate_msg_box_bg_data(type, stroke) {
-   return 'url(\"data:image/svg+xml;utf8,' +
+// ico@vt.edu 2020-08-31: if you thought the original hack was
+// ugly, wait until you see this new version. Hold onto your 
+// binary barf bags...
+function generate_msg_box_bg_data(type, stroke, height) {
+    //post("height="+height);
+    var header = 'url(\"data:image/svg+xml;utf8,' +
             '<svg ' +
               "xmlns:svg='http://www.w3.org/2000/svg' " +
               "xmlns='http://www.w3.org/2000/svg' " +
@@ -5890,20 +5958,43 @@ function generate_msg_box_bg_data(type, stroke) {
               "version='1.0' " +
               "viewBox='0 0 10 10' " +
               "preserveAspectRatio='none'" +
-            ">" +
-              "<polyline vector-effect='non-scaling-stroke' " +
+            ">";
+
+    var line_header = "<polyline vector-effect='non-scaling-stroke' " +
                 "id='bubbles' " +
                 "fill='none' " +
                 "stroke=' " +
                   stroke + // Here's our stroke color
-                "' " +
-                "stroke-width='1' " +
-                (type === "head" ?
-                    "points='10 0 0 0 0 10 10 10' " : // box
-                    "points='0 0 10 0 0 2 0 8 10 10 0 10' ") + // flag
-              "/>" +
-            "</svg>" +
+                "' ";
+
+    var line_ender = "</svg>" +
           '")';
+
+    if (type === "head")
+    {
+        return header + line_header + "stroke-width='2' points='10 0 0 0 0 10 10 10' />" + line_ender;
+    }
+    else {
+        // testing scaling of the flags with the increasing number of lines, top_flag, then bottom_flag
+        // 1 line:  2.5   7.5
+        // 2 lines: 1.5   8.5
+        // 3 lines: 1     9
+        // 4 lines: 0.75  9.25
+        var top_flag  = 2.5;
+        var decrement = 1;
+        while(height > 1)
+        {
+            top_flag -= decrement;
+            decrement /= 2;
+            height--;
+        }
+        var bottom_flag = 10 - top_flag;
+        return header +
+            line_header + "stroke-width='2' points='0 0 10 0' />" +
+            line_header + "stroke-width='2' points='0 10 10 10' />" +
+            line_header + "stroke-width='1' points='10 0 1 " + top_flag + " 1 " + bottom_flag + " 10 10' />" +
+            line_ender;
+    }
 }
 
 // Big problem here-- CSS fails miserably at something as simple as the
@@ -5918,12 +6009,47 @@ function generate_msg_box_bg_data(type, stroke) {
 // more and more apparent.
 // Anyhow, this enormous workaround makes it possible to just specify the
 // edit box color in CSS for the presets.
-function shove_svg_background_data_into_css(w) {
+function shove_svg_background_data_into_css(w, height) {
     var head_style = get_style_by_selector(w, "#new_object_textentry.msg"),
         tail_style = get_style_by_selector(w, "p.msg::after"),
         stroke = head_style.outlineColor;
-    head_style.backgroundImage = generate_msg_box_bg_data("head", stroke);
-    tail_style.backgroundImage = generate_msg_box_bg_data("tail", stroke);
+    head_style.backgroundImage = generate_msg_box_bg_data("head", stroke, height);
+    tail_style.backgroundImage = generate_msg_box_bg_data("tail", stroke, height);
+}
+
+function textarea_line_height_kludge(font_size) {
+	switch(font_size) {
+		case 8: return "133%";
+		case 10: return "133%";
+		case 12: return "140%";
+		case 16: return "120%";
+		case 24: return "128%";
+		case 36: return "122%";
+	}
+}
+
+function textarea_y_offset_kludge(font_size) {
+	switch(font_size) {
+		case 8: return 1.5;
+		case 10: return 0.5;
+		case 12: return 1.5;
+		case 16: return 1.5;
+		case 24: return 1.5;
+		case 36: return 1.5;
+	}
+}
+
+function textarea_msg_kludge(zoom) {
+    switch(zoom) {
+        case 0: return -1;
+        case 1: return -0.5;
+        case 2: return -0.5;
+        case 3: return -0.5;
+        case 4: return -0.5;
+        case 5: return -0.5;
+        case 6: return -0.5;
+        case 7: return -0.5;
+    }
 }
 
 function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
@@ -5954,8 +6080,6 @@ function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
         svg_view = patchwin[cid].window.document.getElementById("patchsvg")
             .viewBox.baseVal;
         p.classList.add(type);
-        // ico@vt.edu: is there a better way to monitor vars inside nw?
-        // p.classList.add("zoom=" + zoom);
         p.contentEditable = "true";
 
         if (is_gop == 0) {
@@ -5976,27 +6100,39 @@ function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
             */   
         }
         
-        p.style.setProperty("left", (x - svg_view.x) + "px");
-        p.style.setProperty("top", (y - svg_view.y) + "px");
+        p.style.setProperty("left", (x - svg_view.x - 0.5) + "px");
+        p.style.setProperty("top", (y - svg_view.y + textarea_y_offset_kludge(font_size)) + "px");
         p.style.setProperty("font-size",
             pd_fontsize_to_gui_fontsize(font_size) + "px");
         p.style.setProperty("line-height",
-            pd_fontsize_to_gui_fontsize(font_size) + 1 + "px");
+        	textarea_line_height_kludge(font_size));
+            //pd_fontsize_to_gui_fontsize(font_size) + 1 + "px");
         p.style.setProperty("transform", "translate(0px, " + 
             (zoom > 0 ? 0.5 : 0) + "px)");
         p.style.setProperty("max-width",
             width_spec > 0 ? width_spec + "ch" : "60ch");
+        //p.style.setProperty("width", -width_spec - 2 + "px");
+        p.style.setProperty("-webkit-padding-after", "1px");
         p.style.setProperty("min-width",
             width_spec == 0 ? "3ch" :
-                (is_gop == 1 ? width_spec + "px" :
-                    (width_spec < 0 ? (-width_spec) + "px" : width_spec + "ch")));
+                (is_gop == 1 ? width_spec - 3 + "px" :
+                    (width_spec < 0 ? (-width_spec) - 2 + "px" : width_spec + "ch")));
 
         if (is_gop == 1) {
-            p.style.setProperty("min-height", height_spec + "px");
+            p.style.setProperty("min-height", height_spec - 4 + "px");
         }
         // set backgroundimage for message box
         if (type === "msg") {
-            shove_svg_background_data_into_css(patchwin[cid].window);
+            // ico@vt.edu: 2020-08-31: message boxes are uniquely borked
+            // so, we do our best to address that here
+            p.style.setProperty("-webkit-padding-before", "2px");
+            p.style.setProperty("-webkit-padding-after", "3px");
+            p.style.setProperty("transform", "translate(0px, " +
+                textarea_msg_kludge(zoom) + "px)");
+            //post("line-height="+ parseInt(p.style.lineHeight) / 100 * font_size);
+            shove_svg_background_data_into_css(patchwin[cid].window,
+                parseInt(get_gobj(cid, tag).getBoundingClientRect().height /
+                    (parseInt(p.style.lineHeight) / 100 * font_size)));
         }
         // remove leading/trailing whitespace
         text = text.trim();
@@ -6005,6 +6141,13 @@ function gui_textarea(cid, tag, type, x, y, width_spec, height_spec, text,
         patchwin[cid].window.document.body.appendChild(p);
         p.focus();
         select_text(cid, p, sel_start, sel_end);
+        if (font_size === 36) {
+            if (is_gop) {
+                p.style.setProperty("padding", "2px 0px 2px 2.5px");
+            } else {
+                p.style.setProperty("padding", "2px 0px 2px 1.5px");
+            }
+        }
         if (state === 1) {
             patchwin[cid].window.canvas_events.text();
         } else {
@@ -6480,8 +6623,20 @@ exports.dialog_bindings = function(did) {
 exports.resize_window = function(did) {
     var w = dialogwin[did].window.document.body.scrollWidth,
         h = dialogwin[did].window.document.body.scrollHeight;
-    dialogwin[did].width = w;
-    dialogwin[did].height = h;
+    // ico@vt.edu: the following is a change needed for the nw.js 0.47
+    // for the dialog window to be properly resized
+    //dialogwin[did].width = w;
+    //dialogwin[did].height = h;
+    //dialogwin[did].window.document.body.titlebar_close_button.style.setProperty
+    //    ("font-size", (process.platform === "win32" ? "21px" : "15px"));
+    /*post(did + " body: w=" + dialogwin[did].window.document.body.clientWidth +
+        " h=" + dialogwin[did].window.document.body.clientHeight + " scroll: w=" +
+        w + " h=" + h);*/
+    dialogwin[did].resizeTo(w,h);
+    //ico@vt.edu: comment the following line when working on dialog sizes...
+    dialogwin[did].setResizable(false);
+    //post("dialog set always on top");
+    //dialogwin[did].setAlwaysOnTop(true);
 }
 
 // External GUI classes
@@ -6572,3 +6727,21 @@ function gui_update_scrollbars(cid) {
 }
 
 exports.gui_update_scrollbars = gui_update_scrollbars;
+
+// ico@vt.edu 2020-08-29: fine-tune appearance of various
+// css elements because, consistency in HTML font rendering
+// across different OSs is a joke
+function gui_check_for_dialog_appearance_inconsistencies(id)
+{
+    if (nw_os_is_osx)
+        gui_osx_dialog_appearance(id);
+}
+
+exports.gui_check_for_dialog_appearance_inconsistencies = gui_check_for_dialog_appearance_inconsistencies;
+
+function gui_osx_dialog_appearance(id)
+{
+    var close_button = dialogwin[id].window.document.getElementById("titlebar_close_button");
+    close_button.style.setProperty("line-height", "14px");
+    close_button.style.setProperty("border-radius", "10px");
+}
\ No newline at end of file
diff --git a/pd/src/g_canvas.c b/pd/src/g_canvas.c
index e29d802d7a92cac7aa11515eabde57056edd7efd..279a69ae86570616cb12366adfedc8edce742c9f 100644
--- a/pd/src/g_canvas.c
+++ b/pd/src/g_canvas.c
@@ -618,6 +618,8 @@ void glist_glist(t_glist *g, t_symbol *s, int argc, t_atom *argv)
 {
     if (canvas_hasarray(g)) return;
     pd_vmess(&g->gl_pd, gensym("editmode"), "i", 1);
+    // disallow creation of new objects in scalars only window
+    if (canvas_has_scalars_only(g) == 2) return;
     t_symbol *sym = atom_getsymbolarg(0, argc, argv);
     /* if we wish to put a graph where the mouse is we need to replace bogus name */
     if (!strcmp(sym->s_name, "NULL")) sym = &s_;  
@@ -728,14 +730,15 @@ void canvas_args_to_string(char *namebuf, t_canvas *x)
     {
         namebuf[0] = 0;
         t_gobj *g = NULL;
+        t_garray *a = NULL;
         t_symbol *arrayname;
-        int found = 0;
+        int found = 0, res;
         for (g = x->gl_list; g; g = g->g_next)
         {
 
             if (pd_class(&g->g_pd) == garray_class)
             {
-                garray_getname((t_garray *)g, &arrayname);
+                res = garray_getname((t_garray *)g, &arrayname);
                 if (found)
                 {
                     strcat(namebuf, " ");
@@ -2445,7 +2448,16 @@ void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x,
         t_glist *owner = glist_getcanvas(x);
         /* Just unvis the object, then vis it once we've done our
            mutation and checks */
-        gobj_vis((t_gobj *)x, owner, 0);
+        /* ico@vt.edu 2020-08-26: this was owner instead of x->gl_owner However,
+           there is a special case where this causes consistency check error 
+           in canvas_vis because a gop patch size is being manipulated on the
+           parent window and its window is also visible, glist_getcanvas() will
+           return its own window even though the user is manipulating the size
+           on the parent window. So, here we ensure that we are always getting
+           the parent window, and then we update the red rectangle on its own
+           window below (see if (x->gl_havewindow)). The same is true for vising
+           towards the bottom of this function. */
+        gobj_vis((t_gobj *)x, x->gl_owner, 0);
         /* struct _glist has its own member e_xnew for storing our offset.
            At some point we need to refactor since our t_scalehandle has
            members for storing offsets already. */
@@ -2481,9 +2493,22 @@ void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x,
         owner->gl_editor->e_xnew = mouse_x;
         owner->gl_editor->e_ynew = mouse_y;
         canvas_fixlinesfor(owner, (t_text *)x);
-        gobj_vis((t_gobj *)x, owner, 1);
+        gobj_vis((t_gobj *)x, x->gl_owner, 1);
         canvas_dirty(owner, 1);
 
+        /* ico@vt.edu 2020-08-26: if we are changing the gop size
+           on the parent window with our own window open, updated the 
+           red rectangle on our own window */
+        if (x->gl_havewindow)
+        {
+            gui_vmess("gui_canvas_redrect_coords", "xiiii",
+                x,
+                x->gl_xmargin,
+                x->gl_ymargin,
+                x->gl_xmargin + x->gl_pixwidth,
+                x->gl_ymargin + x->gl_pixheight);
+        }
+
         int properties = gfxstub_haveproperties((void *)x);
         if (properties)
         {
@@ -2517,6 +2542,14 @@ void canvasgop__motionhook(t_scalehandle *sh, t_floatarg mouse_x,
             properties_set_field_int(properties,
                 "y_pix",x->gl_pixheight + sh->h_dragy);
         }
+        /* ico@vt.edu: resize parent window gop rectangle if visible
+           as an added bonus, this also works even if it is only
+           visible inside another gop (gop within a gop within a gop) */
+        if (x->gl_owner && glist_isvisible(x->gl_owner))
+        {
+            gobj_vis(&x->gl_gobj, x->gl_owner, 0);
+            gobj_vis(&x->gl_gobj, x->gl_owner, 1);
+        }
     }
     else /* move_gop hook */
     {
diff --git a/pd/src/g_canvas.h b/pd/src/g_canvas.h
index 964d8fab820992ae09b20e49af661c5d8f472645..af31d80f1e000ba10e4837b2f43792dd27b54c37 100644
--- a/pd/src/g_canvas.h
+++ b/pd/src/g_canvas.h
@@ -572,6 +572,8 @@ EXTERN t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos,
     int *x1p, int *y1p, int *x2p, int *y2p);
 EXTERN int canvas_setdeleting(t_canvas *x, int flag);
 EXTERN int canvas_hasarray(t_canvas *x);
+EXTERN int canvas_has_scalars_only(t_canvas *x);
+
 
 #define LB_LOAD 0       /* "loadbang" actions - 0 for original meaning */
 #define LB_INIT 1       /* loaded but not yet connected to parent patch */
diff --git a/pd/src/g_editor.c b/pd/src/g_editor.c
index ecec351057873f5664ce0de70d38f7569c7e406e..5e30db534613c65e74e9f73fd82fb8c96fb41fe1 100644
--- a/pd/src/g_editor.c
+++ b/pd/src/g_editor.c
@@ -2674,6 +2674,14 @@ void canvas_map(t_canvas *x, t_floatarg f);
 //extern t_rtext *glist_findrtext(t_glist *gl, t_text *who);
 //extern void rtext_gettext(t_rtext *x, char **buf, int *bufsize);
 
+// ico@vt.edu 2020-08-24: update initial menu settings
+void canvas_init_menu(t_canvas *x)
+{   
+    //post("g_editor.c canvas_init_menu %d", x->gl_font);
+    // ico@vt.edu 2020-08-24: we now need this to init the menu font size
+    gui_vmess("gui_menu_font_set_initial_size", "xi", x, x->gl_font);
+}
+
 void canvas_vis(t_canvas *x, t_floatarg f)
 {
     //fprintf(stderr,"canvas_vis .x%lx %f\n", (t_int)x, f);
@@ -2757,6 +2765,7 @@ void canvas_vis(t_canvas *x, t_floatarg f)
             /* It looks like this font size call is no longer needed,
                but I'm not sure why it was needed in the first place... */
             //sys_vgui("pdtk_canvas_set_font .x%lx %d\n", x, x->gl_font);
+
             //canvas_reflecttitle(x);
             x->gl_havewindow = 1;
 
@@ -3457,7 +3466,7 @@ static int text_resizing_hotspot(t_canvas *x, t_object *ob, int xpos, int ypos,
 
         /* gop canvases, gop red rectangle, scope, grid, iemguis except [cnv] */
     if ((ob->te_iemgui && ob->ob_pd != my_canvas_class) ||
-        ob->ob_pd == canvas_class ||
+        (ob->ob_pd == canvas_class && ((t_canvas *)ob)->gl_isgraph) ||
         ob->ob_pd->c_name == gensym("Scope~") ||
         ob->ob_pd->c_name == gensym("grid"))
     {
@@ -3805,7 +3814,7 @@ void canvas_doclick(t_canvas *x, int xpos, int ypos, int which,
                         x->gl_editor->e_xwas = hotspot + IOWIDTH / 2;
                         x->gl_editor->e_ywas = y2 - 2;
                         /* This repetition of args needs to be pruned below */
-                        gui_vmess("gui_canvas_line", "xssiiiiiiiiii",
+                        gui_vmess("gui_canvas_line", "xssiiiiiiiiiii",
                             x,
                             "newcord",
                             (issignal ? "signal" : "control"),
@@ -4309,7 +4318,7 @@ void canvas_drawconnection(t_canvas *x, int lx1, int ly1, int lx2, int ly2,
     }
     if (yoff > ymax) yoff = ymax;
     sprintf(tagbuf, "l%lx", (long unsigned int)tag);
-    gui_vmess("gui_canvas_line", "xssiiiiiiiiii",
+    gui_vmess("gui_canvas_line", "xssiiiiiiiiiii",
         x,
         tagbuf,
         (issignal ? "signal" : "control"),
@@ -4322,7 +4331,8 @@ void canvas_drawconnection(t_canvas *x, int lx1, int ly1, int lx2, int ly2,
         lx2,
         ly2 - yoff,
         lx2,
-        ly2);
+        ly2,
+        0);
 }
 
 void canvas_updateconnection(t_canvas *x, int lx1, int ly1, int lx2, int ly2,
@@ -6005,15 +6015,22 @@ void canvas_menuclose(t_canvas *x, t_floatarg fforce)
 }
 
     /* put up a dialog which may call canvas_font back to do the work */
-static void canvas_menufont(t_canvas *x)
+static void canvas_menufont(t_canvas *x, t_floatarg newsize)
 {
     t_canvas *x2 = canvas_getrootfor(x);
-    gfxstub_deleteforkey(x2);
-    char *gfxstub = gfxstub_new2(&x2->gl_pd, &x2->gl_pd);
-    gui_vmess("gui_font_dialog", "xsi",
-        x2,
-        gfxstub,
-        x2->gl_font);
+    //gfxstub_deleteforkey(x2);
+    //char *gfxstub = gfxstub_new2(&x2->gl_pd, &x2->gl_pd);
+    if (newsize != x2->gl_font)
+    {
+        // additional args copied from dialog_font.html
+        canvas_font(x2, newsize, x2->gl_font, 100.0, 0.0);
+    }
+    /*{
+        gui_vmess("gui_font_dialog", "xi",
+            x2,
+            //gfxstub,
+            x2->gl_font);
+    }*/
 }
 
 static int canvas_find_index1, canvas_find_index2, canvas_find_wholeword;
@@ -7948,7 +7965,10 @@ void canvas_editmode(t_canvas *x, t_floatarg fyesplease)
     //fprintf(stderr,"canvas_editmode %f\n", fyesplease);
 
     /* first check if this is a canvas hosting an array and if so
-       refuse to add any further objects */
+       refuse to add any further objects. we allow edit mode on the
+       subpatches that have only scalars, as that allows for their
+       repositioning/deletion/etc.
+    */
     if (canvas_hasarray(x)) return;
 
     int yesplease = fyesplease;
@@ -8067,11 +8087,11 @@ static void canvas_dofont(t_canvas *x, t_floatarg font, t_floatarg xresize,
 {
     t_gobj *y;
     x->gl_font = font;
-    if (x->gl_isgraph && !canvas_isabstraction(x) &&
+    /*if (x->gl_isgraph && !canvas_isabstraction(x) &&
         (xresize != 1 || yresize != 1) && !glist_istoplevel(x))
     {
         vmess(&x->gl_pd, gensym("menu-open"), "");
-    }
+    }*/
     if (xresize != 1 || yresize != 1)
     {
         for (y = x->gl_list; y; y = y->g_next)
@@ -8335,7 +8355,9 @@ void g_editor_setup(void)
     class_addmethod(canvas_class, (t_method)canvas_print,
         gensym("print"), A_SYMBOL, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_menufont,
-        gensym("menufont"), A_NULL);
+        gensym("menufont"), A_FLOAT, A_NULL);
+    class_addmethod(canvas_class, (t_method)canvas_init_menu,
+        gensym("updatemenu"), A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_font,
         gensym("font"), A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_NULL);
     class_addmethod(canvas_class, (t_method)canvas_zoom,
diff --git a/pd/src/g_graph.c b/pd/src/g_graph.c
index 7f806a721942d12811177f6bdba77f15b2e558a6..7c1bf59e92c7257e98b22dc206fea99e14be3237 100644
--- a/pd/src/g_graph.c
+++ b/pd/src/g_graph.c
@@ -60,6 +60,79 @@ int canvas_isgroup(t_canvas *x)
 extern t_template *canvas_findtemplate(t_canvas *c);
 extern t_canvas *canvas_templatecanvas_forgroup(t_canvas *c);
 
+
+/* ico@vt.edu 2020-08-24:
+check if canvas consists of only scalars and returns 2. if the canvas only
+has the last object as a non-scalar (e.g. a new object has just been created,
+then we return 1, otherwise return 0. this is used to prevent creation of new
+objects in an GOP window that only has scalars inside it or scalars with one
+newly created object that is yet to be typed into and therefore properly
+instantiated */
+int canvas_has_scalars_only(t_canvas *x)
+{
+    t_gobj *g = x->gl_list;
+    int hasonlyscalars = 2;
+    while (g)
+    {
+        //post("g...");
+        if (pd_class(&g->g_pd) != scalar_class)
+        {
+            /*
+            post("...scalar=NO %s %s", 
+                (pd_class(&g->g_pd) == text_class ? "text_class" : "NOT_text_class"),
+                (((t_text *)g)->te_type == T_TEXT) ? "T_TEXT" : "NOT_T_TEXT");
+            */
+
+            /* ico@vt.edu 2020-08-24:
+            if we have one more object or the last object is not newly
+            instantiated text object
+            to distinguish between a comment and a text object that is 
+            yet to be instantiated we use:
+               1) comment is text_class and its te_type is T_TEXT
+               2) blank object one is typing into is text_class but is NOT T_TEXT
+               3) instantiated object is something other than text_class (unless)
+                  it is a comment
+               4) object that has failed to create is same as blank object
+            */
+            if (g->g_next || (pd_class(&g->g_pd) != text_class || ((t_text *)g)->te_type == T_TEXT))
+                hasonlyscalars = 0;
+            else
+                hasonlyscalars = 1;
+            break;
+        }
+        //post("...scalar, comment, or uninitialized object=yes");
+        g = g->g_next;
+    }
+    //post("has scalars only=%d", hasonlyscalars);
+    return(hasonlyscalars);
+}
+
+/* ico@vt.edu 2020-08-24: this draws or erases redrect on a gop window
+   and is being refactored due to complex logic involving subpatches with
+   scalars only that should not have a redrect until a non-scalar object
+   has been instantiated (this does not include empty objects that are
+   yet to be typed into, as this is one way how one can instantiate new
+   scalar inside a subpatch)
+*/
+void glist_update_redrect(t_glist *x)
+{
+    t_gobj *y = x->gl_list;
+    while(y->g_next) y = y->g_next;
+
+    if (x->gl_editor && x->gl_isgraph && !x->gl_goprect
+        && pd_checkobject(&y->g_pd) && !canvas_has_scalars_only(x))
+    {
+        //post("glist_add drawredrect %d", canvas_has_scalars_only(x));
+        x->gl_goprect = 1;
+        canvas_drawredrect(x, 1);
+    }
+    else if (canvas_has_scalars_only(x) && x->gl_goprect)
+    {
+         x->gl_goprect = 0;
+        canvas_drawredrect(x, 0);       
+    }
+}
+
 void glist_add(t_glist *x, t_gobj *y)
 {
     //fprintf(stderr,"glist_add %lx %d\n", (t_int)x, (x->gl_editor ? 1 : 0));    
@@ -84,12 +157,7 @@ void glist_add(t_glist *x, t_gobj *y)
         //    canvas_undo_set_create(x, index), "create");
         //glist_noselect(x);
     }
-    if (x->gl_editor && x->gl_isgraph && !x->gl_goprect
-        && pd_checkobject(&y->g_pd))
-    {
-        x->gl_goprect = 1;
-        canvas_drawredrect(x, 1);
-    }
+    glist_update_redrect(x);
     if (glist_isvisible(x))
         gobj_vis(y, x, 1);
     if (class_isdrawcommand(y->g_pd)) 
@@ -257,6 +325,8 @@ void glist_delete(t_glist *x, t_gobj *y)
             //fprintf(stderr,"glist_delete late_rtext_free\n");
             rtext_free(rt);
         }
+
+        if (x->gl_list) glist_update_redrect(x);
     }
 }
 
@@ -962,6 +1032,7 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
     }
 
         /* Sanity check */
+    //post("parent_glist=%lx x->gl_obj=%lx", parent_glist, &x->gl_obj);
     rtext = glist_findrtext(parent_glist, &x->gl_obj);
     if (!rtext)
     {
@@ -1028,6 +1099,16 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
             gui_vmess("gui_graph_fill_border", "xsi",
                 glist_getcanvas(x->gl_owner),
                 tag);
+			/* ico@vt.edu: do we need to redraw scalars here? */
+			for (g = x->gl_list; g; g = g->g_next)
+			{
+				gop_redraw = 1;
+				//fprintf(stderr,"drawing gop objects\n");
+				if (g->g_pd == scalar_class)
+					gobj_vis(g, x, 1);
+				//fprintf(stderr,"done\n");
+				gop_redraw = 0;
+			}
         }
         else if (gobj_shouldvis(gr, parent_glist))
         {
@@ -1089,7 +1170,7 @@ static void graph_vis(t_gobj *gr, t_glist *parent_glist, int vis)
                 gui_end_array();
             }
         }
-            /* Finally, end the final array as wel as the call to the GUI */
+            /* Finally, end the final array as well as the call to the GUI */
         gui_end_array();
         gui_end_vmess();
 
diff --git a/pd/src/g_numbox.c b/pd/src/g_numbox.c
index 80d3a66f9514376bbb8f97dc086d4404749b2a3c..63dd1bfd1cf0d55009de50699e6dc9b0b8ede853 100644
--- a/pd/src/g_numbox.c
+++ b/pd/src/g_numbox.c
@@ -166,7 +166,11 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
     t_canvas *canvas=glist_getcanvas(glist);
     char cbuf[8];
     sprintf(cbuf, "#%6.6x", x->x_gui.x_bcol);
-    int half=x->x_gui.x_h/2, d=1+x->x_gui.x_h/34;
+    int half=x->x_gui.x_h/2;
+    // ico@vt.edu 2020-08-24: this offset is better as float to ensure
+    // that the vertical positioning of the number is as close to the center
+    // as nw.js allows
+    t_float d=0.5+x->x_gui.x_h/34.0;
     int x1=text_xpix(&x->x_gui.x_obj, glist), x2=x1+x->x_numwidth;
     int y1=text_ypix(&x->x_gui.x_obj, glist), y2=y1+x->x_gui.x_h;
 
@@ -190,7 +194,7 @@ static void my_numbox_draw_new(t_my_numbox *x, t_glist *glist)
     }
     my_numbox_ftoa(x);
     sprintf(cbuf, "#%6.6x", x->x_gui.x_fcol);
-    gui_vmess("gui_numbox_draw_text", "xxsisiiii",
+    gui_vmess("gui_numbox_draw_text", "xxsisifii",
         canvas,
         x,
         x->x_buf,
diff --git a/pd/src/g_scalar.c b/pd/src/g_scalar.c
index 73c944ab5a00d108a6f3739ca979c0c4023a4c5a..2017535c27330d2b6c71a5182247bd82d49bb57a 100644
--- a/pd/src/g_scalar.c
+++ b/pd/src/g_scalar.c
@@ -148,7 +148,7 @@ void word_restore(t_word *wp, t_template *template,
                 argv++, argc--;
             }
             else f = 0;
-            wp->w_float = f; 
+            wp->w_float = f;
         }
         else if (type == DT_SYMBOL)
         {
diff --git a/pd/src/m_pd.h b/pd/src/m_pd.h
index bc8ee7fd33c93ab2e16b4876b023b6dbec0ebfb5..021f8493f7cce4c31d67a4048a3bef0fc4d10434 100644
--- a/pd/src/m_pd.h
+++ b/pd/src/m_pd.h
@@ -692,6 +692,7 @@ EXTERN void garray_setsaveit(t_garray *x, int saveit);
 EXTERN t_glist *garray_getglist(t_garray *x);
 EXTERN t_array *garray_getarray(t_garray *x);
 EXTERN t_class *scalar_class;
+EXTERN t_class *text_class;
 
 EXTERN t_float *value_get(t_symbol *s);
 EXTERN void value_release(t_symbol *s);
diff --git a/pd/src/x_text.c b/pd/src/x_text.c
index 333433a86c1e76c9dc863cc585dd197b3fb44937..4e5fe060e3758b3f00092ec17da895c212a53bac 100644
--- a/pd/src/x_text.c
+++ b/pd/src/x_text.c
@@ -131,8 +131,8 @@ static void textbuf_open(t_textbuf *x)
         gui_vmess("gui_text_dialog", "xsiii",
             x,
             x->b_sym->s_name,
-            600,
-            340,
+            480,
+            550,
             sys_hostfontsize(glist_getfont(x->b_canvas)));
         //textbuf_senditup(x);
     }