bug#43397: 28.0.50; Adding tool bar items: update tool bar

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

bug#43397: 28.0.50; Adding tool bar items: update tool bar

Caio Henrique
Hi all,

I don't know if this is a bug or the expected behavior of the function
tool-bar-add-item-from-menu:

1. emacs -Q
2. paste and eval this:
(progn
  (tool-bar-add-item-from-menu 'undo-redo
                               "redo" nil :vert-only t)
  (redraw-display)
  (force-mode-line-update))

I'm using both redraw-display and force-mode-line-update to try to force
the tool-bar to draw the icon (I know that I should'nt do this, I'm just
trying to figure if this is a bug); but the icon only appears when I
click one or two times with the mouse anywhere in the buffer.

If there is a bug, this is possibly related to it:
https://lists.gnu.org/archive/html/emacs-devel/2020-09/msg00603.html
https://lists.gnu.org/archive/html/emacs-devel/2020-09/msg00726.html
https://lists.gnu.org/archive/html/emacs-devel/2020-09/msg00780.html

And also this:
https://lists.gnu.org/archive/html/emacs-devel/2020-09/msg01089.html
https://lists.gnu.org/archive/html/emacs-devel/2020-09/msg01101.html
> Eli: Here, the above displays nothing at all on the tool bar.
(If I click with the mouse anywhere in the buffer, that icon also gets
displayed for me)

Thanks!

____
In GNU Emacs 28.0.50 (build 19, x86_64-pc-linux-gnu, GTK+ Version
3.24.13, cairo version 1.16.0)

Configured features:
XPM JPEG TIFF GIF PNG CAIRO SOUND DBUS GSETTINGS GLIB NOTIFY INOTIFY
LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ ZLIB TOOLKIT_SCROLL_BARS
GTK3 X11 XDBE XIM MODULES THREADS JSON PDUMPER



Reply | Threaded
Open this post in threaded view
|

bug#43397: 28.0.50; Adding tool bar items: update tool bar

Caio Henrique
Gnus has a function called gnus-tool-bar-update. I tried using it but
got the same result, i.e. the icon is only displayed when I click with
the mouse on the buffer.

1. emacs -Q
2. eval this:
(progn
  (defvar tool-bar-mode)

  (defun gnus-tool-bar-update (&rest ignore)
    "Update the tool bar."
    (when (and (boundp 'tool-bar-mode)
               tool-bar-mode)
      (let* ((args nil)
             (func (cond ((fboundp 'tool-bar-update)
                          'tool-bar-update)
                         ((fboundp 'force-window-update)
                          'force-window-update)
                         ((fboundp 'redraw-frame)
                          (setq args (list (selected-frame)))
                          'redraw-frame)
                         (t 'ignore))))
        (apply func args))))

  (tool-bar-add-item-from-menu 'undo-redo
                               "redo" nil :vert-only t)

  (gnus-tool-bar-update))



Reply | Threaded
Open this post in threaded view
|

bug#43397: 28.0.50; Adding tool bar items: update tool bar

Eli Zaretskii
In reply to this post by Caio Henrique
> From: Caio Henrique <[hidden email]>
> Date: Mon, 14 Sep 2020 11:30:22 -0300
>
> 1. emacs -Q
> 2. paste and eval this:
> (progn
>   (tool-bar-add-item-from-menu 'undo-redo
>       "redo" nil :vert-only t)
>   (redraw-display)
>   (force-mode-line-update))
>
> I'm using both redraw-display and force-mode-line-update to try to force
> the tool-bar to draw the icon (I know that I should'nt do this, I'm just
> trying to figure if this is a bug)

(Calling force-mode-line-update won't help, because
tool-bar-add-item-from-menu does it internally.)

> but the icon only appears when I
> click one or two times with the mouse anywhere in the buffer.

I've now looked into this, and I'm quite sure it is not a redisplay
bug.  The display engine faithfully inspects the tool-bar items each
time it is invoked after the above code runs, and each time it finds
that the tool-bar items haven't changed -- until they do.

Based on what I see, and on the modified recipe below, it looks like
we stick to the old value of the tool-bar items, like if we cached
them somewhere.  Since I don't understand where is that "cache", I
don't really have a clear idea of what triggers the flushing of that
"cache", but one trigger I found is -- surprise! -- GC.  To see this,
perform the following greatly simplified recipe:

  emacs -Q
  M-x blink-cursor-mode RET
  M-x global-eldoc-mode RET

(The last two commands are to make sure there are no redisplay cycles
except due to changes in buffers or strings.)

Then evaluate:

  (defun myfun ()
    (interactive)
    (tool-bar-add-item "redo" 'undo-redo 'undo-redo)
    (garbage-collect))

  (global-set-key [f5] 'myfun)

Finally, press F5: you should see the "redo" icon appear immediately.

Now repeat the same, in a fresh Emacs session, but this time remove
the call to garbage-collect from myfun, and instead do this before
evaluating the function and the global-set-key form:

  M-x set-variable RET garbage-collection-messages RET t RET

Then evaluate the forms and press F5.  The tool bar won't change.  Now
do some random clicks, watching the echo area: you will see that the
tool bar is updated with the "redo" icon precisely when the "Garbage
collecting..." message appears in the echo area.

Maybe Stefan (CC'ed) can help us understand why this happens and how
GC is involved in this...



Reply | Threaded
Open this post in threaded view
|

bug#43397: 28.0.50; Adding tool bar items: update tool bar

Eli Zaretskii
> From: Stefan Monnier <[hidden email]>
> Cc: Caio Henrique <[hidden email]>,  [hidden email]
> Date: Tue, 15 Sep 2020 16:05:53 -0400
>
> > Maybe Stefan (CC'ed) can help us understand why this happens and how
> > GC is involved in this...
>
> I'm afraid I don't know much more than you do here.

We are basically talking about modifying a keymap, since this is what
tool-bar-add-item and friends do.  The question is: why isn't the
modified keymap immediately visible? why does the old keymap continue
to be visible until the next GC?

> `compact_font_caches` maybe?

I will look there, thanks.