diff options
| author | Juri Linkov | 2021-08-18 20:32:32 +0300 |
|---|---|---|
| committer | Juri Linkov | 2021-08-18 20:32:32 +0300 |
| commit | e6bea0cbc76bc47f435be9c7f6f3c4b770994924 (patch) | |
| tree | 2ee98e933d595d6ad970b78a8c51d7a51597f210 /src | |
| parent | 54039d721c5b7fd210a79dc641914cba8fc82185 (diff) | |
| download | emacs-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.h | 4 | ||||
| -rw-r--r-- | src/keyboard.c | 6 | ||||
| -rw-r--r-- | src/term.c | 17 | ||||
| -rw-r--r-- | src/termchar.h | 4 | ||||
| -rw-r--r-- | src/w32inevt.c | 6 | ||||
| -rw-r--r-- | src/w32term.c | 20 | ||||
| -rw-r--r-- | src/xdisp.c | 81 | ||||
| -rw-r--r-- | src/xterm.c | 8 |
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); |
| 3416 | extern Lisp_Object find_hot_spot (Lisp_Object, int, int); | 3416 | extern Lisp_Object find_hot_spot (Lisp_Object, int, int); |
| 3417 | 3417 | ||
| 3418 | extern void handle_tab_bar_click (struct frame *, | 3418 | extern Lisp_Object handle_tab_bar_click (struct frame *, |
| 3419 | int, int, bool, int); | 3419 | int, int, bool, int); |
| 3420 | extern void handle_tool_bar_click (struct frame *, | 3420 | extern 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 | ||
| 236 | struct input_event; | 236 | struct input_event; |
| 237 | extern bool tty_handle_tab_bar_click (struct frame *, int, int, bool, | 237 | extern 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; | |||
| 168 | int w32_message_fd = -1; | 168 | int w32_message_fd = -1; |
| 169 | #endif /* CYGWIN */ | 169 | #endif /* CYGWIN */ |
| 170 | 170 | ||
| 171 | static void w32_handle_tab_bar_click (struct frame *, | 171 | static Lisp_Object w32_handle_tab_bar_click (struct frame *, |
| 172 | struct input_event *); | 172 | struct input_event *); |
| 173 | static void w32_handle_tool_bar_click (struct frame *, | 173 | static void w32_handle_tool_bar_click (struct frame *, |
| 174 | struct input_event *); | 174 | struct input_event *); |
| 175 | static void w32_define_cursor (Window, Emacs_Cursor); | 175 | static 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 | ||
| 3687 | static void | 3687 | static Lisp_Object |
| 3688 | w32_handle_tab_bar_click (struct frame *f, struct input_event *button_event) | 3688 | w32_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 | ||
| 13748 | void | 13748 | Lisp_Object |
| 13749 | handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, | 13749 | handle_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. */ |
| 13923 | bool | 13923 | Lisp_Object |
| 13924 | tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, | 13924 | tty_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, |