diff --git a/src/g_editor.c b/src/g_editor.c
index 7cb7972694aaeb2e48078c2a8aa60082b486028c..26f8f5619a59ed5745dadffbb195b9e733020166 100644
--- a/src/g_editor.c
+++ b/src/g_editor.c
@@ -3485,8 +3485,12 @@ void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av)
             || !strcmp(gotkeysym->s_name, "Down")
             || !strcmp(gotkeysym->s_name, "Left")
             || !strcmp(gotkeysym->s_name, "Right")
-			|| !strcmp(gotkeysym->s_name, "CtrlHome")
-			|| !strcmp(gotkeysym->s_name, "CtrlEnd")
+			|| !strcmp(gotkeysym->s_name, "CtrlLeft")
+			|| !strcmp(gotkeysym->s_name, "CtrlRight")
+			|| !strcmp(gotkeysym->s_name, "ShiftLeft")
+			|| !strcmp(gotkeysym->s_name, "ShiftRight")
+			|| !strcmp(gotkeysym->s_name, "CtrlShiftLeft")
+			|| !strcmp(gotkeysym->s_name, "CtrlShiftRight")
 			|| !strcmp(gotkeysym->s_name, "Home")
 			|| !strcmp(gotkeysym->s_name, "End")))
         {
diff --git a/src/g_rtext.c b/src/g_rtext.c
index bcfa6588e4bcf46f72909d07a96e8e020826de19..42daac36d894417545a4cab0e924a6c7a1f6a3d0 100644
--- a/src/g_rtext.c
+++ b/src/g_rtext.c
@@ -31,6 +31,12 @@
 #define SEND_UPDATE 2
 #define SEND_CHECK 0
 
+// selection for shift+arrow selecting
+// 0 = none;
+// 1 = start;
+// 2 = end;
+static int last_sel = 0;
+
 struct _rtext
 {
     char *x_buf;
@@ -447,7 +453,7 @@ void rtext_key(t_rtext *x, int keynum, t_symbol *keysym)
 {
     int w = 0, h = 0, indx, i, newsize, ndel;
     char *s1, *s2;
-	//post("keysym=%s", keysym->s_name);
+	//fprintf(stderr,"rtext_key keysym=%s\n", keysym->s_name);
     if (keynum)
     {
         int n = keynum;
@@ -506,6 +512,7 @@ be printable in whatever 8-bit character set we find ourselves. */
             x->x_selend = x->x_selstart = x->x_selstart + 1;
         else
             x->x_selstart = x->x_selend;
+		last_sel = 0;		
     }
     else if (!strcmp(keysym->s_name, "Left"))
     {
@@ -513,6 +520,30 @@ be printable in whatever 8-bit character set we find ourselves. */
             x->x_selend = x->x_selstart = x->x_selstart - 1;
         else
             x->x_selend = x->x_selstart;
+		last_sel = 0;
+    }
+    else if (!strcmp(keysym->s_name, "ShiftRight"))
+    {
+		if (!last_sel) last_sel = 2;
+		if (last_sel == 1 && x->x_selstart < x->x_selend) {
+		    if (x->x_selstart < x->x_bufsize)
+		        x->x_selstart =  x->x_selstart + 1;			
+		} else {
+			last_sel = 2;
+		    if (x->x_selend < x->x_bufsize)
+		        x->x_selend =  x->x_selend + 1;
+		}
+    }
+    else if (!strcmp(keysym->s_name, "ShiftLeft"))
+    {
+		if (!last_sel) last_sel = 1;
+        if (last_sel == 2 && x->x_selend > x->x_selstart) {
+            x->x_selend = x->x_selend - 1;
+		} else {
+			last_sel = 1;
+		    if (x->x_selstart > 0)
+		        x->x_selstart = x->x_selstart - 1;
+		}
     }
         /* this should be improved...  life's too short */
     else if (!strcmp(keysym->s_name, "Up") || !strcmp(keysym->s_name, "Home"))
@@ -522,6 +553,7 @@ be printable in whatever 8-bit character set we find ourselves. */
         while (x->x_selstart > 0 && x->x_buf[x->x_selstart] != '\n')
             x->x_selstart--;
         x->x_selend = x->x_selstart;
+		last_sel = 0;
     }
     else if (!strcmp(keysym->s_name, "Down") || !strcmp(keysym->s_name, "End"))
     {
@@ -531,8 +563,9 @@ be printable in whatever 8-bit character set we find ourselves. */
         if (x->x_selend < x->x_bufsize)
             x->x_selend++;
         x->x_selstart = x->x_selend;
+		last_sel = 0;
     }
-    else if (!strcmp(keysym->s_name, "CtrlHome"))
+    else if (!strcmp(keysym->s_name, "CtrlLeft"))
     {
 		/* first find first non-space char going back */
 		while (x->x_selstart > 0 && x->x_buf[x->x_selstart-1] == ' ')
@@ -542,11 +575,15 @@ be printable in whatever 8-bit character set we find ourselves. */
 		  x->x_buf[x->x_selstart] != '\n' &&
 		  x->x_buf[x->x_selstart-1] != ' ')
             x->x_selstart--;
-        x->x_selend = x->x_selstart;
+		if (x->x_buf[x->x_selstart+1] == ' ')
+			x->x_selstart++;
+		x->x_selend = x->x_selstart;
     }
-    else if (!strcmp(keysym->s_name, "CtrlEnd"))
+    else if (!strcmp(keysym->s_name, "CtrlRight"))
     {
 		/* now go forward until you find another space or the end of the buffer */
+		if (x->x_selend < x->x_bufsize - 1)
+			x->x_selend++;
         while (x->x_selend < x->x_bufsize &&
           x->x_buf[x->x_selend] != '\n' &&
 		  x->x_buf[x->x_selend] != ' ')
@@ -554,9 +591,71 @@ be printable in whatever 8-bit character set we find ourselves. */
 		/* now skip all the spaces and land before next word */
         while (x->x_selend < x->x_bufsize &&
 		  x->x_buf[x->x_selend] == ' ')
-            x->x_selend++;		
-        x->x_selstart = x->x_selend;
+            x->x_selend++;
+		if (x->x_selend > 0 && x->x_buf[x->x_selend-1] == ' ')
+			x->x_selend--;
+		x->x_selstart = x->x_selend;
     }
+    else if (!strcmp(keysym->s_name, "CtrlShiftLeft"))
+	{
+		int swap = 0;
+		int *target;
+		if (!last_sel) last_sel = 1;
+		if (last_sel == 2 && x->x_selend > x->x_selstart)
+			target = &x->x_selend;
+		else {
+			last_sel = 1;
+			target = &x->x_selstart;
+		}
+		/* first find first non-space char going back */
+		while (*target > 0 && x->x_buf[*target-1] == ' ')
+			(*target)--;
+		/* now go back until you find another space or the beginning of the buffer */
+        while (*target > 0 &&
+		  x->x_buf[*target] != '\n' &&
+		  x->x_buf[*target-1] != ' ')
+            (*target)--;
+		if (x->x_buf[*target+1] == ' ')
+			(*target)++;
+        if (x->x_selstart > x->x_selend) {
+			swap = x->x_selend;
+			x->x_selend = x->x_selstart;
+			x->x_selstart = swap;
+			last_sel = 1;
+		}
+	}
+    else if (!strcmp(keysym->s_name, "CtrlShiftRight"))
+	{
+		int swap = 0;
+		int *target;
+		if (!last_sel) last_sel = 2;
+		if (last_sel == 1 && x->x_selstart < x->x_selend)
+			target = &x->x_selstart;
+		else {
+			last_sel = 2;
+			target = &x->x_selend;
+		}
+		/* now go forward until you find another space or the end of the buffer */
+		if (*target < x->x_bufsize - 1)
+			(*target)++;
+        while (*target < x->x_bufsize &&
+          x->x_buf[*target] != '\n' &&
+		  x->x_buf[*target] != ' ')
+            (*target)++;
+		/* now skip all the spaces and land before next word */
+        while (*target < x->x_bufsize &&
+		  x->x_buf[*target] == ' ')
+            (*target)++;
+		if (*target > 0 && x->x_buf[*target-1] == ' ')
+			(*target)--;
+        if (x->x_selstart > x->x_selend) {
+			swap = x->x_selend;
+			x->x_selend = x->x_selstart;
+			x->x_selstart = swap;
+			last_sel = 2;
+		}
+	}
+
     rtext_senditup(x, SEND_UPDATE, &w, &h, &indx);
 }
 
