summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h4
-rw-r--r--src/keyboard.c6
-rw-r--r--src/menu.c9
-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.c104
-rw-r--r--src/xterm.c10
9 files changed, 83 insertions, 97 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 *,
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 4b0e4a1f772..ac8c6b0d953 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5654,6 +5654,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/menu.c b/src/menu.c
index d43360ec4ea..1aafa78c3ce 100644
--- a/src/menu.c
+++ b/src/menu.c
@@ -1127,9 +1127,12 @@ x_popup_menu_1 (Lisp_Object position, Lisp_Object menu)
/* Decode the first argument: find the window and the coordinates. */
if (EQ (position, Qt)
- || (CONSP (position) && (EQ (XCAR (position), Qmenu_bar)
- || EQ (XCAR (position), Qtab_bar)
- || EQ (XCAR (position), Qtool_bar))))
+ || (CONSP (position)
+ && (EQ (XCAR (position), Qmenu_bar)
+ || EQ (XCAR (position), Qtab_bar)
+ || (CONSP (XCDR (position))
+ && EQ (XCAR (XCDR (position)), Qtab_bar))
+ || EQ (XCAR (position), Qtool_bar))))
{
get_current_pos_p = 1;
}
diff --git a/src/term.c b/src/term.c
index 6651b967927..7d9fe8cee30 100644
--- a/src/term.c
+++ b/src/term.c
@@ -2575,21 +2575,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 f50c1bfb6ea..7ab9337fbe7 100644
--- a/src/termchar.h
+++ b/src/termchar.h
@@ -234,7 +234,7 @@ 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 *);
+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 1255072b7f3..9a69b32bcb0 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 ebd672361bf..9ee3b1ed1f2 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -168,8 +168,8 @@ int w32_keyboard_codepage;
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);
@@ -3687,17 +3687,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);
}
@@ -5189,6 +5189,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_arg = Qnil;
bool tab_bar_p = 0;
bool tool_bar_p = 0;
int button = 0;
@@ -5211,12 +5212,12 @@ w32_read_socket (struct terminal *terminal,
if (EQ (window, f->tab_bar_window))
{
- w32_handle_tab_bar_click (f, &inev);
+ tab_bar_arg = w32_handle_tab_bar_click (f, &inev);
tab_bar_p = 1;
}
}
- if (tab_bar_p
+ if ((tab_bar_p && NILP (tab_bar_arg))
|| (dpyinfo->w32_focus_frame
&& f != dpyinfo->w32_focus_frame
/* This does not help when the click happens in
@@ -5224,6 +5225,9 @@ w32_read_socket (struct terminal *terminal,
&& !frame_ancestor_p (f, dpyinfo->w32_focus_frame)))
inev.kind = NO_EVENT;
+ if (!NILP (tab_bar_arg))
+ inev.arg = tab_bar_arg;
+
/* 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 b2fcc165a9f..45c7090fc00 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13759,7 +13759,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)
{
@@ -13773,16 +13773,13 @@ handle_tab_bar_click (struct frame *f, int x, int y, bool down_p,
frame_to_window_pixel_xy (w, &x, &y);
ts = get_tab_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx, &close_p);
- if (ts == -1
- /* 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;
+ if (ts == -1)
+ 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)
{
@@ -13793,24 +13790,24 @@ 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;
}
+
+ Lisp_Object caption =
+ Fcopy_sequence (AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION));
+
+ AUTO_LIST2 (props, Qmenu_item,
+ list3 (AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_KEY),
+ AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_BINDING),
+ close_p ? Qt : Qnil));
+
+ Fadd_text_properties (make_fixnum (0), make_fixnum (SCHARS (caption)),
+ props, caption);
+
+ return Fcons (Qtab_bar, Fcons (caption, make_fixnum (0)));
}
@@ -13908,7 +13905,7 @@ note_tab_bar_highlight (struct frame *f, int x, int y)
/* 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)
+tty_get_tab_bar_item (struct frame *f, int x, int *prop_idx, bool *close_p)
{
ptrdiff_t clen = 0;
@@ -13921,8 +13918,11 @@ tty_get_tab_bar_item (struct frame *f, int x, int *idx, ptrdiff_t *end)
clen += SCHARS (caption);
if (x < clen)
{
- *idx = i;
- *end = clen;
+ *prop_idx = i;
+ *close_p = !NILP (Fget_text_property (make_fixnum (SCHARS (caption)
+ - (clen - x)),
+ Qclose_tab,
+ caption));
return caption;
}
}
@@ -13934,61 +13934,45 @@ 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;
- ptrdiff_t clen;
- Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &clen);
+ bool close_p;
+ Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &close_p);
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;
- }
+ f->last_tab_bar_item = -1;
- return true;
+ caption = Fcopy_sequence (caption);
+
+ AUTO_LIST2 (props, Qmenu_item,
+ list3 (AREF (f->tab_bar_items, prop_idx * TAB_BAR_ITEM_NSLOTS
+ + TAB_BAR_ITEM_KEY),
+ AREF (f->tab_bar_items, prop_idx * TAB_BAR_ITEM_NSLOTS
+ + TAB_BAR_ITEM_BINDING),
+ close_p ? Qt : Qnil));
+
+ Fadd_text_properties (make_fixnum (0), make_fixnum (SCHARS (caption)),
+ props, caption);
+
+ return Fcons (Qtab_bar, Fcons (caption, make_fixnum (0)));
}
@@ -33569,7 +33553,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
&& y < FRAME_MENU_BAR_LINES (f) + FRAME_TAB_BAR_LINES (f)))
{
int prop_idx;
- ptrdiff_t ignore;
+ bool ignore;
Lisp_Object caption = tty_get_tab_bar_item (f, x, &prop_idx, &ignore);
if (!NILP (caption))
diff --git a/src/xterm.c b/src/xterm.c
index b478eff2906..4c1754ac80c 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9169,6 +9169,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_arg = Qnil;
bool tab_bar_p = false;
bool tool_bar_p = false;
@@ -9217,8 +9218,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
window = window_from_coordinates (f, x, y, 0, true, true);
tab_bar_p = EQ (window, f->tab_bar_window);
- if (tab_bar_p && event->xbutton.button < 4)
- handle_tab_bar_click
+ if (tab_bar_p)
+ tab_bar_arg = handle_tab_bar_click
(f, x, y, event->xbutton.type == ButtonPress,
x_x_to_emacs_modifiers (dpyinfo, event->xbutton.state));
}
@@ -9242,7 +9243,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_arg)) && !tool_bar_p)
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (! popup_activated ())
#endif
@@ -9260,6 +9261,9 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
else
x_construct_mouse_click (&inev.ie, &event->xbutton, f);
+
+ if (!NILP (tab_bar_arg))
+ inev.ie.arg = tab_bar_arg;
}
if (FRAME_X_EMBEDDED_P (f))
xembed_send_message (f, event->xbutton.time,