diff --git a/VersionASM b/VersionASM
index 7aaffeda5a26ed11ab87952a322e9b6e7416ccc6..be5f6d6a0321df0b3fd38617ec9ec8ef0b24f471 100644
--- a/VersionASM
+++ b/VersionASM
@@ -9,12 +9,12 @@
                         GBLS    Module_ApplicationDate
                         GBLS    Module_HelpVersion
                         GBLS    Module_ComponentName
-Module_MajorVersion     SETS    "5.65"
-Module_Version          SETA    565
+Module_MajorVersion     SETS    "5.66"
+Module_Version          SETA    566
 Module_MinorVersion     SETS    ""
-Module_Date             SETS    "14 Dec 2019"
-Module_ApplicationDate  SETS    "14-Dec-19"
+Module_Date             SETS    "18 Dec 2019"
+Module_ApplicationDate  SETS    "18-Dec-19"
 Module_ComponentName    SETS    "Wimp"
-Module_FullVersion      SETS    "5.65"
-Module_HelpVersion      SETS    "5.65 (14 Dec 2019)"
+Module_FullVersion      SETS    "5.66"
+Module_HelpVersion      SETS    "5.66 (18 Dec 2019)"
                         END
diff --git a/VersionNum b/VersionNum
index 341a3b1575e15d2ae57c21482486f4df9ea95279..f77a2650195f74c6ffb9bd0658961e01f9fb3cc4 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,21 +1,21 @@
-/* (5.65)
+/* (5.66)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  *
  */
-#define Module_MajorVersion_CMHG        5.65
+#define Module_MajorVersion_CMHG        5.66
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                14 Dec 2019
+#define Module_Date_CMHG                18 Dec 2019
 
-#define Module_MajorVersion             "5.65"
-#define Module_Version                  565
+#define Module_MajorVersion             "5.66"
+#define Module_Version                  566
 #define Module_MinorVersion             ""
-#define Module_Date                     "14 Dec 2019"
+#define Module_Date                     "18 Dec 2019"
 
-#define Module_ApplicationDate          "14-Dec-19"
+#define Module_ApplicationDate          "18-Dec-19"
 
 #define Module_ComponentName            "Wimp"
 
-#define Module_FullVersion              "5.65"
-#define Module_HelpVersion              "5.65 (14 Dec 2019)"
-#define Module_LibraryVersionInfo       "5:65"
+#define Module_FullVersion              "5.66"
+#define Module_HelpVersion              "5.66 (18 Dec 2019)"
+#define Module_LibraryVersionInfo       "5:66"
diff --git a/s/CBTask b/s/CBTask
index 1810f2aef7157edbb1f5d6258d97020a394ee9e7..2790d0f11152e34764ac37024b5599bbc663698a 100644
--- a/s/CBTask
+++ b/s/CBTask
@@ -390,6 +390,8 @@ cbtask_paste_filexfer
         BVS     cbtask_export_finished
 
         ; now inform recipient of what we've done
