[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master ad76020 1/2: Support mouse clicks on tab bar on TTY
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] master ad76020 1/2: Support mouse clicks on tab bar on TTY frames |
Date: |
Sun, 6 Oct 2019 12:55:10 -0400 (EDT) |
branch: master
commit ad76020af8498d148984daf4de545d5d610d0589
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
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.
---
src/termchar.h | 4 ++
src/w32console.c | 9 +++-
src/w32inevt.c | 25 +++++++----
src/xdisp.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 146 insertions(+), 17 deletions(-)
diff --git a/src/termchar.h b/src/termchar.h
index 796453d..11c964b 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -231,4 +231,8 @@ extern struct tty_display_info *tty_list;
#define CURTTY() FRAME_TTY (SELECTED_FRAME())
+struct input_event;
+extern bool tty_handle_tab_bar_click (struct frame *, int, int, bool,
+ struct input_event *);
+
#endif /* EMACS_TERMCHAR_H */
diff --git a/src/w32console.c b/src/w32console.c
index 8575c93..c50bb67 100644
--- a/src/w32console.c
+++ b/src/w32console.c
@@ -503,7 +503,14 @@ w32con_set_terminal_modes (struct terminal *t)
SetConsoleActiveScreenBuffer (cur_screen);
- SetConsoleMode (keyboard_handle, ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT);
+ /* If Quick Edit is enabled for the console, it will get in the way
+ of receiving mouse events, so we disable it. But leave the
+ Insert Mode as it was set by the user. */
+ DWORD new_console_mode
+ = ENABLE_MOUSE_INPUT | ENABLE_WINDOW_INPUT | ENABLE_EXTENDED_FLAGS;
+ if ((prev_console_mode & ENABLE_INSERT_MODE) != 0)
+ new_console_mode |= ENABLE_INSERT_MODE;
+ SetConsoleMode (keyboard_handle, new_console_mode);
/* Initialize input mode: interrupt_input off, no flow control, allow
8 bit character input, standard quit char. */
diff --git a/src/w32inevt.c b/src/w32inevt.c
index 0a1321c..1a901d4 100644
--- a/src/w32inevt.c
+++ b/src/w32inevt.c
@@ -559,8 +559,6 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
if (event->dwButtonState == button_state)
return 0;
- emacs_ev->kind = MOUSE_CLICK_EVENT;
-
/* Find out what button has changed state since the last button
event. */
but_change = button_state ^ event->dwButtonState;
@@ -576,15 +574,24 @@ do_mouse_event (MOUSE_EVENT_RECORD *event,
}
button_state = event->dwButtonState;
- emacs_ev->modifiers =
- w32_kbd_mods_to_emacs (event->dwControlKeyState, 0)
- | ((event->dwButtonState & mask) ? down_modifier : up_modifier);
+ emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState,
0);
+ emacs_ev->timestamp = GetTickCount ();
+
+ 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 */
- XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
- XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
- XSETFRAME (emacs_ev->frame_or_window, get_frame ());
+ emacs_ev->modifiers |= ((button_state & mask)
+ ? down_modifier : up_modifier);
+
+ emacs_ev->kind = MOUSE_CLICK_EVENT;
+ XSETFASTINT (emacs_ev->x, x);
+ XSETFASTINT (emacs_ev->y, y);
+ XSETFRAME (emacs_ev->frame_or_window, f);
emacs_ev->arg = Qnil;
- emacs_ev->timestamp = GetTickCount ();
return 1;
}
diff --git a/src/xdisp.c b/src/xdisp.c
index f5dedc2..8aa38c8 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12746,12 +12746,12 @@ display_tab_bar (struct window *w)
/* Display all items of the tab bar. */
items = it.f->tab_bar_items;
- for (i = 0; i < it.f->n_tab_bar_items; ++i)
+ int j;
+ for (i = 0, j = 0; i < it.f->n_tab_bar_items; ++i, j += TAB_BAR_ITEM_NSLOTS)
{
- Lisp_Object string;
+ Lisp_Object string = AREF (items, j + TAB_BAR_ITEM_CAPTION);
/* Stop at nil string. */
- string = AREF (items, i * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_CAPTION);
if (NILP (string))
break;
@@ -13180,7 +13180,7 @@ tab_bar_item_info (struct frame *f, struct glyph *glyph,
int *prop_idx, bool *close_p)
{
Lisp_Object prop;
- int charpos;
+ ptrdiff_t charpos;
/* This function can be called asynchronously, which means we must
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,
void
handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
- int modifiers)
+ int modifiers)
{
Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
struct window *w = XWINDOW (f->tab_bar_window);
@@ -13420,6 +13420,96 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
#endif /* HAVE_WINDOW_SYSTEM */
+/* Find the tab-bar item at X coordinate and return its information. */
+static Lisp_Object
+tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
+{
+ ptrdiff_t clen = 0;
+ Lisp_Object caption;
+
+ int i, j;
+ for (i = 0, j = 0; i < f->n_tab_bar_items; i++, j += TAB_BAR_ITEM_NSLOTS)
+ {
+ caption = AREF (f->tab_bar_items, j + TAB_BAR_ITEM_CAPTION);
+ if (NILP (caption))
+ return Qnil;
+ clen += SCHARS (caption);
+ if (x < clen)
+ break;
+ }
+ if (i < f->n_tab_bar_items)
+ {
+ *idx = i;
+ *end = clen;
+ return caption;
+ }
+ else
+ return Qnil;
+}
+
+/* Handle a mouse click at X/Y on the tab bar of TTY frame F. If the
+ click was on the tab bar and was handled, populate the EVENT
+ structure, store it in keyboard queue, and return true; otherwise
+ return false. MODIFIERS are event modifiers for generating the tab
+ release event. */
+bool
+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;
+
+ /* Find the tab-bar item where the X,Y coordinates belong. */
+ int prop_idx;
+ ptrdiff_t clen;
+ Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen);
+
+ if (NILP (caption))
+ return false;
+
+ if (NILP (AREF (f->tab_bar_items,
+ prop_idx * TAB_BAR_ITEM_NSLOTS + TAB_BAR_ITEM_ENABLED_P)))
+ return false;
+
+ if (down_p)
+ f->last_tab_bar_item = prop_idx;
+ else
+ {
+ /* 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 = frame;
+ kbd_buffer_store_event (event);
+
+ 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;
+}
+
/***********************************************************************
@@ -14065,7 +14155,7 @@ static bool
tool_bar_item_info (struct frame *f, struct glyph *glyph, int *prop_idx)
{
Lisp_Object prop;
- int charpos;
+ ptrdiff_t charpos;
/* This function can be called asynchronously, which means we must
exclude any possibility that Fget_text_property signals an
@@ -32711,9 +32801,30 @@ note_mouse_highlight (struct frame *f, int x, int y)
&& part != ON_TAB_LINE))
clear_mouse_face (hlinfo);
- /* Reset help_echo_string. It will get recomputed below. */
+ /* Reset help_echo_string. It will get recomputed below. */
help_echo_string = Qnil;
+ /* Handle tab-bar highlight on mouse-capable TTY frames. */
+ if (!FRAME_WINDOW_P (f)
+ && (y >= FRAME_MENU_BAR_LINES (f)
+ && y < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f)))
+ {
+ int prop_idx;
+ ptrdiff_t ignore;
+ Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &ignore);
+
+ if (!NILP (caption))
+ {
+ help_echo_object = help_echo_window = Qnil;
+ help_echo_pos = -1;
+ help_echo_string = AREF (f->tab_bar_items,
+ prop_idx * TAB_BAR_ITEM_NSLOTS
+ + TAB_BAR_ITEM_HELP);
+ if (NILP (help_echo_string))
+ help_echo_string = caption;
+ }
+ }
+
#ifdef HAVE_WINDOW_SYSTEM
/* If the cursor is on the internal border of FRAME and FRAME's
internal border is draggable, provide some visual feedback. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master ad76020 1/2: Support mouse clicks on tab bar on TTY frames,
Eli Zaretskii <=