bug#81561: 31.0.91; speedbar-window-mode creates stale idle timers
Vincenzo Pupillo <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
Ciao Daniel, In data mercoledì 12 agosto 2026 22:11:23 Ora legale dell’Europa centrale, Daniel Mendler ha scritto: > Vincenzo Pupillo <[email protected]> writes: > > Ciao, I wasn’t able to reproduce the problem reported by Daniel. The only > > way was to kill the 'speedbar-buffer' process. So I added a > > 'kill-buffer-hook' to handle this event. I also eliminated a few other > > causes of stale idle timers. > > > > @Daniel, could you please try this patch? > > Would it make sense to instead move the (with-current-buffer > speedbar-buffer ...) into speedbar-set-timer instead of replicating it > so often? That's right, I added the calls to 'with-current-buffer' one at a time, but in the end, it's needed everywhere... Attached is the new version of the patch. > > Daniel Thanks. Vincenzo
0001-Handle-speedbar-buffer-kill-when-in-speedbar-window-.patch
(text/x-patch, 4 KB)
From 344f25607d8ce81f9bed7b7ce647fa227d5f5d7c Mon Sep 17 00:00:00 2001 From: Vincenzo Pupillo <[email protected]> Date: Wed, 12 Aug 2026 18:11:25 +0200 Subject: [PATCH] Handle 'speedbar-buffer' kill when in 'speedbar-window-mode'. This patch handle the DFRAME TIMER ERROR reported by Daniel Mendler (bug#81561). In addition, it eliminates other causes of stale idle timers. * lisp/speedbar.el (speedbar-window-mode): Added a 'kill-buffer' handler. Removed a unnecessary 'speedbar-mode' invocation. (speedbar-window--close): New optional parameter used bye the 'kill-buffer' handler for 'speedbar-buffer'. (speedbar-set-timer): Make sure that 'speedbar-set-timer' is called in 'speedbar-buffer', this prevents the creation of stale idle timers. (speedbar--speedbar-live-p): Make sure that 'speedbar-buffer' is still live. --- lisp/speedbar.el | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/lisp/speedbar.el b/lisp/speedbar.el index 3e965d4286c..778c5f5f12f 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -1083,7 +1083,6 @@ speedbar-window-mode speedbar-last-selected-file nil) (set-buffer speedbar-buffer) - (speedbar-mode) ;; let's create the window (setq speedbar--window @@ -1102,14 +1101,19 @@ speedbar-window-mode (speedbar-update-contents) (speedbar-set-timer dframe-update-speed) + ;; handle kill-buffer + (add-hook 'kill-buffer-hook (lambda () (speedbar-window--close t)) nil t) + ;; hscroll (setq-local auto-hscroll-mode nil) ;; reset the selection variable (setq speedbar-last-selected-file nil) (select-window current-window)))) -(defun speedbar-window--close () - "Close `speedbar-window'." +(defun speedbar-window--close (&optional no-kill-buffer) + "Close `speedbar-window'. +When NO-KILL-BUFFER is not nil, close window without killing +'speedbar-buffer', which is useful for 'kill-buffer-hook'." (when (speedbar-window--live-p) (let ((current-window (selected-window))) ;; store the current window width @@ -1123,10 +1127,11 @@ speedbar-window--close (setq speedbar--window nil speedbar-frame nil dframe-attached-frame nil) - (with-current-buffer speedbar-buffer - (speedbar-set-timer nil)) - (kill-buffer speedbar-buffer) - (setq speedbar-buffer nil) + + (speedbar-set-timer nil) + (unless no-kill-buffer + (kill-buffer speedbar-buffer) + (setq speedbar-buffer nil)) (when (and current-window (window-live-p current-window)) (select-window current-window))))) @@ -2724,13 +2729,15 @@ speedbar-set-timer "Set up the speedbar timer with TIMEOUT. Uses `dframe-set-timer'. Also resets scanner functions." - (dframe-set-timer timeout 'speedbar-timer-fn 'speedbar-update-flag) - ;; Apply a revert hook that will reset the scanners. We attach to revert - ;; because most reverts occur during VC state change, and this lets our - ;; VC scanner fix itself. - (if timeout - (add-hook 'after-revert-hook 'speedbar-reset-scanners) - (remove-hook 'after-revert-hook 'speedbar-reset-scanners)) + ;; `dframe-set-timer' must be called from `speedbar-buffer'. + (with-current-buffer speedbar-buffer + (dframe-set-timer timeout 'speedbar-timer-fn 'speedbar-update-flag) + ;; Apply a revert hook that will reset the scanners. We attach to revert + ;; because most reverts occur during VC state change, and this lets our + ;; VC scanner fix itself. + (if timeout + (add-hook 'after-revert-hook 'speedbar-reset-scanners) + (remove-hook 'after-revert-hook 'speedbar-reset-scanners))) ;; change this if it changed for some reason (speedbar-set-mode-line-format)) @@ -2740,7 +2747,7 @@ speedbar--speedbar-live-p ((and (speedbar-current-frame) (frame-live-p (speedbar-current-frame))) t) - ((speedbar-window--window-live-p) t) + ((speedbar-window--live-p) t) (t nil))) (defun speedbar-timer-fn () -- 2.55.0