+        MOV     R0,#Message_DataLoad
+        STR     R0,[R7,#ms_action]
         MOV     R0,#User_Message_Recorded
         LDR     R1,[R7,#ms_myref]
         STR     R1,[R7,#ms_yourref]
@@ -534,6 +536,7 @@ cbtask_pastedata_perform_noxfer
         ; r8,r9=window, icon handle to receive the data
         MOV     R0,#clipboard_flexblock_pastedata
         BL      cbtask_insert_text_into_icon
+        CLRV
         MOV     R0,#clipboard_flexblock_pastedata
         MOV     R1,#0
         BL      clipboard_flex_set_block_size
@@ -589,6 +592,7 @@ cbtask_insert_text_into_icon
 
         ; invalid paste
         SWI     XOS_WriteI+7
+        SETV
         B       %FT89
 71
         MOV     R0,R10
@@ -682,6 +686,7 @@ cbtask_insert_text_into_icon
       [ UTF8
         Pull    "R8"
       ]
+        SETV
         B       %FT89                   ; free up resources
 88
         ; report error
@@ -2045,7 +2050,7 @@ cbtask_dragdrop_internal_xfer
         LDR     R9,ghostcaretdata+ghostcareticon     ; icon
         ; remove ghost caret
         MOV     R0,#-1
-        LDR     R2,=cbtask_TASK3
+        LDR     R2,cbtask_TASK3
         MOV     R4,#crf_ghostcaret
         SWI     XWimp_SetCaretPosition
 
@@ -2102,7 +2107,7 @@ cbtask_dragdrop_internal_xfer
 
         ; delete selection from source icon if necessary,  tidy up
         MOVVC   R9,#CNPTRUE
-
+        CLRV
         MOV     R10,#clipboard_flexblock_dragdata
         B       cbtask_export_finished
 70
@@ -2262,6 +2267,7 @@ cbtask_dragdrop_internal_xfer
         BLVC    cbtask_insert_text_into_icon
         MOVVS   R9,#CNPFALSE
         MOVVC   R9,#CNPTRUE
+        CLRV
         B       cbtask_export_finished
 
 ; ---------------------------------------------------------------------------------------
diff --git a/s/CnPCaret b/s/CnPCaret
index 4d785b0e1dbd02293c5fb8853941cee8fc16425e..3db69e2ec89cffb160adc360e79e144e4bd08c11 100644
--- a/s/CnPCaret
+++ b/s/CnPCaret
@@ -29,6 +29,36 @@
 int_set_caret_position ROUT
         Push    "R0-R6,R11,R14"
 
+      [ CnP
+        ; if we're called with R5=-1 then R4,R5 are calculated from R0-R3
+        ; however, R4 is undefined on entry so could be anything.
+        ; Internally we'd like to be able to use the call to put a ghost caret
+        ; to a mouse click...
+        ; we're doing the call by a SWI now, so need a way to get ghost caret calculations
+        ; add R5=-2 for this purpose - calculate ghost caret details from x/y coords
+        ; R4 *must* now be a valid flag set
+        CMP     R5,#-1
+        BNE     %FT00
+        CMP     R1,#-1
+        MOVNE   R4,#-1                 ; R4 now is -1 (ie no flags)
+00
+        CMP     R5,#-2
+        MOVEQ   R5,#-1
+      ]
+
+        ; validate existing caret blocks
+        LDR     handle,caretdata
+        CMP     handle,#nullptr
+        BLNE    checkhandle
+        MOVVS   handle,#nullptr
+        STRVS   handle,caretdata
+
+        LDR     handle,ghostcaretdata
+        CMP     handle,#nullptr
+        BLNE    checkhandle
+        MOVVS   handle,#nullptr
+        STRVS   handle,ghostcaretdata
+
         LDR     R14,taskhandle          ; calling task
         Push    "R14"                   ; preserve for later
 
@@ -73,48 +103,57 @@ int_set_caret_position ROUT
         MOV     handle,R0
         BL      checkhandle             ; valid window handle?
         BVC     %FT01
-        BVS     wscp_remove_only        ; destination isn't valid, so just remove the caret
+        BVS     %FT08                   ; destination isn't valid, so just remove the caret
 07
         ; if we've been called with r0=-1 then we may need to add some flags...
-        CMP     R0,#-1
-        BNE     wscp_remove_only
-
         LDR     R14,taskidentifier1     ; 'TASK'
         CMP     R2,R14                  ; is R2 'TASK'
         MOVNE   R4,#0                   ; if we're called with TASK then R4 has correct flags.  If not, we need
         ; to make sure we have some valid flags
         MOVEQ   R2,#0                   ; if we were called with R2='TASK' then
-        STREQ   R2,[sp,#(2+1)*4]        ; ensure R2=0 on return - taskhandle stacked below r2
+        STREQ   R2,[sp,#(2+1+8)*4]      ; ensure R2=0 on return - taskhandle stacked below r2
+08
+        SavePSR R6                      ; keep V flag for exiting later
+        Push    "R6"
+        STR     R0,[sp,#8]              ; preserve error message
+        MOV     R0,#-1                  ; carry on as an invalid window handle
 
-wscp_remove_only
         BL      wscp_remove_current_caret ; remove the caret, queue redraw as necessary
 
         ; need to clear the appropriate data blocks
         MOV     R14,#nullptr
-        TST     R4,#crf_ghostcaret :OR: crf_selection   ; normal caret?
+        CMP     R4,#-1
+        TSTNE   R4,#crf_ghostcaret :OR: crf_selection   ; normal caret?
         STREQ   R14,caretdata
-        BEQ     exitsetcaret
+        BEQ     exitsetcaret_abort
 
         TST     R4,#crf_ghostcaret                      ; ghost caret?
         STRNE   R14,ghostcaretdata
-        BNE     exitsetcaret
+        BNE     exitsetcaret_abort
 
         TST     R4,#crf_selection                       ; unshaded selection?
-        BEQ     exitsetcaret
+        BEQ     exitsetcaret_abort
 
         LDR     R11,selectionwindow
         CMP     R11,#nullptr
-        BEQ     exitsetcaret
+        BEQ     exitsetcaret_abort
 
         BL      clipboard_check_current_drag_op ; stop drag op if selection has been terminated
 
         Abs     R11,R11
         STR     R14,[R11,#w_seldata]                    ; update if handle is valid
         STR     R14,selectionwindow                     ; current selection window is now invalid too
-        B       exitsetcaret
+        B       exitsetcaret_abort
 01
         ; continues - r0 is a confirmed valid window handle
 
+        ; is the window currently open and able to receive a focus?
+        Push    "R1,R10"
+        MOV     R1,#-1
+        BL      setfocus
+        Pull    "R1,R10"
+        BVS     %BT08                                   ; no - abort and clear caret
+02
         ; set up the hascaret etc. blocks for the current state of the icon before gaining caret
         LDR     R14,caretdata
         EORS    R14,R14,R0
@@ -272,6 +311,9 @@ wscp_remove_only
         BL      check_shaded_selection_window
         BL      send_gaincaret
         BL      focuson
+        MOVVS   R14,#nullptr
+        STRVS   R14,[R11]
+        BVS     exitsetcaret
 20
         ; redraw the target icon
         Push    "R0-R2"
@@ -290,10 +332,11 @@ wscp_workarea
         ; no need to calculate string offsets etc
         ; just place the caret and leave
         BL      upcaret
-        BVS     %FT21
+        BVS     %FT22
 
         ; upcaret corrupts R11
-        TST     R4,#crf_ghostcaret
+        CMP     R4,#-1
+        TSTNE   R4,#crf_ghostcaret
         ADREQL  R11,caretdata
         ADRNEL  R11,ghostcaretdata
 
@@ -312,6 +355,14 @@ wscp_workarea
         MOVVS   R14,#nullptr            ; if not successful, clear the caret block
         STRVS   R14,[R11,#0]
         B       exitsetcaret
+22
+        MOV     R14,#nullptr
+        CMP     R4,#-1
+        TSTNE   R4,#crf_ghostcaret
+        ADREQL  R11,caretdata           ; upcaret may corrupt R11
+        ADRNEL  R11,ghostcaretdata
+        STR     R14,[R11,#0]
+        B       exitsetcaret
 40
         ; we are updating a selection caret
         BL      wscp_remove_current_caret
@@ -439,6 +490,9 @@ wscp_workarea
         ; fall through...
 
 exitsetcaret
+        SavePSR R6
+        Push    "R6"
+exitsetcaret_abort
         CheckAllWindows "int_set_caret_position (after)"
 
         ; do we need to recalculate the main caret?
@@ -457,14 +511,17 @@ exitsetcaret
         BLNE    int_set_icon_state
 
         ; and return
+        Pull    "R6"                    ; get saved PSR
         Pull    "R14"                   ; taskhandle is remembered
         Task    R14,,"Restoring after SetCaret"
 
         ; did we need to move input focus to match the selection?
         LDR     R14,refreshmaincaret
         TEQ     R14,#2
-        Pull    "R0-R6,R11,PC",NE       ; no, continue as normal by exiting
-
+        BEQ     %FT01
+        RestPSR R6
+        Pull    "R0-R6,R11,PC"          ; no, continue as normal by exiting
+01
         ; yes.  We've finished our things, so we can re-call set_caret_position to set the input focus.
         ; that way losefocus/gainfocus messages etc will be sent properly and so on
 
@@ -476,6 +533,7 @@ exitsetcaret
         ; everything else can stay the same
         BL      int_set_caret_position  ; back round again for another go
 
+        RestPSR R6
         Pull    "R0-R6,R11,PC"          ; finally quit
 
 wscp_remove_current_caret ROUT
diff --git a/s/Wimp05 b/s/Wimp05
index 7d9a98481899c710144ded4567fc59b49ec43bda..d12578556d3c279a539be0433526d12467077175 100644
--- a/s/Wimp05
+++ b/s/Wimp05
@@ -41,18 +41,6 @@ SWIWimp_SetCaretPosition ROUT
         ]
         ]
 
-      [ CnP
-        ; if we're called with R5=-1 then R4,R5 are calculated from R0-R3
-        ; however, R4 is undefined on entry so could be anything.
-        ; Internally we'd like to be able to use the call to put a ghost caret
-        ; to a mouse click...
-        ; we're doing the call by a SWI now, so need a way to get ghost caret calculations
-        ; add R5=-2 for this purpose - calculate ghost caret details from x/y coords
-        ; R4 *must* now be a valid flag set
-        CMP     R5,#-2
-        MOVEQ   R5,#-1
-      ]
-
         BL      int_set_caret_position
         B       ExitWimp
 
@@ -557,6 +545,11 @@ getfoclp2
         MOVNE   R2,R3
         BNE     getfoclp2
 
+        [ CnP
+        CMP     R1,#-1
+        BEQ     exitsetfocus
+        ]
+
 ; Convert to an Abs handle
 
         SUB     handle,R2,#w_active_link