Example #1
0
        public static void Recreate(CommandManager manager, CommandEntrySet entrySet, HashSet <object> ignoreCommands)
        {
            if (manager == null)
            {
                throw new ArgumentException("manager");
            }
            if (MacMainMenu.manager != null)
            {
                MacMainMenu.manager.CommandActivating -= OnCommandActivating;
            }
            MacMainMenu.manager = manager;
            MacMainMenu.manager.CommandActivating += OnCommandActivating;

            if (rootMenu == IntPtr.Zero)
            {
                rootMenu = HIToolbox.CreateMenu(idSeq++, GetName(entrySet), 0);
                CreateChildren(rootMenu, entrySet, ignoreCommands);
                InstallRootMenu();
            }
            else
            {
                Destroy(false);
                CreateChildren(rootMenu, entrySet, ignoreCommands);
            }
        }
Example #2
0
        public static void AddAppMenuItems(CommandManager manager, params object [] cmdIds)
        {
            //FIXME: we assume we get first pick of cmdIDs

            HIMenuItem mnu = HIToolbox.GetMenuItem((uint)CarbonCommandID.Hide);

            appMenu = mnu.MenuRef;
            var appMenuId = HIToolbox.GetMenuID(appMenu);

            for (int i = cmdIds.Length - 1; i >= 0; i--)
            {
                var cmdId = cmdIds[i];
                if (cmdId == Command.Separator)
                {
                    HIToolbox.InsertMenuSeparator(mnu.MenuRef, 0);
                    continue;
                }

                Command cmd = manager.GetCommand(cmdId);
                if (cmd == null)
                {
                    MonoDevelop.Core.LoggingService.LogError("Null command in Mac app menu for ID {0}", cmdId);
                    continue;
                }

                uint   macCmdId = GetNewMenuItemId(cmd);
                ushort pos      = HIToolbox.InsertMenuItem(mnu.MenuRef, (cmd.Text ?? "").Replace("_", ""), 0, 0, macCmdId);
                SetMenuAccelerator(new HIMenuItem(mnu.MenuRef, pos), cmd.AccelKey);
                menuIdMap[cmdId] = appMenuId;
            }
        }
Example #3
0
        static void BuildDynamicSubMenu(IntPtr rootMenu, IntPtr parentMenu, ushort index, uint macCmdID, CommandInfoSet cinfoSet)
        {
            IntPtr menuRef = HIToolbox.CreateMenu(idSeq++, GetCleanCommandText(cinfoSet), MenuAttributes.CondenseSeparators);

            objectsToDestroyOnMenuClose.Add(new DestructableMenu(menuRef));
            HIToolbox.CheckResult(HIToolbox.SetMenuItemHierarchicalMenu(parentMenu, index, menuRef));

            ushort count = (ushort)cinfoSet.CommandInfos.Count;

            for (ushort i = 1, j = 0; i <= count; i++)
            {
                CommandInfo ci = cinfoSet.CommandInfos[j++];
                if (ci.IsArraySeparator)
                {
                    HIToolbox.AppendMenuSeparator(menuRef);
                }
                else
                {
                    HIToolbox.AppendMenuItem(menuRef, ci.Text, 0, macCmdID);
                    UpdateMenuItem(rootMenu, menuRef, ref i, ref count, macCmdID, ci);

                    objectsToDestroyOnMenuClose.Add(ci.DataItem);
                    uint refcon = (uint)objectsToDestroyOnMenuClose.Count;
                    HIToolbox.SetMenuItemReferenceConstant(new HIMenuItem(menuRef, i), refcon);
                }
            }
        }
Example #4
0
        internal static void RunMenuCommand(CarbonCommandID commandID)
        {
            var item = HIToolbox.GetMenuItem((uint)commandID);
            var cmd  = new CarbonHICommand((uint)commandID, item);

            Carbon.ProcessHICommand(ref cmd);
        }
        public static void Recreate(CommandManager manager, CommandEntrySet entrySet)
        {
            if (manager == null)
            {
                throw new ArgumentException("manager");
            }
            if (MacMainMenu.manager != null)
            {
                MacMainMenu.manager.CommandActivating -= OnCommandActivating;
            }
            MacMainMenu.manager = manager;
            MacMainMenu.manager.CommandActivating += OnCommandActivating;

            if (rootMenu == IntPtr.Zero)
            {
                rootMenu = HIToolbox.CreateMenu(idSeq++, GetName(entrySet), 0);
                AddMenuItems(new HIMenuItem(rootMenu, 0), entrySet);
                InstallRootMenu();
            }
            else
            {
                Destroy(false);
                AddMenuItems(new HIMenuItem(rootMenu, 0), entrySet);
            }
        }
