summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-05-16 15:54:50 +0800
committerPo Lu <luangruo@yahoo.com>2023-05-16 15:54:50 +0800
commitbb8bf9203ed33de0bb269c8ff69067aa7b3a692a (patch)
tree9aeb35760a2997f734b3f706048e381300b514c1 /src
parent44da7d75ed3fa6322d64d66d250bc78e91636ff5 (diff)
Add touchscreen support to the tab bar
* lisp/menu-bar.el (popup-menu-normalize-position): Normalize `touchscreen-begin' events correctly. * lisp/tab-bar.el (tab-bar-mouse-context-menu): New argument POSN. Use it if specified. (touch-screen-track-tap, tab-bar-handle-timeout) (tab-bar-touchscreen-begin): New functions. (tab-bar-map): Bind [tab-bar touchscreen-begin]. * lisp/touch-screen.el (touch-screen-track-drag): Fix doc string. * src/dispextern.h: Export `get_tab_bar_item_kbd'. * src/keyboard.c (coords_in_tab_bar_window): New function. (make_lispy_event): Adjust touchscreen begin event mouse position list for tab bar. * src/xdisp.c (tab_bar_item_info): Allow CLOSE_P to be NULL. (get_tab_bar_item): Adjust doc string. (get_tab_bar_item_kbd): New function.
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h1
-rw-r--r--src/keyboard.c71
-rw-r--r--src/xdisp.c61
3 files changed, 121 insertions, 12 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 36e998070a4..402972d33d9 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3528,6 +3528,7 @@ extern void get_glyph_string_clip_rect (struct glyph_string *,
NativeRectangle *nr);
extern Lisp_Object find_hot_spot (Lisp_Object, int, int);
+extern int get_tab_bar_item_kbd (struct frame *, int, int, int *, bool *);
extern Lisp_Object handle_tab_bar_click (struct frame *,
int, int, bool, int);
extern void handle_tool_bar_click (struct frame *,
diff --git a/src/keyboard.c b/src/keyboard.c
index 6e63cd71f30..c0d201f72ad 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5875,6 +5875,25 @@ coords_in_menu_bar_window (struct frame *f, int x, int y)
#endif
+/* Return whether or not the coordinates X and Y are inside the
+ tab-bar window of the given frame F. */
+
+static bool
+coords_in_tab_bar_window (struct frame *f, int x, int y)
+{
+ struct window *window;
+
+ if (!WINDOWP (f->tab_bar_window))
+ return false;
+
+ window = XWINDOW (f->tab_bar_window);
+
+ return (y >= WINDOW_TOP_EDGE_Y (window)
+ && x >= WINDOW_LEFT_EDGE_X (window)
+ && y <= WINDOW_BOTTOM_EDGE_Y (window)
+ && x <= WINDOW_RIGHT_EDGE_X (window));
+}
+
/* Given a struct input_event, build the lisp event which represents
it. If EVENT is 0, build a mouse movement event from the mouse
movement buffer, which should have a movement event in it.
@@ -6522,11 +6541,14 @@ make_lispy_event (struct input_event *event)
case TOUCHSCREEN_END_EVENT:
{
Lisp_Object x, y, id, position;
- struct frame *f = XFRAME (event->frame_or_window);
+ struct frame *f;
+ int tab_bar_item;
+ bool close;
#if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR
int column, row, dummy;
-#endif
+#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
+ f = XFRAME (event->frame_or_window);
id = event->arg;
x = event->x;
y = event->y;
@@ -6589,10 +6611,53 @@ make_lispy_event (struct input_event *event)
return Qnil;
}
-#endif
+#endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */
position = make_lispy_position (f, x, y, event->timestamp);
+#ifdef HAVE_WINDOW_SYSTEM
+
+ /* Now check if POSITION lies on the tab bar. If so, look up
+ the corresponding tab bar item's propertized string as the
+ OBJECT. */
+
+ if (coords_in_tab_bar_window (f, XFIXNUM (event->x),
+ XFIXNUM (event->y))
+ /* `get_tab_bar_item_kbd' returns 0 if the item was
+ previously highlighted, 1 otherwise, and -1 if there is
+ no tab bar item. */
+ && get_tab_bar_item_kbd (f, XFIXNUM (event->x),
+ XFIXNUM (event->y), &tab_bar_item,
+ &close) >= 0)
+ {
+ /* First, obtain the propertized string. */
+ x = Fcopy_sequence (AREF (f->tab_bar_items,
+ (tab_bar_item
+ + TAB_BAR_ITEM_CAPTION)));
+
+ /* Next, add the key binding. */
+ AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items,
+ (tab_bar_item
+ + TAB_BAR_ITEM_KEY)),
+ AREF (f->tab_bar_items,
+ (tab_bar_item
+ + TAB_BAR_ITEM_BINDING)),
+ close ? Qt : Qnil));
+
+ /* And add the new properties to the propertized string. */
+ Fadd_text_properties (make_fixnum (0),
+ make_fixnum (SCHARS (x)),
+ y, x);
+
+ /* Set the position to 0. */
+ x = Fcons (x, make_fixnum (0));
+
+ /* Finally, add the OBJECT. */
+ position = nconc2 (position, Fcons (x, Qnil));
+ }
+
+#endif /* HAVE_WINDOW_SYSTEM */
+
return list2 (((event->kind
== TOUCHSCREEN_BEGIN_EVENT)
? Qtouchscreen_begin
diff --git a/src/xdisp.c b/src/xdisp.c
index 89b1ae77e6f..09b1cc616f2 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -14584,21 +14584,32 @@ tab_bar_item_info (struct frame *f, struct glyph *glyph,
Qmenu_item, f->current_tab_bar_string);
if (! FIXNUMP (prop))
return false;
+
*prop_idx = XFIXNUM (prop);
- *close_p = !NILP (Fget_text_property (make_fixnum (charpos),
- Qclose_tab,
- f->current_tab_bar_string));
+ if (close_p)
+ *close_p = !NILP (Fget_text_property (make_fixnum (charpos),
+ Qclose_tab,
+ f->current_tab_bar_string));
return true;
}
-/* Get information about the tab-bar item at position X/Y on frame F.
- Return in *GLYPH a pointer to the glyph of the tab-bar item in
- the current matrix of the tab-bar window of F, or NULL if not
- on a tab-bar item. Return in *PROP_IDX the index of the tab-bar
- item in F->tab_bar_items. Value is
+/* Get information about the tab-bar item at position X/Y on frame F's
+ tab bar window.
+
+ Set *GLYPH to a pointer to the glyph of the tab-bar item in the
+ current matrix of the tab-bar window of F, or NULL if not on a
+ tab-bar item. Return in *PROP_IDX the index of the tab-bar item in
+ F->tab_bar_items.
+
+ Place the window-relative vpos of Y in *VPOS, and the
+ window-relative hpos of X in *HPOS. If CLOSE_P, set it to whether
+ or not the tab bar item represents a button that should close a
+ tab.
+
+ Value is
-1 if X/Y is not on a tab-bar item
0 if X/Y is on the same item that was highlighted before.
@@ -14606,7 +14617,7 @@ tab_bar_item_info (struct frame *f, struct glyph *glyph,
static int
get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
- int *hpos, int *vpos, int *prop_idx, bool *close_p)
+ int *hpos, int *vpos, int *prop_idx, bool *close_p)
{
struct window *w = XWINDOW (f->tab_bar_window);
int area;
@@ -14624,6 +14635,38 @@ get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph,
return *prop_idx == f->last_tab_bar_item ? 0 : 1;
}
+/* EXPORT:
+
+ Like `get_tab_bar_item'. However, don't return anything for GLYPH,
+ HPOS, or VPOS, and treat X and Y as relative to F itself, as
+ opposed to its tab bar window. */
+
+int
+get_tab_bar_item_kbd (struct frame *f, int x, int y, int *prop_idx,
+ bool *close_p)
+{
+ struct window *w;
+ int area, vpos, hpos;
+ struct glyph *glyph;
+
+ w = XWINDOW (f->tab_bar_window);
+
+ /* Convert X and Y to window coordinates. */
+ frame_to_window_pixel_xy (w, &x, &y);
+
+ /* Find the glyph under X/Y. */
+ glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0,
+ 0, &area);
+ if (glyph == NULL)
+ return -1;
+
+ /* Get the start of this tab-bar item's properties in
+ f->tab_bar_items. */
+ if (!tab_bar_item_info (f, glyph, prop_idx, close_p))
+ return -1;
+
+ return *prop_idx == f->last_tab_bar_item ? 0 : 1;
+}
/* EXPORT:
Handle mouse button event on the tab-bar of frame F, at