comparison src/macmenu.c @ 56849:49d188f9179f

* macmenu.c (_widget_value): Added lname and lkey. (single_submenu): Set lname and lkey in widget_value instead of name and key. (update_submenu_strings): New function. (set_frame_menubar): Remove call to inhibit_garbage_collection, call update_submenu_strings.
author Jan Djärv <jan.h.d@swipnet.se>
date Mon, 30 Aug 2004 20:32:00 +0000
parents 6bd9ebab1440
children ca08ff660c73
comparison
equal deleted inserted replaced
56848:7201186afcb7 56849:49d188f9179f
88 /* This structure is based on the one in ../lwlib/lwlib.h, modified 88 /* This structure is based on the one in ../lwlib/lwlib.h, modified
89 for Mac OS. */ 89 for Mac OS. */
90 typedef struct _widget_value 90 typedef struct _widget_value
91 { 91 {
92 /* name of widget */ 92 /* name of widget */
93 Lisp_Object lname;
93 char* name; 94 char* name;
94 /* value (meaning depend on widget type) */ 95 /* value (meaning depend on widget type) */
95 char* value; 96 char* value;
96 /* keyboard equivalent. no implications for XtTranslations */ 97 /* keyboard equivalent. no implications for XtTranslations */
98 Lisp_Object lkey;
97 char* key; 99 char* key;
98 /* Help string or nil if none. 100 /* Help string or nil if none.
99 GC finds this string through the frame's menu_bar_vector 101 GC finds this string through the frame's menu_bar_vector
100 or through menu_items. */ 102 or through menu_items. */
101 Lisp_Object help; 103 Lisp_Object help;
1219 wv = xmalloc_widget_value (); 1221 wv = xmalloc_widget_value ();
1220 if (save_wv) 1222 if (save_wv)
1221 save_wv->next = wv; 1223 save_wv->next = wv;
1222 else 1224 else
1223 first_wv->contents = wv; 1225 first_wv->contents = wv;
1224 wv->name = pane_string; 1226 wv->lname = pane_name;
1225 /* Ignore the @ that means "separate pane". 1227 /* Set value to 1 so update_submenu_strings can handle '@' */
1226 This is a kludge, but this isn't worth more time. */ 1228 wv->value = (char *)1;
1227 if (!NILP (prefix) && wv->name[0] == '@')
1228 wv->name++;
1229 wv->value = 0;
1230 wv->enabled = 1; 1229 wv->enabled = 1;
1231 wv->button_type = BUTTON_TYPE_NONE; 1230 wv->button_type = BUTTON_TYPE_NONE;
1232 wv->help = Qnil; 1231 wv->help = Qnil;
1233 } 1232 }
1234 save_wv = wv; 1233 save_wv = wv;
1267 if (prev_wv) 1266 if (prev_wv)
1268 prev_wv->next = wv; 1267 prev_wv->next = wv;
1269 else 1268 else
1270 save_wv->contents = wv; 1269 save_wv->contents = wv;
1271 1270
1272 wv->name = (char *) SDATA (item_name); 1271 wv->lname = item_name;
1273 if (!NILP (descrip)) 1272 if (!NILP (descrip))
1274 wv->key = (char *) SDATA (descrip); 1273 wv->lkey = descrip;
1275 wv->value = 0; 1274 wv->value = 0;
1276 /* The EMACS_INT cast avoids a warning. There's no problem 1275 /* The EMACS_INT cast avoids a warning. There's no problem
1277 as long as pointers have enough bits to hold small integers. */ 1276 as long as pointers have enough bits to hold small integers. */
1278 wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0); 1277 wv->call_data = (!NILP (def) ? (void *) (EMACS_INT) i : 0);
1279 wv->enabled = !NILP (enable); 1278 wv->enabled = !NILP (enable);
1308 return wv; 1307 return wv;
1309 } 1308 }
1310 1309
1311 return first_wv; 1310 return first_wv;
1312 } 1311 }
1312 /* Walk through the widget_value tree starting at FIRST_WV and update
1313 the char * pointers from the corresponding lisp values.
1314 We do this after building the whole tree, since GC may happen while the
1315 tree is constructed, and small strings are relocated. So we must wait
1316 until no GC can happen before storing pointers into lisp values. */
1317 static void
1318 update_submenu_strings (first_wv)
1319 widget_value *first_wv;
1320 {
1321 widget_value *wv;
1322
1323 for (wv = first_wv; wv; wv = wv->next)
1324 {
1325 if (wv->lname && ! NILP (wv->lname))
1326 {
1327 wv->name = SDATA (wv->lname);
1328
1329 /* Ignore the @ that means "separate pane".
1330 This is a kludge, but this isn't worth more time. */
1331 if (wv->value == (char *)1)
1332 {
1333 if (wv->name[0] == '@')
1334 wv->name++;
1335 wv->value = 0;
1336 }
1337 }
1338
1339 if (wv->lkey && ! NILP (wv->lkey))
1340 wv->key = SDATA (wv->lkey);
1341
1342 if (wv->contents)
1343 update_submenu_strings (wv->contents);
1344 }
1345 }
1346
1313 1347
1314 /* Set the contents of the menubar widgets of frame F. 1348 /* Set the contents of the menubar widgets of frame F.
1315 The argument FIRST_TIME is currently ignored; 1349 The argument FIRST_TIME is currently ignored;
1316 it is set the first time this is called, from initialize_frame_menubar. */ 1350 it is set the first time this is called, from initialize_frame_menubar. */
1317 1351
1385 call0 (Qrecompute_lucid_menubar); 1419 call0 (Qrecompute_lucid_menubar);
1386 safe_run_hooks (Qmenu_bar_update_hook); 1420 safe_run_hooks (Qmenu_bar_update_hook);
1387 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f)); 1421 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
1388 1422
1389 items = FRAME_MENU_BAR_ITEMS (f); 1423 items = FRAME_MENU_BAR_ITEMS (f);
1390
1391 inhibit_garbage_collection ();
1392 1424
1393 /* Save the frame's previous menu bar contents data. */ 1425 /* Save the frame's previous menu bar contents data. */
1394 if (previous_menu_items_used) 1426 if (previous_menu_items_used)
1395 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items, 1427 bcopy (XVECTOR (f->menu_bar_vector)->contents, previous_items,
1396 previous_menu_items_used * sizeof (Lisp_Object)); 1428 previous_menu_items_used * sizeof (Lisp_Object));
1452 Lisp_Object string; 1484 Lisp_Object string;
1453 string = XVECTOR (items)->contents[i + 1]; 1485 string = XVECTOR (items)->contents[i + 1];
1454 if (NILP (string)) 1486 if (NILP (string))
1455 break; 1487 break;
1456 wv->name = (char *) SDATA (string); 1488 wv->name = (char *) SDATA (string);
1489 update_submenu_strings (wv->contents);
1457 wv = wv->next; 1490 wv = wv->next;
1458 } 1491 }
1459 1492
1460 f->menu_bar_vector = menu_items; 1493 f->menu_bar_vector = menu_items;
1461 f->menu_bar_items_used = menu_items_used; 1494 f->menu_bar_items_used = menu_items_used;