Mercurial > emacs
comparison src/xmenu.c @ 8166:6fa3cd9b176d
(xmenu_show) [USE_X_TOOLKIT]: Keyboard input exits the menu.
ButtonRelease does so if within Vdouble_click_time.
Ignore mouse motion if button was already released.
(menu_item_selection): Declare volatile, if __STDC__.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Thu, 07 Jul 1994 06:29:09 +0000 |
parents | dda8e966edf5 |
children | c3bc5fca374f |
comparison
equal
deleted
inserted
replaced
8165:02ee07034f11 | 8166:6fa3cd9b176d |
---|---|
1062 } | 1062 } |
1063 } | 1063 } |
1064 return Qnil; | 1064 return Qnil; |
1065 } | 1065 } |
1066 | 1066 |
1067 #ifdef __STDC__ | |
1068 static Lisp_Object *volatile menu_item_selection; | |
1069 #else | |
1067 static Lisp_Object *menu_item_selection; | 1070 static Lisp_Object *menu_item_selection; |
1071 #endif | |
1068 | 1072 |
1069 static void | 1073 static void |
1070 popup_selection_callback (widget, id, client_data) | 1074 popup_selection_callback (widget, id, client_data) |
1071 Widget widget; | 1075 Widget widget; |
1072 LWLIB_ID id; | 1076 LWLIB_ID id; |
1364 TITLE is the specified menu title. | 1368 TITLE is the specified menu title. |
1365 ERROR is a place to store an error message string in case of failure. | 1369 ERROR is a place to store an error message string in case of failure. |
1366 (We return nil on failure, but the value doesn't actually matter.) */ | 1370 (We return nil on failure, but the value doesn't actually matter.) */ |
1367 | 1371 |
1368 #ifdef USE_X_TOOLKIT | 1372 #ifdef USE_X_TOOLKIT |
1373 | |
1374 extern unsigned last_event_timestamp; | |
1375 extern Lisp_Object Vdouble_click_time; | |
1369 | 1376 |
1370 extern unsigned int x_mouse_grabbed; | 1377 extern unsigned int x_mouse_grabbed; |
1371 extern Lisp_Object Vmouse_depressed; | 1378 extern Lisp_Object Vmouse_depressed; |
1372 | 1379 |
1373 static Lisp_Object | 1380 static Lisp_Object |
1609 pop_up_menu (mw, &dummy); | 1616 pop_up_menu (mw, &dummy); |
1610 } | 1617 } |
1611 | 1618 |
1612 /* No need to check a second time since this is done in the XEvent loop. | 1619 /* No need to check a second time since this is done in the XEvent loop. |
1613 This slows done the execution. */ | 1620 This slows done the execution. */ |
1614 #if 0 | 1621 #ifdef XMENU_FOO |
1615 /* Check again whether the mouse has moved to another menu bar item. */ | 1622 /* Check again whether the mouse has moved to another menu bar item. */ |
1616 if (check_mouse_other_menu_bar (f)) | 1623 if (check_mouse_other_menu_bar (f)) |
1617 { | 1624 { |
1618 /* The mouse moved into a different menu bar item. | 1625 /* The mouse moved into a different menu bar item. |
1619 We should bring up that item's menu instead. | 1626 We should bring up that item's menu instead. |
1629 | 1636 |
1630 /* Process events that apply to the menu. */ | 1637 /* Process events that apply to the menu. */ |
1631 while (1) | 1638 while (1) |
1632 { | 1639 { |
1633 XEvent event; | 1640 XEvent event; |
1641 int queue_and_exit = 0; | |
1634 | 1642 |
1635 XtAppNextEvent (Xt_app_con, &event); | 1643 XtAppNextEvent (Xt_app_con, &event); |
1636 if (event.type == ButtonRelease) | 1644 if (event.type == ButtonRelease) |
1637 { | 1645 { |
1638 XtDispatchEvent (&event); | 1646 XtDispatchEvent (&event); |
1644 has been set to grabbed. Reset it now. */ | 1652 has been set to grabbed. Reset it now. */ |
1645 x_mouse_grabbed &= ~(1 << event.xbutton.button); | 1653 x_mouse_grabbed &= ~(1 << event.xbutton.button); |
1646 if (!x_mouse_grabbed) | 1654 if (!x_mouse_grabbed) |
1647 Vmouse_depressed = Qnil; | 1655 Vmouse_depressed = Qnil; |
1648 } | 1656 } |
1649 break; | 1657 if (! (menu_item_selection == 0 |
1658 && (((XButtonEvent *) (&event))->time - last_event_timestamp | |
1659 < XINT (Vdouble_click_time)))) | |
1660 break; | |
1661 } | |
1662 else if (event.type == ButtonPress) | |
1663 { | |
1664 /* Any mouse button activity that doesn't select in the menu | |
1665 should unpost the menu. */ | |
1666 if (menu_item_selection == 0) | |
1667 break; | |
1668 } | |
1669 else if (event.type == KeyPress) | |
1670 { | |
1671 /* Exit the loop, but first queue this event for reuse. */ | |
1672 queue_and_exit = 1; | |
1650 } | 1673 } |
1651 else if (event.type == Expose) | 1674 else if (event.type == Expose) |
1652 process_expose_from_menu (event); | 1675 process_expose_from_menu (event); |
1653 else if (event.type == MotionNotify) | 1676 /* If the mouse moves to a different menu bar item, switch to |
1677 that item's menu. But only if the button is still held down. */ | |
1678 else if (event.type == MotionNotify | |
1679 && x_mouse_grabbed) | |
1654 { | 1680 { |
1655 int event_x = (event.xmotion.x_root | 1681 int event_x = (event.xmotion.x_root |
1656 - (f->display.x->widget->core.x | 1682 - (f->display.x->widget->core.x |
1657 + f->display.x->widget->core.border_width)); | 1683 + f->display.x->widget->core.border_width)); |
1658 int event_y = (event.xmotion.y_root | 1684 int event_y = (event.xmotion.y_root |
1677 break; | 1703 break; |
1678 } | 1704 } |
1679 } | 1705 } |
1680 | 1706 |
1681 XtDispatchEvent (&event); | 1707 XtDispatchEvent (&event); |
1682 if (XtWindowToWidget(XDISPLAY event.xany.window) != menu) | 1708 if (queue_and_exit |
1709 || XtWindowToWidget (XDISPLAY event.xany.window) != menu) | |
1683 { | 1710 { |
1684 queue_tmp | 1711 queue_tmp |
1685 = (struct event_queue *) malloc (sizeof (struct event_queue)); | 1712 = (struct event_queue *) malloc (sizeof (struct event_queue)); |
1686 | 1713 |
1687 if (queue_tmp != NULL) | 1714 if (queue_tmp != NULL) |
1689 queue_tmp->event = event; | 1716 queue_tmp->event = event; |
1690 queue_tmp->next = queue; | 1717 queue_tmp->next = queue; |
1691 queue = queue_tmp; | 1718 queue = queue_tmp; |
1692 } | 1719 } |
1693 } | 1720 } |
1721 if (queue_and_exit) | |
1722 break; | |
1694 } | 1723 } |
1695 | 1724 |
1696 pop_down: | 1725 pop_down: |
1697 /* Unhighlight the menu bar item (if any) that led to this menu. */ | 1726 /* Unhighlight the menu bar item (if any) that led to this menu. */ |
1698 if (menubarp) | 1727 if (menubarp) |