Example #6
0
        public static void Destroy(bool removeRoot)
        {
            if (mainMenus.Count > 0)
            {
                foreach (IntPtr ptr in mainMenus)
                {
                    HIToolbox.DeleteMenu(ptr);
                    CoreFoundation.Release(ptr);
                }
                DestroyOldMenuObjects();
                mainMenus.Clear();
                linkCommands.Clear();
                idSeq = 1;
            }

            HIToolbox.ClearMenuBar();

            if (removeRoot && rootMenu != IntPtr.Zero)
            {
                HIToolbox.DeleteMenu(rootMenu);
                CoreFoundation.Release(rootMenu);
                HIToolbox.CheckResult(HIToolbox.SetRootMenu(IntPtr.Zero));
                Carbon.RemoveEventHandler(commandHandlerRef);
                Carbon.RemoveEventHandler(openingHandlerRef);
                Carbon.RemoveEventHandler(closedHandlerRef);
                commandHandlerRef = openingHandlerRef = rootMenu = IntPtr.Zero;
                idSeq             = 0;
            }
        }
Example #7
0
        static void InstallRootMenu()
        {
            HIToolbox.CheckResult(HIToolbox.SetRootMenu(rootMenu));

            openingHandlerRef = Carbon.InstallApplicationEventHandler(HandleMenuOpening, CarbonEventMenu.Opening);
            closedHandlerRef  = Carbon.InstallApplicationEventHandler(HandleMenuClosed, CarbonEventMenu.Closed);
            commandHandlerRef = Carbon.InstallApplicationEventHandler(HandleMenuCommand, CarbonEventCommand.Process);
        }
Example #8
0
 public void Destroy()
 {
     if (Ref != IntPtr.Zero)
     {
         HIToolbox.DeleteMenu(Ref);
         CoreFoundation.Release(Ref);
         Ref = IntPtr.Zero;
     }
 }
        static CarbonEventHandlerStatus HandleMenuCommand(IntPtr callRef, IntPtr eventRef, IntPtr userData)
        {
            try
            {
                CarbonHICommand hiCmd  = GetCarbonHICommand(eventRef);
                uint            refCon = HIToolbox.GetMenuItemReferenceConstant(hiCmd.MenuItem);

                //link commands
                if (hiCmd.CommandID == linkCommandId)
                {
                    string url = "";
                    try
                    {
                        url = linkCommands[(int)refCon];
                        MacPlatformService.OpenUrl(url);
                    }
                    catch (Exception ex)
                    {
                        Gtk.Application.Invoke(delegate
                        {
                            MonoDevelop.Ide.MessageService.ShowException(ex, MonoDevelop.Core.GettextCatalog.GetString("Could not open the url {0}", url));
                        });
                    }
                    DestroyOldMenuObjects();
                    return(CarbonEventHandlerStatus.Handled);
                }

                //normal commands
                object cmdID = GetCommandID(hiCmd);
                if (cmdID != null)
                {
                    if (refCon > 0)
                    {
                        object data = objectsToDestroyOnMenuClose[(int)refCon - 1];
                        //need to return before we execute the command, so that the menu unhighlights
                        Gtk.Application.Invoke(delegate
                        {
                            manager.DispatchCommand(cmdID, data, CommandSource.MainMenu);
                        });
                    }
                    else
                    {
                        Gtk.Application.Invoke(delegate
                        {
                            manager.DispatchCommand(cmdID, CommandSource.MainMenu);
                        });
                    }
                    DestroyOldMenuObjects();
                    return(CarbonEventHandlerStatus.Handled);
                }
            }
            catch (Exception ex)
            {
                MonoDevelop.Core.LoggingService.LogError("Unhandled error handling menu command", ex);
            }
            return(CarbonEventHandlerStatus.NotHandled);
        }
        static uint[] GetMenuCommandIDs(IntPtr menuRef)
        {
            int count         = HIToolbox.CountMenuItems(menuRef);
            var existingitems = new uint[count];

            for (int i = 0; i < count; i++)
            {
                existingitems[i] = HIToolbox.GetMenuItemCommandID(new HIMenuItem(menuRef, (ushort)(i + 1)));
            }
            return(existingitems);
        }
