patch-desktop.el 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. ;;; desktop.el patches
  2. ;;; Fix 28945.
  3. ;;; Replace
  4. ;;; (setq desktop-autosave-was-enabled
  5. ;;; (memq 'desktop-auto-save-set-timer 'window-configuration-change-hook))
  6. ;;; with
  7. ;;; (setq desktop-autosave-was-enabled
  8. ;;; (memq 'desktop-auto-save-set-timer (default-toplevel-value 'window-configuration-change-hook)))
  9. (defun desktop-read (&optional dirname)
  10. "Read and process the desktop file in directory DIRNAME.
  11. Look for a desktop file in DIRNAME, or if DIRNAME is omitted, look in
  12. directories listed in `desktop-path'. If a desktop file is found, it
  13. is processed and `desktop-after-read-hook' is run. If no desktop file
  14. is found, clear the desktop and run `desktop-no-desktop-file-hook'.
  15. This function is a no-op when Emacs is running in batch mode.
  16. It returns t if a desktop file was loaded, nil otherwise."
  17. (interactive)
  18. (unless noninteractive
  19. (setq desktop-dirname
  20. (file-name-as-directory
  21. (expand-file-name
  22. (or
  23. ;; If DIRNAME is specified, use it.
  24. (and (< 0 (length dirname)) dirname)
  25. ;; Otherwise search desktop file in desktop-path.
  26. (let ((dirs desktop-path))
  27. (while (and dirs
  28. (not (file-exists-p
  29. (desktop-full-file-name (car dirs)))))
  30. (setq dirs (cdr dirs)))
  31. (and dirs (car dirs)))
  32. ;; If not found and `desktop-path' is non-nil, use its first element.
  33. (and desktop-path (car desktop-path))
  34. ;; Default: .emacs.d.
  35. user-emacs-directory))))
  36. (if (file-exists-p (desktop-full-file-name))
  37. ;; Desktop file found, but is it already in use?
  38. (let ((desktop-first-buffer nil)
  39. (desktop-buffer-ok-count 0)
  40. (desktop-buffer-fail-count 0)
  41. (owner (desktop-owner))
  42. ;; Avoid desktop saving during evaluation of desktop buffer.
  43. (desktop-save nil)
  44. (desktop-autosave-was-enabled))
  45. (if (and owner
  46. (memq desktop-load-locked-desktop '(nil ask))
  47. (or (null desktop-load-locked-desktop)
  48. (and (daemonp) (= (length (visible-frame-list)) 1)) ; PATCH
  49. (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\n\
  50. Using it may cause conflicts. Use it anyway? " owner)))))
  51. (let ((default-directory desktop-dirname))
  52. (setq desktop-dirname nil)
  53. (run-hooks 'desktop-not-loaded-hook)
  54. (unless desktop-dirname
  55. (message "Desktop file in use; not loaded.")))
  56. (desktop-lazy-abort)
  57. ;; Temporarily disable the autosave that will leave it
  58. ;; disabled when loading the desktop fails with errors,
  59. ;; thus not overwriting the desktop with broken contents.
  60. (setq desktop-autosave-was-enabled
  61. (memq 'desktop-auto-save-set-timer
  62. ;; Use the toplevel value of the hook, in case some
  63. ;; feature makes window-configuration-change-hook
  64. ;; buffer-local, and puts there stuff which
  65. ;; doesn't include our timer.
  66. (default-toplevel-value
  67. 'window-configuration-change-hook)))
  68. (desktop-auto-save-disable)
  69. ;; Evaluate desktop buffer and remember when it was modified.
  70. (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name))))
  71. (load (desktop-full-file-name) t t t)
  72. ;; If it wasn't already, mark it as in-use, to bother other
  73. ;; desktop instances.
  74. (unless (eq (emacs-pid) owner)
  75. (condition-case nil
  76. (desktop-claim-lock)
  77. (file-error (message "Couldn't record use of desktop file")
  78. (sit-for 1))))
  79. (unless (desktop-restoring-frameset-p)
  80. ;; `desktop-create-buffer' puts buffers at end of the buffer list.
  81. ;; We want buffers existing prior to evaluating the desktop (and
  82. ;; not reused) to be placed at the end of the buffer list, so we
  83. ;; move them here.
  84. (mapc 'bury-buffer
  85. (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list))))))
  86. (switch-to-buffer (car (buffer-list))))
  87. (run-hooks 'desktop-delay-hook)
  88. (setq desktop-delay-hook nil)
  89. (desktop-restore-frameset)
  90. (run-hooks 'desktop-after-read-hook)
  91. (message "Desktop: %s%d buffer%s restored%s%s."
  92. (if desktop-saved-frameset
  93. (let ((fn (length (frameset-states desktop-saved-frameset))))
  94. (format "%d frame%s, "
  95. fn (if (= fn 1) "" "s")))
  96. "")
  97. desktop-buffer-ok-count
  98. (if (= 1 desktop-buffer-ok-count) "" "s")
  99. (if (< 0 desktop-buffer-fail-count)
  100. (format ", %d failed to restore" desktop-buffer-fail-count)
  101. "")
  102. (if desktop-buffer-args-list
  103. (format ", %d to restore lazily"
  104. (length desktop-buffer-args-list))
  105. ""))
  106. (unless (desktop-restoring-frameset-p)
  107. ;; Bury the *Messages* buffer to not reshow it when burying
  108. ;; the buffer we switched to above.
  109. (when (buffer-live-p (get-buffer "*Messages*"))
  110. (bury-buffer "*Messages*"))
  111. ;; Clear all windows' previous and next buffers, these have
  112. ;; been corrupted by the `switch-to-buffer' calls in
  113. ;; `desktop-restore-file-buffer' (bug#11556). This is a
  114. ;; brute force fix and should be replaced by a more subtle
  115. ;; strategy eventually.
  116. (walk-window-tree (lambda (window)
  117. (set-window-prev-buffers window nil)
  118. (set-window-next-buffers window nil))))
  119. (setq desktop-saved-frameset nil)
  120. (if desktop-autosave-was-enabled (desktop-auto-save-enable))
  121. t))
  122. ;; No desktop file found.
  123. (let ((default-directory desktop-dirname))
  124. (run-hooks 'desktop-no-desktop-file-hook))
  125. (message "No desktop file.")
  126. nil)))
  127. ;;; Fix 30421
  128. ;;; Return nil if the PID found is not owned by a process named Emacs.
  129. ;;; This assumes that no other name would be using the desktop file.
  130. ;;; Upstream decided not to do this because of possible clashes when emacs
  131. ;;; process is running remotely. Start desktop-mode in
  132. ;;; `server-after-make-frame-hook' instead (requires Emacs>=27).
  133. (defun desktop-owner (&optional dirname)
  134. "Return the PID of the Emacs process that owns the desktop file in DIRNAME.
  135. Return nil if no desktop file found or no Emacs process is using it.
  136. DIRNAME omitted or nil means use `desktop-dirname'."
  137. (let (owner
  138. (file (desktop-full-lock-name dirname)))
  139. (and (file-exists-p file)
  140. (ignore-errors
  141. (with-temp-buffer
  142. (insert-file-contents-literally file)
  143. (goto-char (point-min))
  144. (setq owner (read (current-buffer)))
  145. (integerp owner)
  146. (process-attributes owner)
  147. (string= "emacs" (alist-get 'comm (process-attributes owner)))))
  148. owner)))