unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#41343: tab-bar-mode: Close tab on mouse-2 click
@ 2020-05-17  4:05 Stefan Kangas
  2020-05-17 22:12 ` Juri Linkov
  2021-08-03 22:33 ` Juri Linkov
  0 siblings, 2 replies; 31+ messages in thread
From: Stefan Kangas @ 2020-05-17  4:05 UTC (permalink / raw)
  To: 41343

Severity: wishlist

Please consider adding a binding to close a tab in tab-bar-mode by
clicking on it using the middle mouse button (mouse-2).

Best regards,
Stefan Kangas





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2020-05-17  4:05 bug#41343: tab-bar-mode: Close tab on mouse-2 click Stefan Kangas
@ 2020-05-17 22:12 ` Juri Linkov
  2020-05-17 22:23   ` Stefan Kangas
  2020-05-18  2:32   ` Eli Zaretskii
  2021-08-03 22:33 ` Juri Linkov
  1 sibling, 2 replies; 31+ messages in thread
From: Juri Linkov @ 2020-05-17 22:12 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 41343

> Please consider adding a binding to close a tab in tab-bar-mode by
> clicking on it using the middle mouse button (mouse-2).

Like in bug#41342, when someone will find a way to emit the <mouse-2> event
on the tab-bar,  I'll immediately bind it to the tab closing command.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2020-05-17 22:12 ` Juri Linkov
@ 2020-05-17 22:23   ` Stefan Kangas
  2020-05-18  2:32   ` Eli Zaretskii
  1 sibling, 0 replies; 31+ messages in thread
From: Stefan Kangas @ 2020-05-17 22:23 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343

Juri Linkov <juri@linkov.net> writes:

> Like in bug#41342, when someone will find a way to emit the <mouse-2> event
> on the tab-bar,  I'll immediately bind it to the tab closing command.

Thanks!

Best regards,
Stefan Kangas





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2020-05-17 22:12 ` Juri Linkov
  2020-05-17 22:23   ` Stefan Kangas
@ 2020-05-18  2:32   ` Eli Zaretskii
  2020-05-19 21:54     ` Juri Linkov
  1 sibling, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2020-05-18  2:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Date: Mon, 18 May 2020 01:12:08 +0300
> Cc: 41343@debbugs.gnu.org
> 
> > Please consider adding a binding to close a tab in tab-bar-mode by
> > clicking on it using the middle mouse button (mouse-2).
> 
> Like in bug#41342, when someone will find a way to emit the <mouse-2> event
> on the tab-bar,  I'll immediately bind it to the tab closing command.

What do you mean by "find a way"?  What is the problem here?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2020-05-18  2:32   ` Eli Zaretskii
@ 2020-05-19 21:54     ` Juri Linkov
  2020-05-20 15:59       ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2020-05-19 21:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> > Please consider adding a binding to close a tab in tab-bar-mode by
>> > clicking on it using the middle mouse button (mouse-2).
>> 
>> Like in bug#41342, when someone will find a way to emit the <mouse-2> event
>> on the tab-bar,  I'll immediately bind it to the tab closing command.
>
> What do you mean by "find a way"?  What is the problem here?

The problem is to figure out how to force clicking different
mouse buttons to emit the corresponding mouse event.  Currently
clicking on the tab-line correctly emits such events, e.g.:

  <tab-line> <mouse-1>
  <tab-line> <mouse-2>

but clicking any mouse button on the tab-bar emits events like:

  <tab-bar> <tab-1>
  <tab-bar> <tab-2>





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2020-05-19 21:54     ` Juri Linkov
@ 2020-05-20 15:59       ` Eli Zaretskii
  0 siblings, 0 replies; 31+ messages in thread
From: Eli Zaretskii @ 2020-05-20 15:59 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Wed, 20 May 2020 00:54:15 +0300
> 
> > What do you mean by "find a way"?  What is the problem here?
> 
> The problem is to figure out how to force clicking different
> mouse buttons to emit the corresponding mouse event.  Currently
> clicking on the tab-line correctly emits such events, e.g.:
> 
>   <tab-line> <mouse-1>
>   <tab-line> <mouse-2>
> 
> but clicking any mouse button on the tab-bar emits events like:
> 
>   <tab-bar> <tab-1>
>   <tab-bar> <tab-2>

We could perhaps have a suitable redirect in function-key-map or one
of the other translation keymaps?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2020-05-17  4:05 bug#41343: tab-bar-mode: Close tab on mouse-2 click Stefan Kangas
  2020-05-17 22:12 ` Juri Linkov
@ 2021-08-03 22:33 ` Juri Linkov
  2021-08-04 11:32   ` Eli Zaretskii
  1 sibling, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-03 22:33 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 41343

[-- Attachment #1: Type: text/plain, Size: 183 bytes --]

> Please consider adding a binding to close a tab in tab-bar-mode by
> clicking on it using the middle mouse button (mouse-2).

Here's the patch that implements mouse-2 tab closing:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tab-close-mouse-2.patch --]
[-- Type: text/x-diff, Size: 4596 bytes --]

diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 7660b217d2..ce4d18a0fa 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -229,7 +229,8 @@ tab-bar-handle-mouse
 This command is used when you click the mouse in the tab bar
 on a console which has no window system but does have a mouse."
   (interactive "e")
-  (let* ((x-position (car (posn-x-y (event-start event))))
+  (let* ((button (event-basic-type event))
+         (x-position (car (posn-x-y (event-start event))))
          (keymap (lookup-key (cons 'keymap (nreverse (current-active-maps))) [tab-bar]))
          (column 0))
     (when x-position
@@ -238,7 +239,9 @@ tab-bar-handle-mouse
                  (lambda (key binding)
                    (when (eq (car-safe binding) 'menu-item)
                      (when (> (+ column (length (nth 1 binding))) x-position)
-                       (if (get-text-property (- x-position column) 'close-tab (nth 1 binding))
+                       (if (or (eq button 'mouse-2)
+                               (get-text-property
+                                (- x-position column) 'close-tab (nth 1 binding)))
                            (let* ((close-key (vector (intern (format "C-%s" key))))
                                   (close-def (lookup-key keymap close-key)))
                              (when close-def
@@ -768,7 +771,8 @@ tab-bar-format-list
 (defun tab-bar-make-keymap-1 ()
   "Generate an actual keymap from `tab-bar-map', without caching."
   (append
-   '(keymap (mouse-1 . tab-bar-handle-mouse))
+   '(keymap (mouse-1 . tab-bar-handle-mouse)
+            (mouse-2 . tab-bar-handle-mouse))
    (tab-bar-format-list tab-bar-format)))
 
 \f
diff --git a/src/dispextern.h b/src/dispextern.h
index 33fcaa4c07..26112de0a9 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3416,7 +3416,7 @@ #define TTY_CAP_STRIKE_THROUGH	0x20
 extern Lisp_Object find_hot_spot (Lisp_Object, int, int);
 
 extern void handle_tab_bar_click (struct frame *,
-                                   int, int, bool, int);
+                                   int, int, bool, int, int);
 extern void handle_tool_bar_click (struct frame *,
                                    int, int, bool, int);
 