diff --git a/src/pd.tk b/src/pd.tk
index 88e755b681b0a3c80aa616f3132313bd0226bc38..8a72ab5f95606ab02c5b89ec3d26df78690fdf91 100644
--- a/src/pd.tk
+++ b/src/pd.tk
@@ -230,6 +230,9 @@ if { $tcl_platform(platform) == "windows" }  {
 	set window_prefs {}
     set pd_nt 0
     set ctrl_key "Control"
+	# Shift modifier
+	set shift_l_down 0
+	set shift_r_down 0
 	# Ctrl modifier
 	set ctrl_l_down 0
 	set ctrl_r_down 0
@@ -739,7 +742,7 @@ pack .controls.dio -side right -padx 20
 #	pack .controls.clr_console -pady 30
 #}
 
-toplevel .printout -class pd-l2ork
+toplevel .printout -class [winfo class .]
 wm title .printout "Console"
 # initial location of the console window (+x+y)
 wm geometry .printout +10+170
@@ -1114,7 +1117,7 @@ proc menu_send {} {
     if { [winfo exists .sendpanel.entry] } {
         raise .sendpanel
     } else {
-		toplevel .sendpanel -class pd-l2ork
+		toplevel .sendpanel -class [winfo class .]
 		wm title .sendpanel {Send Message to Pd}
 		wm resizable .sendpanel 0 0
 		match_linux_wm [list .sendpanel configure]
@@ -1235,7 +1238,7 @@ proc menu_opentext {filename} {
         raise .about
     } else {
 		destroy .about
-		toplevel .about -class pd-l2ork
+		toplevel .about -class [winfo class .]
 		wm title .about "About Pd"
 		wm geometry .about 550x480
 		match_linux_wm [list text .about.text -relief sunken -bd 1 -font text_font \
@@ -1606,7 +1609,7 @@ proc makeapp_embedprefs {appdir patch_to_open} {
 }
 
 proc makeapp_busypanel {appdir} {
-	toplevel .makeapp -class pd-l2ork
+	toplevel .makeapp -class [winfo class .]
 	wm title .makeapp "Making App"
 	wm attributes .makeapp -topmost 1
 	wm resizable .makeapp 0 0
@@ -2058,7 +2061,7 @@ proc menu_findobject {canvas} {
 
 		set find_canvas $canvas
 		
-		toplevel .find -class pd-l2ork
+		toplevel .find -class [winfo class .]
 		wm title .find "Find"
 		match_linux_wm [list .find configure]
 		#wm geometry .find =400x125+150+100
@@ -2211,9 +2214,9 @@ proc pdtk_canvas_new {name width height geometry editable} {
 	}
 
 	if {$::menu($name) == 1} {
-    	toplevel $name -menu $name.m -class pd-l2ork
+    	toplevel $name -menu $name.m -class [winfo class .]
 	} else {
-		toplevel $name -menu "" -class pd-l2ork
+		toplevel $name -menu "" -class [winfo class .]
 	}
 
 	# initialize variable to reflect that this window has been open
@@ -3028,7 +3031,7 @@ proc pdtk_array_listview_new {id arrayName page} {
     set pd_array_listview_id($arrayName) $id
     set windowName [format ".%sArrayWindow" $arrayName]
     if [winfo exists $windowName] then [destroy $windowName]
-    toplevel $windowName -class pd-l2ork
+    toplevel $windowName -class [winfo class .]
 	wm geometry $windowName 220x400
 	wm minsize $windowName 220 400
 	#pdtk_standardkeybindings $windowName
@@ -3546,8 +3549,10 @@ proc pdtk_canvas_sendkey {name state key iso shift focus} {
     global pd_nt
 	global ctrl_l_down
 	global ctrl_r_down
+	global shift_l_down
+	global shift_r_down
 
-	# pdtk_post "key = $name $state $key $iso $shift\n"
+	#puts stderr "key = $name $state $key $iso $shift\n"
 
 	if {$key == "BackSpace"} {
 		set iso ""
@@ -3586,6 +3591,20 @@ proc pdtk_canvas_sendkey {name state key iso shift focus} {
 			set ctrl_r_down 0
 		}
 	}
+	if {$key == "Shift_L"} {
+		if {$state == 1} {
+			set shift_l_down 1
+		} else {
+			set shift_l_down 0
+		}
+	}
+	if {$key == "Shift_R"} {
+		if {$state == 1} {
+			set shift_r_down 1
+		} else {
+			set shift_r_down 0
+		}
+	}
 
 	if {$ctrl_l_down || $ctrl_r_down} {
 		set ctrl 1
@@ -3593,16 +3612,54 @@ proc pdtk_canvas_sendkey {name state key iso shift focus} {
 		set ctrl 0
 	}
 
-	if {[string match Home $key] && $ctrl} {
-		set key "CtrlHome"
-		set state 1
+	if {$shift_l_down || $shift_r_down} {
+		set shift 1
+	} else {
+		set shift 0
 	}
 
-	if {[string match End $key] && $ctrl} {
-		set key "CtrlEnd"
-		set state 1
+	#puts stderr "shift=$shift ctrl=$ctrl key=$key"
+
+	#if {[string match Home $key] && $ctrl} {
+	#	set key "CtrlHome"
+	#	set state 1
+	#}
+
+	#if {[string match End $key] && $ctrl} {
+	#	set key "CtrlEnd"
+	#	set state 1
+	#}
+
+	if {[string match Left $key]} {
+		if {$ctrl == 1 && $shift == 0} {
+			set key "CtrlLeft"
+			set state 1
+		}
+		if {$ctrl == 0 && $shift == 1} {
+			set key "ShiftLeft"
+		}
+		if {$ctrl == 1 && $shift == 1} {
+			set key "CtrlShiftLeft"
+			set state 1
+		}
 	}
 
+	if {[string match Right $key]} {
+		if {$ctrl == 1 && $shift == 0} {
+			set key "CtrlRight"
+			set state 1
+		}
+		if {$ctrl == 0 && $shift == 1} {
+			set key "ShiftRight"
+		}
+		if {$ctrl == 1 && $shift == 1} {
+			set key "CtrlShiftRight"
+			set state 1
+		}
+	}
+
+	#puts stderr "FINAL key=$key"
+
 	pd [canvastosym $name] key $state $key $shift $focus\;
 }
 
@@ -3943,7 +4000,7 @@ proc pdtk_canvas_dofont {name canvas initsize} {
 	set font_properties $name
 	set font_canvas $canvas
     
-    toplevel $name -class pd-l2ork
+    toplevel $name -class [winfo class .]
 	match_linux_wm [list $name configure]
 	wm resizable $name 0 0
     wm title $name  {Font Settings}
@@ -4112,7 +4169,7 @@ proc pdtk_gatom_dialog {id initwidth initlo inithi \
     set $var_gatomsymfrom [gatom_unescape $symfrom]
     set $var_gatomsymto [gatom_unescape $symto]
 
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
     wm title $id "Atom Box Properties"
 	match_linux_wm [list $id configure] 
     wm resizable $id 0 0
@@ -4852,7 +4909,7 @@ proc pdtk_iemgui_dialog {id mainheader \
     
     set $var_iemgui_l2_f1_b0 0
 
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
     wm title $id [format "%s Properties" $mainheader]
 	match_linux_wm [list $id configure]
     wm resizable $id 0 0
@@ -5242,7 +5299,7 @@ proc pdtk_array_dialog {id name n flags newone canvas} {
     set $var_array_drawasrects [expr ( $flags & 2 ) != 0]
     set $var_array_otherflag 0
 
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
     wm title $id {Edit Array}
 	match_linux_wm [list $id configure]
     wm resizable $id 0 0
@@ -5541,7 +5598,7 @@ proc pdtk_canvas_dialog {id xscale yscale graphme x1 y1 x2 y2 \
     set $var_canvas_xmargin $xmargin
     set $var_canvas_ymargin $ymargin
 
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
     wm title $id {Canvas Properties}
 	match_linux_wm [list $id configure]
 	wm resizable $id 0 0
@@ -5671,7 +5728,7 @@ proc dodata_ok {name} {
 proc pdtk_data_dialog {name stuff} {
     global pd_deffont
 	global pd_nt
-    toplevel $name -class pd-l2ork
+    toplevel $name -class [winfo class .]
     match_linux_wm [list $name configure]
     wm title $name {Atom}
     wm protocol $name WM_DELETE_WINDOW [concat dodata_cancel $name]
@@ -6067,7 +6124,7 @@ proc pdtk_pd_texteditor {stuff} {
     } else {
 		set name .texteditor
 
-		toplevel $name -class pd-l2ork
+		toplevel $name -class [winfo class .]
 		match_linux_wm [list $name configure]
 		wm title $name {Text Editor}
 
@@ -6292,7 +6349,7 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \
     set audio_sr $sr
     set audio_advance $advance
     set audio_callback $callback
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
 	match_linux_wm [list $id configure]
     wm title $id {Audio Settings}
 	wm resizable $id 0 0
@@ -6570,7 +6627,7 @@ proc pdtk_midi_dialog {id indev1 indev2 indev3 indev4 \
     set midi_alsain [llength $midi_indevlist]
     set midi_alsaout [llength $midi_outdevlist]
 
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
 	match_linux_wm [list $id configure]
 	wm resizable $id 0 0
 	wm title $id {MIDI Settings}
@@ -6765,7 +6822,7 @@ proc pdtk_alsa_midi_dialog {id indev1 indev2 indev3 indev4 \
     set midi_alsain [llength $midi_indevlist]
     set midi_alsaout [llength $midi_outdevlist]
     
-    toplevel $id -class pd-l2ork
+    toplevel $id -class [winfo class .]
     match_linux_wm [list $id configure]
 	wm resizable $id 0 0
 	wm title $id {MIDI Settings}
@@ -7202,7 +7259,7 @@ namespace eval dlg_ScrollBoxWindow {
     proc make { id listdata add_method edit_method commit_method title width height } {
 		global pd_nt
  
-		toplevel $id -class pd-l2ork
+		toplevel $id -class [winfo class .]
 		match_linux_wm [list $id configure]
         wm title $id $title
 		
@@ -7322,7 +7379,7 @@ namespace eval dlg_Startup {
         global cmd
         set cmd $initialValue
 
-        toplevel .inputBox -class pd-l2ork
+        toplevel .inputBox -class [winfo class .]
         wm title .inputBox $prompt
         wm minsize .inputBox 450 30
         wm resizable .inputBox 1 0
@@ -7479,7 +7536,7 @@ if { [info tclversion] >= 8.5 && $pd_nt == 0 } {
 		set rgb_g [expr 0x$hex_rgb_g]
 		set rgb_b [expr 0x$hex_rgb_b]
 
-		toplevel $name -class pd-l2ork
+		toplevel $name -class [winfo class .]
 
 		wm resizable $name 0 0
 		#global tmp_xpix tmp_ypix
diff --git a/src/s_inter.c b/src/s_inter.c
index 6cd666aaf3c76050715eb2ac69bae8322e6871d9..913df89db3496275d1cb8b98604d3242864bb7c1 100644
--- a/src/s_inter.c
+++ b/src/s_inter.c
@@ -1096,8 +1096,8 @@ int sys_startgui(const char *guidir)
 #else
             sprintf(cmdbuf,
                 "TCL_LIBRARY=\"%s/tcl/library\" TK_LIBRARY=\"%s/tk/library\" \
-                 \"%s/pd-gui\" %d\n",
-                 sys_libdir->s_name, sys_libdir->s_name, guidir, portno);
+                 \"%s/pd-gui\" %d localhost %s\n",
+                 sys_libdir->s_name, sys_libdir->s_name, guidir, portno, (sys_k12_mode ? "pd-l2ork-k12" : "pd-l2ork"));
 #endif
             sys_guicmd = cmdbuf;
         }
diff --git a/src/t_main.c b/src/t_main.c
index 54811d31e1441bc7d67ea4a12207005161632a17..6ed972303086b0fa927b0f0bcdaa077a009313a3 100644
--- a/src/t_main.c
+++ b/src/t_main.c
@@ -56,6 +56,11 @@ main(int argc, char **argv)
         argc--; argv++;
         argv[0] = "pd-l2ork";
     }
+    if (argc == 2)
+    {
+        //specify root window name
+        argc--; argv++;
+    }
     Tk_Main(argc, argv, Tcl_AppInit);
     return 0;                   /* Needed only to prevent compiler warning. */
 }