* bug#75844: Update for window-tool-bar
@ 2025-01-25 22:38 Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-01 11:02 ` Eli Zaretskii
0 siblings, 1 reply; 12+ messages in thread
From: Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-01-25 22:38 UTC (permalink / raw)
To: 75844
[-- Attachment #1: Type: text/plain, Size: 613 bytes --]
Attached is a patch to window-tool-bar. This adds support for the rest
of the tool bar item specifiers. I have been running with this locally
for a couple of months to ensure it had no major performance regressions
because it does add more code run per tool bar item refresh.
Separately, I also have an example tool bar mode that I use alongside
developing the window-tool-bar. This example shows off the capabilities
of tool bars. At the moment, it is limited to just what window-tool-bar
supports. I'd be happy to add that as well to Emacs for any further
tool bar development in general.
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Update-window-tool-bar.patch --]
[-- Type: text/x-diff; name=0001-Update-window-tool-bar.patch, Size: 18243 bytes --]
From 04428f42d866c0dabcd890a9a4fb3e3b7da5efea Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Sun, 19 Jan 2025 19:02:46 -0800
Subject: [PATCH] Update window-tool-bar
Add support for the remaining tool bar item specs, new user
option `window-tool-bar-style', and add support for older Emacs
versions.
* doc/emacs/windows.texi (Window Tool Bar): Add documentation
for new user option `window-tool-bar-style'.
* lisp/window-tool-bar.el (window-tool-bar-string): Do not show
spacers after hidden buttons.
(window-tool-bar--keymap-entry-to-string): Call new function
`window-tool-bar--style'. Add handling for :visible, :filter,
:button, :vert-only, and :help item specs. Show key bindings.
(window-tool-bar--allow-images): Delete this, it is replaced by
new user option `window-tool-bar-style'.
(window-tool-bar--use-images): Delete this, it is replaced by new
function `window-tool-bar--style'.
(window-tool-bar--turn-on): Move earlier in file, no changes.
(window-tool-bar-style): New user option supporting all values
`tool-bar-style' supports as well as inheriting from
tool-bar-style.
(window-tool-bar--style): New function to calculate active tool
bar style based on `window-tool-bar-style', `tool-bar-style',
and frame capabilities.
(global-window-tool-bar-mode, window-tool-bar-button)
(window-tool-bar-button-hover, window-tool-bar-button-disabled):
Retroactively add package-version.
(window-tool-bar-button-checked)
(window-tool-bar-button-checked-hover): New faces for :button
item spec.
(window-tool-bar--get-keymap): Call new function
`window-tool-bar--style'.
---
doc/emacs/windows.texi | 10 ++
lisp/window-tool-bar.el | 276 +++++++++++++++++++++++++++-------------
2 files changed, 201 insertions(+), 85 deletions(-)
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index a992f26fcdd..8b2e4249a70 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -728,6 +728,16 @@ Window Tool Bar
(add-hook 'special-mode-hook 'window-tool-bar-mode)
@end example
+@vindex window-tool-bar-style
+@cindex Window Tool Bar style
+On graphical displays the window tool bar can be displayed in multiple
+different styles. By default, the window tool bar displays items as
+just images. To impose a specific style, customize the variable
+@code{window-tool-bar-style}.
+
+On text-only displays the window tool bar only shows text for each
+button.
+
Emacs can also display a single tool bar at the top of frames
(@pxref{Tool Bars}).
diff --git a/lisp/window-tool-bar.el b/lisp/window-tool-bar.el
index e2c886c41e5..87718d354a5 100644
--- a/lisp/window-tool-bar.el
+++ b/lisp/window-tool-bar.el
@@ -4,8 +4,9 @@
;; Author: Jared Finder <jared@finder.org>
;; Created: Nov 21, 2023
-;; Version: 0.2.1
+;; Version: 0.3
;; Keywords: mouse
+;; URL: http://github.com/chaosemer/window-tool-bar
;; Package-Requires: ((emacs "27.1") (compat "29.1"))
;; This is a GNU ELPA :core package. Avoid adding functionality that
@@ -54,44 +55,32 @@
;;; Known issues:
;;
-;; On GNU Emacs 29.1, terminals dragging to resize windows will error
-;; with message "<tab-line> <mouse-movement> is undefined". This is a
-;; bug in GNU Emacs,
+;; On GNU Emacs 29.1 and earlier, terminals dragging to resize windows
+;; will error with message "<tab-line> <mouse-movement> is undefined".
+;; This is a bug in GNU Emacs,
;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=67457>.
;;
-;; On GNU Emacs 29, performance in terminals is lower than on
-;; graphical frames. This is due to a workaround, see "Workaround for
-;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334", below.
+;; On GNU Emacs 29 and earlier, performance in terminals is lower than
+;; on graphical frames. This is due to a workaround, see "Workaround
+;; for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334", below.
+;;
+;; Dragging empty space on the tab-line (which this package uses to
+;; display the window tool bar) doesn't resize windows. This is
+;; unlike the mode line, where dragging empty space resizes the
+;; window.
;;; Todo:
;;
;; Not all features planned are implemented yet. Eventually I would
;; like to also generally make tool bars better.
;;
-;; Targeting 0.3:
-;; * Properly support remaining less frequently used tool bar item specs. From
-;; `parse_tool_bar_item':
-;; * :visible
-;; * :filter
-;; * :button
-;; * :wrap
-;; * Add display customization similar to `tool-bar-style'.
-;;
-;; Targeting 1.0:
+;; Post 1.0 work:
;;
;; * Clean up Emacs tool bars
;; * Default: Remove default tool-bar entirely
;; * grep, vc: Remove default tool-bar inherited
;; * info: Remove Next / Prev / Up, which is already in the header
;; * smerge: Add tool bar for next/prev
-;;
-;; Post 1.0 work:
-;;
-;; * Show keyboard shortcut on help text.
-;;
-;; * Add a bit more documentation.
-;; * Add customization option: ignore-default-tool-bar-map
-;; * Make tab-line dragging resize the window
;;; Code:
@@ -227,7 +216,7 @@ window-tool-bar-string--cache
(defun window-tool-bar-string ()
"Return a (propertized) string for the tool bar.
-This is for when you want more customizations than
+This is for when you want more customizations than the command
`window-tool-bar-mode' provides. Commonly added to the variable
`tab-line-format', `header-line-format', or `mode-line-format'"
(if (or (null window-tool-bar-string--cache)
@@ -235,13 +224,14 @@ window-tool-bar-string
(let* ((mem0 (memory-use-counts))
(toolbar-menu (window-tool-bar--get-keymap))
(mem1 (memory-use-counts))
- (result (mapconcat #'window-tool-bar--keymap-entry-to-string
- (cdr toolbar-menu) ;Skip 'keymap
+ (strs (mapcar #'window-tool-bar--keymap-entry-to-string
+ (cdr toolbar-menu))) ;Skip 'keymap
+ (result (mapconcat #'identity
+ (delete nil strs)
;; Without spaces between the text, hovering
;; highlights all adjacent buttons.
- (if (window-tool-bar--use-images)
- (propertize " " 'invisible t)
- " ")))
+ (if (eq 'text (window-tool-bar--style)) " "
+ (propertize " " 'invisible t))))
(mem2 (memory-use-counts)))
(cl-mapl (lambda (l-init l0 l1)
(cl-incf (car l-init) (- (car l1) (car l0))))
@@ -281,45 +271,101 @@ window-tool-bar--keymap-entry-to-string
((or `(,_ "--")
`(,_ menu-item ,(and (pred stringp)
(pred (string-prefix-p "--")))))
- (if (window-tool-bar--use-images)
- window-tool-bar--graphical-separator
- "|"))
+ (if (eq 'text (window-tool-bar--style)) "|"
+ window-tool-bar--graphical-separator))
;; Menu item, turn into propertized string button
(`(,key menu-item ,name-expr ,binding . ,plist)
- (when binding ; If no binding exists, then button is hidden.
- (let* ((name (eval name-expr))
- (str (upcase-initials (or (plist-get plist :label)
- (string-trim-right name "\\.+"))))
- (len (length str))
- (enable-form (plist-get plist :enable))
- (enabled (or (not enable-form)
- (eval enable-form))))
- (if enabled
+ (let* ((visible-entry (plist-member plist :visible))
+ (visible (or (null visible-entry) ;Default is visible
+ (eval (cadr visible-entry))))
+ (wrap (plist-get plist :wrap))
+ (filter (plist-get plist :filter)))
+ (when filter
+ (setf binding
+ ;; You would expect this to use `funcall', but existing
+ ;; code in `parse_tool_bar_item' uses `eval'.
+ (eval `(,filter ',binding))))
+ (when (and binding
+ visible
+ (null wrap))
+ (let* ((name (eval name-expr))
+ (str (upcase-initials (or (plist-get plist :label)
+ (string-trim-right name "\\.+"))))
+ (len (length str))
+ (enable-form (plist-get plist :enable))
+ (enabled (or (not enable-form)
+ (eval enable-form)))
+ (button-spec (plist-get plist :button))
+ (button-selected (eval (cdr-safe button-spec)))
+ (vert-only (plist-get plist :vert-only))
+ image-start
+ image-end)
+ ;; Depending on style, Images can be displayed to the
+ ;; left, to the right, or in place of the text
+ (pcase-exhaustive (window-tool-bar--style)
+ ('image
+ (setf image-start 0
+ image-end len))
+ ('text
+ ;; Images shouldn't be available
+ )
+ ((or 'both 'both-horiz)
+ (if vert-only
+ (setf image-start 0 image-end len)
+ (setf str (concat " " str)
+ image-start 0
+ image-end 1
+ len (1+ len))))
+ ('text-image-horiz
+ (if vert-only
+ (setf image-start 0 image-end len)
+ (setf str (concat str " ")
+ image-start len
+ image-end (1+ len)
+ len (1+ len)))))
+
+ (cond
+ ((and enabled button-selected)
+ (add-text-properties 0 len
+ '(mouse-face
+ window-tool-bar-button-checked-hover
+ keymap window-tool-bar--button-keymap
+ face window-tool-bar-button-checked)
+ str))
+ (enabled
(add-text-properties 0 len
'(mouse-face window-tool-bar-button-hover
keymap window-tool-bar--button-keymap
face window-tool-bar-button)
- str)
- (put-text-property 0 len
- 'face
- 'window-tool-bar-button-disabled
- str))
- (when-let* ((spec (and (window-tool-bar--use-images)
- (plist-get menu-item :image))))
- (put-text-property 0 len
- 'display
- (append spec
- (if enabled '(:margin 2 :ascent center)
- '(:margin 2 :ascent center
- :conversion disabled)))
- str))
- (put-text-property 0 len
- 'help-echo
- (or (plist-get plist :help) name)
- str)
- (put-text-property 0 len 'tool-bar-key key str)
- str)))))
+ str))
+ (t
+ (put-text-property 0 len
+ 'face
+ 'window-tool-bar-button-disabled
+ str)))
+ (when-let* ((spec (and image-start image-end
+ (plist-get menu-item :image))))
+ (put-text-property image-start image-end
+ 'display
+ (append spec
+ (if enabled '(:margin 2 :ascent center)
+ '(:margin 2 :ascent center
+ :conversion disabled)))
+ str))
+ (let ((help-text (or (plist-get plist :help) name))
+ (keys (where-is-internal binding nil t)))
+ (put-text-property 0 len
+ 'help-echo
+ (if keys
+ (concat help-text
+ " ("
+ (key-description keys)
+ ")")
+ help-text)
+ str))
+ (put-text-property 0 len 'tool-bar-key key str)
+ str))))))
(defun window-tool-bar--call-button ()
"Call the button that was clicked on in the tab line."
@@ -415,20 +461,52 @@ window-tool-bar-mode
(define-globalized-minor-mode global-window-tool-bar-mode
window-tool-bar-mode window-tool-bar--turn-on
:group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.1")
(add-hook 'isearch-mode-hook #'window-tool-bar--turn-on)
(add-hook 'isearch-mode-end-hook #'window-tool-bar--turn-on))
-(defvar window-tool-bar--allow-images t
- "Internal debug flag to force text mode.")
-
-(defun window-tool-bar--use-images ()
- "Internal function.
-Respects `window-tool-bar--allow-images' as well as frame
-capabilities."
- (and window-tool-bar--allow-images
- (display-images-p)))
+(defun window-tool-bar--turn-on ()
+ "Internal function called by the command `global-window-tool-bar-mode'."
+ (when global-window-tool-bar-mode
+ (window-tool-bar-mode 1)))
\f
;;; Display styling:
+(defcustom window-tool-bar-style 'image
+ "Tool bar style to use for window tool bars.
+The meanining is the same as for `tool-bar-style', which see. If
+set to the symbol `tool-bar-style', then use the value of
+`tool-bar-style' instead.
+
+When images can not be displayed (see `display-images-p'), text
+is used."
+ :type '(choice (const :tag "Images" :value image)
+ (const :tag "Text" :value text)
+ ;; This option would require multiple tool bar lines.
+ ;;(const :tag "Both" :value both)
+ (const :tag "Both-horiz" :value both-horiz)
+ (const :tag "Text-image-horiz" :value text-image-horiz)
+ (const :tag "Inherit tool-bar-style" :value tool-bar-style)
+ (const :tag "System default" :value nil))
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
+
+(defun window-tool-bar--style ()
+ "Return the effective style based on `window-tool-bar-style'.
+
+This also takes into account frame capabilities. If the current
+frame can not display images (see `dislay-images-p'), then this
+will always return text."
+ (if (not (display-images-p))
+ 'text
+ (let ((style window-tool-bar-style))
+ (when (eq style 'tool-bar-style)
+ (setf style tool-bar-style))
+ (unless (memq style '(image text both both-horiz text-image-horiz))
+ (setf style (if (fboundp 'tool-bar-get-system-style)
+ (tool-bar-get-system-style)
+ 'image)))
+ style)))
+
(defface window-tool-bar-button
'((default
:inherit tab-line)
@@ -441,7 +519,8 @@ window-tool-bar-button
(t
:inverse-video t))
"Face used for buttons when the mouse is not hovering over the button."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
(defface window-tool-bar-button-hover
'((default
@@ -452,7 +531,8 @@ window-tool-bar-button-hover
(t
:inverse-video t))
"Face used for buttons when the mouse is hovering over the button."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
(defface window-tool-bar-button-disabled
'((default
@@ -465,7 +545,38 @@ window-tool-bar-button-disabled
:inverse-video t
:background "brightblack"))
"Face used for buttons when the button is disabled."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
+
+(defface window-tool-bar-button-checked
+ '((default
+ :inherit tab-line)
+ (((supports :box t))
+ :box (:line-width -1 :style pressed-button)
+ :background "grey85")
+ (((class color))
+ :background "blue"
+ :foreground "white")
+ (t
+ :inverse-video t))
+ "Face used for buttons when they are toggled."
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
+
+(defface window-tool-bar-button-checked-hover
+ '((default
+ :inherit tab-line)
+ (((class color) (min-colors 88) (supports :box t))
+ :box (:line-width -1 :style pressed-button)
+ :background "grey95")
+ (((class color))
+ :background "brightblue"
+ :foreground "white")
+ (t
+ :inverse-video t))
+ "Face used for buttons when the mouse is hovering over the button."
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
\f
;;; Workaround for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334.
@@ -476,10 +587,10 @@ window-tool-bar--get-keymap
"Return the tool bar keymap."
(let ((tool-bar-always-show-default nil))
(if (and (version< emacs-version "30")
- (not (window-tool-bar--use-images)))
- ;; This code path is a less efficient workaround.
- (window-tool-bar--make-keymap-1)
- (keymap-global-lookup "<tool-bar>"))))
+ (eq 'text (window-tool-bar--style)))
+ ;; This code path is a less efficient workaround.
+ (window-tool-bar--make-keymap-1)
+ (keymap-global-lookup "<tool-bar>"))))
(declare-function image-mask-p "image.c" (spec &optional frame))
@@ -506,12 +617,7 @@ window-tool-bar--make-keymap-1
(plist-put plist :image image)))
bind))
tool-bar-map))
-
-(defun window-tool-bar--turn-on ()
- "Internal function called by `global-window-tool-bar-mode'."
- (when global-window-tool-bar-mode
- (window-tool-bar-mode 1)))
-
+\f
(provide 'window-tool-bar)
;;; window-tool-bar.el ends here
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-01-25 22:38 bug#75844: Update for window-tool-bar Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-01 11:02 ` Eli Zaretskii
2025-02-02 8:52 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2025-02-01 11:02 UTC (permalink / raw)
To: Jared Finder, martin rudalics; +Cc: 75844
> Date: Sat, 25 Jan 2025 14:38:51 -0800
> From: Jared Finder via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>
> Attached is a patch to window-tool-bar. This adds support for the rest
> of the tool bar item specifiers. I have been running with this locally
> for a couple of months to ensure it had no major performance regressions
> because it does add more code run per tool bar item refresh.
Thanks. Martin, any comments?
I see you use :package-version, but doing so should also update
customize-package-emacs-version-alist, AFAIU. Any reasons why you
didn't?
> Separately, I also have an example tool bar mode that I use alongside
> developing the window-tool-bar. This example shows off the capabilities
> of tool bars. At the moment, it is limited to just what window-tool-bar
> supports. I'd be happy to add that as well to Emacs for any further
> tool bar development in general.
Sorry, I don't understand what does "example tool bar mode" mean. Can
you elaborate what would be the use of that in Emacs?
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-01 11:02 ` Eli Zaretskii
@ 2025-02-02 8:52 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-02 21:17 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 12+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-02 8:52 UTC (permalink / raw)
To: Eli Zaretskii, Jared Finder; +Cc: 75844
> Thanks. Martin, any comments?
Just the obvious: "The meanining is ..." should be fixed and "can not"
should become "cannot".
BTW this
;; Dragging empty space on the tab-line (which this package uses to
;; display the window tool bar) doesn't resize windows. This is
;; unlike the mode line, where dragging empty space resizes the
;; window.
apparently hasn't been fixed. Why not?
martin
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-02 8:52 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-02 21:17 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-02 21:19 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-03 7:36 ` Juri Linkov
0 siblings, 2 replies; 12+ messages in thread
From: Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-02 21:17 UTC (permalink / raw)
To: martin rudalics; +Cc: Eli Zaretskii, 75844
On 2025-02-02 00:52, martin rudalics wrote:
>> Thanks. Martin, any comments?
>
> Just the obvious: "The meanining is ..." should be fixed and "can not"
> should become "cannot".
Thanks. Typos fixed and I added a mapping to
customize-package-emacs-version-alist.
> BTW this
>
> ;; Dragging empty space on the tab-line (which this package uses to
> ;; display the window tool bar) doesn't resize windows. This is
> ;; unlike the mode line, where dragging empty space resizes the
> ;; window.
>
> apparently hasn't been fixed. Why not?
People I know in person have mentioned this to me directly which is why
I added this. I think this is actually better fixed in tab-line.el,
though. tab-line-mode has the same issue. If you think it's more useful
to file a separate bug for this, I can do so and delete this as a known
issue of window-tool-bar.
-- MJF
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-02 21:17 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-02 21:19 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-03 7:36 ` Juri Linkov
1 sibling, 0 replies; 12+ messages in thread
From: Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-02 21:19 UTC (permalink / raw)
To: martin rudalics; +Cc: Eli Zaretskii, 75844
[-- Attachment #1: Type: text/plain, Size: 998 bytes --]
I forgot to attach the patch, sorry. Now attached.
On 2025-02-02 13:17, Jared Finder wrote:
> On 2025-02-02 00:52, martin rudalics wrote:
>>> Thanks. Martin, any comments?
>>
>> Just the obvious: "The meanining is ..." should be fixed and "can not"
>> should become "cannot".
>
> Thanks. Typos fixed and I added a mapping to
> customize-package-emacs-version-alist.
>
>> BTW this
>>
>> ;; Dragging empty space on the tab-line (which this package uses to
>> ;; display the window tool bar) doesn't resize windows. This is
>> ;; unlike the mode line, where dragging empty space resizes the
>> ;; window.
>>
>> apparently hasn't been fixed. Why not?
>
> People I know in person have mentioned this to me directly which is why
> I added this. I think this is actually better fixed in tab-line.el,
> though. tab-line-mode has the same issue. If you think it's more
> useful to file a separate bug for this, I can do so and delete this as
> a known issue of window-tool-bar.
>
> -- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Update-window-tool-bar.patch --]
[-- Type: text/x-diff; name=0001-Update-window-tool-bar.patch, Size: 19454 bytes --]
From 2aaa472678a7e2b1897c6f812741fa46d1860d80 Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Sun, 2 Feb 2025 10:11:20 -0800
Subject: [PATCH] Update window-tool-bar
Add support for the remaining tool bar item specs, new user
option `window-tool-bar-style', and add support for older Emacs
versions.
* doc/emacs/windows.texi (Window Tool Bar): Add documentation
for new user option `window-tool-bar-style'.
* lisp/window-tool-bar.el
(customize-package-emacs-version-alist): Add package-version to
Emacs version mapping.
(window-tool-bar-string): Do not show spacers after hidden
buttons.
(window-tool-bar--keymap-entry-to-string): Call new function
`window-tool-bar--style'. Add handling for :visible, :filter,
:button, :vert-only, and :help item specs. Show key bindings.
(window-tool-bar--last-command-triggers-refresh-p): Use "cannot"
in comment.
(window-tool-bar--allow-images): Delete this, it is replaced by
new user option `window-tool-bar-style'.
(window-tool-bar--use-images): Delete this, it is replaced by
new function `window-tool-bar--style'.
(window-tool-bar--turn-on): Move earlier in file, no changes.
(window-tool-bar-style): New user option supporting all values
`tool-bar-style' supports as well as inheriting from
tool-bar-style.
(window-tool-bar--style): New function to calculate active tool
bar style based on `window-tool-bar-style', `tool-bar-style',
and frame capabilities.
(global-window-tool-bar-mode, window-tool-bar-button)
(window-tool-bar-button-hover, window-tool-bar-button-disabled):
Retroactively add package-version.
(window-tool-bar-button-checked)
(window-tool-bar-button-checked-hover): New faces for :button
item spec.
(window-tool-bar--get-keymap): Call new function
`window-tool-bar--style'.
---
doc/emacs/windows.texi | 10 ++
lisp/window-tool-bar.el | 285 ++++++++++++++++++++++++++++------------
2 files changed, 208 insertions(+), 87 deletions(-)
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index a992f26fcdd..8b2e4249a70 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -728,6 +728,16 @@ Window Tool Bar
(add-hook 'special-mode-hook 'window-tool-bar-mode)
@end example
+@vindex window-tool-bar-style
+@cindex Window Tool Bar style
+On graphical displays the window tool bar can be displayed in multiple
+different styles. By default, the window tool bar displays items as
+just images. To impose a specific style, customize the variable
+@code{window-tool-bar-style}.
+
+On text-only displays the window tool bar only shows text for each
+button.
+
Emacs can also display a single tool bar at the top of frames
(@pxref{Tool Bars}).
diff --git a/lisp/window-tool-bar.el b/lisp/window-tool-bar.el
index e2c886c41e5..c900cb53c0b 100644
--- a/lisp/window-tool-bar.el
+++ b/lisp/window-tool-bar.el
@@ -4,8 +4,9 @@
;; Author: Jared Finder <jared@finder.org>
;; Created: Nov 21, 2023
-;; Version: 0.2.1
+;; Version: 0.3
;; Keywords: mouse
+;; URL: http://github.com/chaosemer/window-tool-bar
;; Package-Requires: ((emacs "27.1") (compat "29.1"))
;; This is a GNU ELPA :core package. Avoid adding functionality that
@@ -54,44 +55,32 @@
;;; Known issues:
;;
-;; On GNU Emacs 29.1, terminals dragging to resize windows will error
-;; with message "<tab-line> <mouse-movement> is undefined". This is a
-;; bug in GNU Emacs,
+;; On GNU Emacs 29.1 and earlier, terminals dragging to resize windows
+;; will error with message "<tab-line> <mouse-movement> is undefined".
+;; This is a bug in GNU Emacs,
;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=67457>.
;;
-;; On GNU Emacs 29, performance in terminals is lower than on
-;; graphical frames. This is due to a workaround, see "Workaround for
-;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334", below.
+;; On GNU Emacs 29 and earlier, performance in terminals is lower than
+;; on graphical frames. This is due to a workaround, see "Workaround
+;; for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334", below.
+;;
+;; Dragging empty space on the tab-line (which this package uses to
+;; display the window tool bar) doesn't resize windows. This is
+;; unlike the mode line, where dragging empty space resizes the
+;; window.
;;; Todo:
;;
;; Not all features planned are implemented yet. Eventually I would
;; like to also generally make tool bars better.
;;
-;; Targeting 0.3:
-;; * Properly support remaining less frequently used tool bar item specs. From
-;; `parse_tool_bar_item':
-;; * :visible
-;; * :filter
-;; * :button
-;; * :wrap
-;; * Add display customization similar to `tool-bar-style'.
-;;
-;; Targeting 1.0:
+;; Post 1.0 work:
;;
;; * Clean up Emacs tool bars
;; * Default: Remove default tool-bar entirely
;; * grep, vc: Remove default tool-bar inherited
;; * info: Remove Next / Prev / Up, which is already in the header
;; * smerge: Add tool bar for next/prev
-;;
-;; Post 1.0 work:
-;;
-;; * Show keyboard shortcut on help text.
-;;
-;; * Add a bit more documentation.
-;; * Add customization option: ignore-default-tool-bar-map
-;; * Make tab-line dragging resize the window
;;; Code:
@@ -99,6 +88,11 @@
(require 'mwheel)
(require 'tab-line)
(require 'tool-bar)
+
+(add-to-list 'customize-package-emacs-version-alist
+ '(window-tool-bar ("0.1" . "30.1")
+ ("0.2" . "30.1")
+ ("0.3" . "31.1")))
\f
;;; Benchmarking code
;;
@@ -227,7 +221,7 @@ window-tool-bar-string--cache
(defun window-tool-bar-string ()
"Return a (propertized) string for the tool bar.
-This is for when you want more customizations than
+This is for when you want more customizations than the command
`window-tool-bar-mode' provides. Commonly added to the variable
`tab-line-format', `header-line-format', or `mode-line-format'"
(if (or (null window-tool-bar-string--cache)
@@ -235,13 +229,14 @@ window-tool-bar-string
(let* ((mem0 (memory-use-counts))
(toolbar-menu (window-tool-bar--get-keymap))
(mem1 (memory-use-counts))
- (result (mapconcat #'window-tool-bar--keymap-entry-to-string
- (cdr toolbar-menu) ;Skip 'keymap
+ (strs (mapcar #'window-tool-bar--keymap-entry-to-string
+ (cdr toolbar-menu))) ;Skip 'keymap
+ (result (mapconcat #'identity
+ (delete nil strs)
;; Without spaces between the text, hovering
;; highlights all adjacent buttons.
- (if (window-tool-bar--use-images)
- (propertize " " 'invisible t)
- " ")))
+ (if (eq 'text (window-tool-bar--style)) " "
+ (propertize " " 'invisible t))))
(mem2 (memory-use-counts)))
(cl-mapl (lambda (l-init l0 l1)
(cl-incf (car l-init) (- (car l1) (car l0))))
@@ -281,45 +276,101 @@ window-tool-bar--keymap-entry-to-string
((or `(,_ "--")
`(,_ menu-item ,(and (pred stringp)
(pred (string-prefix-p "--")))))
- (if (window-tool-bar--use-images)
- window-tool-bar--graphical-separator
- "|"))
+ (if (eq 'text (window-tool-bar--style)) "|"
+ window-tool-bar--graphical-separator))
;; Menu item, turn into propertized string button
(`(,key menu-item ,name-expr ,binding . ,plist)
- (when binding ; If no binding exists, then button is hidden.
- (let* ((name (eval name-expr))
- (str (upcase-initials (or (plist-get plist :label)
- (string-trim-right name "\\.+"))))
- (len (length str))
- (enable-form (plist-get plist :enable))
- (enabled (or (not enable-form)
- (eval enable-form))))
- (if enabled
+ (let* ((visible-entry (plist-member plist :visible))
+ (visible (or (null visible-entry) ;Default is visible
+ (eval (cadr visible-entry))))
+ (wrap (plist-get plist :wrap))
+ (filter (plist-get plist :filter)))
+ (when filter
+ (setf binding
+ ;; You would expect this to use `funcall', but existing
+ ;; code in `parse_tool_bar_item' uses `eval'.
+ (eval `(,filter ',binding))))
+ (when (and binding
+ visible
+ (null wrap))
+ (let* ((name (eval name-expr))
+ (str (upcase-initials (or (plist-get plist :label)
+ (string-trim-right name "\\.+"))))
+ (len (length str))
+ (enable-form (plist-get plist :enable))
+ (enabled (or (not enable-form)
+ (eval enable-form)))
+ (button-spec (plist-get plist :button))
+ (button-selected (eval (cdr-safe button-spec)))
+ (vert-only (plist-get plist :vert-only))
+ image-start
+ image-end)
+ ;; Depending on style, Images can be displayed to the
+ ;; left, to the right, or in place of the text
+ (pcase-exhaustive (window-tool-bar--style)
+ ('image
+ (setf image-start 0
+ image-end len))
+ ('text
+ ;; Images shouldn't be available
+ )
+ ((or 'both 'both-horiz)
+ (if vert-only
+ (setf image-start 0 image-end len)
+ (setf str (concat " " str)
+ image-start 0
+ image-end 1
+ len (1+ len))))
+ ('text-image-horiz
+ (if vert-only
+ (setf image-start 0 image-end len)
+ (setf str (concat str " ")
+ image-start len
+ image-end (1+ len)
+ len (1+ len)))))
+
+ (cond
+ ((and enabled button-selected)
+ (add-text-properties 0 len
+ '(mouse-face
+ window-tool-bar-button-checked-hover
+ keymap window-tool-bar--button-keymap
+ face window-tool-bar-button-checked)
+ str))
+ (enabled
(add-text-properties 0 len
'(mouse-face window-tool-bar-button-hover
keymap window-tool-bar--button-keymap
face window-tool-bar-button)
- str)
- (put-text-property 0 len
- 'face
- 'window-tool-bar-button-disabled
- str))
- (when-let* ((spec (and (window-tool-bar--use-images)
- (plist-get menu-item :image))))
- (put-text-property 0 len
- 'display
- (append spec
- (if enabled '(:margin 2 :ascent center)
- '(:margin 2 :ascent center
- :conversion disabled)))
- str))
- (put-text-property 0 len
- 'help-echo
- (or (plist-get plist :help) name)
- str)
- (put-text-property 0 len 'tool-bar-key key str)
- str)))))
+ str))
+ (t
+ (put-text-property 0 len
+ 'face
+ 'window-tool-bar-button-disabled
+ str)))
+ (when-let* ((spec (and image-start image-end
+ (plist-get menu-item :image))))
+ (put-text-property image-start image-end
+ 'display
+ (append spec
+ (if enabled '(:margin 2 :ascent center)
+ '(:margin 2 :ascent center
+ :conversion disabled)))
+ str))
+ (let ((help-text (or (plist-get plist :help) name))
+ (keys (where-is-internal binding nil t)))
+ (put-text-property 0 len
+ 'help-echo
+ (if keys
+ (concat help-text
+ " ("
+ (key-description keys)
+ ")")
+ help-text)
+ str))
+ (put-text-property 0 len 'tool-bar-key key str)
+ str))))))
(defun window-tool-bar--call-button ()
"Call the button that was clicked on in the tab line."
@@ -378,8 +429,8 @@ window-tool-bar--last-command-triggers-refresh-p
;; interactions that can alter the tool bar. Specifically, this
;; excludes mouse movement, mouse wheel scroll, and pinch.
(not (member type window-tool-bar--ignored-event-types))
- ;; Assume that any command that triggers shift select can't alter
- ;; the tool bar. This excludes pure navigation commands.
+ ;; Assume that any command that triggers shift select cannot
+ ;; alter the tool bar. This excludes pure navigation commands.
(not (window-tool-bar--command-triggers-shift-select-p last-command))
;; Assume that self-insert-command won't alter the tool bar.
;; This is the most commonly executed command.
@@ -415,20 +466,52 @@ window-tool-bar-mode
(define-globalized-minor-mode global-window-tool-bar-mode
window-tool-bar-mode window-tool-bar--turn-on
:group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.1")
(add-hook 'isearch-mode-hook #'window-tool-bar--turn-on)
(add-hook 'isearch-mode-end-hook #'window-tool-bar--turn-on))
-(defvar window-tool-bar--allow-images t
- "Internal debug flag to force text mode.")
-
-(defun window-tool-bar--use-images ()
- "Internal function.
-Respects `window-tool-bar--allow-images' as well as frame
-capabilities."
- (and window-tool-bar--allow-images
- (display-images-p)))
+(defun window-tool-bar--turn-on ()
+ "Internal function called by the command `global-window-tool-bar-mode'."
+ (when global-window-tool-bar-mode
+ (window-tool-bar-mode 1)))
\f
;;; Display styling:
+(defcustom window-tool-bar-style 'image
+ "Tool bar style to use for window tool bars.
+The meaning is the same as for `tool-bar-style', which see. If
+set to the symbol `tool-bar-style', then use the value of
+`tool-bar-style' instead.
+
+When images cannot be displayed (see `display-images-p'), text
+is used."
+ :type '(choice (const :tag "Images" :value image)
+ (const :tag "Text" :value text)
+ ;; This option would require multiple tool bar lines.
+ ;;(const :tag "Both" :value both)
+ (const :tag "Both-horiz" :value both-horiz)
+ (const :tag "Text-image-horiz" :value text-image-horiz)
+ (const :tag "Inherit tool-bar-style" :value tool-bar-style)
+ (const :tag "System default" :value nil))
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
+
+(defun window-tool-bar--style ()
+ "Return the effective style based on `window-tool-bar-style'.
+
+This also takes into account frame capabilities. If the current
+frame cannot display images (see `display-images-p'), then this
+will always return text."
+ (if (not (display-images-p))
+ 'text
+ (let ((style window-tool-bar-style))
+ (when (eq style 'tool-bar-style)
+ (setf style tool-bar-style))
+ (unless (memq style '(image text both both-horiz text-image-horiz))
+ (setf style (if (fboundp 'tool-bar-get-system-style)
+ (tool-bar-get-system-style)
+ 'image)))
+ style)))
+
(defface window-tool-bar-button
'((default
:inherit tab-line)
@@ -441,7 +524,8 @@ window-tool-bar-button
(t
:inverse-video t))
"Face used for buttons when the mouse is not hovering over the button."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
(defface window-tool-bar-button-hover
'((default
@@ -452,7 +536,8 @@ window-tool-bar-button-hover
(t
:inverse-video t))
"Face used for buttons when the mouse is hovering over the button."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
(defface window-tool-bar-button-disabled
'((default
@@ -465,7 +550,38 @@ window-tool-bar-button-disabled
:inverse-video t
:background "brightblack"))
"Face used for buttons when the button is disabled."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
+
+(defface window-tool-bar-button-checked
+ '((default
+ :inherit tab-line)
+ (((supports :box t))
+ :box (:line-width -1 :style pressed-button)
+ :background "grey85")
+ (((class color))
+ :background "blue"
+ :foreground "white")
+ (t
+ :inverse-video t))
+ "Face used for buttons when they are toggled."
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
+
+(defface window-tool-bar-button-checked-hover
+ '((default
+ :inherit tab-line)
+ (((class color) (min-colors 88) (supports :box t))
+ :box (:line-width -1 :style pressed-button)
+ :background "grey95")
+ (((class color))
+ :background "brightblue"
+ :foreground "white")
+ (t
+ :inverse-video t))
+ "Face used for buttons when the mouse is hovering over the button."
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
\f
;;; Workaround for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334.
@@ -476,10 +592,10 @@ window-tool-bar--get-keymap
"Return the tool bar keymap."
(let ((tool-bar-always-show-default nil))
(if (and (version< emacs-version "30")
- (not (window-tool-bar--use-images)))
- ;; This code path is a less efficient workaround.
- (window-tool-bar--make-keymap-1)
- (keymap-global-lookup "<tool-bar>"))))
+ (eq 'text (window-tool-bar--style)))
+ ;; This code path is a less efficient workaround.
+ (window-tool-bar--make-keymap-1)
+ (keymap-global-lookup "<tool-bar>"))))
(declare-function image-mask-p "image.c" (spec &optional frame))
@@ -506,12 +622,7 @@ window-tool-bar--make-keymap-1
(plist-put plist :image image)))
bind))
tool-bar-map))
-
-(defun window-tool-bar--turn-on ()
- "Internal function called by `global-window-tool-bar-mode'."
- (when global-window-tool-bar-mode
- (window-tool-bar-mode 1)))
-
+\f
(provide 'window-tool-bar)
;;; window-tool-bar.el ends here
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-02 21:17 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-02 21:19 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-03 7:36 ` Juri Linkov
2025-02-03 8:33 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 6:20 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
1 sibling, 2 replies; 12+ messages in thread
From: Juri Linkov @ 2025-02-03 7:36 UTC (permalink / raw)
To: Jared Finder; +Cc: martin rudalics, Eli Zaretskii, 75844
>> BTW this
>> ;; Dragging empty space on the tab-line (which this package uses to
>> ;; display the window tool bar) doesn't resize windows. This is
>> ;; unlike the mode line, where dragging empty space resizes the
>> ;; window.
>> apparently hasn't been fixed. Why not?
>
> People I know in person have mentioned this to me directly which is why
> I added this. I think this is actually better fixed in tab-line.el,
> though. tab-line-mode has the same issue. If you think it's more useful to
> file a separate bug for this, I can do so and delete this as a known issue
> of window-tool-bar.
Dragging empty space on the tab-line would be nice to have
when it doesn't preclude from dragging tabs to reorder them.
Please file a separate request if you intend to implement this.
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-03 7:36 ` Juri Linkov
@ 2025-02-03 8:33 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 6:20 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
1 sibling, 0 replies; 12+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-03 8:33 UTC (permalink / raw)
To: Juri Linkov, Jared Finder; +Cc: Eli Zaretskii, 75844
> Dragging empty space on the tab-line would be nice to have
> when it doesn't preclude from dragging tabs to reorder them.
> Please file a separate request if you intend to implement this.
I don't overly like that empty space dragging anyway. For me the best
solution would be to use a uniform 8-dot Braille pattern on both sides
to indicate the locations from where one can start dragging any of these
lines.
martin
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-03 7:36 ` Juri Linkov
2025-02-03 8:33 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-04 6:20 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 7:40 ` Juri Linkov
2025-02-04 8:09 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
1 sibling, 2 replies; 12+ messages in thread
From: Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-04 6:20 UTC (permalink / raw)
To: Juri Linkov; +Cc: martin rudalics, Eli Zaretskii, 75844
On 2025-02-02 23:36, Juri Linkov wrote:
>>> BTW this
>>> ;; Dragging empty space on the tab-line (which this package uses to
>>> ;; display the window tool bar) doesn't resize windows. This is
>>> ;; unlike the mode line, where dragging empty space resizes the
>>> ;; window.
>>> apparently hasn't been fixed. Why not?
>>
>> People I know in person have mentioned this to me directly which is
>> why
>> I added this. I think this is actually better fixed in tab-line.el,
>> though. tab-line-mode has the same issue. If you think it's more
>> useful to
>> file a separate bug for this, I can do so and delete this as a known
>> issue
>> of window-tool-bar.
>
> Dragging empty space on the tab-line would be nice to have
> when it doesn't preclude from dragging tabs to reorder them.
> Please file a separate request if you intend to implement this.
Will do. It's especially strange since dragging on a header line *does*
resize the window. If you have a header line and a tab line both
visible, you end up with the following stack at the boundary between
windows:
Top window content
--- MINIBUFFER --- (draggable)
--- TAB LINE ----- (not draggable)
--- HEADER LINE -- (draggable)
Bottom window content
I'll file a separate bug for making dragging empty space on the tab line
work and will delete this line from the patch next time I'm near my
Emacs-development computer.
Any other feedback here?
-- MJF
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-04 6:20 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-04 7:40 ` Juri Linkov
2025-02-06 5:47 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 8:09 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
1 sibling, 1 reply; 12+ messages in thread
From: Juri Linkov @ 2025-02-04 7:40 UTC (permalink / raw)
To: Jared Finder; +Cc: martin rudalics, Eli Zaretskii, 75844
>>>> BTW this
>>>> ;; Dragging empty space on the tab-line (which this package uses to
>>>> ;; display the window tool bar) doesn't resize windows. This is
>>>> ;; unlike the mode line, where dragging empty space resizes the
>>>> ;; window.
>>>> apparently hasn't been fixed. Why not?
>>> People I know in person have mentioned this to me directly which is why
>>> I added this. I think this is actually better fixed in tab-line.el,
>>> though. tab-line-mode has the same issue. If you think it's more useful
>>> to
>>> file a separate bug for this, I can do so and delete this as a known
>>> issue
>>> of window-tool-bar.
>> Dragging empty space on the tab-line would be nice to have
>> when it doesn't preclude from dragging tabs to reorder them.
>> Please file a separate request if you intend to implement this.
>
> Will do. It's especially strange since dragging on a header line *does*
> resize the window. If you have a header line and a tab line both visible,
> you end up with the following stack at the boundary between windows:
>
> Top window content
> --- MINIBUFFER --- (draggable)
> --- TAB LINE ----- (not draggable)
> --- HEADER LINE -- (draggable)
> Bottom window content
Indeed, this omission is especially glaring in this case.
It's interesting to note that hovering over the mode line changes
the mouse icon to indicate resizing, but hovering over the header line
doesn't change the mouse icon, so no indication that it's draggable.
> I'll file a separate bug for making dragging empty space on the tab line
> work and will delete this line from the patch next time I'm near my
> Emacs-development computer.
Thanks in advance.
> Any other feedback here?
I have no more feedback.
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-04 6:20 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 7:40 ` Juri Linkov
@ 2025-02-04 8:09 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
1 sibling, 0 replies; 12+ messages in thread
From: martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-04 8:09 UTC (permalink / raw)
To: Jared Finder, Juri Linkov; +Cc: Eli Zaretskii, 75844
> --- MINIBUFFER --- (draggable)
Strictly spoken a MINIBUFFER is not draggable. The mode line above is.
martin
^ permalink raw reply [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-04 7:40 ` Juri Linkov
@ 2025-02-06 5:47 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 9:34 ` Eli Zaretskii
0 siblings, 1 reply; 12+ messages in thread
From: Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2025-02-06 5:47 UTC (permalink / raw)
To: Juri Linkov; +Cc: martin rudalics, Eli Zaretskii, 75844
[-- Attachment #1: Type: text/plain, Size: 1181 bytes --]
On 2025-02-03 23:40, Juri Linkov wrote:
>>>>> BTW this
>>>>> ;; Dragging empty space on the tab-line (which this package uses to
>>>>> ;; display the window tool bar) doesn't resize windows. This is
>>>>> ;; unlike the mode line, where dragging empty space resizes the
>>>>> ;; window.
>>>>> apparently hasn't been fixed. Why not?
>>>> People I know in person have mentioned this to me directly which is
>>>> why
>>>> I added this. I think this is actually better fixed in tab-line.el,
>>>> though. tab-line-mode has the same issue. If you think it's more
>>>> useful
>>>> to
>>>> file a separate bug for this, I can do so and delete this as a known
>>>> issue
>>>> of window-tool-bar.
>>> Dragging empty space on the tab-line would be nice to have
>>> when it doesn't preclude from dragging tabs to reorder them.
>>> Please file a separate request if you intend to implement this.
>>
>> Will do.
...
>> Any other feedback here?
>
> I have no more feedback.
Attached is a patch with the issue around dragging the header line not
mentioned. I'll be filing a bug immediately after this to track fixing
header line dragging (it will take a bit longer to address).
-- MJF
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Update-window-tool-bar.patch --]
[-- Type: text/x-diff; name=0001-Update-window-tool-bar.patch, Size: 19238 bytes --]
From 64d048cda92067dcf0cce7d72be72804e65eb08b Mon Sep 17 00:00:00 2001
From: Jared Finder <jared@finder.org>
Date: Sun, 2 Feb 2025 10:11:20 -0800
Subject: [PATCH] Update window-tool-bar
Add support for the remaining tool bar item specs, new user
option `window-tool-bar-style', and add support for older Emacs
versions.
* doc/emacs/windows.texi (Window Tool Bar): Add documentation
for new user option `window-tool-bar-style'.
* lisp/window-tool-bar.el
(customize-package-emacs-version-alist): Add package-version to
Emacs version mapping.
(window-tool-bar-string): Do not show spacers after hidden
buttons.
(window-tool-bar--keymap-entry-to-string): Call new function
`window-tool-bar--style'. Add handling for :visible, :filter,
:button, :vert-only, and :help item specs. Show key bindings.
(window-tool-bar--last-command-triggers-refresh-p): Use "cannot"
in comment.
(window-tool-bar--allow-images): Delete this, it is replaced by
new user option `window-tool-bar-style'.
(window-tool-bar--use-images): Delete this, it is replaced by
new function `window-tool-bar--style'.
(window-tool-bar--turn-on): Move earlier in file, no changes.
(window-tool-bar-style): New user option supporting all values
`tool-bar-style' supports as well as inheriting from
tool-bar-style.
(window-tool-bar--style): New function to calculate active tool
bar style based on `window-tool-bar-style', `tool-bar-style',
and frame capabilities.
(global-window-tool-bar-mode, window-tool-bar-button)
(window-tool-bar-button-hover, window-tool-bar-button-disabled):
Retroactively add package-version.
(window-tool-bar-button-checked)
(window-tool-bar-button-checked-hover): New faces for :button
item spec.
(window-tool-bar--get-keymap): Call new function
`window-tool-bar--style'.
---
doc/emacs/windows.texi | 10 ++
lisp/window-tool-bar.el | 280 +++++++++++++++++++++++++++-------------
2 files changed, 203 insertions(+), 87 deletions(-)
diff --git a/doc/emacs/windows.texi b/doc/emacs/windows.texi
index a992f26fcdd..8b2e4249a70 100644
--- a/doc/emacs/windows.texi
+++ b/doc/emacs/windows.texi
@@ -728,6 +728,16 @@ Window Tool Bar
(add-hook 'special-mode-hook 'window-tool-bar-mode)
@end example
+@vindex window-tool-bar-style
+@cindex Window Tool Bar style
+On graphical displays the window tool bar can be displayed in multiple
+different styles. By default, the window tool bar displays items as
+just images. To impose a specific style, customize the variable
+@code{window-tool-bar-style}.
+
+On text-only displays the window tool bar only shows text for each
+button.
+
Emacs can also display a single tool bar at the top of frames
(@pxref{Tool Bars}).
diff --git a/lisp/window-tool-bar.el b/lisp/window-tool-bar.el
index e2c886c41e5..132a41880d7 100644
--- a/lisp/window-tool-bar.el
+++ b/lisp/window-tool-bar.el
@@ -4,8 +4,9 @@
;; Author: Jared Finder <jared@finder.org>
;; Created: Nov 21, 2023
-;; Version: 0.2.1
+;; Version: 0.3
;; Keywords: mouse
+;; URL: http://github.com/chaosemer/window-tool-bar
;; Package-Requires: ((emacs "27.1") (compat "29.1"))
;; This is a GNU ELPA :core package. Avoid adding functionality that
@@ -54,44 +55,27 @@
;;; Known issues:
;;
-;; On GNU Emacs 29.1, terminals dragging to resize windows will error
-;; with message "<tab-line> <mouse-movement> is undefined". This is a
-;; bug in GNU Emacs,
+;; On GNU Emacs 29.1 and earlier, terminals dragging to resize windows
+;; will error with message "<tab-line> <mouse-movement> is undefined".
+;; This is a bug in GNU Emacs,
;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=67457>.
;;
-;; On GNU Emacs 29, performance in terminals is lower than on
-;; graphical frames. This is due to a workaround, see "Workaround for
-;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334", below.
+;; On GNU Emacs 29 and earlier, performance in terminals is lower than
+;; on graphical frames. This is due to a workaround, see "Workaround
+;; for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334", below.
;;; Todo:
;;
;; Not all features planned are implemented yet. Eventually I would
;; like to also generally make tool bars better.
;;
-;; Targeting 0.3:
-;; * Properly support remaining less frequently used tool bar item specs. From
-;; `parse_tool_bar_item':
-;; * :visible
-;; * :filter
-;; * :button
-;; * :wrap
-;; * Add display customization similar to `tool-bar-style'.
-;;
-;; Targeting 1.0:
+;; Post 1.0 work:
;;
;; * Clean up Emacs tool bars
;; * Default: Remove default tool-bar entirely
;; * grep, vc: Remove default tool-bar inherited
;; * info: Remove Next / Prev / Up, which is already in the header
;; * smerge: Add tool bar for next/prev
-;;
-;; Post 1.0 work:
-;;
-;; * Show keyboard shortcut on help text.
-;;
-;; * Add a bit more documentation.
-;; * Add customization option: ignore-default-tool-bar-map
-;; * Make tab-line dragging resize the window
;;; Code:
@@ -99,6 +83,11 @@
(require 'mwheel)
(require 'tab-line)
(require 'tool-bar)
+
+(add-to-list 'customize-package-emacs-version-alist
+ '(window-tool-bar ("0.1" . "30.1")
+ ("0.2" . "30.1")
+ ("0.3" . "31.1")))
\f
;;; Benchmarking code
;;
@@ -227,7 +216,7 @@ window-tool-bar-string--cache
(defun window-tool-bar-string ()
"Return a (propertized) string for the tool bar.
-This is for when you want more customizations than
+This is for when you want more customizations than the command
`window-tool-bar-mode' provides. Commonly added to the variable
`tab-line-format', `header-line-format', or `mode-line-format'"
(if (or (null window-tool-bar-string--cache)
@@ -235,13 +224,14 @@ window-tool-bar-string
(let* ((mem0 (memory-use-counts))
(toolbar-menu (window-tool-bar--get-keymap))
(mem1 (memory-use-counts))
- (result (mapconcat #'window-tool-bar--keymap-entry-to-string
- (cdr toolbar-menu) ;Skip 'keymap
+ (strs (mapcar #'window-tool-bar--keymap-entry-to-string
+ (cdr toolbar-menu))) ;Skip 'keymap
+ (result (mapconcat #'identity
+ (delete nil strs)
;; Without spaces between the text, hovering
;; highlights all adjacent buttons.
- (if (window-tool-bar--use-images)
- (propertize " " 'invisible t)
- " ")))
+ (if (eq 'text (window-tool-bar--style)) " "
+ (propertize " " 'invisible t))))
(mem2 (memory-use-counts)))
(cl-mapl (lambda (l-init l0 l1)
(cl-incf (car l-init) (- (car l1) (car l0))))
@@ -281,45 +271,101 @@ window-tool-bar--keymap-entry-to-string
((or `(,_ "--")
`(,_ menu-item ,(and (pred stringp)
(pred (string-prefix-p "--")))))
- (if (window-tool-bar--use-images)
- window-tool-bar--graphical-separator
- "|"))
+ (if (eq 'text (window-tool-bar--style)) "|"
+ window-tool-bar--graphical-separator))
;; Menu item, turn into propertized string button
(`(,key menu-item ,name-expr ,binding . ,plist)
- (when binding ; If no binding exists, then button is hidden.
- (let* ((name (eval name-expr))
- (str (upcase-initials (or (plist-get plist :label)
- (string-trim-right name "\\.+"))))
- (len (length str))
- (enable-form (plist-get plist :enable))
- (enabled (or (not enable-form)
- (eval enable-form))))
- (if enabled
+ (let* ((visible-entry (plist-member plist :visible))
+ (visible (or (null visible-entry) ;Default is visible
+ (eval (cadr visible-entry))))
+ (wrap (plist-get plist :wrap))
+ (filter (plist-get plist :filter)))
+ (when filter
+ (setf binding
+ ;; You would expect this to use `funcall', but existing
+ ;; code in `parse_tool_bar_item' uses `eval'.
+ (eval `(,filter ',binding))))
+ (when (and binding
+ visible
+ (null wrap))
+ (let* ((name (eval name-expr))
+ (str (upcase-initials (or (plist-get plist :label)
+ (string-trim-right name "\\.+"))))
+ (len (length str))
+ (enable-form (plist-get plist :enable))
+ (enabled (or (not enable-form)
+ (eval enable-form)))
+ (button-spec (plist-get plist :button))
+ (button-selected (eval (cdr-safe button-spec)))
+ (vert-only (plist-get plist :vert-only))
+ image-start
+ image-end)
+ ;; Depending on style, Images can be displayed to the
+ ;; left, to the right, or in place of the text
+ (pcase-exhaustive (window-tool-bar--style)
+ ('image
+ (setf image-start 0
+ image-end len))
+ ('text
+ ;; Images shouldn't be available
+ )
+ ((or 'both 'both-horiz)
+ (if vert-only
+ (setf image-start 0 image-end len)
+ (setf str (concat " " str)
+ image-start 0
+ image-end 1
+ len (1+ len))))
+ ('text-image-horiz
+ (if vert-only
+ (setf image-start 0 image-end len)
+ (setf str (concat str " ")
+ image-start len
+ image-end (1+ len)
+ len (1+ len)))))
+
+ (cond
+ ((and enabled button-selected)
+ (add-text-properties 0 len
+ '(mouse-face
+ window-tool-bar-button-checked-hover
+ keymap window-tool-bar--button-keymap
+ face window-tool-bar-button-checked)
+ str))
+ (enabled
(add-text-properties 0 len
'(mouse-face window-tool-bar-button-hover
keymap window-tool-bar--button-keymap
face window-tool-bar-button)
- str)
- (put-text-property 0 len
- 'face
- 'window-tool-bar-button-disabled
- str))
- (when-let* ((spec (and (window-tool-bar--use-images)
- (plist-get menu-item :image))))
- (put-text-property 0 len
- 'display
- (append spec
- (if enabled '(:margin 2 :ascent center)
- '(:margin 2 :ascent center
- :conversion disabled)))
- str))
- (put-text-property 0 len
- 'help-echo
- (or (plist-get plist :help) name)
- str)
- (put-text-property 0 len 'tool-bar-key key str)
- str)))))
+ str))
+ (t
+ (put-text-property 0 len
+ 'face
+ 'window-tool-bar-button-disabled
+ str)))
+ (when-let* ((spec (and image-start image-end
+ (plist-get menu-item :image))))
+ (put-text-property image-start image-end
+ 'display
+ (append spec
+ (if enabled '(:margin 2 :ascent center)
+ '(:margin 2 :ascent center
+ :conversion disabled)))
+ str))
+ (let ((help-text (or (plist-get plist :help) name))
+ (keys (where-is-internal binding nil t)))
+ (put-text-property 0 len
+ 'help-echo
+ (if keys
+ (concat help-text
+ " ("
+ (key-description keys)
+ ")")
+ help-text)
+ str))
+ (put-text-property 0 len 'tool-bar-key key str)
+ str))))))
(defun window-tool-bar--call-button ()
"Call the button that was clicked on in the tab line."
@@ -378,8 +424,8 @@ window-tool-bar--last-command-triggers-refresh-p
;; interactions that can alter the tool bar. Specifically, this
;; excludes mouse movement, mouse wheel scroll, and pinch.
(not (member type window-tool-bar--ignored-event-types))
- ;; Assume that any command that triggers shift select can't alter
- ;; the tool bar. This excludes pure navigation commands.
+ ;; Assume that any command that triggers shift select cannot
+ ;; alter the tool bar. This excludes pure navigation commands.
(not (window-tool-bar--command-triggers-shift-select-p last-command))
;; Assume that self-insert-command won't alter the tool bar.
;; This is the most commonly executed command.
@@ -415,20 +461,52 @@ window-tool-bar-mode
(define-globalized-minor-mode global-window-tool-bar-mode
window-tool-bar-mode window-tool-bar--turn-on
:group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.1")
(add-hook 'isearch-mode-hook #'window-tool-bar--turn-on)
(add-hook 'isearch-mode-end-hook #'window-tool-bar--turn-on))
-(defvar window-tool-bar--allow-images t
- "Internal debug flag to force text mode.")
-
-(defun window-tool-bar--use-images ()
- "Internal function.
-Respects `window-tool-bar--allow-images' as well as frame
-capabilities."
- (and window-tool-bar--allow-images
- (display-images-p)))
+(defun window-tool-bar--turn-on ()
+ "Internal function called by the command `global-window-tool-bar-mode'."
+ (when global-window-tool-bar-mode
+ (window-tool-bar-mode 1)))
\f
;;; Display styling:
+(defcustom window-tool-bar-style 'image
+ "Tool bar style to use for window tool bars.
+The meaning is the same as for `tool-bar-style', which see. If
+set to the symbol `tool-bar-style', then use the value of
+`tool-bar-style' instead.
+
+When images cannot be displayed (see `display-images-p'), text
+is used."
+ :type '(choice (const :tag "Images" :value image)
+ (const :tag "Text" :value text)
+ ;; This option would require multiple tool bar lines.
+ ;;(const :tag "Both" :value both)
+ (const :tag "Both-horiz" :value both-horiz)
+ (const :tag "Text-image-horiz" :value text-image-horiz)
+ (const :tag "Inherit tool-bar-style" :value tool-bar-style)
+ (const :tag "System default" :value nil))
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
+
+(defun window-tool-bar--style ()
+ "Return the effective style based on `window-tool-bar-style'.
+
+This also takes into account frame capabilities. If the current
+frame cannot display images (see `display-images-p'), then this
+will always return text."
+ (if (not (display-images-p))
+ 'text
+ (let ((style window-tool-bar-style))
+ (when (eq style 'tool-bar-style)
+ (setf style tool-bar-style))
+ (unless (memq style '(image text both both-horiz text-image-horiz))
+ (setf style (if (fboundp 'tool-bar-get-system-style)
+ (tool-bar-get-system-style)
+ 'image)))
+ style)))
+
(defface window-tool-bar-button
'((default
:inherit tab-line)
@@ -441,7 +519,8 @@ window-tool-bar-button
(t
:inverse-video t))
"Face used for buttons when the mouse is not hovering over the button."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
(defface window-tool-bar-button-hover
'((default
@@ -452,7 +531,8 @@ window-tool-bar-button-hover
(t
:inverse-video t))
"Face used for buttons when the mouse is hovering over the button."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
(defface window-tool-bar-button-disabled
'((default
@@ -465,7 +545,38 @@ window-tool-bar-button-disabled
:inverse-video t
:background "brightblack"))
"Face used for buttons when the button is disabled."
- :group 'window-tool-bar)
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.2"))
+
+(defface window-tool-bar-button-checked
+ '((default
+ :inherit tab-line)
+ (((supports :box t))
+ :box (:line-width -1 :style pressed-button)
+ :background "grey85")
+ (((class color))
+ :background "blue"
+ :foreground "white")
+ (t
+ :inverse-video t))
+ "Face used for buttons when they are toggled."
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
+
+(defface window-tool-bar-button-checked-hover
+ '((default
+ :inherit tab-line)
+ (((class color) (min-colors 88) (supports :box t))
+ :box (:line-width -1 :style pressed-button)
+ :background "grey95")
+ (((class color))
+ :background "brightblue"
+ :foreground "white")
+ (t
+ :inverse-video t))
+ "Face used for buttons when the mouse is hovering over the button."
+ :group 'window-tool-bar
+ :package-version '(window-tool-bar . "0.3"))
\f
;;; Workaround for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68334.
@@ -476,10 +587,10 @@ window-tool-bar--get-keymap
"Return the tool bar keymap."
(let ((tool-bar-always-show-default nil))
(if (and (version< emacs-version "30")
- (not (window-tool-bar--use-images)))
- ;; This code path is a less efficient workaround.
- (window-tool-bar--make-keymap-1)
- (keymap-global-lookup "<tool-bar>"))))
+ (eq 'text (window-tool-bar--style)))
+ ;; This code path is a less efficient workaround.
+ (window-tool-bar--make-keymap-1)
+ (keymap-global-lookup "<tool-bar>"))))
(declare-function image-mask-p "image.c" (spec &optional frame))
@@ -506,12 +617,7 @@ window-tool-bar--make-keymap-1
(plist-put plist :image image)))
bind))
tool-bar-map))
-
-(defun window-tool-bar--turn-on ()
- "Internal function called by `global-window-tool-bar-mode'."
- (when global-window-tool-bar-mode
- (window-tool-bar-mode 1)))
-
+\f
(provide 'window-tool-bar)
;;; window-tool-bar.el ends here
--
2.39.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* bug#75844: Update for window-tool-bar
2025-02-06 5:47 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2025-02-06 9:34 ` Eli Zaretskii
0 siblings, 0 replies; 12+ messages in thread
From: Eli Zaretskii @ 2025-02-06 9:34 UTC (permalink / raw)
To: Jared Finder; +Cc: rudalics, 75844, juri
> Date: Wed, 05 Feb 2025 21:47:38 -0800
> From: Jared Finder <jared@finder.org>
> Cc: martin rudalics <rudalics@gmx.at>, Eli Zaretskii <eliz@gnu.org>,
> 75844@debbugs.gnu.org
>
> > I have no more feedback.
>
> Attached is a patch with the issue around dragging the header line not
> mentioned. I'll be filing a bug immediately after this to track fixing
> header line dragging (it will take a bit longer to address).
Thanks, a few minor comments below.
> +@vindex window-tool-bar-style
> +@cindex Window Tool Bar style
Index entries should preferably be all-lowercase, to make sure their
sorting does not depend on the locale where the manual is generated.
> +On graphical displays the window tool bar can be displayed in multiple
> +different styles.
I'd use "several". "Multiple" could be interpreted as meaning "at the
same time", which is not what you mean.
> +On text-only displays the window tool bar only shows text for each
> +button.
I'm guessing you mean "even if another style is specified", right?
If so, please say so explicitly.
> +(defcustom window-tool-bar-style 'image
> + "Tool bar style to use for window tool bars.
> +The meaning is the same as for `tool-bar-style', which see. If
> +set to the symbol `tool-bar-style', then use the value of
> +`tool-bar-style' instead.
> +
> +When images cannot be displayed (see `display-images-p'), text
> +is used."
Passive tense alert!
> + :type '(choice (const :tag "Images" :value image)
> + (const :tag "Text" :value text)
> + ;; This option would require multiple tool bar lines.
> + ;;(const :tag "Both" :value both)
> + (const :tag "Both-horiz" :value both-horiz)
> + (const :tag "Text-image-horiz" :value text-image-horiz)
> + (const :tag "Inherit tool-bar-style" :value tool-bar-style)
> + (const :tag "System default" :value nil))
Many of these tags have cryptic text. Can we make this text more
user-friendly? It is there to explain the meaning of each value to
the users when they customize the option.
> +(defun window-tool-bar--style ()
> + "Return the effective style based on `window-tool-bar-style'.
> +
> +This also takes into account frame capabilities. If the current
> +frame cannot display images (see `display-images-p'), then this
> +will always return text."
> + (if (not (display-images-p))
> + 'text
Should we perhaps test for support of specific image types?
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-02-06 9:34 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-25 22:38 bug#75844: Update for window-tool-bar Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-01 11:02 ` Eli Zaretskii
2025-02-02 8:52 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-02 21:17 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-02 21:19 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-03 7:36 ` Juri Linkov
2025-02-03 8:33 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 6:20 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-04 7:40 ` Juri Linkov
2025-02-06 5:47 ` Jared Finder via Bug reports for GNU Emacs, the Swiss army knife of text editors
2025-02-06 9:34 ` Eli Zaretskii
2025-02-04 8:09 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.