diff --git a/src/w32term.c b/src/w32term.c
index ad4d1a3282..f53114a857 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -3691,10 +3691,11 @@ w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event)
   int y = XFIXNAT (button_event->y);
 
   if (button_event->modifiers & down_modifier)
-    handle_tab_bar_click (f, x, y, 1, 0);
+    handle_tab_bar_click (f, x, y, 1, 0, button_event->code + 1);
   else
     handle_tab_bar_click (f, x, y, 0,
-                          button_event->modifiers & ~up_modifier);
+                          button_event->modifiers & ~up_modifier,
+                          button_event->code + 1);
 }
 
 
diff --git a/src/xdisp.c b/src/xdisp.c
index 70d15aee68..9ca6234264 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13747,7 +13747,7 @@ get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
 
 void
 handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
-		      int modifiers)
+		      int modifiers, int button)
 {
   Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
   struct window *w = XWINDOW (f->tab_bar_window);
@@ -13793,7 +13793,7 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
       event.kind = TAB_BAR_EVENT;
       event.frame_or_window = frame;
       event.arg = key;
-      event.modifiers = close_p ? ctrl_modifier | modifiers : modifiers;
+      event.modifiers = (close_p || button == 2) ? ctrl_modifier | modifiers : modifiers;
       kbd_buffer_store_event (&event);
       f->last_tab_bar_item = -1;
     }
@@ -13962,6 +13962,8 @@ tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
       bool close_p = false;
       if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
 	close_p = true;
+      if (event->code == 1) /* mouse-2 */
+	close_p = true;
 
       event->code = 0;
       XSETFRAME (frame, f);