Example #11
0
        //updates commands and populates arrays and dynamic menus
        static CarbonEventHandlerStatus HandleMenuOpening(IntPtr callRef, IntPtr eventRef, IntPtr user_data)
        {
            DestroyOldMenuObjects();
            menuOpenDepth++;
            try {
                IntPtr menuRef = Carbon.GetEventParameter(eventRef, CarbonEventParameterName.DirectObject, CarbonEventParameterType.MenuRef);

                //don't update dynamic menus recursively
                if (!mainMenus.Contains(menuRef) && menuRef != appMenu)
                {
                    return(CarbonEventHandlerStatus.NotHandled);
                }

                //	uint cmd = HIToolbox.GetMenuItemCommandID (new HIMenuItem (menuRef, 0));

                CommandTargetRoute route = new CommandTargetRoute();
                ushort             count = HIToolbox.CountMenuItems(menuRef);
                for (ushort i = 1; i <= count; i++)
                {
                    HIMenuItem mi       = new HIMenuItem(menuRef, i);
                    uint       macCmdID = HIToolbox.GetMenuItemCommandID(mi);
                    object     cmdID;

                    //link items
                    if (macCmdID == linkCommandId)
                    {
                        if (IsGloballyDisabled)
                        {
                            HIToolbox.DisableMenuItem(mi);
                        }
                        else
                        {
                            HIToolbox.EnableMenuItem(mi);
                        }
                        continue;
                    }

                    //items that map to command objects
                    if (!commands.TryGetValue(macCmdID, out cmdID) || cmdID == null)
                    {
                        continue;
                    }

                    CommandInfo cinfo = manager.GetCommandInfo(cmdID, route);
                    menuIdMap[cmdID] = HIToolbox.GetMenuID(menuRef);
                    UpdateMenuItem(menuRef, menuRef, ref i, ref count, macCmdID, cinfo);
                }
            } catch (Exception ex) {
                System.Console.WriteLine(ex);
            }

            return(CarbonEventHandlerStatus.NotHandled);
        }
Example #12
0
        static void UpdateAutoHide(HIMenuItem item)
        {
            IntPtr submenu;

            if (HIToolbox.GetMenuItemHierarchicalMenu(item.MenuRef, item.Index, out submenu) != CarbonMenuStatus.Ok)
            {
                return;
            }

            if (HasVisibleItems(submenu))
            {
                HIToolbox.ChangeMenuItemAttributes(item, 0, MenuItemAttributes.Hidden);
            }
            else
            {
                HIToolbox.ChangeMenuItemAttributes(item, MenuItemAttributes.Hidden, 0);
            }
        }
Example #13
0
        static void OnCommandActivating(object sender, CommandActivationEventArgs args)
        {
            uint menuId;

            if (args.Source == CommandSource.Keybinding && menuIdMap.TryGetValue(args.CommandId, out menuId))
            {
                //FIXME: for some reason we have to flash again after a delay to toggle the previous flash off?
                //some flashes can be unreliable, e.g. minimize, and modal dialogs don't seem to run timeouts, so the flash comes late
                GLib.Timeout.Add(50, delegate {
                    HIToolbox.FlashMenuBar(menuId);
                    return(false);
                });
                GLib.Timeout.Add(250, delegate {
                    HIToolbox.FlashMenuBar(menuId);
                    return(false);
                });
            }
        }
Example #14
0
        static void UpdateMenuItem(IntPtr rootMenu, IntPtr menuRef, ref ushort index, ref ushort count,
                                   uint macCmdID, CommandInfo cinfo)
        {
            if (cinfo.ArrayInfo != null)
            {
                //remove the existing items, except one, which we hide, so it gets updated next time even if the list is empty
                HIToolbox.ChangeMenuItemAttributes(new HIMenuItem(menuRef, index), MenuItemAttributes.Hidden, 0);
                index++;
                while (index <= count && HIToolbox.GetMenuItemCommandID(new HIMenuItem(menuRef, index)) == macCmdID)
                {
                    HIToolbox.DeleteMenuItem(menuRef, index);
                    count--;
                }
                index--;

                //add the new items
                foreach (CommandInfo ci in cinfo.ArrayInfo)
                {
                    count++;
                    HIToolbox.InsertMenuItem(menuRef, ci.Text, index++, 0, macCmdID);

                    //associate a reference constant with the menu, used to index the DataItem
                    //it's one-based, so that 0 can be used as a flag that there's no associated object
                    objectsToDestroyOnMenuClose.Add(ci.DataItem);
                    uint refcon = (uint)objectsToDestroyOnMenuClose.Count;

                    SetMenuItemAttributes(new HIMenuItem(menuRef, index), ci, refcon);
                    if (ci is CommandInfoSet)
                    {
                        BuildDynamicSubMenu(rootMenu, menuRef, index, macCmdID, (CommandInfoSet)ci);
                    }
                }
            }
            else
            {
                SetMenuItemAttributes(new HIMenuItem(menuRef, index), cinfo, 0);
                if (cinfo is CommandInfoSet)
                {
                    BuildDynamicSubMenu(rootMenu, menuRef, index, macCmdID, (CommandInfoSet)cinfo);
                }
            }
        }
