diff options
| author | Po Lu | 2023-05-16 15:54:50 +0800 |
|---|---|---|
| committer | Po Lu | 2023-05-16 15:54:50 +0800 |
| commit | bb8bf9203ed33de0bb269c8ff69067aa7b3a692a (patch) | |
| tree | 9aeb35760a2997f734b3f706048e381300b514c1 /src | |
| parent | 44da7d75ed3fa6322d64d66d250bc78e91636ff5 (diff) | |
| download | emacs-bb8bf9203ed33de0bb269c8ff69067aa7b3a692a.tar.gz emacs-bb8bf9203ed33de0bb269c8ff69067aa7b3a692a.zip | |
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 *, | |||
| 3528 | NativeRectangle *nr); | 3528 | NativeRectangle *nr); |
| 3529 | extern Lisp_Object find_hot_spot (Lisp_Object, int, int); | 3529 | extern Lisp_Object find_hot_spot (Lisp_Object, int, int); |
| 3530 | 3530 | ||
| 3531 | extern int get_tab_bar_item_kbd (struct frame *, int, int, int *, bool *); | ||
| 3531 | extern Lisp_Object handle_tab_bar_click (struct frame *, | 3532 | extern Lisp_Object handle_tab_bar_click (struct frame *, |
| 3532 | int, int, bool, int); | 3533 | int, int, bool, int); |
| 3533 | extern void handle_tool_bar_click (struct frame *, | 3534 | 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) | |||
| 5875 | 5875 | ||
| 5876 | #endif | 5876 | #endif |
| 5877 | 5877 | ||
| 5878 | /* Return whether or not the coordinates X and Y are inside the | ||
| 5879 | tab-bar window of the given frame F. */ | ||
| 5880 | |||
| 5881 | static bool | ||
| 5882 | coords_in_tab_bar_window (struct frame *f, int x, int y) | ||
| 5883 | { | ||
| 5884 | struct window *window; | ||
| 5885 | |||
| 5886 | if (!WINDOWP (f->tab_bar_window)) | ||
| 5887 | return false; | ||
| 5888 | |||
| 5889 | window = XWINDOW (f->tab_bar_window); | ||
| 5890 | |||
| 5891 | return (y >= WINDOW_TOP_EDGE_Y (window) | ||
| 5892 | && x >= WINDOW_LEFT_EDGE_X (window) | ||
| 5893 | && y <= WINDOW_BOTTOM_EDGE_Y (window) | ||
| 5894 | && x <= WINDOW_RIGHT_EDGE_X (window)); | ||
| 5895 | } | ||
| 5896 | |||
| 5878 | /* Given a struct input_event, build the lisp event which represents | 5897 | /* Given a struct input_event, build the lisp event which represents |
| 5879 | it. If EVENT is 0, build a mouse movement event from the mouse | 5898 | it. If EVENT is 0, build a mouse movement event from the mouse |
| 5880 | movement buffer, which should have a movement event in it. | 5899 | movement buffer, which should have a movement event in it. |
| @@ -6522,11 +6541,14 @@ make_lispy_event (struct input_event *event) | |||
| 6522 | case TOUCHSCREEN_END_EVENT: | 6541 | case TOUCHSCREEN_END_EVENT: |
| 6523 | { | 6542 | { |
| 6524 | Lisp_Object x, y, id, position; | 6543 | Lisp_Object x, y, id, position; |
| 6525 | struct frame *f = XFRAME (event->frame_or_window); | 6544 | struct frame *f; |
| 6545 | int tab_bar_item; | ||
| 6546 | bool close; | ||
| 6526 | #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR | 6547 | #if defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR |
| 6527 | int column, row, dummy; | 6548 | int column, row, dummy; |
| 6528 | #endif | 6549 | #endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */ |
| 6529 | 6550 | ||
| 6551 | f = XFRAME (event->frame_or_window); | ||
| 6530 | id = event->arg; | 6552 | id = event->arg; |
| 6531 | x = event->x; | 6553 | x = event->x; |
| 6532 | y = event->y; | 6554 | y = event->y; |
| @@ -6589,10 +6611,53 @@ make_lispy_event (struct input_event *event) | |||
| 6589 | 6611 | ||
| 6590 | return Qnil; | 6612 | return Qnil; |
| 6591 | } | 6613 | } |
| 6592 | #endif | 6614 | #endif /* defined HAVE_WINDOW_SYSTEM && !defined HAVE_EXT_MENU_BAR */ |
| 6593 | 6615 | ||
| 6594 | position = make_lispy_position (f, x, y, event->timestamp); | 6616 | position = make_lispy_position (f, x, y, event->timestamp); |
| 6595 | 6617 | ||
| 6618 | #ifdef HAVE_WINDOW_SYSTEM | ||
| 6619 | |||
| 6620 | /* Now check if POSITION lies on the tab bar. If so, look up | ||
| 6621 | the corresponding tab bar item's propertized string as the | ||
| 6622 | OBJECT. */ | ||
| 6623 | |||
| 6624 | if (coords_in_tab_bar_window (f, XFIXNUM (event->x), | ||
| 6625 | XFIXNUM (event->y)) | ||
| 6626 | /* `get_tab_bar_item_kbd' returns 0 if the item was | ||
| 6627 | previously highlighted, 1 otherwise, and -1 if there is | ||
| 6628 | no tab bar item. */ | ||
| 6629 | && get_tab_bar_item_kbd (f, XFIXNUM (event->x), | ||
| 6630 | XFIXNUM (event->y), &tab_bar_item, | ||
| 6631 | &close) >= 0) | ||
| 6632 | { | ||
| 6633 | /* First, obtain the propertized string. */ | ||
| 6634 | x = Fcopy_sequence (AREF (f->tab_bar_items, | ||
| 6635 | (tab_bar_item | ||
| 6636 | + TAB_BAR_ITEM_CAPTION))); | ||
| 6637 | |||
| 6638 | /* Next, add the key binding. */ | ||
| 6639 | AUTO_LIST2 (y, Qmenu_item, list3 (AREF (f->tab_bar_items, | ||
| 6640 | (tab_bar_item | ||
| 6641 | + TAB_BAR_ITEM_KEY)), | ||
| 6642 | AREF (f->tab_bar_items, | ||
| 6643 | (tab_bar_item | ||
| 6644 | + TAB_BAR_ITEM_BINDING)), | ||
| 6645 | close ? Qt : Qnil)); | ||
| 6646 | |||
| 6647 | /* And add the new properties to the propertized string. */ | ||
| 6648 | Fadd_text_properties (make_fixnum (0), | ||
| 6649 | make_fixnum (SCHARS (x)), | ||
| 6650 | y, x); | ||
| 6651 | |||
| 6652 | /* Set the position to 0. */ | ||
| 6653 | x = Fcons (x, make_fixnum (0)); | ||
| 6654 | |||
| 6655 | /* Finally, add the OBJECT. */ | ||
| 6656 | position = nconc2 (position, Fcons (x, Qnil)); | ||
| 6657 | } | ||
| 6658 | |||
| 6659 | #endif /* HAVE_WINDOW_SYSTEM */ | ||
| 6660 | |||
| 6596 | return list2 (((event->kind | 6661 | return list2 (((event->kind |
| 6597 | == TOUCHSCREEN_BEGIN_EVENT) | 6662 | == TOUCHSCREEN_BEGIN_EVENT) |
| 6598 | ? Qtouchscreen_begin | 6663 | ? 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, | |||
| 14584 | Qmenu_item, f->current_tab_bar_string); | 14584 | Qmenu_item, f->current_tab_bar_string); |
| 14585 | if (! FIXNUMP (prop)) | 14585 | if (! FIXNUMP (prop)) |
| 14586 | return false; | 14586 | return false; |
| 14587 | |||
| 14587 | *prop_idx = XFIXNUM (prop); | 14588 | *prop_idx = XFIXNUM (prop); |
| 14588 | 14589 | ||
| 14589 | *close_p = !NILP (Fget_text_property (make_fixnum (charpos), | 14590 | if (close_p) |
| 14590 | Qclose_tab, | 14591 | *close_p = !NILP (Fget_text_property (make_fixnum (charpos), |
| 14591 | f->current_tab_bar_string)); | 14592 | Qclose_tab, |
| 14593 | f->current_tab_bar_string)); | ||
| 14592 | 14594 | ||
| 14593 | return true; | 14595 | return true; |
| 14594 | } | 14596 | } |
| 14595 | 14597 | ||
| 14596 | 14598 | ||
| 14597 | /* Get information about the tab-bar item at position X/Y on frame F. | 14599 | /* Get information about the tab-bar item at position X/Y on frame F's |
| 14598 | Return in *GLYPH a pointer to the glyph of the tab-bar item in | 14600 | tab bar window. |
| 14599 | the current matrix of the tab-bar window of F, or NULL if not | 14601 | |
| 14600 | on a tab-bar item. Return in *PROP_IDX the index of the tab-bar | 14602 | Set *GLYPH to a pointer to the glyph of the tab-bar item in the |
| 14601 | item in F->tab_bar_items. Value is | 14603 | current matrix of the tab-bar window of F, or NULL if not on a |
| 14604 | tab-bar item. Return in *PROP_IDX the index of the tab-bar item in | ||
| 14605 | F->tab_bar_items. | ||
| 14606 | |||
| 14607 | Place the window-relative vpos of Y in *VPOS, and the | ||
| 14608 | window-relative hpos of X in *HPOS. If CLOSE_P, set it to whether | ||
| 14609 | or not the tab bar item represents a button that should close a | ||
| 14610 | tab. | ||
| 14611 | |||
| 14612 | Value is | ||
| 14602 | 14613 | ||
| 14603 | -1 if X/Y is not on a tab-bar item | 14614 | -1 if X/Y is not on a tab-bar item |
| 14604 | 0 if X/Y is on the same item that was highlighted before. | 14615 | 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, | |||
| 14606 | 14617 | ||
| 14607 | static int | 14618 | static int |
| 14608 | get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph, | 14619 | get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph, |
| 14609 | int *hpos, int *vpos, int *prop_idx, bool *close_p) | 14620 | int *hpos, int *vpos, int *prop_idx, bool *close_p) |
| 14610 | { | 14621 | { |
| 14611 | struct window *w = XWINDOW (f->tab_bar_window); | 14622 | struct window *w = XWINDOW (f->tab_bar_window); |
| 14612 | int area; | 14623 | int area; |
| @@ -14624,6 +14635,38 @@ get_tab_bar_item (struct frame *f, int x, int y, struct glyph **glyph, | |||
| 14624 | return *prop_idx == f->last_tab_bar_item ? 0 : 1; | 14635 | return *prop_idx == f->last_tab_bar_item ? 0 : 1; |
| 14625 | } | 14636 | } |
| 14626 | 14637 | ||
| 14638 | /* EXPORT: | ||
| 14639 | |||
| 14640 | Like `get_tab_bar_item'. However, don't return anything for GLYPH, | ||
| 14641 | HPOS, or VPOS, and treat X and Y as relative to F itself, as | ||
| 14642 | opposed to its tab bar window. */ | ||
| 14643 | |||
| 14644 | int | ||
| 14645 | get_tab_bar_item_kbd (struct frame *f, int x, int y, int *prop_idx, | ||
| 14646 | bool *close_p) | ||
| 14647 | { | ||
| 14648 | struct window *w; | ||
| 14649 | int area, vpos, hpos; | ||
| 14650 | struct glyph *glyph; | ||
| 14651 | |||
| 14652 | w = XWINDOW (f->tab_bar_window); | ||
| 14653 | |||
| 14654 | /* Convert X and Y to window coordinates. */ | ||
| 14655 | frame_to_window_pixel_xy (w, &x, &y); | ||
| 14656 | |||
| 14657 | /* Find the glyph under X/Y. */ | ||
| 14658 | glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, | ||
| 14659 | 0, &area); | ||
| 14660 | if (glyph == NULL) | ||
| 14661 | return -1; | ||
| 14662 | |||
| 14663 | /* Get the start of this tab-bar item's properties in | ||
| 14664 | f->tab_bar_items. */ | ||
| 14665 | if (!tab_bar_item_info (f, glyph, prop_idx, close_p)) | ||
| 14666 | return -1; | ||
| 14667 | |||
| 14668 | return *prop_idx == f->last_tab_bar_item ? 0 : 1; | ||
| 14669 | } | ||
| 14627 | 14670 | ||
| 14628 | /* EXPORT: | 14671 | /* EXPORT: |
| 14629 | Handle mouse button event on the tab-bar of frame F, at | 14672 | Handle mouse button event on the tab-bar of frame F, at |