diff --git a/lisp/simple.el b/lisp/simple.el
index 1db14a8..9e1301f 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2511,12 +2511,17 @@ Return what remains of the list."
         ;; We use oldlist only to check for EQ.  ++kfs
         (oldlist buffer-undo-list)
         (did-apply nil)
-        (next nil))
+        (next nil)
+        (window-of-current-buffer (get-buffer-window (current-buffer)))
+        (selected-window (selected-window)))
     (while (> arg 0)
       (while (setq next (pop list))     ;Exit inner loop at undo boundary.
         ;; Handle an integer by setting point to that value.
         (pcase next
-          ((pred integerp) (goto-char next))
+          ((pred integerp)
+            (goto-char next)
+              (unless (eq window-of-current-buffer selected-window)
+                (set-window-point window-of-current-buffer next)))
           ;; Element (t . TIME) records previous modtime.
           ;; Preserve any flag of NONEXISTENT_MODTIME_NSECS or
           ;; UNKNOWN_MODTIME_NSECS.
@@ -2524,28 +2529,39 @@ Return what remains of the list."
            ;; If this records an obsolete save
            ;; (not matching the actual disk file)
            ;; then don't mark unmodified.
-           (when (or (equal time (visited-file-modtime))
-                     (and (consp time)
-                          (equal (list (car time) (cdr time))
-                                 (visited-file-modtime))))
-             (when (fboundp 'unlock-buffer)
-               (unlock-buffer))
-             (set-buffer-modified-p nil)))
+            (when (or (equal time (visited-file-modtime))
+                      (and (consp time)
+                           (equal (list (car time) (cdr time)) (visited-file-modtime))))
+              (when (fboundp 'unlock-buffer)
+                (unlock-buffer))
+              (set-buffer-modified-p nil)))
           ;; Element (nil PROP VAL BEG . END) is property change.
           (`(nil . ,(or `(,prop ,val ,beg . ,end) pcase--dontcare))
-           (when (or (> (point-min) beg) (< (point-max) end))
-             (error "Changes to be undone are outside visible portion of buffer"))
+            (when (or (> (point-min) beg) (< (point-max) end))
+              (let ((debug-on-quit nil)
+                    (msg (concat
+                           "undo-tree--primitive-undo (1 of 4):"
+                           "  "
+                           "Changes to be undone are outside visible portion of buffer.")))
+                (signal 'quit `(,msg))))
            (put-text-property beg end prop val))
           ;; Element (BEG . END) means range was inserted.
           (`(,(and beg (pred integerp)) . ,(and end (pred integerp)))
            ;; (and `(,beg . ,end) `(,(pred integerp) . ,(pred integerp)))
            ;; Ideally: `(,(pred integerp beg) . ,(pred integerp end))
-           (when (or (> (point-min) beg) (< (point-max) end))
-             (error "Changes to be undone are outside visible portion of buffer"))
+            (when (or (> (point-min) beg) (< (point-max) end))
+              (let ((debug-on-quit nil)
+                    (msg (concat
+                           "undo-tree--primitive-undo (2 of 4):"
+                           "  "
+                           "Changes to be undone are outside visible portion of buffer.")))
+                (signal 'quit `(,msg))))
            ;; Set point first thing, so that undoing this undo
            ;; does not send point back to where it is now.
            (goto-char beg)
-           (delete-region beg end))
+           (delete-region beg end)
+           (unless (eq window-of-current-buffer selected-window)
+             (set-window-point window-of-current-buffer beg)))
           ;; Element (apply FUN . ARGS) means call FUN to undo.
           (`(apply . ,fun-args)
            (let ((currbuff (current-buffer)))
@@ -2554,8 +2570,13 @@ Return what remains of the list."
                  (pcase-let* ((`(,delta ,start ,end ,fun . ,args) fun-args)
                               (start-mark (copy-marker start nil))
                               (end-mark (copy-marker end t)))
-                   (when (or (> (point-min) start) (< (point-max) end))
-                     (error "Changes to be undone are outside visible portion of buffer"))
+                    (when (or (> (point-min) start) (< (point-max) end))
+              (let ((debug-on-quit nil)
+                    (msg (concat
+                           "undo-tree--primitive-undo (3 of 4):"
+                           "  "
+                           "Changes to be undone are outside visible portion of buffer.")))
+                (signal 'quit `(,msg))))
                    (apply fun args) ;; Use `save-current-buffer'?
                    ;; Check that the function did what the entry
                    ;; said it would do.
@@ -2571,8 +2592,13 @@ Return what remains of the list."
           ;; Element (STRING . POS) means STRING was deleted.
           (`(,(and string (pred stringp)) . ,(and pos (pred integerp)))
            (when (let ((apos (abs pos)))
-                   (or (< apos (point-min)) (> apos (point-max))))
-             (error "Changes to be undone are outside visible portion of buffer"))
+                    (or (< apos (point-min)) (> apos (point-max))))
+              (let ((debug-on-quit nil)
+                    (msg (concat
+                           "undo-tree--primitive-undo (4 of 4):"
+                           "  "
+                           "Changes to be undone are outside visible portion of buffer.")))
+                (signal 'quit `(,msg))))
            (let (valid-marker-adjustments)
              ;; Check that marker adjustments which were recorded
              ;; with the (STRING . POS) record are still valid, ie
@@ -2594,18 +2620,20 @@ Return what remains of the list."
                (goto-char pos)
                (insert string)
                (goto-char pos))
+             (unless (eq window-of-current-buffer selected-window)
+               (set-window-point window-of-current-buffer pos))
              ;; Adjust the valid marker adjustments
              (dolist (adj valid-marker-adjustments)
-               ;; Insert might have invalidated some of the markers
-               ;; via modification hooks.  Update only the currently
-               ;; valid ones (bug#25599).
-               (if (marker-buffer (car adj))
-                   (set-marker (car adj)
-                               (- (car adj) (cdr adj)))))))
+               (set-marker (car adj)
+                           (- (car adj) (cdr adj))))))
           ;; (MARKER . OFFSET) means a marker MARKER was adjusted by OFFSET.
           (`(,(and marker (pred markerp)) . ,(and offset (pred integerp)))
-           (warn "Encountered %S entry in undo list with no matching (TEXT . POS) entry"
-                 next)
+            (let ((msg
+                    (concat
+                      "undo-tree--primitive-undo:  "
+                      (format "Encountered %S entry in undo list with no matching (TEXT . POS) entry"
+                              next))))
+              (message msg))
            ;; Even though these elements are not expected in the undo
            ;; list, adjust them to be conservative for the 24.4
            ;; release.  (Bug#16818)
@@ -2613,7 +2641,10 @@ Return what remains of the list."
              (set-marker marker
                          (- marker offset)
                          (marker-buffer marker))))
-          (_ (error "Unrecognized entry in undo list %S" next))))
+          (_
+            (if (eq next 'undo-tree-canary)
+              (message "undo-tree--primitive-undo:  catch-all found `%s'." next)
+              (error "Unrecognized entry in undo list %S" next)))))
       (setq arg (1- arg)))
     ;; Make sure an apply entry produces at least one undo entry,
     ;; so the test in `undo' for continuing an undo series
