diff options
| author | Jan Djärv | 2004-01-12 01:45:22 +0000 |
|---|---|---|
| committer | Jan Djärv | 2004-01-12 01:45:22 +0000 |
| commit | 244c93fe5767497dd45bb3d3ad22a9c72ccc2d5b (patch) | |
| tree | d383c54483d68845ca5ce18f92491bc097d78a94 | |
| parent | 0fbe422d1c18358c87d481898d25bad7e2bd02da (diff) | |
| download | emacs-244c93fe5767497dd45bb3d3ad22a9c72ccc2d5b.tar.gz emacs-244c93fe5767497dd45bb3d3ad22a9c72ccc2d5b.zip | |
Changes for lucid popup menus (keyboard traversal enabled) and dialogs
(Xaw and Xm pop down on ESC).
| -rw-r--r-- | lwlib/ChangeLog | 28 | ||||
| -rw-r--r-- | lwlib/lwlib-Xaw.c | 17 | ||||
| -rw-r--r-- | lwlib/lwlib-Xlw.c | 31 | ||||
| -rw-r--r-- | lwlib/lwlib-Xm.c | 33 | ||||
| -rw-r--r-- | lwlib/xlwmenu.c | 109 | ||||
| -rw-r--r-- | lwlib/xlwmenu.h | 3 | ||||
| -rw-r--r-- | lwlib/xlwmenuP.h | 1 |
7 files changed, 171 insertions, 51 deletions
diff --git a/lwlib/ChangeLog b/lwlib/ChangeLog index f41b323c04c..3b69d955392 100644 --- a/lwlib/ChangeLog +++ b/lwlib/ChangeLog | |||
| @@ -1,3 +1,31 @@ | |||
| 1 | 2004-01-12 Jan Dj,Ad(Brv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * xlwmenuP.h (_XlwMenu_part): Added top_depth. | ||
| 4 | |||
| 5 | * xlwmenu.h: Removed declaration of pop_up_menu | ||
| 6 | |||
| 7 | * xlwmenu.c (Start): Get correct time if time in event is CurrentTime. | ||
| 8 | (find_first_selectable, find_next_selectable) | ||
| 9 | (find_prev_selectable): Add parameter skip_no_call_data to skip | ||
| 10 | over items with no call data (popup menu titles). | ||
| 11 | (Down, Up): Compare old_depth to top_depth instead of 2. | ||
| 12 | Pass True to find_*_selectable:s new parameter if this is a popup menu. | ||
| 13 | (Left, Right): Compare old_depth to top_depth instead of 2. | ||
| 14 | Pass 0 to find_*_selectable:s new parameter. | ||
| 15 | (pop_up_menu): Set top_depth to 1 for pop up menus and 2 for | ||
| 16 | menu bar menus, to enable keyboard traversal of popups. | ||
| 17 | |||
| 18 | * lwlib-Xm.c (dialog_key_cb): New function. | ||
| 19 | (make_dialog): Add event handlers to dialog_key_cb for key press | ||
| 20 | so we can pop down on ESC. | ||
| 21 | |||
| 22 | * lwlib-Xlw.c (xlw_popup_menu): Replace call to pop_up_menu with | ||
| 23 | XtCallActionProc ("start"). Use a full XEvent since "start" copies it. | ||
| 24 | |||
| 25 | * lwlib-Xaw.c (make_dialog): Add override so dialog pops down | ||
| 26 | on ESC. | ||
| 27 | (wm_delete_window): If widget isn't a shell, use the parent. | ||
| 28 | |||
| 1 | 2003-05-22 Dave Love <fx@gnu.org> | 29 | 2003-05-22 Dave Love <fx@gnu.org> |
| 2 | 30 | ||
| 3 | * xlwmenu.c: Include lisp.h, not ../src/lisp.h. | 31 | * xlwmenu.c: Include lisp.h, not ../src/lisp.h. |
diff --git a/lwlib/lwlib-Xaw.c b/lwlib/lwlib-Xaw.c index 7f37596457f..867193c7cc8 100644 --- a/lwlib/lwlib-Xaw.c +++ b/lwlib/lwlib-Xaw.c | |||
| @@ -277,6 +277,9 @@ xaw_pop_instance (instance, up) | |||
| 277 | 277 | ||
| 278 | static char overrideTrans[] = | 278 | static char overrideTrans[] = |
| 279 | "<Message>WM_PROTOCOLS: lwlib_delete_dialog()"; | 279 | "<Message>WM_PROTOCOLS: lwlib_delete_dialog()"; |
| 280 | /* Dialogs pop down on any key press */ | ||
| 281 | static char dialogOverride[] = | ||
| 282 | "<KeyPress>: lwlib_delete_dialog()"; | ||
| 280 | static void wm_delete_window(); | 283 | static void wm_delete_window(); |
| 281 | static XtActionsRec xaw_actions [] = { | 284 | static XtActionsRec xaw_actions [] = { |
| 282 | {"lwlib_delete_dialog", wm_delete_window} | 285 | {"lwlib_delete_dialog", wm_delete_window} |
| @@ -333,6 +336,8 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, ra | |||
| 333 | 336 | ||
| 334 | ac = 0; | 337 | ac = 0; |
| 335 | dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac); | 338 | dialog = XtCreateManagedWidget (name, dialogWidgetClass, shell, av, ac); |
| 339 | override = XtParseTranslationTable (dialogOverride); | ||
| 340 | XtOverrideTranslations (dialog, override); | ||
| 336 | 341 | ||
| 337 | bc = 0; | 342 | bc = 0; |
| 338 | button = 0; | 343 | button = 0; |
| @@ -511,8 +516,8 @@ xaw_generic_callback (widget, closure, call_data) | |||
| 511 | } | 516 | } |
| 512 | 517 | ||
| 513 | static void | 518 | static void |
| 514 | wm_delete_window (shell, closure, call_data) | 519 | wm_delete_window (w, closure, call_data) |
| 515 | Widget shell; | 520 | Widget w; |
| 516 | XtPointer closure; | 521 | XtPointer closure; |
| 517 | XtPointer call_data; | 522 | XtPointer call_data; |
| 518 | { | 523 | { |
| @@ -520,7 +525,13 @@ wm_delete_window (shell, closure, call_data) | |||
| 520 | Cardinal nkids; | 525 | Cardinal nkids; |
| 521 | int i; | 526 | int i; |
| 522 | Widget *kids = 0; | 527 | Widget *kids = 0; |
| 523 | Widget widget; | 528 | Widget widget, shell; |
| 529 | |||
| 530 | if (XtIsSubclass (w, dialogWidgetClass)) | ||
| 531 | shell = XtParent (w); | ||
| 532 | else | ||
| 533 | shell = w; | ||
| 534 | |||
| 524 | if (! XtIsSubclass (shell, shellWidgetClass)) | 535 | if (! XtIsSubclass (shell, shellWidgetClass)) |
| 525 | abort (); | 536 | abort (); |
| 526 | XtVaGetValues (shell, XtNnumChildren, &nkids, NULL); | 537 | XtVaGetValues (shell, XtNnumChildren, &nkids, NULL); |
diff --git a/lwlib/lwlib-Xlw.c b/lwlib/lwlib-Xlw.c index d0800e0ca0e..248e4e8be74 100644 --- a/lwlib/lwlib-Xlw.c +++ b/lwlib/lwlib-Xlw.c | |||
| @@ -180,6 +180,7 @@ xlw_create_popup_menu (instance) | |||
| 180 | XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance); | 180 | XtAddCallback (widget, XtNselect, pick_hook, (XtPointer)instance); |
| 181 | XtAddCallback (widget, XtNhighlightCallback, highlight_hook, | 181 | XtAddCallback (widget, XtNhighlightCallback, highlight_hook, |
| 182 | (XtPointer)instance); | 182 | (XtPointer)instance); |
| 183 | |||
| 183 | return popup_shell; | 184 | return popup_shell; |
| 184 | } | 185 | } |
| 185 | 186 | ||
| @@ -251,7 +252,6 @@ xlw_popup_menu (widget, event) | |||
| 251 | Widget widget; | 252 | Widget widget; |
| 252 | XEvent *event; | 253 | XEvent *event; |
| 253 | { | 254 | { |
| 254 | XButtonPressedEvent dummy; | ||
| 255 | XlwMenuWidget mw; | 255 | XlwMenuWidget mw; |
| 256 | 256 | ||
| 257 | if (!XtIsShell (widget)) | 257 | if (!XtIsShell (widget)) |
| @@ -260,21 +260,24 @@ xlw_popup_menu (widget, event) | |||
| 260 | mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0]; | 260 | mw = (XlwMenuWidget)((CompositeWidget)widget)->composite.children [0]; |
| 261 | 261 | ||
| 262 | if (event) | 262 | if (event) |
| 263 | pop_up_menu (mw, (XButtonPressedEvent*) event); | 263 | XtCallActionProc ((Widget) mw, "start", event, NULL, 0); |
| 264 | else | 264 | else |
| 265 | { | 265 | { |
| 266 | dummy.type = ButtonPress; | 266 | XEvent dummy; |
| 267 | dummy.serial = 0; | 267 | XButtonPressedEvent *bd = &dummy.xbutton; |
| 268 | dummy.send_event = 0; | 268 | |
| 269 | dummy.display = XtDisplay (widget); | 269 | bd->type = ButtonPress; |
| 270 | dummy.window = XtWindow (XtParent (widget)); | 270 | bd->serial = 0; |
| 271 | dummy.time = CurrentTime; | 271 | bd->send_event = 0; |
| 272 | dummy.button = 0; | 272 | bd->display = XtDisplay (widget); |
| 273 | XQueryPointer (dummy.display, dummy.window, &dummy.root, | 273 | bd->window = XtWindow (XtParent (widget)); |
| 274 | &dummy.subwindow, &dummy.x_root, &dummy.y_root, | 274 | bd->time = CurrentTime; |
| 275 | &dummy.x, &dummy.y, &dummy.state); | 275 | bd->button = 0; |
| 276 | 276 | XQueryPointer (bd->display, bd->window, &bd->root, | |
| 277 | pop_up_menu (mw, &dummy); | 277 | &bd->subwindow, &bd->x_root, &bd->y_root, |
| 278 | &bd->x, &bd->y, &bd->state); | ||
| 279 | |||
| 280 | XtCallActionProc ((Widget) mw, "start", &dummy, NULL, 0); | ||
| 278 | } | 281 | } |
| 279 | } | 282 | } |
| 280 | 283 | ||
diff --git a/lwlib/lwlib-Xm.c b/lwlib/lwlib-Xm.c index f63d13c85ee..e57fa57f939 100644 --- a/lwlib/lwlib-Xm.c +++ b/lwlib/lwlib-Xm.c | |||
| @@ -1035,6 +1035,33 @@ activate_button (widget, closure, call_data) | |||
| 1035 | 1035 | ||
| 1036 | /* creation functions */ | 1036 | /* creation functions */ |
| 1037 | 1037 | ||
| 1038 | /* Called for key press in dialogs. Used to pop down dialog on ESC. */ | ||
| 1039 | static void | ||
| 1040 | dialog_key_cb (widget, closure, event, continue_to_dispatch) | ||
| 1041 | Widget widget; | ||
| 1042 | XtPointer closure; | ||
| 1043 | XEvent *event; | ||
| 1044 | Boolean *continue_to_dispatch; | ||
| 1045 | { | ||
| 1046 | KeySym sym = 0; | ||
| 1047 | Modifiers modif_ret; | ||
| 1048 | |||
| 1049 | XtTranslateKeycode (event->xkey.display, event->xkey.keycode, 0, | ||
| 1050 | &modif_ret, &sym); | ||
| 1051 | |||
| 1052 | if (sym == osfXK_Cancel) | ||
| 1053 | { | ||
| 1054 | Widget w = *((Widget *) closure); | ||
| 1055 | |||
| 1056 | while (w && ! XtIsShell (w)) | ||
| 1057 | w = XtParent (w); | ||
| 1058 | |||
| 1059 | if (XtIsShell (w)) XtPopdown (w); | ||
| 1060 | } | ||
| 1061 | |||
| 1062 | *continue_to_dispatch = TRUE; | ||
| 1063 | } | ||
| 1064 | |||
| 1038 | /* dialogs */ | 1065 | /* dialogs */ |
| 1039 | static Widget | 1066 | static Widget |
| 1040 | make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, | 1067 | make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, |
| @@ -1123,6 +1150,8 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, | |||
| 1123 | XtSetArg(al[ac], XmNmarginWidth, 10); ac++; | 1150 | XtSetArg(al[ac], XmNmarginWidth, 10); ac++; |
| 1124 | XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; | 1151 | XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; |
| 1125 | children [n_children] = XmCreatePushButton (row, button_name, al, ac); | 1152 | children [n_children] = XmCreatePushButton (row, button_name, al, ac); |
| 1153 | XtAddEventHandler (children [n_children], | ||
| 1154 | KeyPressMask, False, dialog_key_cb, result); | ||
| 1126 | 1155 | ||
| 1127 | if (i == 0) | 1156 | if (i == 0) |
| 1128 | { | 1157 | { |
| @@ -1149,6 +1178,9 @@ make_dialog (name, parent, pop_up_p, shell_title, icon_name, text_input_slot, | |||
| 1149 | XtSetArg(al[ac], XmNmarginWidth, 10); ac++; | 1178 | XtSetArg(al[ac], XmNmarginWidth, 10); ac++; |
| 1150 | XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; | 1179 | XtSetArg(al[ac], XmNnavigationType, XmTAB_GROUP); ac++; |
| 1151 | children [n_children] = XmCreatePushButton (row, button_name, al, ac); | 1180 | children [n_children] = XmCreatePushButton (row, button_name, al, ac); |
| 1181 | XtAddEventHandler (children [n_children], | ||
| 1182 | KeyPressMask, False, dialog_key_cb, result); | ||
| 1183 | |||
| 1152 | if (! button) button = children [n_children]; | 1184 | if (! button) button = children [n_children]; |
| 1153 | n_children++; | 1185 | n_children++; |
| 1154 | } | 1186 | } |
| @@ -1491,6 +1523,7 @@ xm_create_dialog (instance) | |||
| 1491 | 1523 | ||
| 1492 | XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback, | 1524 | XtAddCallback (widget, XmNpopdownCallback, xm_nosel_callback, |
| 1493 | (XtPointer) instance); | 1525 | (XtPointer) instance); |
| 1526 | |||
| 1494 | return widget; | 1527 | return widget; |
| 1495 | } | 1528 | } |
| 1496 | 1529 | ||
diff --git a/lwlib/xlwmenu.c b/lwlib/xlwmenu.c index 917181226c7..973fc6ec5d5 100644 --- a/lwlib/xlwmenu.c +++ b/lwlib/xlwmenu.c | |||
| @@ -197,6 +197,8 @@ static void Select(); | |||
| 197 | static void Key(); | 197 | static void Key(); |
| 198 | static void Nothing(); | 198 | static void Nothing(); |
| 199 | static int separator_height __P ((enum menu_separator)); | 199 | static int separator_height __P ((enum menu_separator)); |
| 200 | static void pop_up_menu __P ((XlwMenuWidget, XButtonPressedEvent *)); | ||
| 201 | |||
| 200 | 202 | ||
| 201 | static XtActionsRec | 203 | static XtActionsRec |
| 202 | xlwMenuActionsList [] = | 204 | xlwMenuActionsList [] = |
| @@ -2004,6 +2006,13 @@ Start (w, ev, params, num_params) | |||
| 2004 | if (!mw->menu.popped_up) | 2006 | if (!mw->menu.popped_up) |
| 2005 | { | 2007 | { |
| 2006 | menu_post_event = *ev; | 2008 | menu_post_event = *ev; |
| 2009 | /* If event is set to CurrentTime, get the last known time stamp. | ||
| 2010 | This is for calculating if (popup) menus should stay up after | ||
| 2011 | a fast click. */ | ||
| 2012 | if (menu_post_event.xbutton.time == CurrentTime) | ||
| 2013 | menu_post_event.xbutton.time | ||
| 2014 | = XtLastTimestampProcessed (XtDisplay (w)); | ||
| 2015 | |||
| 2007 | pop_up_menu (mw, (XButtonPressedEvent*) ev); | 2016 | pop_up_menu (mw, (XButtonPressedEvent*) ev); |
| 2008 | } | 2017 | } |
| 2009 | else | 2018 | else |
| @@ -2044,15 +2053,17 @@ Nothing (w, ev, params, num_params) | |||
| 2044 | { | 2053 | { |
| 2045 | } | 2054 | } |
| 2046 | 2055 | ||
| 2047 | widget_value * | 2056 | static widget_value * |
| 2048 | find_first_selectable (mw, item) | 2057 | find_first_selectable (mw, item, skip_no_call_data) |
| 2049 | XlwMenuWidget mw; | 2058 | XlwMenuWidget mw; |
| 2050 | widget_value *item; | 2059 | widget_value *item; |
| 2060 | int skip_no_call_data; | ||
| 2051 | { | 2061 | { |
| 2052 | widget_value *current = item; | 2062 | widget_value *current = item; |
| 2053 | enum menu_separator separator; | 2063 | enum menu_separator separator; |
| 2054 | 2064 | ||
| 2055 | while (lw_separator_p (current->name, &separator, 0) || !current->enabled) | 2065 | while (lw_separator_p (current->name, &separator, 0) || !current->enabled |
| 2066 | || (skip_no_call_data && !current->call_data)) | ||
| 2056 | if (current->next) | 2067 | if (current->next) |
| 2057 | current=current->next; | 2068 | current=current->next; |
| 2058 | else | 2069 | else |
| @@ -2061,8 +2072,8 @@ find_first_selectable (mw, item) | |||
| 2061 | return current; | 2072 | return current; |
| 2062 | } | 2073 | } |
| 2063 | 2074 | ||
| 2064 | widget_value * | 2075 | static widget_value * |
| 2065 | find_next_selectable (mw, item) | 2076 | find_next_selectable (mw, item, skip_no_call_data) |
| 2066 | XlwMenuWidget mw; | 2077 | XlwMenuWidget mw; |
| 2067 | widget_value *item; | 2078 | widget_value *item; |
| 2068 | { | 2079 | { |
| @@ -2070,7 +2081,8 @@ find_next_selectable (mw, item) | |||
| 2070 | enum menu_separator separator; | 2081 | enum menu_separator separator; |
| 2071 | 2082 | ||
| 2072 | while (current->next && (current=current->next) && | 2083 | while (current->next && (current=current->next) && |
| 2073 | (lw_separator_p (current->name, &separator, 0) || !current->enabled)) | 2084 | (lw_separator_p (current->name, &separator, 0) || !current->enabled |
| 2085 | || (skip_no_call_data && !current->call_data))) | ||
| 2074 | ; | 2086 | ; |
| 2075 | 2087 | ||
| 2076 | if (current == item) | 2088 | if (current == item) |
| @@ -2079,7 +2091,9 @@ find_next_selectable (mw, item) | |||
| 2079 | return current; | 2091 | return current; |
| 2080 | current = mw->menu.old_stack [mw->menu.old_depth - 2]->contents; | 2092 | current = mw->menu.old_stack [mw->menu.old_depth - 2]->contents; |
| 2081 | 2093 | ||
| 2082 | while (lw_separator_p (current->name, &separator, 0) || !current->enabled) | 2094 | while (lw_separator_p (current->name, &separator, 0) |
| 2095 | || !current->enabled | ||
| 2096 | || (skip_no_call_data && !current->call_data)) | ||
| 2083 | { | 2097 | { |
| 2084 | if (current->next) | 2098 | if (current->next) |
| 2085 | current=current->next; | 2099 | current=current->next; |
| @@ -2093,15 +2107,16 @@ find_next_selectable (mw, item) | |||
| 2093 | return current; | 2107 | return current; |
| 2094 | } | 2108 | } |
| 2095 | 2109 | ||
| 2096 | widget_value * | 2110 | static widget_value * |
| 2097 | find_prev_selectable (mw, item) | 2111 | find_prev_selectable (mw, item, skip_no_call_data) |
| 2098 | XlwMenuWidget mw; | 2112 | XlwMenuWidget mw; |
| 2099 | widget_value *item; | 2113 | widget_value *item; |
| 2100 | { | 2114 | { |
| 2101 | widget_value *current = item; | 2115 | widget_value *current = item; |
| 2102 | widget_value *prev = item; | 2116 | widget_value *prev = item; |
| 2103 | 2117 | ||
| 2104 | while ((current=find_next_selectable (mw, current)) != item) | 2118 | while ((current=find_next_selectable (mw, current, skip_no_call_data)) |
| 2119 | != item) | ||
| 2105 | { | 2120 | { |
| 2106 | if (prev == current) | 2121 | if (prev == current) |
| 2107 | break; | 2122 | break; |
| @@ -2120,15 +2135,23 @@ Down (w, ev, params, num_params) | |||
| 2120 | { | 2135 | { |
| 2121 | XlwMenuWidget mw = (XlwMenuWidget) w; | 2136 | XlwMenuWidget mw = (XlwMenuWidget) w; |
| 2122 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2137 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2138 | int popup_menu_p = mw->menu.top_depth == 1; | ||
| 2123 | 2139 | ||
| 2124 | /* Inside top-level menu-bar? */ | 2140 | /* Inside top-level menu-bar? */ |
| 2125 | if (mw->menu.old_depth == 2) | 2141 | if (mw->menu.old_depth == mw->menu.top_depth) |
| 2126 | /* When <down> in the menu-bar is pressed, display the corresponding | 2142 | /* When <down> in the menu-bar is pressed, display the corresponding |
| 2127 | sub-menu and select the first selectable menu item there. */ | 2143 | sub-menu and select the first selectable menu item there. |
| 2128 | set_new_state (mw, find_first_selectable (mw, selected_item->contents), mw->menu.old_depth); | 2144 | If this is a popup menu, skip items with zero call data (title of |
| 2145 | the popup). */ | ||
| 2146 | set_new_state (mw, | ||
| 2147 | find_first_selectable (mw, | ||
| 2148 | selected_item->contents, | ||
| 2149 | popup_menu_p), | ||
| 2150 | mw->menu.old_depth); | ||
| 2129 | else | 2151 | else |
| 2130 | /* Highlight next possible (enabled and not separator) menu item. */ | 2152 | /* Highlight next possible (enabled and not separator) menu item. */ |
| 2131 | set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2153 | set_new_state (mw, find_next_selectable (mw, selected_item, popup_menu_p), |
| 2154 | mw->menu.old_depth - 1); | ||
| 2132 | 2155 | ||
| 2133 | remap_menubar (mw); | 2156 | remap_menubar (mw); |
| 2134 | } | 2157 | } |
| @@ -2142,27 +2165,39 @@ Up (w, ev, params, num_params) | |||
| 2142 | { | 2165 | { |
| 2143 | XlwMenuWidget mw = (XlwMenuWidget) w; | 2166 | XlwMenuWidget mw = (XlwMenuWidget) w; |
| 2144 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2167 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2168 | int popup_menu_p = mw->menu.top_depth == 1; | ||
| 2145 | 2169 | ||
| 2146 | /* Inside top-level menu-bar? */ | 2170 | /* Inside top-level menu-bar? */ |
| 2147 | if (mw->menu.old_depth == 2) | 2171 | if (mw->menu.old_depth == mw->menu.top_depth) |
| 2148 | { | 2172 | { |
| 2149 | /* FIXME: this is tricky. <up> in the menu-bar should select the | 2173 | /* FIXME: this is tricky. <up> in the menu-bar should select the |
| 2150 | last selectable item in the list. So we select the first | 2174 | last selectable item in the list. So we select the first |
| 2151 | selectable one and find the previous selectable item. Is there | 2175 | selectable one and find the previous selectable item. Is there |
| 2152 | a better way? */ | 2176 | a better way? */ |
| 2153 | set_new_state (mw, find_first_selectable (mw, selected_item->contents), mw->menu.old_depth); | 2177 | /* If this is a popup menu, skip items with zero call data (title of |
| 2178 | the popup). */ | ||
| 2179 | set_new_state (mw, | ||
| 2180 | find_first_selectable (mw, | ||
| 2181 | selected_item->contents, | ||
| 2182 | popup_menu_p), | ||
| 2183 | mw->menu.old_depth); | ||
| 2154 | remap_menubar (mw); | 2184 | remap_menubar (mw); |
| 2155 | selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2185 | selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2156 | set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2186 | set_new_state (mw, |
| 2187 | find_prev_selectable (mw, | ||
| 2188 | selected_item, | ||
| 2189 | popup_menu_p), | ||
| 2190 | mw->menu.old_depth - 1); | ||
| 2157 | } | 2191 | } |
| 2158 | else | 2192 | else |
| 2159 | /* Highlight previous (enabled and not separator) menu item. */ | 2193 | /* Highlight previous (enabled and not separator) menu item. */ |
| 2160 | set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2194 | set_new_state (mw, find_prev_selectable (mw, selected_item, popup_menu_p), |
| 2195 | mw->menu.old_depth - 1); | ||
| 2161 | 2196 | ||
| 2162 | remap_menubar (mw); | 2197 | remap_menubar (mw); |
| 2163 | } | 2198 | } |
| 2164 | 2199 | ||
| 2165 | static void | 2200 | void |
| 2166 | Left (w, ev, params, num_params) | 2201 | Left (w, ev, params, num_params) |
| 2167 | Widget w; | 2202 | Widget w; |
| 2168 | XEvent *ev; | 2203 | XEvent *ev; |
| @@ -2173,31 +2208,36 @@ Left (w, ev, params, num_params) | |||
| 2173 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2208 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2174 | 2209 | ||
| 2175 | /* Inside top-level menu-bar? */ | 2210 | /* Inside top-level menu-bar? */ |
| 2176 | if (mw->menu.old_depth == 2) | 2211 | if (mw->menu.old_depth == mw->menu.top_depth) |
| 2177 | /* When <left> in the menu-bar is pressed, display the previous item on | 2212 | /* When <left> in the menu-bar is pressed, display the previous item on |
| 2178 | the menu-bar. If the current item is the first one, highlight the | 2213 | the menu-bar. If the current item is the first one, highlight the |
| 2179 | last item in the menubar (probably Help). */ | 2214 | last item in the menubar (probably Help). */ |
| 2180 | set_new_state (mw, find_prev_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2215 | set_new_state (mw, find_prev_selectable (mw, selected_item, 0), |
| 2216 | mw->menu.old_depth - 1); | ||
| 2181 | else if (mw->menu.old_depth == 1 | 2217 | else if (mw->menu.old_depth == 1 |
| 2182 | && selected_item->contents) /* Is this menu item expandable? */ | 2218 | && selected_item->contents) /* Is this menu item expandable? */ |
| 2183 | { | 2219 | { |
| 2184 | set_new_state (mw, selected_item->contents, mw->menu.old_depth); | 2220 | set_new_state (mw, selected_item->contents, mw->menu.old_depth); |
| 2185 | remap_menubar (mw); | 2221 | remap_menubar (mw); |
| 2186 | selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2222 | selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2187 | if (!selected_item->enabled && find_first_selectable (mw, selected_item)) | 2223 | if (!selected_item->enabled && find_first_selectable (mw, |
| 2188 | set_new_state (mw, find_first_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2224 | selected_item, |
| 2225 | 0)) | ||
| 2226 | set_new_state (mw, find_first_selectable (mw, selected_item, 0), | ||
| 2227 | mw->menu.old_depth - 1); | ||
| 2189 | } | 2228 | } |
| 2190 | 2229 | ||
| 2191 | else | 2230 | else |
| 2192 | { | 2231 | { |
| 2193 | pop_new_stack_if_no_contents (mw); | 2232 | pop_new_stack_if_no_contents (mw); |
| 2194 | set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2); | 2233 | set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], |
| 2234 | mw->menu.old_depth - 2); | ||
| 2195 | } | 2235 | } |
| 2196 | 2236 | ||
| 2197 | remap_menubar (mw); | 2237 | remap_menubar (mw); |
| 2198 | } | 2238 | } |
| 2199 | 2239 | ||
| 2200 | static void | 2240 | void |
| 2201 | Right (w, ev, params, num_params) | 2241 | Right (w, ev, params, num_params) |
| 2202 | Widget w; | 2242 | Widget w; |
| 2203 | XEvent *ev; | 2243 | XEvent *ev; |
| @@ -2208,23 +2248,28 @@ Right (w, ev, params, num_params) | |||
| 2208 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2248 | widget_value* selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2209 | 2249 | ||
| 2210 | /* Inside top-level menu-bar? */ | 2250 | /* Inside top-level menu-bar? */ |
| 2211 | if (mw->menu.old_depth == 2) | 2251 | if (mw->menu.old_depth == mw->menu.top_depth) |
| 2212 | /* When <right> in the menu-bar is pressed, display the next item on | 2252 | /* When <right> in the menu-bar is pressed, display the next item on |
| 2213 | the menu-bar. If the current item is the last one, highlight the | 2253 | the menu-bar. If the current item is the last one, highlight the |
| 2214 | first item (probably File). */ | 2254 | first item (probably File). */ |
| 2215 | set_new_state (mw, find_next_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2255 | set_new_state (mw, find_next_selectable (mw, selected_item, 0), |
| 2256 | mw->menu.old_depth - 1); | ||
| 2216 | else if (selected_item->contents) /* Is this menu item expandable? */ | 2257 | else if (selected_item->contents) /* Is this menu item expandable? */ |
| 2217 | { | 2258 | { |
| 2218 | set_new_state (mw, selected_item->contents, mw->menu.old_depth); | 2259 | set_new_state (mw, selected_item->contents, mw->menu.old_depth); |
| 2219 | remap_menubar (mw); | 2260 | remap_menubar (mw); |
| 2220 | selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; | 2261 | selected_item = mw->menu.old_stack [mw->menu.old_depth - 1]; |
| 2221 | if (!selected_item->enabled && find_first_selectable (mw, selected_item)) | 2262 | if (!selected_item->enabled && find_first_selectable (mw, |
| 2222 | set_new_state (mw, find_first_selectable (mw, selected_item), mw->menu.old_depth - 1); | 2263 | selected_item, |
| 2264 | 0)) | ||
| 2265 | set_new_state (mw, find_first_selectable (mw, selected_item, 0), | ||
| 2266 | mw->menu.old_depth - 1); | ||
| 2223 | } | 2267 | } |
| 2224 | else | 2268 | else |
| 2225 | { | 2269 | { |
| 2226 | pop_new_stack_if_no_contents (mw); | 2270 | pop_new_stack_if_no_contents (mw); |
| 2227 | set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], mw->menu.old_depth - 2); | 2271 | set_new_state (mw, mw->menu.old_stack [mw->menu.old_depth - 2], |
| 2272 | mw->menu.old_depth - 2); | ||
| 2228 | } | 2273 | } |
| 2229 | 2274 | ||
| 2230 | remap_menubar (mw); | 2275 | remap_menubar (mw); |
| @@ -2305,7 +2350,7 @@ Select (w, ev, params, num_params) | |||
| 2305 | 2350 | ||
| 2306 | 2351 | ||
| 2307 | /* Special code to pop-up a menu */ | 2352 | /* Special code to pop-up a menu */ |
| 2308 | void | 2353 | static void |
| 2309 | pop_up_menu (mw, event) | 2354 | pop_up_menu (mw, event) |
| 2310 | XlwMenuWidget mw; | 2355 | XlwMenuWidget mw; |
| 2311 | XButtonPressedEvent* event; | 2356 | XButtonPressedEvent* event; |
| @@ -2349,6 +2394,7 @@ pop_up_menu (mw, event) | |||
| 2349 | display_menu (mw, 0, False, NULL, NULL, NULL, NULL, NULL); | 2394 | display_menu (mw, 0, False, NULL, NULL, NULL, NULL, NULL); |
| 2350 | mw->menu.windows [0].x = x + borderwidth; | 2395 | mw->menu.windows [0].x = x + borderwidth; |
| 2351 | mw->menu.windows [0].y = y + borderwidth; | 2396 | mw->menu.windows [0].y = y + borderwidth; |
| 2397 | mw->menu.top_depth = 1; /* Popup menus don't have a bar so top is 1 */ | ||
| 2352 | } | 2398 | } |
| 2353 | else | 2399 | else |
| 2354 | { | 2400 | { |
| @@ -2359,6 +2405,7 @@ pop_up_menu (mw, event) | |||
| 2359 | /* notes the absolute position of the menubar window */ | 2405 | /* notes the absolute position of the menubar window */ |
| 2360 | mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x; | 2406 | mw->menu.windows [0].x = ev->xmotion.x_root - ev->xmotion.x; |
| 2361 | mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y; | 2407 | mw->menu.windows [0].y = ev->xmotion.y_root - ev->xmotion.y; |
| 2408 | mw->menu.top_depth = 2; | ||
| 2362 | } | 2409 | } |
| 2363 | 2410 | ||
| 2364 | #ifdef emacs | 2411 | #ifdef emacs |
diff --git a/lwlib/xlwmenu.h b/lwlib/xlwmenu.h index 3057998d17a..c1f37b5617b 100644 --- a/lwlib/xlwmenu.h +++ b/lwlib/xlwmenu.h | |||
| @@ -53,9 +53,6 @@ typedef struct _XlwMenuClassRec *XlwMenuWidgetClass; | |||
| 53 | 53 | ||
| 54 | extern WidgetClass xlwMenuWidgetClass; | 54 | extern WidgetClass xlwMenuWidgetClass; |
| 55 | 55 | ||
| 56 | void | ||
| 57 | pop_up_menu __P ((XlwMenuWidget, XButtonPressedEvent*)); | ||
| 58 | |||
| 59 | #endif /* _XlwMenu_h */ | 56 | #endif /* _XlwMenu_h */ |
| 60 | 57 | ||
| 61 | /* arch-tag: 0c019735-d61b-4080-be85-4fdd6e50ae07 | 58 | /* arch-tag: 0c019735-d61b-4080-be85-4fdd6e50ae07 |
diff --git a/lwlib/xlwmenuP.h b/lwlib/xlwmenuP.h index c3e62830184..f6aa0f4a58c 100644 --- a/lwlib/xlwmenuP.h +++ b/lwlib/xlwmenuP.h | |||
| @@ -47,6 +47,7 @@ typedef struct _XlwMenu_part | |||
| 47 | unsigned free_bottom_shadow_color_p : 1; | 47 | unsigned free_bottom_shadow_color_p : 1; |
| 48 | 48 | ||
| 49 | /* State of the XlwMenu */ | 49 | /* State of the XlwMenu */ |
| 50 | int top_depth; | ||
| 50 | int old_depth; | 51 | int old_depth; |
| 51 | widget_value** old_stack; | 52 | widget_value** old_stack; |
| 52 | int old_stack_length; | 53 | int old_stack_length; |