Example #15
0
        static bool HasVisibleItems(IntPtr submenu)
        {
            var    route = new CommandTargetRoute();
            ushort count = HIToolbox.CountMenuItems(submenu);

            for (ushort i = 1; i <= count; i++)
            {
                HIMenuItem mi       = new HIMenuItem(submenu, i);
                uint       macCmdID = HIToolbox.GetMenuItemCommandID(mi);
                object     cmdID;

                if (macCmdID == linkCommandId)
                {
                    return(true);
                }

                if (!commands.TryGetValue(macCmdID, out cmdID) || cmdID == null)
                {
                    continue;
                }

                CommandInfo cinfo = manager.GetCommandInfo(cmdID, route);
                if (cinfo.ArrayInfo != null)
                {
                    foreach (CommandInfo ci in cinfo.ArrayInfo)
                    {
                        if (ci.Visible)
                        {
                            return(true);
                        }
                    }
                }
                else if (cinfo.Visible)
                {
                    return(true);
                }
            }

            return(false);
        }
Example #16
0
        static void SetMenuAccelerator(HIMenuItem item, string accelKey)
        {
            MenuAccelModifier mod;
            ushort            glyphCode, charCode, hardwareCode;

            if (GetAcceleratorKeys(accelKey, out glyphCode, out charCode, out hardwareCode, out mod))
            {
                if (glyphCode != 0)
                {
                    HIToolbox.SetMenuItemKeyGlyph(item.MenuRef, item.Index, (short)glyphCode);
                }
                else if (hardwareCode != 0)
                {
                    HIToolbox.SetMenuItemCommandKey(item.MenuRef, item.Index, true, hardwareCode);
                }
                else
                {
                    HIToolbox.SetMenuItemCommandKey(item.MenuRef, item.Index, false, charCode);
                }
                HIToolbox.SetMenuItemModifiers(item.MenuRef, item.Index, mod);
            }
        }
