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 | |
| 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.
| -rw-r--r-- | lisp/menu-bar.el | 15 | ||||
| -rw-r--r-- | lisp/tab-bar.el | 83 | ||||
| -rw-r--r-- | lisp/touch-screen.el | 2 | ||||
| -rw-r--r-- | src/dispextern.h | 1 | ||||
| -rw-r--r-- | src/keyboard.c | 71 | ||||
| -rw-r--r-- | src/xdisp.c | 61 |
6 files changed, 211 insertions, 22 deletions
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 949d805465d..da002a46621 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el | |||
| @@ -2669,20 +2669,25 @@ FROM-MENU-BAR, if non-nil, means we are dropping one of menu-bar's menus." | |||
| 2669 | POSITION can be an event, a posn- value, a value having the | 2669 | POSITION can be an event, a posn- value, a value having the |
| 2670 | form ((XOFFSET YOFFSET) WINDOW), or nil. | 2670 | form ((XOFFSET YOFFSET) WINDOW), or nil. |
| 2671 | If nil, the current mouse position is used, or nil if there is no mouse." | 2671 | If nil, the current mouse position is used, or nil if there is no mouse." |
| 2672 | (pcase position | 2672 | (cond |
| 2673 | ;; nil -> mouse cursor position | 2673 | ;; nil -> mouse cursor position |
| 2674 | ('nil | 2674 | ((eq position nil) |
| 2675 | (let ((mp (mouse-pixel-position))) | 2675 | (let ((mp (mouse-pixel-position))) |
| 2676 | (list (list (cadr mp) (cddr mp)) (car mp)))) | 2676 | (list (list (cadr mp) (cddr mp)) (car mp)))) |
| 2677 | ;; Value returned from `event-end' or `posn-at-point'. | 2677 | ;; Value returned from `event-end' or `posn-at-point'. |
| 2678 | ((pred posnp) | 2678 | ((posnp position) |
| 2679 | (let ((xy (posn-x-y position))) | 2679 | (let ((xy (posn-x-y position))) |
| 2680 | (list (list (car xy) (cdr xy)) | 2680 | (list (list (car xy) (cdr xy)) |
| 2681 | (posn-window position)))) | 2681 | (posn-window position)))) |
| 2682 | ;; `touchscreen-begin' or `touchscreen-end' event. | ||
| 2683 | ((or (eq (car-safe position) 'touchscreen-begin) | ||
| 2684 | (eq (car-safe position) 'touchscreen-end)) | ||
| 2685 | position) | ||
| 2682 | ;; Event. | 2686 | ;; Event. |
| 2683 | ((pred eventp) | 2687 | ((eventp position) |
| 2684 | (popup-menu-normalize-position (event-end position))) | 2688 | (popup-menu-normalize-position (event-end position))) |
| 2685 | (_ position))) | 2689 | ;; Some other value. |
| 2690 | (t position))) | ||
| 2686 | 2691 | ||
| 2687 | (defcustom tty-menu-open-use-tmm nil | 2692 | (defcustom tty-menu-open-use-tmm nil |
| 2688 | "If non-nil, \\[menu-bar-open] on a TTY will invoke `tmm-menubar'. | 2693 | "If non-nil, \\[menu-bar-open] on a TTY will invoke `tmm-menubar'. |
diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 9d703b5d048..1a33eda0866 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el | |||
| @@ -341,10 +341,12 @@ only when you click on its \"x\" close button." | |||
| 341 | (unless (eq tab-number t) | 341 | (unless (eq tab-number t) |
| 342 | (tab-bar-close-tab tab-number)))) | 342 | (tab-bar-close-tab tab-number)))) |
| 343 | 343 | ||
| 344 | (defun tab-bar-mouse-context-menu (event) | 344 | (defun tab-bar-mouse-context-menu (event &optional posn) |
| 345 | "Pop up the context menu for the tab on which you click." | 345 | "Pop up the context menu for the tab on which you click. |
| 346 | EVENT is a mouse or touch screen event. POSN is nil or the | ||
| 347 | position of EVENT." | ||
| 346 | (interactive "e") | 348 | (interactive "e") |
| 347 | (let* ((item (tab-bar--event-to-item (event-start event))) | 349 | (let* ((item (tab-bar--event-to-item (or posn (event-start event)))) |
| 348 | (tab-number (tab-bar--key-to-number (nth 0 item))) | 350 | (tab-number (tab-bar--key-to-number (nth 0 item))) |
| 349 | (menu (make-sparse-keymap (propertize "Context Menu" 'hide t)))) | 351 | (menu (make-sparse-keymap (propertize "Context Menu" 'hide t)))) |
| 350 | 352 | ||
| @@ -397,6 +399,78 @@ at the mouse-down event to the position at mouse-up event." | |||
| 397 | (tab-bar-move-tab-to | 399 | (tab-bar-move-tab-to |
| 398 | (if (null to) (1+ (tab-bar--current-tab-index)) to) from)))) | 400 | (if (null to) (1+ (tab-bar--current-tab-index)) to) from)))) |
| 399 | 401 | ||
| 402 | |||
| 403 | |||
| 404 | ;;; Tab bar touchscreen support. | ||
| 405 | |||
| 406 | (declare-function touch-screen-track-tap "touch-screen.el") | ||
| 407 | |||
| 408 | (defun tab-bar-handle-timeout () | ||
| 409 | "Handle a touch-screen timeout on the tab bar. | ||
| 410 | Beep, then throw to `context-menu' and return." | ||
| 411 | (beep) | ||
| 412 | (throw 'context-menu 'context-menu)) | ||
| 413 | |||
| 414 | (defun tab-bar-touchscreen-begin (event) | ||
| 415 | "Handle a touchscreen begin EVENT on the tab bar. | ||
| 416 | |||
| 417 | Determine where the touch was made. If it was made on a tab | ||
| 418 | itself, start a timer set to go off after a certain amount of | ||
| 419 | time, and wait for the touch point to be released, and either | ||
| 420 | display a context menu or select a tab as appropriate. | ||
| 421 | |||
| 422 | Otherwise, if it was made on a button, close or create a tab as | ||
| 423 | appropriate." | ||
| 424 | (interactive "e") | ||
| 425 | (let* ((posn (cdadr event)) | ||
| 426 | (item (tab-bar--event-to-item posn)) | ||
| 427 | (number (tab-bar--key-to-number (car item))) | ||
| 428 | timer) | ||
| 429 | (when (eq (catch 'context-menu | ||
| 430 | (cond ((integerp number) | ||
| 431 | ;; The touch began on a tab. Start a context | ||
| 432 | ;; menu timer and start tracking the tap. | ||
| 433 | (unwind-protect | ||
| 434 | (progn | ||
| 435 | (setq timer (run-at-time touch-screen-delay nil | ||
| 436 | #'tab-bar-handle-timeout)) | ||
| 437 | ;; Now wait for the tap to complete. | ||
| 438 | (when (touch-screen-track-tap event) | ||
| 439 | ;; And select the tab, or close it, | ||
| 440 | ;; depending on whether or not the | ||
| 441 | ;; close button was pressed. | ||
| 442 | (if (caddr item) | ||
| 443 | (tab-bar-close-tab number) | ||
| 444 | (tab-bar-select-tab number)))) | ||
| 445 | ;; Cancel the timer. | ||
| 446 | (cancel-timer timer))) | ||
| 447 | ((and (memq (car item) '(add-tab history-back | ||
| 448 | history-forward)) | ||
| 449 | (functionp (cadr item))) | ||
| 450 | ;; This is some kind of button. Wait for the | ||
| 451 | ;; tap to complete and press it. | ||
| 452 | (when (touch-screen-track-tap event) | ||
| 453 | (call-interactively (cadr item)))) | ||
| 454 | (t | ||
| 455 | ;; The touch began on the tab bar itself. | ||
| 456 | ;; Start a context menu timer and start | ||
| 457 | ;; tracking the tap, but don't do anything | ||
| 458 | ;; afterwards. | ||
| 459 | (unwind-protect | ||
| 460 | (progn | ||
| 461 | (setq timer (run-at-time touch-screen-delay nil | ||
| 462 | #'tab-bar-handle-timeout)) | ||
| 463 | ;; Now wait for the tap to complete. | ||
| 464 | (touch-screen-track-tap event)) | ||
| 465 | ;; Cancel the timer. | ||
| 466 | (cancel-timer timer))))) | ||
| 467 | 'context-menu) | ||
| 468 | ;; Display the context menu in response to a time out waiting | ||
| 469 | ;; for the tap to complete. | ||
| 470 | (tab-bar-mouse-context-menu event posn)))) | ||
| 471 | |||
| 472 | |||
| 473 | |||
| 400 | (defvar-keymap tab-bar-map | 474 | (defvar-keymap tab-bar-map |
| 401 | :doc "Keymap for the commands used on the tab bar." | 475 | :doc "Keymap for the commands used on the tab bar." |
| 402 | "<down-mouse-1>" #'tab-bar-mouse-down-1 | 476 | "<down-mouse-1>" #'tab-bar-mouse-down-1 |
| @@ -418,7 +492,8 @@ at the mouse-down event to the position at mouse-up event." | |||
| 418 | "S-<wheel-up>" #'tab-bar-move-tab-backward | 492 | "S-<wheel-up>" #'tab-bar-move-tab-backward |
| 419 | "S-<wheel-down>" #'tab-bar-move-tab | 493 | "S-<wheel-down>" #'tab-bar-move-tab |
| 420 | "S-<wheel-left>" #'tab-bar-move-tab-backward | 494 | "S-<wheel-left>" #'tab-bar-move-tab-backward |
| 421 | "S-<wheel-right>" #'tab-bar-move-tab) | 495 | "S-<wheel-right>" #'tab-bar-move-tab |
| 496 | "<touchscreen-begin>" #'tab-bar-touchscreen-begin) | ||
| 422 | 497 | ||
| 423 | (global-set-key [tab-bar] | 498 | (global-set-key [tab-bar] |
| 424 | `(menu-item ,(purecopy "tab bar") ,(make-sparse-keymap) | 499 | `(menu-item ,(purecopy "tab bar") ,(make-sparse-keymap) |
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el index 31d46b062ed..a7fa5b4829c 100644 --- a/lisp/touch-screen.el +++ b/lisp/touch-screen.el | |||
| @@ -529,7 +529,7 @@ otherwise, return t once the `touchscreen-end' event arrives." | |||
| 529 | 529 | ||
| 530 | (defun touch-screen-track-drag (event update &optional data) | 530 | (defun touch-screen-track-drag (event update &optional data) |
| 531 | "Track a single drag starting from EVENT. | 531 | "Track a single drag starting from EVENT. |
| 532 | EVENT should be a `touchscreen-end' event. | 532 | EVENT should be a `touchscreen-begin' event. |
| 533 | 533 | ||
| 534 | Read touch screen events until a `touchscreen-end' event is | 534 | Read touch screen events until a `touchscreen-end' event is |
| 535 | received with the same ID as in EVENT. For each | 535 | received with the same ID as in EVENT. For each |
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 |