diff --git a/src/xterm.c b/src/xterm.c
index 1887c3255d..5a22bc31d4 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9217,7 +9217,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 if (tab_bar_p && event->xbutton.button < 4)
 		  handle_tab_bar_click
 		    (f, x, y, event->xbutton.type == ButtonPress,
-		     x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
+		     x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state),
+		     event->xbutton.button);
               }
 
 #if ! defined (USE_GTK)

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-03 22:33 ` Juri Linkov
@ 2021-08-04 11:32   ` Eli Zaretskii
  2021-08-04 20:13     ` Juri Linkov
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-04 11:32 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Date: Wed, 04 Aug 2021 01:33:45 +0300
> Cc: 41343@debbugs.gnu.org
> 
> > Please consider adding a binding to close a tab in tab-bar-mode by
> > clicking on it using the middle mouse button (mouse-2).
> 
> Here's the patch that implements mouse-2 tab closing:

Do we really have to hard-code the mouse button this way, including
explicit values in C?  Why is that necessary or justified?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-04 11:32   ` Eli Zaretskii
@ 2021-08-04 20:13     ` Juri Linkov
  2021-08-05  5:43       ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-04 20:13 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> > Please consider adding a binding to close a tab in tab-bar-mode by
>> > clicking on it using the middle mouse button (mouse-2).
>> 
>> Here's the patch that implements mouse-2 tab closing:
>
> Do we really have to hard-code the mouse button this way, including
> explicit values in C?  Why is that necessary or justified?

In tab-line.el it was very easy to bind mouse-2 to close the tab:

  (defvar tab-line-tab-map
    (let ((map (make-sparse-keymap)))
      (define-key map [tab-line mouse-1] 'tab-line-select-tab)
      (define-key map [tab-line mouse-2] 'tab-line-close-tab)

But it's impossible to do the same for the menu-bar and the tool-bar
and so in the tab-bar too.

There is no other way to bind mouse-2 to close the tab
that would work in X, xterm, console, w32, w32term.

Ot do you mean adding an integer variable that holds
a number of the mouse button used to close the tab?
For example, tab-bar-close-tab-mouse-button = 2.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-04 20:13     ` Juri Linkov
@ 2021-08-05  5:43       ` Eli Zaretskii
  2021-08-06  0:41         ` Juri Linkov
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-05  5:43 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Wed, 04 Aug 2021 23:13:12 +0300
> 
> > Do we really have to hard-code the mouse button this way, including
> > explicit values in C?  Why is that necessary or justified?
> 
> In tab-line.el it was very easy to bind mouse-2 to close the tab:
> 
>   (defvar tab-line-tab-map
>     (let ((map (make-sparse-keymap)))
>       (define-key map [tab-line mouse-1] 'tab-line-select-tab)
>       (define-key map [tab-line mouse-2] 'tab-line-close-tab)
> 
> But it's impossible to do the same for the menu-bar and the tool-bar
> and so in the tab-bar too.

Why not?  What prevents that?

> Ot do you mean adding an integer variable that holds
> a number of the mouse button used to close the tab?
> For example, tab-bar-close-tab-mouse-button = 2.

I think we should explore such possibilities only after we understand
why normal key bindings don't work.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-05  5:43       ` Eli Zaretskii
@ 2021-08-06  0:41         ` Juri Linkov
  2021-08-06  6:26           ` Eli Zaretskii
  2021-08-06 16:21           ` bug#41343: [External] : " Drew Adams
  0 siblings, 2 replies; 31+ messages in thread
From: Juri Linkov @ 2021-08-06  0:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> > Do we really have to hard-code the mouse button this way, including
>> > explicit values in C?  Why is that necessary or justified?
>>
>> In tab-line.el it was very easy to bind mouse-2 to close the tab:
>>
>>   (defvar tab-line-tab-map
>>     (let ((map (make-sparse-keymap)))
>>       (define-key map [tab-line mouse-1] 'tab-line-select-tab)
>>       (define-key map [tab-line mouse-2] 'tab-line-close-tab)
>>
>> But it's impossible to do the same for the menu-bar and the tool-bar
>> and so in the tab-bar too.
>
> Why not?  What prevents that?

It's too late to change how keys are implemented for tab-bar.
The tab-bar keymap contains such keys as 'tab-1' and 'C-tab-2',
and clicking mouse-1 on tabs emits such events.  It doesn't emit
'mouse-1' and 'mouse-2'.

>> Or do you mean adding an integer variable that holds
>> a number of the mouse button used to close the tab?
>> For example, tab-bar-close-tab-mouse-button = 2.
>
> I think we should explore such possibilities only after we understand
> why normal key bindings don't work.

It should be possible to implement normal key bindings mouse-1/mouse-2,
but such change will not be backward-compatible.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-06  0:41         ` Juri Linkov
@ 2021-08-06  6:26           ` Eli Zaretskii
  2021-08-06  8:20             ` Juri Linkov
  2021-08-06 16:21           ` bug#41343: [External] : " Drew Adams
  1 sibling, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-06  6:26 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Fri, 06 Aug 2021 03:41:17 +0300
> 
> >>   (defvar tab-line-tab-map
> >>     (let ((map (make-sparse-keymap)))
> >>       (define-key map [tab-line mouse-1] 'tab-line-select-tab)
> >>       (define-key map [tab-line mouse-2] 'tab-line-close-tab)
> >>
> >> But it's impossible to do the same for the menu-bar and the tool-bar
> >> and so in the tab-bar too.
> >
> > Why not?  What prevents that?
> 
> It's too late to change how keys are implemented for tab-bar.
> The tab-bar keymap contains such keys as 'tab-1' and 'C-tab-2',
> and clicking mouse-1 on tabs emits such events.  It doesn't emit
> 'mouse-1' and 'mouse-2'.

How do we translate mouse clicks into the likes of C-tab-2?  And what
prevents us from emitting something like tab-close-2 when mouse-2 is
clicked?

> >> Or do you mean adding an integer variable that holds
> >> a number of the mouse button used to close the tab?
> >> For example, tab-bar-close-tab-mouse-button = 2.
> >
> > I think we should explore such possibilities only after we understand
> > why normal key bindings don't work.
> 
> It should be possible to implement normal key bindings mouse-1/mouse-2,
> but such change will not be backward-compatible.

In what way will it be incompatible?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-06  6:26           ` Eli Zaretskii
@ 2021-08-06  8:20             ` Juri Linkov
  2021-08-06 12:38               ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-06  8:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> It's too late to change how keys are implemented for tab-bar.
>> The tab-bar keymap contains such keys as 'tab-1' and 'C-tab-2',
>> and clicking mouse-1 on tabs emits such events.  It doesn't emit
>> 'mouse-1' and 'mouse-2'.
>
> How do we translate mouse clicks into the likes of C-tab-2?

When mouse-1 is clicked on the close button, then the
Control modifier 'C-' is added to the menu-item symbol tab-2
emitted as an event.

> And what prevents us from emitting something like tab-close-2 when
> mouse-2 is clicked?

Then mouse-2 is still hard-coded and tab-close-2 is not much different
from the previous patch that emits C-tab-2.

Or in "tab-close-2" what does "2" mean: the button number 2 (mouse-2),
or the tab number 2 (tab-2)?

Should they then cover all combinations?  tab-1-mouse-1,
tab-1-mouse-2, tab-2-mouse-1, tab-2-mouse-2, ...

>> It should be possible to implement normal key bindings mouse-1/mouse-2,
>> but such change will not be backward-compatible.
>
> In what way will it be incompatible?

Currently tab-bar-make-keymap returns a keymap with menu-items.
This is like menu-bar is implemented.  The menu-bar displays
menu-items, and clicking on them emits events with their symbols.
The tool-bar is implemented the same way: it displays
menu-items, and clicking emits their symbols.
The tab-bar is exactly the same: displays menu-items
on the tab-bar, and clicking mouse-1 emits events
with tab names, e.g. tab-2.

Users already are using such add-advice that expect
tab-bar-make-keymap returning a keymap with menu-items.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-06  8:20             ` Juri Linkov
@ 2021-08-06 12:38               ` Eli Zaretskii
  2021-08-09  7:03                 ` Juri Linkov
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-06 12:38 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Fri, 06 Aug 2021 11:20:29 +0300
> 
> >> It's too late to change how keys are implemented for tab-bar.
> >> The tab-bar keymap contains such keys as 'tab-1' and 'C-tab-2',
> >> and clicking mouse-1 on tabs emits such events.  It doesn't emit
> >> 'mouse-1' and 'mouse-2'.
> >
> > How do we translate mouse clicks into the likes of C-tab-2?
> 
> When mouse-1 is clicked on the close button, then the
> Control modifier 'C-' is added to the menu-item symbol tab-2
> emitted as an event.

Are you talking about handle_tab_bar_click and the processing of
TAB_BAR_EVENT in make_lispy_event?  Or are there other/additional
parts to this processing?

IOW, where are the symbols like tab-2 produced?

> > And what prevents us from emitting something like tab-close-2 when
> > mouse-2 is clicked?
> 
> Then mouse-2 is still hard-coded and tab-close-2 is not much different
> from the previous patch that emits C-tab-2.
> 
> Or in "tab-close-2" what does "2" mean: the button number 2 (mouse-2),
> or the tab number 2 (tab-2)?
> 
> Should they then cover all combinations?  tab-1-mouse-1,
> tab-1-mouse-2, tab-2-mouse-1, tab-2-mouse-2, ...

I don't know, I don't think I have a clear idea of how these symbols
are produced yet, and you didn't tell enough for me to get such a
clear idea.  Please tell more details, so that this discussion could
be more efficient.

> >> It should be possible to implement normal key bindings mouse-1/mouse-2,
> >> but such change will not be backward-compatible.
> >
> > In what way will it be incompatible?
> 
> Currently tab-bar-make-keymap returns a keymap with menu-items.
> This is like menu-bar is implemented.  The menu-bar displays
> menu-items, and clicking on them emits events with their symbols.
> The tool-bar is implemented the same way: it displays
> menu-items, and clicking emits their symbols.
> The tab-bar is exactly the same: displays menu-items
> on the tab-bar, and clicking mouse-1 emits events
> with tab names, e.g. tab-2.
> 
> Users already are using such add-advice that expect
> tab-bar-make-keymap returning a keymap with menu-items.

If we find a way to produce a different symbol when mouse-2 is clicked
on a tab, there will be no incompatibility, right?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: [External] : bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-06  0:41         ` Juri Linkov
  2021-08-06  6:26           ` Eli Zaretskii
@ 2021-08-06 16:21           ` Drew Adams
  2021-08-09  7:06             ` Juri Linkov
  1 sibling, 1 reply; 31+ messages in thread
From: Drew Adams @ 2021-08-06 16:21 UTC (permalink / raw)
  To: Juri Linkov, Eli Zaretskii; +Cc: 41343@debbugs.gnu.org, stefankangas@gmail.com

> It's too late to change how keys are implemented for tab-bar.
> The tab-bar keymap contains such keys as 'tab-1' and 'C-tab-2',
> and clicking mouse-1 on tabs emits such events.  It doesn't emit
> 'mouse-1' and 'mouse-2'.

IIUC, tab-bar is not in any Emacs release, the most
recent of which is Emacs 27.2.  If that's correct,
how is it that it's too late to change something in
the implementation or design of the incipient Emacs
28 feature tab-bar?

Just asking.  A priori, I don't care one way or the
other about how tab-bar implements keys, and I don't
know how it does that currently.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-06 12:38               ` Eli Zaretskii
@ 2021-08-09  7:03                 ` Juri Linkov
  2021-08-10 12:38                   ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-09  7:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

[-- Attachment #1: Type: text/plain, Size: 906 bytes --]

forcemerge 41343 41342
tags 41342 + patch
tags 41343 + patch
thanks

> Are you talking about handle_tab_bar_click and the processing of
> TAB_BAR_EVENT in make_lispy_event?  Or are there other/additional
> parts to this processing?

So now I've completely redesigned the event processing on the tab bar.
With the following patch

'down-mouse-1' is bound to 'tab-bar-mouse-select-tab'
'down-mouse-2' is bound to 'tab-bar-mouse-close-tab'
'down-mouse-3' is bound to 'tab-bar-mouse-context-menu'

The context menu that pops up on down-mouse-3 was requested in bug#41342.
Now also it should be possible even to implement drag-drop to move tabs
with the mouse since they produce normal mouse events that now are accepted
by the tab bar.

All aforementioned bindings work on X, xterm, and even on console.
For example, clicking mouse-3 on the tab bar displays a menu
with blue background on a console terminal.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tab-bar-events.patch --]
[-- Type: text/x-diff, Size: 16988 bytes --]

diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el
index 7459e1b78c..162dc43876 100644
--- a/lisp/tab-bar.el
+++ b/lisp/tab-bar.el
@@ -224,6 +224,11 @@ tab-bar-mode
       (tab-bar--define-keys)
     (tab-bar--undefine-keys)))
 
+(defun tab--symbol-to-number (symbol)
+  (unless (eq symbol 'current-tab)
+    (string-to-number
+     (string-replace "tab-" "" (format "%S" symbol)))))
+
 (defun tab-bar-handle-mouse (event)
   "Text-mode emulation of switching tabs on the tab bar.
 This command is used when you click the mouse in the tab bar
@@ -238,18 +243,52 @@ tab-bar-handle-mouse
                  (lambda (key binding)
                    (when (eq (car-safe binding) 'menu-item)
                      (when (> (+ column (length (nth 1 binding))) x-position)
-                       (if (get-text-property (- x-position column) 'close-tab (nth 1 binding))
-                           (let* ((close-key (vector (intern (format "C-%s" key))))
-                                  (close-def (lookup-key keymap close-key)))
-                             (when close-def
-                               (call-interactively close-def)))
-                         (call-interactively (nth 2 binding)))
+                       (if (get-text-property
+                            (- x-position column) 'close-tab (nth 1 binding))
+                           (tab-bar-close-tab (tab--symbol-to-number key))
+                         (if (nth 2 binding)
+                             (call-interactively (nth 2 binding))
+                           (tab-bar-select-tab (tab--symbol-to-number key))))
                        (throw 'done t))
                      (setq column (+ column (length (nth 1 binding))))))
                  keymap))
         ;; Clicking anywhere outside existing tabs will add a new tab
         (tab-bar-new-tab)))))
 
+(defun tab-bar-mouse-select-tab (event)
+  (interactive "e")
+  (if (posn-window (event-start event))
+      (let* ((tab (posn-string (event-start event)))
+             (tab-symbol (nth 0 tab))
+             (tab-number (tab--symbol-to-number tab-symbol)))
+        (if (nth 1 tab)
+            (tab-bar-close-tab tab-number)
+          (let ((binding (lookup-key (cons 'keymap (nreverse (current-active-maps)))
+                                     (vector 'tab-bar tab-symbol))))
+            (if binding
+                (call-interactively binding)
+              (tab-bar-select-tab tab-number)))))
+    ;; TTY
+    (tab-bar-handle-mouse event)))
+
+(defun tab-bar-mouse-close-tab (event)
+  (interactive "e")
+  (tab-bar-close-tab (tab--symbol-to-number
+                      (nth 0 (posn-string (event-start event))))))
+
+(defun tab-bar-mouse-context-menu (event)
+  (interactive "e")
+  (let* ((tab (posn-string (event-start event)))
+         (tab-number (tab--symbol-to-number (nth 0 tab)))
+         (menu (make-sparse-keymap "Context Menu")))
+
+    (define-key-after menu [close]
+      `(menu-item "Close" (lambda () (interactive)
+                            (tab-bar-close-tab ,tab-number))
+                  :help "Close the tab"))
+
+    (popup-menu menu event)))
+
 (defun toggle-tab-bar-mode-from-frame (&optional arg)
   "Toggle tab bar on or off, based on the status of the current frame.
 Used in the Show/Hide menu, to have the toggle reflect the current frame.
@@ -614,19 +654,12 @@ tab-bar--format-tab
      `((,(intern (format "tab-%i" i))
         menu-item
         ,(funcall tab-bar-tab-name-format-function tab i)
-        ,(or
-          (alist-get 'binding tab)
-          `(lambda ()
-             (interactive)
-             (tab-bar-select-tab ,i)))
+        ,(alist-get 'binding tab)
         :help "Click to visit tab"))))
-   `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
-      menu-item ""
-      ,(or
-        (alist-get 'close-binding tab)
-        `(lambda ()
-           (interactive)
-           (tab-bar-close-tab ,i)))))))
+   (when (alist-get 'close-binding tab)
+     `((,(if (eq (car tab) 'current-tab) 'C-current-tab (intern (format "C-tab-%i" i)))
+        menu-item ""
+        ,(alist-get 'close-binding tab))))))
 
 (defun tab-bar-format-tabs ()
   (let ((i 0))
@@ -767,7 +800,11 @@ tab-bar-format-list
 (defun tab-bar-make-keymap-1 ()
   "Generate an actual keymap from `tab-bar-map', without caching."
   (append
-   '(keymap (mouse-1 . tab-bar-handle-mouse))
+   '(keymap (down-mouse-1 . tab-bar-mouse-select-tab)
+            (mouse-1 . ignore)
+            (down-mouse-2 . tab-bar-mouse-close-tab)
+            (mouse-2 . ignore)
+            (down-mouse-3 . tab-bar-mouse-context-menu))
    (tab-bar-format-list tab-bar-format)))
 
 \f
diff --git a/src/dispextern.h b/src/dispextern.h
index 33fcaa4c07..f4c7575b35 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3415,8 +3415,8 @@ #define TTY_CAP_STRIKE_THROUGH	0x20
                                         NativeRectangle *nr);
 extern Lisp_Object find_hot_spot (Lisp_Object, int, int);
 
-extern void handle_tab_bar_click (struct frame *,
-                                   int, int, bool, int);
+extern Lisp_Object handle_tab_bar_click (struct frame *,
+					 int, int, bool, int);
 extern void handle_tool_bar_click (struct frame *,
                                    int, int, bool, int);
 
diff --git a/src/keyboard.c b/src/keyboard.c
index 820229cf8f..5dabad98a8 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5647,6 +5647,12 @@ make_lispy_event (struct input_event *event)
 
 	    position = make_lispy_position (f, event->x, event->y,
 					    event->timestamp);
+
+	    if (CONSP (event->arg) && EQ (XCAR (event->arg), Qtab_bar))
+	      {
+		XSETCAR (XCDR (position), Qtab_bar);
+		position = nconc2(position, Fcons (XCDR (event->arg), Qnil));
+	      }
 	  }
 #ifndef USE_TOOLKIT_SCROLL_BARS
 	else
diff --git a/src/term.c b/src/term.c
index c995a4499c..89b3568003 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2568,21 +2568,8 @@ handle_one_term_event (struct tty_display_info *tty, Gpm_Event *event)
     {
       f->mouse_moved = 0;
       term_mouse_click (&ie, event, f);
-      /* eassert (ie.kind == MOUSE_CLICK_EVENT); */
-      if (tty_handle_tab_bar_click (f, event->x, event->y,
-                                    (ie.modifiers & down_modifier) != 0, &ie))
-        {
-          /* eassert (ie.kind == MOUSE_CLICK_EVENT
-           *          || ie.kind == TAB_BAR_EVENT); */
-          /* tty_handle_tab_bar_click stores 2 events in the event
-             queue, so we are done here.  */
-          /* FIXME: Actually, `tty_handle_tab_bar_click` returns true
-             without storing any events, when
-             (ie.modifiers & down_modifier) != 0  */
-          count += 2;
-          return count;
-        }
-      /* eassert (ie.kind == MOUSE_CLICK_EVENT); */
+      ie.arg = tty_handle_tab_bar_click (f, event->x, event->y,
+					 (ie.modifiers & down_modifier) != 0, &ie);
       kbd_buffer_store_event (&ie);
       count++;
     }
diff --git a/src/termchar.h b/src/termchar.h
index f50c1bfb6e..7ab9337fbe 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -234,7 +234,7 @@ #define FRAME_TTY(f)                            \
 #define CURTTY() FRAME_TTY (SELECTED_FRAME())
 
 struct input_event;
-extern bool tty_handle_tab_bar_click (struct frame *, int, int, bool,
-				      struct input_event *);
+extern Lisp_Object tty_handle_tab_bar_click (struct frame *, int, int, bool,
+					     struct input_event *);
 
 #endif /* EMACS_TERMCHAR_H */
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 1255072b7f..9a69b32bcb 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -586,9 +586,8 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
       int x = event->dwMousePosition.X;
       int y = event->dwMousePosition.Y;
       struct frame *f = get_frame ();
-      if (tty_handle_tab_bar_click (f, x, y, (button_state & mask) != 0,
-				    emacs_ev))
-	return 0;	/* tty_handle_tab_bar_click adds the event to queue */
+      emacs_ev->arg = tty_handle_tab_bar_click (f, x, y, (button_state & mask) != 0,
+						emacs_ev);
 
       emacs_ev->modifiers |= ((button_state & mask)
 			      ? down_modifier : up_modifier);
@@ -597,7 +596,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
       XSETFASTINT (emacs_ev->x, x);
       XSETFASTINT (emacs_ev->y, y);
       XSETFRAME (emacs_ev->frame_or_window, f);
-      emacs_ev->arg = Qnil;
 
       return 1;
     }
diff --git a/src/w32term.c b/src/w32term.c
index ad4d1a3282..c9570b0c67 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -168,8 +168,8 @@ #define SM_CYVIRTUALSCREEN 79
 int w32_message_fd = -1;
 #endif /* CYGWIN */
 
-static void w32_handle_tab_bar_click (struct frame *,
-                                      struct input_event *);
+static Lisp_Object w32_handle_tab_bar_click (struct frame *,
+					     struct input_event *);
 static void w32_handle_tool_bar_click (struct frame *,
                                        struct input_event *);
 static void w32_define_cursor (Window, Emacs_Cursor);
@@ -3684,17 +3684,17 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
    frame-relative coordinates X/Y.  EVENT_TYPE is either ButtonPress
    or ButtonRelease.  */
 
-static void
+static Lisp_Object
 w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event)
 {
   int x = XFIXNAT (button_event->x);
   int y = XFIXNAT (button_event->y);
 
   if (button_event->modifiers & down_modifier)
-    handle_tab_bar_click (f, x, y, 1, 0);
+    return handle_tab_bar_click (f, x, y, 1, 0);
   else
-    handle_tab_bar_click (f, x, y, 0,
-                          button_event->modifiers & ~up_modifier);
+    return handle_tab_bar_click (f, x, y, 0,
+				 button_event->modifiers & ~up_modifier);
 }
 
 
@@ -5186,6 +5186,7 @@ w32_read_socket (struct terminal *terminal,
 	  {
             /* If we decide we want to generate an event to be seen
                by the rest of Emacs, we put it here.  */
+	    Lisp_Object tab_bar_key = Qnil;
 	    bool tab_bar_p = 0;
 	    bool tool_bar_p = 0;
 	    int button = 0;
@@ -5208,12 +5209,12 @@ w32_read_socket (struct terminal *terminal,
 
                     if (EQ (window, f->tab_bar_window))
                       {
-                        w32_handle_tab_bar_click (f, &inev);
+                        tab_bar_key = w32_handle_tab_bar_click (f, &inev);
                         tab_bar_p = 1;
                       }
                   }
 
-                if (tab_bar_p
+                if ((tab_bar_p && NILP (tab_bar_key))
 		    || (dpyinfo->w32_focus_frame
 			&& f != dpyinfo->w32_focus_frame
 			/* This does not help when the click happens in
@@ -5221,6 +5222,9 @@ w32_read_socket (struct terminal *terminal,
 			&& !frame_ancestor_p (f, dpyinfo->w32_focus_frame)))
 		  inev.kind = NO_EVENT;
 
+		  if (!NILP (tab_bar_key))
+		    inev.arg = tab_bar_key;
+
                 /* Is this in the tool-bar?  */
                 if (WINDOWP (f->tool_bar_window)
                     && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
diff --git a/src/xdisp.c b/src/xdisp.c
index e62f7e3df6..0cbfa4bfff 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13745,7 +13745,7 @@ get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
    false for button release.  MODIFIERS is event modifiers for button
    release.  */
 
-void
+Lisp_Object
 handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
 		      int modifiers)
 {
@@ -13763,12 +13763,12 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
       /* If the button is released on a tab other than the one where
 	 it was pressed, don't generate the tab-bar button click event.  */
       || (ts != 0 && !down_p))
-    return;
+    return Qnil;
 
   /* If item is disabled, do nothing.  */
   enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P);
   if (NILP (enabled_p))
-    return;
+    return Qnil;
 
   if (down_p)
     {
@@ -13779,24 +13779,15 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
     }
   else
     {
-      Lisp_Object key, frame;
-      struct input_event event;
-      EVENT_INIT (event);
-
       /* Show item in released state.  */
       if (!NILP (Vmouse_highlight))
 	show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
-
-      key = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY);
-
-      XSETFRAME (frame, f);
-      event.kind = TAB_BAR_EVENT;
-      event.frame_or_window = frame;
-      event.arg = key;
-      event.modifiers = close_p ? ctrl_modifier | modifiers : modifiers;
-      kbd_buffer_store_event (&event);
       f->last_tab_bar_item = -1;
     }
+
+  return list3 (Qtab_bar,
+		AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY),
+		close_p ? Qt : Qnil);
 }
 
 
@@ -13920,14 +13911,14 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
    structure, store it in keyboard queue, and return true; otherwise
    return false.  MODIFIERS are event modifiers for generating the tab
    release event.  */
-bool
+Lisp_Object
 tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
 			  struct input_event *event)
 {
   /* Did they click on the tab bar?  */
   if (y < FRAME_MENU_BAR_LINES (f)
       || y >= FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
-    return false;
+    return Qnil;
 
   /* Find the tab-bar item where the X,Y coordinates belong.  */
   int prop_idx;
@@ -13935,46 +13926,33 @@ tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
   Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen);
 
   if (NILP (caption))
-    return false;
+    return Qnil;
 
   if (NILP (AREF (f->tab_bar_items,
 		  prop_idx * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_ENABLED_P)))
-    return false;
+    return Qnil;
 
   if (down_p)
     f->last_tab_bar_item = prop_idx;
   else
     {
-      /* Force reset of up_modifier bit from the event modifiers.  */
-      if (event->modifiers & up_modifier)
-        event->modifiers &= ~up_modifier;
-
-      /* Generate a TAB_BAR_EVENT event.  */
-      Lisp_Object frame;
-      Lisp_Object key = AREF (f->tab_bar_items,
-			      prop_idx * TAB_BAR_ITEM_NSLOTS
-			      + TAB_BAR_ITEM_KEY);
-      /* Kludge alert: we assume the last two characters of a tab
-	 label are " x", and treat clicks on those 2 characters as a
-	 Close Tab command.  */
-      eassert (STRINGP (caption));
-      int lastc = SSDATA (caption)[SCHARS (caption) - 1];
-      bool close_p = false;
-      if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
-	close_p = true;
-
-      event->code = 0;
-      XSETFRAME (frame, f);
-      event->kind = TAB_BAR_EVENT;
-      event->frame_or_window = frame;
-      event->arg = key;
-      if (close_p)
-	event->modifiers |= ctrl_modifier;
-      kbd_buffer_store_event (event);
       f->last_tab_bar_item = -1;
     }
 
-  return true;
+  /* Generate a TAB_BAR_EVENT event.  */
+  Lisp_Object key = AREF (f->tab_bar_items,
+			  prop_idx * TAB_BAR_ITEM_NSLOTS
+			  + TAB_BAR_ITEM_KEY);
+  /* Kludge alert: we assume the last two characters of a tab
+     label are " x", and treat clicks on those 2 characters as a
+     Close Tab command.  */
+  eassert (STRINGP (caption));
+  int lastc = SSDATA (caption)[SCHARS (caption) - 1];
+  bool close_p = false;
+  if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
+    close_p = true;
+
+  return list3 (Qtab_bar, key, close_p ? Qt : Qnil);
 }
 
 \f
diff --git a/src/xterm.c b/src/xterm.c
index 1887c3255d..80fa747b97 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9166,6 +9166,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
       {
         /* If we decide we want to generate an event to be seen
            by the rest of Emacs, we put it here.  */
+        Lisp_Object tab_bar_key = Qnil;
         bool tab_bar_p = false;
         bool tool_bar_p = false;
 
@@ -9215,7 +9216,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                 tab_bar_p = EQ (window, f->tab_bar_window);
 
                 if (tab_bar_p && event->xbutton.button < 4)
-		  handle_tab_bar_click
+		  tab_bar_key = handle_tab_bar_click
 		    (f, x, y, event->xbutton.type == ButtonPress,
 		     x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
               }
@@ -9239,7 +9240,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
               }
 #endif /* !USE_GTK */
 
-            if (!tab_bar_p && !tool_bar_p)
+            if (!(tab_bar_p && NILP (tab_bar_key)) && !tool_bar_p)
 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
               if (! popup_activated ())
 #endif
@@ -9257,6 +9258,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
                     }
                   else
                     x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+
+		  if (!NILP (tab_bar_key))
+		    inev.ie.arg = tab_bar_key;
                 }
             if (FRAME_X_EMBEDDED_P (f))
               xembed_send_message (f, event->xbutton.time,

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* bug#41343: [External] : bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-06 16:21           ` bug#41343: [External] : " Drew Adams
@ 2021-08-09  7:06             ` Juri Linkov
  0 siblings, 0 replies; 31+ messages in thread
From: Juri Linkov @ 2021-08-09  7:06 UTC (permalink / raw)
  To: Drew Adams; +Cc: 41343@debbugs.gnu.org, stefankangas@gmail.com

> IIUC, tab-bar is not in any Emacs release, the most
> recent of which is Emacs 27.2.  If that's correct,
> how is it that it's too late to change something in
> the implementation or design of the incipient Emacs
> 28 feature tab-bar?

You missed all the fun that everyone had with tabs in Emacs 27.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-09  7:03                 ` Juri Linkov
@ 2021-08-10 12:38                   ` Eli Zaretskii
  2021-08-11  7:01                     ` Juri Linkov
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-10 12:38 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Mon, 09 Aug 2021 10:03:28 +0300
> 
> So now I've completely redesigned the event processing on the tab bar.
> With the following patch
> 
> 'down-mouse-1' is bound to 'tab-bar-mouse-select-tab'
> 'down-mouse-2' is bound to 'tab-bar-mouse-close-tab'
> 'down-mouse-3' is bound to 'tab-bar-mouse-context-menu'
> 
> The context menu that pops up on down-mouse-3 was requested in bug#41342.
> Now also it should be possible even to implement drag-drop to move tabs
> with the mouse since they produce normal mouse events that now are accepted
> by the tab bar.

Thanks, this looks much, much better to me.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-10 12:38                   ` Eli Zaretskii
@ 2021-08-11  7:01                     ` Juri Linkov
  2021-08-11 11:56                       ` Eli Zaretskii
  0 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-11  7:01 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> So now I've completely redesigned the event processing on the tab bar.
>
> Thanks, this looks much, much better to me.

Could you please help to check if everything is correct
on the Windows part (unfortunately, I don't have Windows).
The changes in w32inevt.c and w32term.c just mirror the changes
in xdisp.c and xterm.c, but I'm sure I might have made a typo.
I could push the changes to a new branch if you want.

There is the need to apply an additional patch below,
because the tab symbol is carried by the event in its
OBJECT slot, but some functions expect that the OBJECT
slot should contain only (STRING . STRING-POS)

The Info node (info "(elisp) Click Events") documents
the event format as:

  (WINDOW POS-OR-AREA (X . Y) TIMESTAMP
   OBJECT TEXT-POS (COL . ROW)
   IMAGE (DX . DY) (WIDTH . HEIGHT))

and the events emitted by the previous patch look like:

  (down-mouse-1 (#<frame...> (tab-bar) (X . Y) TIMESTAMP (tab-5 t)))

where '(tab-5 t)' in the OBJECT slot defines the clicked tab symbol
and whether the close button was clicked.

And I can't find a slot more suitable than OBJECT to carry event metadata.

diff --git a/lisp/mouse.el b/lisp/mouse.el
index cf7c17be28..557d9ab1df 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -1176,7 +1362,7 @@ mouse-posn-property
 its value is returned."
   (if (consp pos)
       (let ((w (posn-window pos)) (pt (posn-point pos))
-	    (str (posn-string pos)))
+	    (str (unless (eq (posn-area pos) 'tab-bar) (posn-string pos))))
         ;; FIXME: When STR has a `category' property and there's another
         ;; `category' property at PT, we should probably disregard the
         ;; `category' property at PT while doing the (get-char-property
@@ -1187,7 +1373,8 @@ mouse-posn-property
             ;; (nth 5).  This is useful but is not exactly where we clicked, so
             ;; don't look up that position's properties!
 	    (and pt (not (memq (posn-area pos) '(left-fringe right-fringe
-                                                 left-margin right-margin)))
+                                                 left-margin right-margin
+                                                 tab-bar)))
 		 (get-char-property pt property w))))
     (get-char-property pos property)))
 






^ permalink raw reply related	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-11  7:01                     ` Juri Linkov
@ 2021-08-11 11:56                       ` Eli Zaretskii
  2021-08-12  8:09                         ` Juri Linkov
                                           ` (2 more replies)
  0 siblings, 3 replies; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-11 11:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Wed, 11 Aug 2021 10:01:53 +0300
> 
> >> So now I've completely redesigned the event processing on the tab bar.
> >
> > Thanks, this looks much, much better to me.
> 
> Could you please help to check if everything is correct
> on the Windows part (unfortunately, I don't have Windows).
> The changes in w32inevt.c and w32term.c just mirror the changes
> in xdisp.c and xterm.c, but I'm sure I might have made a typo.

I will, if you tell me what to try after applying the patch.

> There is the need to apply an additional patch below,
> because the tab symbol is carried by the event in its
> OBJECT slot, but some functions expect that the OBJECT
> slot should contain only (STRING . STRING-POS)

That expectation is according to the documented behavior, so it is
correct.  I don't quite understand why you need to break the contract
here.  Can you elaborate where do the deviant values come and why they
must have a different value form?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-11 11:56                       ` Eli Zaretskii
@ 2021-08-12  8:09                         ` Juri Linkov
  2021-08-12  8:43                           ` Eli Zaretskii
  2021-08-18 18:11                         ` Juri Linkov
  2021-09-05 17:17                         ` Juri Linkov
  2 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-12  8:09 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> There is the need to apply an additional patch below,
>> because the tab symbol is carried by the event in its
>> OBJECT slot, but some functions expect that the OBJECT
>> slot should contain only (STRING . STRING-POS)
>
> That expectation is according to the documented behavior, so it is
> correct.  I don't quite understand why you need to break the contract
> here.  Can you elaborate where do the deviant values come and why they
> must have a different value form?

Events emitted on the tab-line contain the tab caption
with text properties that help to identify the clicked tab:

 (#<window 391 on buffer.el> tab-line (30 . 10) 29999999
  (#(" buffer.el x" 1 10 (tab #<buffer buffer.el>)) . 4)

The tab-bar could do the same, but how to support existing code
that doesn't add text properties to the tab-bar tab captions
in the tab-bar-format function?

This means that text properties identifying the clicked tab
should be added to the tab caption only after clicking
in the emitted event.  But then the problem that the added
text properties might conflict with the existing text properties
added in the tab-bar-format function.

For example, the tab-bar-format function puts the text property
'close-tab' on the close button.  If the emitted event
will add another property with the same name 'close-tab'
to indicate whether the close button was clicked, it might overwrite
the existing text property on the tab caption.  Maybe then
add the property only on the first character, on the assumption
that it would be less likely to overwrite the existing property.

IOW, with the existing event format, the only way to add event metadata
is to stuff more text properties on the tab caption that already
contains some text properties, such as tab face, and properties
denoting the close button.  But how to do this in a non-conflicting way?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-12  8:09                         ` Juri Linkov
@ 2021-08-12  8:43                           ` Eli Zaretskii
  2021-08-13  7:24                             ` Juri Linkov
  0 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2021-08-12  8:43 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343, stefankangas

> From: Juri Linkov <juri@linkov.net>
> Cc: stefankangas@gmail.com,  41343@debbugs.gnu.org
> Date: Thu, 12 Aug 2021 11:09:35 +0300
> 
> Events emitted on the tab-line contain the tab caption
> with text properties that help to identify the clicked tab:
> 
>  (#<window 391 on buffer.el> tab-line (30 . 10) 29999999
>   (#(" buffer.el x" 1 10 (tab #<buffer buffer.el>)) . 4)
> 
> The tab-bar could do the same, but how to support existing code
> that doesn't add text properties to the tab-bar tab captions
> in the tab-bar-format function?

Hmm... I cannot find a function named tab-bar-format, so I don't think
I understand the question.  In general, if existing code doesn't add
some text properties, how can that be a problem?

> This means that text properties identifying the clicked tab
> should be added to the tab caption only after clicking
> in the emitted event.  But then the problem that the added
> text properties might conflict with the existing text properties
> added in the tab-bar-format function.
> 
> For example, the tab-bar-format function puts the text property
> 'close-tab' on the close button.  If the emitted event
> will add another property with the same name 'close-tab'
> to indicate whether the close button was clicked, it might overwrite
> the existing text property on the tab caption.  Maybe then
> add the property only on the first character, on the assumption
> that it would be less likely to overwrite the existing property.

If you use property names that are unlikely to conflict, I see no
problem here.  These are special properties used by Emacs for internal
needs of handling the tab bar, so we can use any name that suits us.
And since all of the property names are produced by Emacs itself, we
can easily enough have a set of names without conflicts.  Right?  Or
what am I missing?

> IOW, with the existing event format, the only way to add event metadata
> is to stuff more text properties on the tab caption that already
> contains some text properties, such as tab face, and properties
> denoting the close button.  But how to do this in a non-conflicting way?

I don't think the problem is severe, see above.

Alternatively, we could introduce a new format for OBJECT, but then
we'd need to document it, and try to make sure it won't cause
compatibility problems in existing code.  I think this is a more
complicated alternative, so my recommendation is to try to deconflict
the properties.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-12  8:43                           ` Eli Zaretskii
@ 2021-08-13  7:24                             ` Juri Linkov
  0 siblings, 0 replies; 31+ messages in thread
From: Juri Linkov @ 2021-08-13  7:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> The tab-bar could do the same, but how to support existing code
>> that doesn't add text properties to the tab-bar tab captions
>> in the tab-bar-format function?
>
> Hmm... I cannot find a function named tab-bar-format, so I don't think
> I understand the question.  In general, if existing code doesn't add
> some text properties, how can that be a problem?

'tab-bar-format' is a variable that contains functions including
'tab-bar-format-tabs' that calls 'tab-bar--format-tab'
that doesn't put special text properties on tab captions.

Without text properties, it's impossible to identify the clicked tab
in the command called by the click event.

> If you use property names that are unlikely to conflict, I see no
> problem here.  These are special properties used by Emacs for internal
> needs of handling the tab bar, so we can use any name that suits us.
> And since all of the property names are produced by Emacs itself, we
> can easily enough have a set of names without conflicts.  Right?  Or
> what am I missing?

Maybe it's not a problem to add text properties, need to test this more.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-11 11:56                       ` Eli Zaretskii
  2021-08-12  8:09                         ` Juri Linkov
@ 2021-08-18 18:11                         ` Juri Linkov
  2021-08-24 14:37                           ` Stefan Kangas
  2021-09-05 17:17                         ` Juri Linkov
  2 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-08-18 18:11 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

I moved the development to the branch 'feature/tab-bar-events'
since more fixes are necessary to support tab-bar events on tty.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-18 18:11                         ` Juri Linkov
@ 2021-08-24 14:37                           ` Stefan Kangas
  2021-09-05 17:18                             ` Juri Linkov
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Kangas @ 2021-08-24 14:37 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343

Juri Linkov <juri@linkov.net> writes:

> I moved the development to the branch 'feature/tab-bar-events'
> since more fixes are necessary to support tab-bar events on tty.

Thanks for working on this.  Please let us know when you have
something you'd like help testing.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-11 11:56                       ` Eli Zaretskii
  2021-08-12  8:09                         ` Juri Linkov
  2021-08-18 18:11                         ` Juri Linkov
@ 2021-09-05 17:17                         ` Juri Linkov
  2 siblings, 0 replies; 31+ messages in thread
From: Juri Linkov @ 2021-09-05 17:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 41343, stefankangas

>> Could you please help to check if everything is correct
>> on the Windows part (unfortunately, I don't have Windows).
>> The changes in w32inevt.c and w32term.c just mirror the changes
>> in xdisp.c and xterm.c, but I'm sure I might have made a typo.
>
> I will, if you tell me what to try after applying the patch.

Now the branch 'feature/tab-bar-events' is ready for merging to master.
What remains to do is to test it on Windows.  Could you please try
on Windows GUI and on Windows console to use mouse-1 to select a tab,
to click mouse-1 a close button to close it, to drag a tab by mouse-1,
to click mouse-2 to close the clicked tab, mouse-3 to pop up
the context menu and select "Close", and also wheel-left/wheel-right
to switch to the next/previous tab, and S-wheel-left/wheel-right
to move the tab.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-08-24 14:37                           ` Stefan Kangas
@ 2021-09-05 17:18                             ` Juri Linkov
  2021-09-06 19:40                               ` Stefan Kangas
  0 siblings, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-09-05 17:18 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 41343

>> I moved the development to the branch 'feature/tab-bar-events'
>> since more fixes are necessary to support tab-bar events on tty.
>
> Thanks for working on this.  Please let us know when you have
> something you'd like help testing.

Now the branch 'feature/tab-bar-events' is ready for testing.
Please help to find any possible problems.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-09-05 17:18                             ` Juri Linkov
@ 2021-09-06 19:40                               ` Stefan Kangas
  2021-09-08 19:28                                 ` Juri Linkov
  2021-09-14  6:43                                 ` Juri Linkov
  0 siblings, 2 replies; 31+ messages in thread
From: Stefan Kangas @ 2021-09-06 19:40 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343

Juri Linkov <juri@linkov.net> writes:

> Now the branch 'feature/tab-bar-events' is ready for testing.
> Please help to find any possible problems.

I have tested it on GNU/Linux and macOS, and it seems to work fine.

One concern is that tabs close on mouse down, rather than release.

In Firefox, tabs close instead on mouse release.  This is good,
because it gives me a second to react and move the mouse cursor away
in case I misclick.

This is currently less important in Emacs, as the buffer survives even
such a misclick.  But maybe in the future users will want tabs to be
more strongly connected to their associated buffers, and work would
then easily be lost to a misclick.

Could we change this to close on mouse release instead?





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-09-06 19:40                               ` Stefan Kangas
@ 2021-09-08 19:28                                 ` Juri Linkov
  2021-09-08 21:18                                   ` Stefan Kangas
  2021-09-14  6:43                                 ` Juri Linkov
  1 sibling, 1 reply; 31+ messages in thread
From: Juri Linkov @ 2021-09-08 19:28 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 41343

> I have tested it on GNU/Linux and macOS, and it seems to work fine.
>
> One concern is that tabs close on mouse down, rather than release.
>
> In Firefox, tabs close instead on mouse release.  This is good,
> because it gives me a second to react and move the mouse cursor away
> in case I misclick.
>
> This is currently less important in Emacs, as the buffer survives even
> such a misclick.  But maybe in the future users will want tabs to be
> more strongly connected to their associated buffers, and work would
> then easily be lost to a misclick.
>
> Could we change this to close on mouse release instead?

It will be easy to implement closing on mouse release.
There are also many other small adjustments planned.
But first I'd like to merge the basic completed work.
Then to continue tweaking in master.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-09-08 19:28                                 ` Juri Linkov
@ 2021-09-08 21:18                                   ` Stefan Kangas
  0 siblings, 0 replies; 31+ messages in thread
From: Stefan Kangas @ 2021-09-08 21:18 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 41343

Juri Linkov <juri@linkov.net> writes:

> It will be easy to implement closing on mouse release.
> There are also many other small adjustments planned.
> But first I'd like to merge the basic completed work.
> Then to continue tweaking in master.

Sounds good, thanks.





^ permalink raw reply	[flat|nested] 31+ messages in thread

* bug#41343: tab-bar-mode: Close tab on mouse-2 click
  2021-09-06 19:40                               ` Stefan Kangas
  2021-09-08 19:28                                 ` Juri Linkov
@ 2021-09-14  6:43                                 ` Juri Linkov
  1 sibling, 0 replies; 31+ messages in thread
From: Juri Linkov @ 2021-09-14  6:43 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: 41343

tags 41343 fixed
close 41343 28.0.50
thanks

>> Now the branch 'feature/tab-bar-events' is ready for testing.
>> Please help to find any possible problems.
>
> I have tested it on GNU/Linux and macOS, and it seems to work fine.
>
> One concern is that tabs close on mouse down, rather than release.
>
> In Firefox, tabs close instead on mouse release.  This is good,
> because it gives me a second to react and move the mouse cursor away
> in case I misclick.
>
> This is currently less important in Emacs, as the buffer survives even
> such a misclick.  But maybe in the future users will want tabs to be
> more strongly connected to their associated buffers, and work would
> then easily be lost to a misclick.
>
> Could we change this to close on mouse release instead?

Thanks for the suggestion.  It was trivially easy to implement this
with the new design of the event handling on the tab bar.





^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2021-09-14  6:43 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-17  4:05 bug#41343: tab-bar-mode: Close tab on mouse-2 click Stefan Kangas
2020-05-17 22:12 ` Juri Linkov
2020-05-17 22:23   ` Stefan Kangas
2020-05-18  2:32   ` Eli Zaretskii
2020-05-19 21:54     ` Juri Linkov
2020-05-20 15:59       ` Eli Zaretskii
2021-08-03 22:33 ` Juri Linkov
2021-08-04 11:32   ` Eli Zaretskii
2021-08-04 20:13     ` Juri Linkov
2021-08-05  5:43       ` Eli Zaretskii
2021-08-06  0:41         ` Juri Linkov
2021-08-06  6:26           ` Eli Zaretskii
2021-08-06  8:20             ` Juri Linkov
2021-08-06 12:38               ` Eli Zaretskii
2021-08-09  7:03                 ` Juri Linkov
2021-08-10 12:38                   ` Eli Zaretskii
2021-08-11  7:01                     ` Juri Linkov
2021-08-11 11:56                       ` Eli Zaretskii
2021-08-12  8:09                         ` Juri Linkov
2021-08-12  8:43                           ` Eli Zaretskii
2021-08-13  7:24                             ` Juri Linkov
2021-08-18 18:11                         ` Juri Linkov
2021-08-24 14:37                           ` Stefan Kangas
2021-09-05 17:18                             ` Juri Linkov
2021-09-06 19:40                               ` Stefan Kangas
2021-09-08 19:28                                 ` Juri Linkov
2021-09-08 21:18                                   ` Stefan Kangas
2021-09-14  6:43                                 ` Juri Linkov
2021-09-05 17:17                         ` Juri Linkov
2021-08-06 16:21           ` bug#41343: [External] : " Drew Adams
2021-08-09  7:06             ` Juri Linkov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).