Subject: bug#79046: (WIP) [PATCH] tab-line: Change close button appearance for modified tabs

From: Elijah Gabe Pérez <[email-masked]>
Date: Fri, 18 Jul 2025 19:21:56 -0600

Tags: patch

When editing multiple buffers the `tab-line-tab-modified` face (which
indicates that a buffer has been modified and not saved) is sometimes
barely visible or hard to distinguish from the tab line.

This patch changes the appearance of the close button icon when the
buffer has been modified, similar to other editors.

The patch is not yet finished, this feature is currently "hardcoded"
(the only way to disable this is removing `tab-line-tab-face-modified`
from `tab-line-tab-face-functions`).

I would like any suggestion, if should this have an option for disable
this.

>From 8730cb498084b96ee968e36259cab9a2480efea2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Sat, 12 Jul 2025 13:16:50 -0600
Subject: [PATCH] tab-line: Add close button for modified tabs

* etc/images/tabs/close-modified.xpm: New file
* lisp/tab-line.el (tab-line-close-modified): Define new icon.
(tab-line-close-modified-button): New internal-variable.
(tab-line-tab-name-format-default): Add new close button only if
the tab was modified.
---
 etc/images/tabs/close-modified.xpm | 16 ++++++++++++++++
 lisp/tab-line.el                   | 24 +++++++++++++++++++++++-
 2 files changed, 39 insertions(+), 1 deletion(-)
 create mode 100644 etc/images/tabs/close-modified.xpm

diff --git a/etc/images/tabs/close-modified.xpm b/etc/images/tabs/close-modified.xpm
new file mode 100644
index 00000000000..44b45d49011
--- /dev/null
+++ b/etc/images/tabs/close-modified.xpm
@@ -0,0 +1,16 @@
+/* XPM */
+static char *dummy[]={
+"9 9 4 1",
+". c None",
+"b c #000000",
+"a c #808080",
+"# c #bfbfbf",
+"..#####..",
+".#######.",
+"###aaa###",
+"##abbba##",
+"##abbba##",
+"##abbba##",
+"###aaa###",
+".#######.",
+"..#####.."};
diff --git a/lisp/tab-line.el b/lisp/tab-line.el
index b93aef2dd53..4153bd8ac2a 100644
--- a/lisp/tab-line.el
+++ b/lisp/tab-line.el
@@ -251,6 +251,26 @@ tab-line-close-button
               'help-echo "Click to close tab")
   "Button for closing the clicked tab.")
 
+(define-icon tab-line-close-modified nil
+  `((image "symbols/dot_medium_16.svg" "tabs/close-modified.xpm"
+           :face shadow
+           :height (1 . em)
+           :margin (2 . 0)
+           :ascent center)
+    (symbol ,(concat " " [#x2022])) ; bullet
+    (text " *"))
+  "Icon for closing the clicked tab when tab is modified."
+  :version "31.1"
+  :help-echo "Click to close tab")
+
+(defvar tab-line-close-modified-button
+  (propertize (icon-string 'tab-line-close-modified)
+              'rear-nonsticky nil
+              'keymap tab-line-tab-close-map
+              'mouse-face 'tab-line-close-highlight
+              'help-echo "Click to close tab")
+  "Button for closing the clicked tab when tab is modified.")
+
 (define-icon tab-line-left nil
   `((image "symbols/chevron_left_16.svg" "tabs/left-arrow.xpm"
            :face shadow
@@ -619,7 +639,9 @@ tab-line-tab-name-format-default
                                          (not (eq tab-line-close-button-show
                                                   (if selected-p 'non-selected
                                                     'selected)))
-                                         tab-line-close-button)
+                                         (if (memq 'tab-line-tab-modified (plist-get face :inherit))
+                                             tab-line-close-modified-button
+                                           tab-line-close-button))
                                     "")))
                      (setq close (copy-sequence close))
                      ;; Don't overwrite the icon face
-- 
2.50.1

-- 
- E.G via GNU Emacs and Org.