aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJuri Linkov2021-08-18 20:32:32 +0300
committerJuri Linkov2021-08-18 20:32:32 +0300
commite6bea0cbc76bc47f435be9c7f6f3c4b770994924 (patch)
tree2ee98e933d595d6ad970b78a8c51d7a51597f210 /src
parent54039d721c5b7fd210a79dc641914cba8fc82185 (diff)
downloademacs-e6bea0cbc76bc47f435be9c7f6f3c4b770994924.tar.gz
emacs-e6bea0cbc76bc47f435be9c7f6f3c4b770994924.zip
Redesign tab-bar event processing (bug#41342, bug#41343)
Instead of emitting menu-item keys like [tab-1], emit normal mouse events like [mouse-1] and [down-mouse-3] for all mouse clicks issued on the tab-bar. * lisp/mouse.el (mouse-posn-property): Handle 'tab-bar' posn-area. * lisp/tab-bar.el (tab--key-to-number): New internal function. (tab-bar-handle-mouse): Use tab key to select/close tab. (tab-bar-mouse-select-tab, tab-bar-mouse-close-tab) (tab-bar-mouse-context-menu): New commands. (tab-bar-map): Bind [down-mouse-1] to tab-bar-mouse-select-tab, [down-mouse-2] to tab-bar-mouse-close-tab, [down-mouse-3] to tab-bar-mouse-context-menu. (tab-bar-keymap-cache): Remove. (tab-bar-make-keymap): Don't use cache. (tab-bar--format-tab): Remove default bindings from menu items. (tab-bar-make-keymap-1): Prepend tab-bar-map. * src/keyboard.c (make_lispy_event): Append event->arg to position for Qtab_bar. * src/term.c (handle_one_term_event): Simplify to set event arg. * src/w32inevt.c (do_mouse_event): Set emacs_ev->arg to the value returned from tty_handle_tab_bar_click. * src/w32term.c (w32_handle_tab_bar_click): Return value from handle_tab_bar_click. (w32_read_socket): Set tab_bar_key to value returned from w32_handle_tab_bar_click, and set event arg from it. * src/xdisp.c (handle_tab_bar_click): Instead of emitting event, return a list with Qtab_bar and tab caption with text properties that contain Qmenu_item with key and binding. (tty_handle_tab_bar_click): Simplify to return a list of Qtab_bar, key and close_p, instead of emitting event. * src/xterm.c (handle_one_xevent): Set tab_bar_key to value returned from handle_tab_bar_click, and set event arg from it.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h4
-rw-r--r--src/keyboard.c6
-rw-r--r--src/term.c17
-rw-r--r--src/termchar.h4
-rw-r--r--src/w32inevt.c6
-rw-r--r--src/w32term.c20
-rw-r--r--src/xdisp.c81
-rw-r--r--src/xterm.c8
8 files changed, 66 insertions, 80 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 33fcaa4c078..f4c7575b352 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3415,8 +3415,8 @@ extern void get_glyph_string_clip_rect (struct glyph_string *,
3415 NativeRectangle *nr); 3415 NativeRectangle *nr);
3416extern Lisp_Object find_hot_spot (Lisp_Object, int, int); 3416extern Lisp_Object find_hot_spot (Lisp_Object, int, int);
3417 3417
3418extern void handle_tab_bar_click (struct frame *, 3418extern Lisp_Object handle_tab_bar_click (struct frame *,
3419 int, int, bool, int); 3419 int, int, bool, int);
3420extern void handle_tool_bar_click (struct frame *, 3420extern void handle_tool_bar_click (struct frame *,
3421 int, int, bool, int); 3421 int, int, bool, int);
3422 3422
diff --git a/src/keyboard.c b/src/keyboard.c
index 2e4c4e6aabf..e25833276c1 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5649,6 +5649,12 @@ make_lispy_event (struct input_event *event)
5649 5649
5650 position = make_lispy_position (f, event->x, event->y, 5650 position = make_lispy_position (f, event->x, event->y,
5651 event->timestamp); 5651 event->timestamp);
5652
5653 if (CONSP (event->arg) && EQ (XCAR (event->arg), Qtab_bar))
5654 {
5655 XSETCAR (XCDR (position), Qtab_bar);
5656 position = nconc2 (position, Fcons (XCDR (event->arg), Qnil));
5657 }
5652 } 5658 }
5653#ifndef USE_TOOLKIT_SCROLL_BARS 5659#ifndef USE_TOOLKIT_SCROLL_BARS
5654 else 5660 else
diff --git a/src/term.c b/src/term.c
index c995a4499cf..89b35680034 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)
2568 { 2568 {
2569 f->mouse_moved = 0; 2569 f->mouse_moved = 0;
2570 term_mouse_click (&ie, event, f); 2570 term_mouse_click (&ie, event, f);
2571 /* eassert (ie.kind == MOUSE_CLICK_EVENT); */ 2571 ie.arg = tty_handle_tab_bar_click (f, event->x, event->y,
2572 if (tty_handle_tab_bar_click (f, event->x, event->y, 2572 (ie.modifiers & down_modifier) != 0, &ie);
2573 (ie.modifiers & down_modifier) != 0, &ie))
2574 {
2575 /* eassert (ie.kind == MOUSE_CLICK_EVENT
2576 * || ie.kind == TAB_BAR_EVENT); */
2577 /* tty_handle_tab_bar_click stores 2 events in the event
2578 queue, so we are done here. */
2579 /* FIXME: Actually, `tty_handle_tab_bar_click` returns true
2580 without storing any events, when
2581 (ie.modifiers & down_modifier) != 0 */
2582 count += 2;
2583 return count;
2584 }
2585 /* eassert (ie.kind == MOUSE_CLICK_EVENT); */
2586 kbd_buffer_store_event (&ie); 2573 kbd_buffer_store_event (&ie);
2587 count++; 2574 count++;
2588 } 2575 }
diff --git a/src/termchar.h b/src/termchar.h
index f50c1bfb6ea..7ab9337fbe7 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -234,7 +234,7 @@ extern struct tty_display_info *tty_list;
234#define CURTTY() FRAME_TTY (SELECTED_FRAME()) 234#define CURTTY() FRAME_TTY (SELECTED_FRAME())
235 235
236struct input_event; 236struct input_event;
237extern bool tty_handle_tab_bar_click (struct frame *, int, int, bool, 237extern Lisp_Object tty_handle_tab_bar_click (struct frame *, int, int, bool,
238 struct input_event *); 238 struct input_event *);
239 239
240#endif /* EMACS_TERMCHAR_H */ 240#endif /* EMACS_TERMCHAR_H */
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 1255072b7f3..9a69b32bcb0 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -586,9 +586,8 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
586 int x = event->dwMousePosition.X; 586 int x = event->dwMousePosition.X;
587 int y = event->dwMousePosition.Y; 587 int y = event->dwMousePosition.Y;
588 struct frame *f = get_frame (); 588 struct frame *f = get_frame ();
589 if (tty_handle_tab_bar_click (f, x, y, (button_state & mask) != 0, 589 emacs_ev->arg = tty_handle_tab_bar_click (f, x, y, (button_state & mask) != 0,
590 emacs_ev)) 590 emacs_ev);
591 return 0; /* tty_handle_tab_bar_click adds the event to queue */
592 591
593 emacs_ev->modifiers |= ((button_state & mask) 592 emacs_ev->modifiers |= ((button_state & mask)
594 ? down_modifier : up_modifier); 593 ? down_modifier : up_modifier);
@@ -597,7 +596,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
597 XSETFASTINT (emacs_ev->x, x); 596 XSETFASTINT (emacs_ev->x, x);
598 XSETFASTINT (emacs_ev->y, y); 597 XSETFASTINT (emacs_ev->y, y);
599 XSETFRAME (emacs_ev->frame_or_window, f); 598 XSETFRAME (emacs_ev->frame_or_window, f);
600 emacs_ev->arg = Qnil;
601 599
602 return 1; 600 return 1;
603 } 601 }
diff --git a/src/w32term.c b/src/w32term.c
index ad4d1a32829..c9570b0c670 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -168,8 +168,8 @@ int w32_keyboard_codepage;
168int w32_message_fd = -1; 168int w32_message_fd = -1;
169#endif /* CYGWIN */ 169#endif /* CYGWIN */
170 170
171static void w32_handle_tab_bar_click (struct frame *, 171static Lisp_Object w32_handle_tab_bar_click (struct frame *,
172 struct input_event *); 172 struct input_event *);
173static void w32_handle_tool_bar_click (struct frame *, 173static void w32_handle_tool_bar_click (struct frame *,
174 struct input_event *); 174 struct input_event *);
175static void w32_define_cursor (Window, Emacs_Cursor); 175static void w32_define_cursor (Window, Emacs_Cursor);
@@ -3684,17 +3684,17 @@ w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
3684 frame-relative coordinates X/Y. EVENT_TYPE is either ButtonPress 3684 frame-relative coordinates X/Y. EVENT_TYPE is either ButtonPress
3685 or ButtonRelease. */ 3685 or ButtonRelease. */
3686 3686
3687static void 3687static Lisp_Object
3688w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event) 3688w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event)
3689{ 3689{
3690 int x = XFIXNAT (button_event->x); 3690 int x = XFIXNAT (button_event->x);
3691 int y = XFIXNAT (button_event->y); 3691 int y = XFIXNAT (button_event->y);
3692 3692
3693 if (button_event->modifiers & down_modifier) 3693 if (button_event->modifiers & down_modifier)
3694 handle_tab_bar_click (f, x, y, 1, 0); 3694 return handle_tab_bar_click (f, x, y, 1, 0);
3695 else 3695 else
3696 handle_tab_bar_click (f, x, y, 0, 3696 return handle_tab_bar_click (f, x, y, 0,
3697 button_event->modifiers & ~up_modifier); 3697 button_event->modifiers & ~up_modifier);
3698} 3698}
3699 3699
3700 3700
@@ -5186,6 +5186,7 @@ w32_read_socket (struct terminal *terminal,
5186 { 5186 {
5187 /* If we decide we want to generate an event to be seen 5187 /* If we decide we want to generate an event to be seen
5188 by the rest of Emacs, we put it here. */ 5188 by the rest of Emacs, we put it here. */
5189 Lisp_Object tab_bar_key = Qnil;
5189 bool tab_bar_p = 0; 5190 bool tab_bar_p = 0;
5190 bool tool_bar_p = 0; 5191 bool tool_bar_p = 0;
5191 int button = 0; 5192 int button = 0;
@@ -5208,12 +5209,12 @@ w32_read_socket (struct terminal *terminal,
5208 5209
5209 if (EQ (window, f->tab_bar_window)) 5210 if (EQ (window, f->tab_bar_window))
5210 { 5211 {
5211 w32_handle_tab_bar_click (f, &inev); 5212 tab_bar_key = w32_handle_tab_bar_click (f, &inev);
5212 tab_bar_p = 1; 5213 tab_bar_p = 1;
5213 } 5214 }
5214 } 5215 }
5215 5216
5216 if (tab_bar_p 5217 if ((tab_bar_p && NILP (tab_bar_key))
5217 || (dpyinfo->w32_focus_frame 5218 || (dpyinfo->w32_focus_frame
5218 && f != dpyinfo->w32_focus_frame 5219 && f != dpyinfo->w32_focus_frame
5219 /* This does not help when the click happens in 5220 /* This does not help when the click happens in
@@ -5221,6 +5222,9 @@ w32_read_socket (struct terminal *terminal,
5221 && !frame_ancestor_p (f, dpyinfo->w32_focus_frame))) 5222 && !frame_ancestor_p (f, dpyinfo->w32_focus_frame)))
5222 inev.kind = NO_EVENT; 5223 inev.kind = NO_EVENT;
5223 5224
5225 if (!NILP (tab_bar_key))
5226 inev.arg = tab_bar_key;
5227
5224 /* Is this in the tool-bar? */ 5228 /* Is this in the tool-bar? */
5225 if (WINDOWP (f->tool_bar_window) 5229 if (WINDOWP (f->tool_bar_window)
5226 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window))) 5230 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)))
diff --git a/src/xdisp.c b/src/xdisp.c
index 972b90177c6..1a4efba4b82 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,
13745 false for button release. MODIFIERS is event modifiers for button 13745 false for button release. MODIFIERS is event modifiers for button
13746 release. */ 13746 release. */
13747 13747
13748void 13748Lisp_Object
13749handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, 13749handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13750 int modifiers) 13750 int modifiers)
13751{ 13751{
@@ -13763,12 +13763,12 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13763 /* If the button is released on a tab other than the one where 13763 /* If the button is released on a tab other than the one where
13764 it was pressed, don't generate the tab-bar button click event. */ 13764 it was pressed, don't generate the tab-bar button click event. */
13765 || (ts != 0 && !down_p)) 13765 || (ts != 0 && !down_p))
13766 return; 13766 return Qnil;
13767 13767
13768 /* If item is disabled, do nothing. */ 13768 /* If item is disabled, do nothing. */
13769 enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P); 13769 enabled_p = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_ENABLED_P);
13770 if (NILP (enabled_p)) 13770 if (NILP (enabled_p))
13771 return; 13771 return Qnil;
13772 13772
13773 if (down_p) 13773 if (down_p)
13774 { 13774 {
@@ -13779,24 +13779,24 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13779 } 13779 }
13780 else 13780 else
13781 { 13781 {
13782 Lisp_Object key, frame;
13783 struct input_event event;
13784 EVENT_INIT (event);
13785
13786 /* Show item in released state. */ 13782 /* Show item in released state. */
13787 if (!NILP (Vmouse_highlight)) 13783 if (!NILP (Vmouse_highlight))
13788 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED); 13784 show_mouse_face (hlinfo, DRAW_IMAGE_RAISED);
13789
13790 key = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY);
13791
13792 XSETFRAME (frame, f);
13793 event.kind = TAB_BAR_EVENT;
13794 event.frame_or_window = frame;
13795 event.arg = key;
13796 event.modifiers = close_p ? ctrl_modifier | modifiers : modifiers;
13797 kbd_buffer_store_event (&event);
13798 f->last_tab_bar_item = -1; 13785 f->last_tab_bar_item = -1;
13799 } 13786 }
13787
13788 Lisp_Object caption =
13789 Fcopy_sequence (AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION));
13790
13791 AUTO_LIST2 (props, Qmenu_item,
13792 list3 (AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY),
13793 AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_BINDING),
13794 close_p ? Qt : Qnil));
13795
13796 Fadd_text_properties (make_fixnum (0), make_fixnum (SCHARS (caption)),
13797 props, caption);
13798
13799 return Fcons (Qtab_bar, Fcons (caption, make_fixnum (0)));
13800} 13800}
13801 13801
13802 13802
@@ -13920,14 +13920,14 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
13920 structure, store it in keyboard queue, and return true; otherwise 13920 structure, store it in keyboard queue, and return true; otherwise
13921 return false. MODIFIERS are event modifiers for generating the tab 13921 return false. MODIFIERS are event modifiers for generating the tab
13922 release event. */ 13922 release event. */
13923bool 13923Lisp_Object
13924tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, 13924tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13925 struct input_event *event) 13925 struct input_event *event)
13926{ 13926{
13927 /* Did they click on the tab bar? */ 13927 /* Did they click on the tab bar? */
13928 if (y < FRAME_MENU_BAR_LINES (f) 13928 if (y < FRAME_MENU_BAR_LINES (f)
13929 || y >= FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f)) 13929 || y >= FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
13930 return false; 13930 return Qnil;
13931 13931
13932 /* Find the tab-bar item where the X,Y coordinates belong. */ 13932 /* Find the tab-bar item where the X,Y coordinates belong. */
13933 int prop_idx; 13933 int prop_idx;
@@ -13935,46 +13935,33 @@ tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13935 Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen); 13935 Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen);
13936 13936
13937 if (NILP (caption)) 13937 if (NILP (caption))
13938 return false; 13938 return Qnil;
13939 13939
13940 if (NILP (AREF (f->tab_bar_items, 13940 if (NILP (AREF (f->tab_bar_items,
13941 prop_idx * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_ENABLED_P))) 13941 prop_idx * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_ENABLED_P)))
13942 return false; 13942 return Qnil;
13943 13943
13944 if (down_p) 13944 if (down_p)
13945 f->last_tab_bar_item = prop_idx; 13945 f->last_tab_bar_item = prop_idx;
13946 else 13946 else
13947 { 13947 {
13948 /* Force reset of up_modifier bit from the event modifiers. */
13949 if (event->modifiers & up_modifier)
13950 event->modifiers &= ~up_modifier;
13951
13952 /* Generate a TAB_BAR_EVENT event. */
13953 Lisp_Object frame;
13954 Lisp_Object key = AREF (f->tab_bar_items,
13955 prop_idx * TAB_BAR_ITEM_NSLOTS
13956 + TAB_BAR_ITEM_KEY);
13957 /* Kludge alert: we assume the last two characters of a tab
13958 label are " x", and treat clicks on those 2 characters as a
13959 Close Tab command. */
13960 eassert (STRINGP (caption));
13961 int lastc = SSDATA (caption)[SCHARS (caption) - 1];
13962 bool close_p = false;
13963 if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
13964 close_p = true;
13965
13966 event->code = 0;
13967 XSETFRAME (frame, f);
13968 event->kind = TAB_BAR_EVENT;
13969 event->frame_or_window = frame;
13970 event->arg = key;
13971 if (close_p)
13972 event->modifiers |= ctrl_modifier;
13973 kbd_buffer_store_event (event);
13974 f->last_tab_bar_item = -1; 13948 f->last_tab_bar_item = -1;
13975 } 13949 }
13976 13950
13977 return true; 13951 /* Generate a TAB_BAR_EVENT event. */
13952 Lisp_Object key = AREF (f->tab_bar_items,
13953 prop_idx * TAB_BAR_ITEM_NSLOTS
13954 + TAB_BAR_ITEM_KEY);
13955 /* Kludge alert: we assume the last two characters of a tab
13956 label are " x", and treat clicks on those 2 characters as a
13957 Close Tab command. */
13958 eassert (STRINGP (caption));
13959 int lastc = SSDATA (caption)[SCHARS (caption) - 1];
13960 bool close_p = false;
13961 if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
13962 close_p = true;
13963
13964 return list3 (Qtab_bar, key, close_p ? Qt : Qnil);
13978} 13965}
13979 13966
13980 13967
diff --git a/src/xterm.c b/src/xterm.c
index 1887c3255d4..80fa747b97d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9166,6 +9166,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9166 { 9166 {
9167 /* If we decide we want to generate an event to be seen 9167 /* If we decide we want to generate an event to be seen
9168 by the rest of Emacs, we put it here. */ 9168 by the rest of Emacs, we put it here. */
9169 Lisp_Object tab_bar_key = Qnil;
9169 bool tab_bar_p = false; 9170 bool tab_bar_p = false;
9170 bool tool_bar_p = false; 9171 bool tool_bar_p = false;
9171 9172
@@ -9215,7 +9216,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9215 tab_bar_p = EQ (window, f->tab_bar_window); 9216 tab_bar_p = EQ (window, f->tab_bar_window);
9216 9217
9217 if (tab_bar_p && event->xbutton.button < 4) 9218 if (tab_bar_p && event->xbutton.button < 4)
9218 handle_tab_bar_click 9219 tab_bar_key = handle_tab_bar_click
9219 (f, x, y, event->xbutton.type == ButtonPress, 9220 (f, x, y, event->xbutton.type == ButtonPress,
9220 x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state)); 9221 x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
9221 } 9222 }
@@ -9239,7 +9240,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9239 } 9240 }
9240#endif /* !USE_GTK */ 9241#endif /* !USE_GTK */
9241 9242
9242 if (!tab_bar_p && !tool_bar_p) 9243 if (!(tab_bar_p && NILP (tab_bar_key)) && !tool_bar_p)
9243#if defined (USE_X_TOOLKIT) || defined (USE_GTK) 9244#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9244 if (! popup_activated ()) 9245 if (! popup_activated ())
9245#endif 9246#endif
@@ -9257,6 +9258,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
9257 } 9258 }
9258 else 9259 else
9259 x_construct_mouse_click (&inev.ie, &event->xbutton, f); 9260 x_construct_mouse_click (&inev.ie, &event->xbutton, f);
9261
9262 if (!NILP (tab_bar_key))
9263 inev.ie.arg = tab_bar_key;
9260 } 9264 }
9261 if (FRAME_X_EMBEDDED_P (f)) 9265 if (FRAME_X_EMBEDDED_P (f))
9262 xembed_send_message (f, event->xbutton.time, 9266 xembed_send_message (f, event->xbutton.time,