Example #17
0
        static void CreateChildren(IntPtr parentMenu, CommandEntrySet entrySet, HashSet <object> ignoreCommands)
        {
            var menuId = HIToolbox.GetMenuID(parentMenu);

            foreach (CommandEntry entry in entrySet)
            {
                CommandEntrySet ces = entry as CommandEntrySet;

                if (ces == null)
                {
                    ushort pos;

                    if (ignoreCommands.Contains(entry.CommandId))
                    {
                        continue;
                    }

                    if (entry.CommandId == Command.Separator)
                    {
                        HIToolbox.AppendMenuSeparator(parentMenu);
                        continue;
                    }

                    if (entry is LinkCommandEntry)
                    {
                        LinkCommandEntry lce = (LinkCommandEntry)entry;
                        pos = HIToolbox.AppendMenuItem(parentMenu, (lce.Text ?? "").Replace("_", ""), 0, linkCommandId);
                        HIToolbox.SetMenuItemReferenceConstant(new HIMenuItem(parentMenu, pos), (uint)linkCommands.Count);
                        linkCommands.Add(lce.Url);
                        continue;
                    }

                    Command cmd = manager.GetCommand(entry.CommandId);
                    if (cmd == null)
                    {
                        MonoDevelop.Core.LoggingService.LogError(
                            "Mac main menu '{0}' child '{1}' maps to null command", entrySet.Name, entry.CommandId);
                        continue;
                    }

                    if (cmd is CustomCommand)
                    {
                        MonoDevelop.Core.LoggingService.LogWarning(
                            "Mac main menu does not support custom command widgets for command '{0}'", entry.CommandId);
                        continue;
                    }

                    menuIdMap[entry.CommandId] = menuId;

                    ActionCommand acmd = cmd as ActionCommand;
                    if (acmd == null)
                    {
                        MonoDevelop.Core.LoggingService.LogWarning(
                            "Mac main menu does not support command type '{0}' for command '{1}'", cmd.GetType(), entry.CommandId);
                        continue;
                    }

                    uint macCmdId = GetNewMenuItemId(cmd);

                    pos = HIToolbox.AppendMenuItem(parentMenu, (cmd.Text ?? "").Replace("_", ""), 0, macCmdId);
                }
                else
                {
                    var    macCmdId = (ces.AutoHide) ? autohideSubmenuCommandId : submenuCommandId;
                    IntPtr menuRef  = HIToolbox.CreateMenu(idSeq++, GetName(ces), MenuAttributes.CondenseSeparators);
                    mainMenus.Add(menuRef);
                    CreateChildren(menuRef, ces, ignoreCommands);
                    ushort pos = HIToolbox.AppendMenuItem(parentMenu, GetName(ces), 0, macCmdId);
                    HIToolbox.CheckResult(HIToolbox.SetMenuItemHierarchicalMenu(parentMenu, pos, menuRef));
                }
            }
        }
        static void AddMenuItems(HIMenuItem afterItem, IEnumerable <CommandEntry> entries)
        {
            IntPtr parentMenu = afterItem.MenuRef;
            var    menuId     = HIToolbox.GetMenuID(parentMenu);
            var    index      = afterItem.Index;

            foreach (CommandEntry entry in entries)
            {
                var ces = entry as CommandEntrySet;
                if (ces != null)
                {
                    var    macMenuCmdId = (ces.AutoHide) ? autohideSubmenuCommandId : submenuCommandId;
                    IntPtr menuRef      = HIToolbox.CreateMenu(idSeq++, GetName(ces), MenuAttributes.CondenseSeparators);
                    mainMenus.Add(menuRef);
                    AddMenuItems(new HIMenuItem(menuRef, 0), ces);
                    index = HIToolbox.InsertMenuItem(parentMenu, GetName(ces), index, 0, macMenuCmdId);
                    HIToolbox.CheckResult(HIToolbox.SetMenuItemHierarchicalMenu(parentMenu, index, menuRef));
                    continue;
                }

                if (entry.CommandId == Command.Separator)
                {
                    index = HIToolbox.InsertMenuSeparator(parentMenu, index);
                    continue;
                }

                if (entry is LinkCommandEntry)
                {
                    var lce = (LinkCommandEntry)entry;
                    index = HIToolbox.InsertMenuItem(parentMenu, (lce.Text ?? "").Replace("_", ""), index, 0, linkCommandId);
                    HIToolbox.SetMenuItemReferenceConstant(new HIMenuItem(parentMenu, index), (uint)linkCommands.Count);
                    linkCommands.Add(lce.Url);
                    continue;
                }

                Command cmd = manager.GetCommand(entry.CommandId);
                if (cmd == null)
                {
                    MonoDevelop.Core.LoggingService.LogError(
                        "Mac main menu item '{0}' maps to null command", entry.CommandId);
                    continue;
                }

                if (cmd is CustomCommand)
                {
                    MonoDevelop.Core.LoggingService.LogWarning(
                        "Mac main menu does not support custom command widget for command '{0}'", entry.CommandId);
                    continue;
                }

                menuIdMap[entry.CommandId] = menuId;

                var acmd = cmd as ActionCommand;
                if (acmd == null)
                {
                    MonoDevelop.Core.LoggingService.LogWarning(
                        "Mac main menu does not support command type '{0}' for command '{1}'", cmd.GetType(), entry.CommandId);
                    continue;
                }

                uint macCmdId = GetMacID(entry.CommandId);

                index = HIToolbox.InsertMenuItem(parentMenu, (cmd.Text ?? "").Replace("_", ""), index, 0, macCmdId);
            }
        }
        public static void SetAppMenuItems(CommandManager manager, CommandEntrySet entrySet)
        {
            HIMenuItem mnu = HIToolbox.GetMenuItem((uint)CarbonCommandID.Hide);

            bool firstTime = appMenu == IntPtr.Zero;

            appMenu = mnu.MenuRef;

            var existingitems = GetMenuCommandIDs(appMenu).ToList();

            for (int i = existingitems.Count - 1; i >= 0; i--)
            {
                var item = new HIMenuItem(appMenu, (ushort)(i + 1));
                //if first time, keep all the existing items except QuitAndCloseAllWindows
                if (firstTime && existingitems [i] != (uint)CarbonCommandID.QuitAndCloseAllWindows)
                {
                    //mark them so we can recognise and keep them in future
                    //HIToolbox.SetMenuItemReferenceConstant (item, uint.MaxValue);
                    continue;
                }

                // if it's not the first time, keep the original items we marked
                if (!firstTime && HIToolbox.GetMenuItemReferenceConstant(item) == UInt32.MaxValue)
                {
                    continue;
                }

                //remove everything else
                HIToolbox.DeleteMenuItem(item);
                existingitems.RemoveAt(i);
            }

            // Iterate backwards over the entries. For each one, try to find a matching built-in item. If successful,
            // get all the items from that point to the last item that was not yet inserted, and insert them
            // at that point.
            var entries         = entrySet.ToList();
            int uninsertedCount = entries.Count;

            for (int i = entries.Count - 1; i >= 0; i--)
            {
                var entry = entries [i];
                if (entry.CommandId == null || entry.CommandId == Command.Separator)
                {
                    continue;
                }
                var id = GetMacID(entry.CommandId);

                //find an existing item
                int match = existingitems.IndexOf(id);

                if (match >= 0)
                {
                    //if there are uninserted items *after* this one, insert them at this point
                    if ((uninsertedCount - i) > 0)
                    {
                        var items          = entries.Skip(i + 1).Take(uninsertedCount - i - 2);
                        var insertionPoint = new HIMenuItem(appMenu, (ushort)(match + 1));
                        AddMenuItems(insertionPoint, items);
                    }
                    uninsertedCount = i;
                }
            }
            // Finally, insert any remaining items at the beginning/top of the menu.
            if (uninsertedCount > 0)
            {
                AddMenuItems(new HIMenuItem(appMenu, 0), entries.Take(uninsertedCount));
            }
        }
