Subject: bug#30182: Update

From: martin rudalics <[email-masked]>
Date: Thu, 01 Feb 2018 10:26:28 +0100

> With the patch applied on top of master, this message is printed in
 > *Messages* when the mouse cursor is moved over the modeline. It happens
 > only once.

Thank you very much.

 > Error during redisplay: (eval (w3m-modeline-title)) signaled (error "Attempt to add [t 23154 31461 636625 nil #[(buffer) \\302!\\205\0rq\\210\\303\\211)\\207 [buffer w3m-modeline-title-timer buffer-live-p nil] 2] (*w3m*) nil 113000] to ([nil 23154 31461 622052 0.5 blink-cursor-timer-function nil nil 870000] [nil 23154 31476 0 60 display-time-event-handler nil nil 0] [nil 23154 31747 353232 300 savehist-autosave nil nil 708000]) while checking timers")

The behavior differs slightly from those seen earlier because the
timer list contains only three timers when it tries to add another
one.  Still the conjecture that we try to add a timer while checking
timers has been proven.

To remember - w3m.el sets `mode-line-buffer-identification' as
follows

   (setq mode-line-buffer-identification
	`(,@(w3m-static-if (featurep 'xemacs)
		(list (cons modeline-buffer-id-right-extent "%b") " ")
	      (nconc (propertized-buffer-identification "%b") '(" ")))
	  [...]
	  (w3m-current-process
	   "Loading..." ,(if (fboundp 'format-mode-line)
			     '(:eval (w3m-modeline-title))
			   (if w3m-use-title-buffer-name
			       ""
			     'w3m-current-title)))))

where `w3m-modeline-title' is specified as

(defun w3m-modeline-title ()
   "Return a truncated title not to cut the right end of the mode line.
It currently works only with Emacs 22 and newer."
   (if w3m-use-title-buffer-name
       ""
     (when w3m-current-title
       (or (and w3m-modeline-title-timer w3m-modeline-title-string)
	  (prog2
	      (setq w3m-modeline-title-string w3m-current-title
		    w3m-modeline-title-timer t)
	      (let ((excess (- (string-width
				(condition-case nil
				    (format-mode-line mode-line-format 1)
				  (error "")))
			       (window-width)))
		    (tlen (string-width w3m-current-title)))
		(when (and (> excess 0)
			   (> tlen 3))
		  (setq w3m-modeline-title-string
			(concat (w3m-replace-in-string
				 (w3m-truncate-string
				  w3m-current-title (max (- tlen excess 3) 2))
				 "[\t ]+\\'" "")
				"...")))
		w3m-modeline-title-string)
	    (run-at-time 0.5 nil
			 (lambda (buffer)
			   (when (buffer-live-p buffer)
			     (with-current-buffer buffer
			       (setq w3m-modeline-title-timer nil))))
			 (current-buffer)))))))

Inherently, this truncates the mode line text when `w3m-current-title'
is too long and installs a timer which inihibts such truncations for
half a second with the motivation

(defvar w3m-modeline-title-timer nil
   "Say time has not gone by after the mode line was updated last time.
It is used to control the `w3m-modeline-title' function running too
frequently, set by the function itself and cleared by a timer.")

So it seems that we do something we are supposed to avoid - call Lisp
from asynchronous redisplay as a consequence of some mouse movement
(presumably).

I have no idea what further to learn or teach from this experience,
though.

martin