aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2019-10-06 19:53:18 +0300
committerEli Zaretskii2019-10-06 19:53:18 +0300
commitad76020af8498d148984daf4de545d5d610d0589 (patch)
tree1f748991403fdb1f7f1f92f449dc38e5ddcceff7 /src
parent9d829b8be5b86668d5165b9d0c0cdc392b558dd3 (diff)
downloademacs-ad76020af8498d148984daf4de545d5d610d0589.tar.gz
emacs-ad76020af8498d148984daf4de545d5d610d0589.zip
Support mouse clicks on tab bar on TTY frames
This for now doesn't work on GPM. * src/xdisp.c (display_tab_bar): Make the loop over tab-bar items more efficient. (tab_bar_item_info, tool_bar_item_info): Correct data type for CHARPOS. (tty_get_tab_bar_item, tty_handle_tab_bar_click): New functions. (note_mouse_highlight): Handle help-echo of tab-bar tabs on TTY frames. * src/w32inevt.c (do_mouse_event): Call tty_handle_tab_bar_click to process mouse clicks on the tab bar. * src/termchar.h (tty_handle_tab_bar_click): Add prototype. * src/w32console.c (w32con_set_terminal_modes): Disable Quick Edit mode on entry, to make sure mouse events get reported to us.
Diffstat (limited to 'src')
-rw-r--r--src/termchar.h4
-rw-r--r--src/w32console.c9
-rw-r--r--src/w32inevt.c25
-rw-r--r--src/xdisp.c125
4 files changed, 146 insertions, 17 deletions
diff --git a/src/termchar.h b/src/termchar.h
index 796453d3cca..11c964b2b6d 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -231,4 +231,8 @@ extern struct tty_display_info *tty_list;
231 231
232#define CURTTY() FRAME_TTY (SELECTED_FRAME()) 232#define CURTTY() FRAME_TTY (SELECTED_FRAME())
233 233
234struct input_event;
235extern bool tty_handle_tab_bar_click (struct frame *, int, int, bool,
236 struct input_event *);
237
234#endif /* EMACS_TERMCHAR_H */ 238#endif /* EMACS_TERMCHAR_H */
diff --git a/src/w32console.c b/src/w32console.c
index 8575c930a85..c50bb67cd2c 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -503,7 +503,14 @@ w32con_set_terminal_modes (struct terminal *t)
503 503
504 SetConsoleActiveScreenBuffer (cur_screen); 504 SetConsoleActiveScreenBuffer (cur_screen);
505 505
506 SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT); 506 /* If Quick Edit is enabled for the console, it will get in the way
507 of receiving mouse events, so we disable it. But leave the
508 Insert Mode as it was set by the user. */
509 DWORD new_console_mode
510 = ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT | ENABLE_EXTENDED_FLAGS;
511 if ((prev_console_mode & ENABLE_INSERT_MODE) != 0)
512 new_console_mode |= ENABLE_INSERT_MODE;
513 SetConsoleMode (keyboard_handle, new_console_mode);
507 514
508 /* Initialize input mode: interrupt_input off, no flow control, allow 515 /* Initialize input mode: interrupt_input off, no flow control, allow
509 8 bit character input, standard quit char. */ 516 8 bit character input, standard quit char. */
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 0a1321c6d89..1a901d4e0aa 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -559,8 +559,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
559 if (event->dwButtonState == button_state) 559 if (event->dwButtonState == button_state)
560 return 0; 560 return 0;
561 561
562 emacs_ev->kind = MOUSE_CLICK_EVENT;
563
564 /* Find out what button has changed state since the last button 562 /* Find out what button has changed state since the last button
565 event. */ 563 event. */
566 but_change = button_state ^ event->dwButtonState; 564 but_change = button_state ^ event->dwButtonState;
@@ -576,15 +574,24 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
576 } 574 }
577 575
578 button_state = event->dwButtonState; 576 button_state = event->dwButtonState;
579 emacs_ev->modifiers = 577 emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, 0);
580 w32_kbd_mods_to_emacs (event->dwControlKeyState, 0) 578 emacs_ev->timestamp = GetTickCount ();
581 | ((event->dwButtonState & mask) ? down_modifier : up_modifier); 579
580 int x = event->dwMousePosition.X;
581 int y = event->dwMousePosition.Y;
582 struct frame *f = get_frame ();
583 if (tty_handle_tab_bar_click (f, x, y, (button_state & mask) != 0,
584 emacs_ev))
585 return 0; /* tty_handle_tab_bar_click adds the event to queue */
582 586
583 XSETFASTINT (emacs_ev->x, event->dwMousePosition.X); 587 emacs_ev->modifiers |= ((button_state & mask)
584 XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y); 588 ? down_modifier : up_modifier);
585 XSETFRAME (emacs_ev->frame_or_window, get_frame ()); 589
590 emacs_ev->kind = MOUSE_CLICK_EVENT;
591 XSETFASTINT (emacs_ev->x, x);
592 XSETFASTINT (emacs_ev->y, y);
593 XSETFRAME (emacs_ev->frame_or_window, f);
586 emacs_ev->arg = Qnil; 594 emacs_ev->arg = Qnil;
587 emacs_ev->timestamp = GetTickCount ();
588 595
589 return 1; 596 return 1;
590 } 597 }
diff --git a/src/xdisp.c b/src/xdisp.c
index f5dedc218e2..8aa38c8034c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12746,12 +12746,12 @@ display_tab_bar (struct window *w)
12746 12746
12747 /* Display all items of the tab bar. */ 12747 /* Display all items of the tab bar. */
12748 items = it.f->tab_bar_items; 12748 items = it.f->tab_bar_items;
12749 for (i = 0; i < it.f->n_tab_bar_items; ++i) 12749 int j;
12750 for (i = 0, j = 0; i < it.f->n_tab_bar_items; ++i, j += TAB_BAR_ITEM_NSLOTS)
12750 { 12751 {
12751 Lisp_Object string; 12752 Lisp_Object string = AREF (items, j + TAB_BAR_ITEM_CAPTION);
12752 12753
12753 /* Stop at nil string. */ 12754 /* Stop at nil string. */
12754 string = AREF (items, i * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_CAPTION);
12755 if (NILP (string)) 12755 if (NILP (string))
12756 break; 12756 break;
12757 12757
@@ -13180,7 +13180,7 @@ tab_bar_item_info (struct frame *f, struct glyph *glyph,
13180 int *prop_idx, bool *close_p) 13180 int *prop_idx, bool *close_p)
13181{ 13181{
13182 Lisp_Object prop; 13182 Lisp_Object prop;
13183 int charpos; 13183 ptrdiff_t charpos;
13184 13184
13185 /* This function can be called asynchronously, which means we must 13185 /* This function can be called asynchronously, which means we must
13186 exclude any possibility that Fget_text_property signals an 13186 exclude any possibility that Fget_text_property signals an
@@ -13256,7 +13256,7 @@ get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
13256 13256
13257void 13257void
13258handle_tab_bar_click (struct frame *f, int x, int y, bool down_p, 13258handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13259 int modifiers) 13259 int modifiers)
13260{ 13260{
13261 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f); 13261 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
13262 struct window *w = XWINDOW (f->tab_bar_window); 13262 struct window *w = XWINDOW (f->tab_bar_window);
@@ -13420,6 +13420,96 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
13420 13420
13421#endif /* HAVE_WINDOW_SYSTEM */ 13421#endif /* HAVE_WINDOW_SYSTEM */
13422 13422
13423/* Find the tab-bar item at X coordinate and return its information. */
13424static Lisp_Object
13425tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
13426{
13427 ptrdiff_t clen = 0;
13428 Lisp_Object caption;
13429
13430 int i, j;
13431 for (i = 0, j = 0; i < f->n_tab_bar_items; i++, j += TAB_BAR_ITEM_NSLOTS)
13432 {
13433 caption = AREF (f->tab_bar_items, j + TAB_BAR_ITEM_CAPTION);
13434 if (NILP (caption))
13435 return Qnil;
13436 clen += SCHARS (caption);
13437 if (x < clen)
13438 break;
13439 }
13440 if (i < f->n_tab_bar_items)
13441 {
13442 *idx = i;
13443 *end = clen;
13444 return caption;
13445 }
13446 else
13447 return Qnil;
13448}
13449
13450/* Handle a mouse click at X/Y on the tab bar of TTY frame F. If the
13451 click was on the tab bar and was handled, populate the EVENT
13452 structure, store it in keyboard queue, and return true; otherwise
13453 return false. MODIFIERS are event modifiers for generating the tab
13454 release event. */
13455bool
13456tty_handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
13457 struct input_event *event)
13458{
13459 /* Did they click on the tab bar? */
13460 if (y < FRAME_MENU_BAR_LINES (f)
13461 || y >= FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f))
13462 return false;
13463
13464 /* Find the tab-bar item where the X,Y coordinates belong. */
13465 int prop_idx;
13466 ptrdiff_t clen;
13467 Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen);
13468
13469 if (NILP (caption))
13470 return false;
13471
13472 if (NILP (AREF (f->tab_bar_items,
13473 prop_idx * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_ENABLED_P)))
13474 return false;
13475
13476 if (down_p)
13477 f->last_tab_bar_item = prop_idx;
13478 else
13479 {
13480 /* Generate a TAB_BAR_EVENT event. */
13481 Lisp_Object frame;
13482 Lisp_Object key = AREF (f->tab_bar_items,
13483 prop_idx * TAB_BAR_ITEM_NSLOTS
13484 + TAB_BAR_ITEM_KEY);
13485 /* Kludge alert: we assume the last two characters of a tab
13486 label are " x", and treat clicks on those 2 characters as a
13487 Close Tab command. */
13488 eassert (STRINGP (caption));
13489 int lastc = SSDATA (caption)[SCHARS (caption) - 1];
13490 bool close_p = false;
13491 if ((x == clen - 1 || (clen > 1 && x == clen - 2)) && lastc == 'x')
13492 close_p = true;
13493
13494 event->code = 0;
13495 XSETFRAME (frame, f);
13496 event->kind = TAB_BAR_EVENT;
13497 event->frame_or_window = frame;
13498 event->arg = frame;
13499 kbd_buffer_store_event (event);
13500
13501 event->kind = TAB_BAR_EVENT;
13502 event->frame_or_window = frame;
13503 event->arg = key;
13504 if (close_p)
13505 event->modifiers |= ctrl_modifier;
13506 kbd_buffer_store_event (event);
13507 f->last_tab_bar_item = -1;
13508 }
13509
13510 return true;
13511}
13512
13423 13513
13424 13514
13425/*********************************************************************** 13515/***********************************************************************
@@ -14065,7 +14155,7 @@ static bool
14065tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx) 14155tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
14066{ 14156{
14067 Lisp_Object prop; 14157 Lisp_Object prop;
14068 int charpos; 14158 ptrdiff_t charpos;
14069 14159
14070 /* This function can be called asynchronously, which means we must 14160 /* This function can be called asynchronously, which means we must
14071 exclude any possibility that Fget_text_property signals an 14161 exclude any possibility that Fget_text_property signals an
@@ -32711,9 +32801,30 @@ note_mouse_highlight (struct frame *f, int x, int y)
32711 && part != ON_TAB_LINE)) 32801 && part != ON_TAB_LINE))
32712 clear_mouse_face (hlinfo); 32802 clear_mouse_face (hlinfo);
32713 32803
32714 /* Reset help_echo_string. It will get recomputed below. */ 32804 /* Reset help_echo_string. It will get recomputed below. */
32715 help_echo_string = Qnil; 32805 help_echo_string = Qnil;
32716 32806
32807 /* Handle tab-bar highlight on mouse-capable TTY frames. */
32808 if (!FRAME_WINDOW_P (f)
32809 && (y >= FRAME_MENU_BAR_LINES (f)
32810 && y < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f)))
32811 {
32812 int prop_idx;
32813 ptrdiff_t ignore;
32814 Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &ignore);
32815
32816 if (!NILP (caption))
32817 {
32818 help_echo_object = help_echo_window = Qnil;
32819 help_echo_pos = -1;
32820 help_echo_string = AREF (f->tab_bar_items,
32821 prop_idx * TAB_BAR_ITEM_NSLOTS
32822 + TAB_BAR_ITEM_HELP);
32823 if (NILP (help_echo_string))
32824 help_echo_string = caption;
32825 }
32826 }
32827
32717#ifdef HAVE_WINDOW_SYSTEM 32828#ifdef HAVE_WINDOW_SYSTEM
32718 /* If the cursor is on the internal border of FRAME and FRAME's 32829 /* If the cursor is on the internal border of FRAME and FRAME's
32719 internal border is draggable, provide some visual feedback. */ 32830 internal border is draggable, provide some visual feedback. */