diff options
| author | Po Lu <luangruo@yahoo.com> | 2023-05-16 15:54:50 +0800 |
|---|---|---|
| committer | Po Lu <luangruo@yahoo.com> | 2023-05-16 15:54:50 +0800 |
| commit | bb8bf9203ed33de0bb269c8ff69067aa7b3a692a (patch) | |
| tree | 9aeb35760a2997f734b3f706048e381300b514c1 /src | |
| parent | 44da7d75ed3fa6322d64d66d250bc78e91636ff5 (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.h | 1 | ||||
| -rw-r--r-- | src/keyboard.c | 71 | ||||
| -rw-r--r-- | src/xdisp.c | 61 |
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 |