Example #20
0
        static void SetMenuItemAttributes(HIMenuItem item, CommandInfo ci, uint refcon)
        {
            MenuItemData data = new MenuItemData();
            IntPtr       text = IntPtr.Zero;

            try {
                if (ci.IsArraySeparator)
                {
                    data.Attributes |= MenuItemAttributes.Separator;
                }
                else if (!ci.Visible)
                {
                    data.Attributes |= MenuItemAttributes.Hidden;
                }
                else
                {
                    data.Attributes &= ~MenuItemAttributes.Hidden;
                    data.CFText      = CoreFoundation.CreateString(GetCleanCommandText(ci));

                    //disable also when MD main window doesn't have toplevel focus, or commands will be
                    //accessible when modal dialogs are active
                    bool disabled = !ci.Enabled || IsGloballyDisabled;
                    data.Enabled = !disabled;
                    if (disabled)
                    {
                        data.Attributes |= MenuItemAttributes.Disabled;
                    }

                    ushort            glyphCode, charCode, hardwareCode;
                    MenuAccelModifier mod;
                    if (GetAcceleratorKeys(ci.AccelKey, out glyphCode, out charCode, out hardwareCode, out mod))
                    {
                        data.CommandKeyModifiers = mod;
                        if (glyphCode != 0)
                        {
                            data.CommandKeyGlyph = glyphCode;
                            data.Attributes     ^= MenuItemAttributes.UseVirtualKey;
                        }
                        else if (hardwareCode != 0)
                        {
                            data.CommandVirtualKey = (char)hardwareCode;
                            data.Attributes       |= MenuItemAttributes.UseVirtualKey;
                        }
                        else
                        {
                            data.CommandKey  = (char)charCode;
                            data.Attributes ^= MenuItemAttributes.UseVirtualKey;
                        }
                    }
                    //else{
                    //FIXME: remove existing commands if necessary

                    data.Mark = ci.Checked
                                                ? ci.CheckedInconsistent
                                                        ? '-' //FIXME: is this a good symbol for CheckedInconsistent?
                                                        : (char)MenuGlyphs.Checkmark
                                                : '\0';

                    data.ReferenceConstant = refcon;
                }
                HIToolbox.SetMenuItemData(item.MenuRef, item.Index, false, ref data);
            } finally {
                if (text != IntPtr.Zero)
                {
                    CoreFoundation.Release(text);
                }
            }
        }