To: vim-dev@vim.org Subject: Patch 7.1.285 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 7.1.285 (extra) Problem: Mac: dialog hotkeys don't work. Solution: Add hotkey support. (Dan Sandler) Files: src/gui_mac.c *** ../vim-7.1.284/src/gui_mac.c Wed Mar 12 21:47:31 2008 --- src/gui_mac.c Sun Mar 16 15:25:13 2008 *************** *** 153,158 **** --- 153,161 ---- /* Keeping track of which scrollbar is being dragged */ static ControlHandle dragged_sb = NULL; + /* Vector of char_u --> control index for hotkeys in dialogs */ + static short *gDialogHotKeys; + static struct { FMFontFamily family; *************** *** 5519,5524 **** --- 5522,5570 ---- SetDialogItemText(itemHandle, itemName); } + + /* ModalDialog() handler for message dialogs that have hotkey accelerators. + * Expects a mapping of hotkey char to control index in gDialogHotKeys; + * setting gDialogHotKeys to NULL disables any hotkey handling. + */ + static pascal Boolean + DialogHotkeyFilterProc ( + DialogRef theDialog, + EventRecord *event, + DialogItemIndex *itemHit) + { + char_u keyHit; + + if (event->what == keyDown || event->what == autoKey) + { + keyHit = (event->message & charCodeMask); + + if (gDialogHotKeys && gDialogHotKeys[keyHit]) + { + #ifdef DEBUG_MAC_DIALOG_HOTKEYS + printf("user pressed hotkey '%c' --> item %d\n", keyHit, gDialogHotKeys[keyHit]); + #endif + *itemHit = gDialogHotKeys[keyHit]; + + /* When handing off to StdFilterProc, pretend that the user + * clicked the control manually. Note that this is also supposed + * to cause the button to hilite briefly (to give some user + * feedback), but this seems not to actually work (or it's too + * fast to be seen). + */ + event->what = kEventControlSimulateHit; + + return true; /* we took care of it */ + } + + /* Defer to the OS's standard behavior for this event. + * This ensures that Enter will still activate the default button. */ + return StdFilterProc(theDialog, event, itemHit); + } + return false; /* Let ModalDialog deal with it */ + } + + /* TODO: There have been some crashes with dialogs, check your inbox * (Jussi) */ *************** *** 5544,5549 **** --- 5590,5597 ---- GrafPtr oldPort; short itemHit; char_u *buttonChar; + short hotKeys[256]; /* map of hotkey -> control ID */ + char_u aHotKey; Rect box; short button; short lastButton; *************** *** 5571,5576 **** --- 5619,5626 ---- WindowRef theWindow; + ModalFilterUPP dialogUPP; + /* Check 'v' flag in 'guioptions': vertical button placement. */ vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL); *************** *** 5610,5615 **** --- 5660,5668 ---- buttonChar = buttons; button = 0; + /* initialize the hotkey mapping */ + memset(hotKeys, 0, sizeof(hotKeys)); + for (;*buttonChar != 0;) { /* Get the name of the button */ *************** *** 5619,5625 **** --- 5672,5689 ---- { if (*buttonChar != DLG_HOTKEY_CHAR) name[++len] = *buttonChar; + else + { + aHotKey = (char_u)*(buttonChar+1); + if (aHotKey >= 'A' && aHotKey <= 'Z') + aHotKey = (char_u)((int)aHotKey + (int)'a' - (int)'A'); + hotKeys[aHotKey] = button; + #ifdef DEBUG_MAC_DIALOG_HOTKEYS + printf("### hotKey for button %d is '%c'\n", button, aHotKey); + #endif + } } + if (*buttonChar != 0) buttonChar++; name[0] = len; *************** *** 5688,5694 **** --- 5752,5764 ---- (void) C2PascalString(textfield, &name); SetDialogItemText(itemHandle, name); inputItm.width = StringWidth(name); + + /* Hotkeys don't make sense if there's a text field */ + gDialogHotKeys = NULL; } + else + /* Install hotkey table */ + gDialogHotKeys = (short *)&hotKeys; /* Set the and button. */ SetDialogDefaultItem(theDialog, dfltbutton); *************** *** 5777,5786 **** dialog_busy = TRUE; #endif /* Hang until one of the button is hit */ do { ! ModalDialog(nil, &itemHit); } while ((itemHit < 1) || (itemHit > lastButton)); #ifdef USE_CARBONKEYHANDLER --- 5847,5859 ---- dialog_busy = TRUE; #endif + /* Prepare the shortcut-handling filterProc for handing to the dialog */ + dialogUPP = NewModalFilterUPP(DialogHotkeyFilterProc); + /* Hang until one of the button is hit */ do { ! ModalDialog(dialogUPP, &itemHit); } while ((itemHit < 1) || (itemHit > lastButton)); #ifdef USE_CARBONKEYHANDLER *************** *** 5803,5808 **** --- 5876,5884 ---- /* Restore the original graphical port */ SetPort(oldPort); + /* Free the modal filterProc */ + DisposeRoutineDescriptor(dialogUPP); + /* Get ride of th edialog (free memory) */ DisposeDialog(theDialog); *** ../vim-7.1.284/src/version.c Thu Mar 20 13:22:47 2008 --- src/version.c Thu Mar 20 14:38:06 2008 *************** *** 668,669 **** --- 668,671 ---- { /* Add new patch number below this line */ + /**/ + 285, /**/ -- hundred-and-one symptoms of being an internet addict: 163. You go outside for the fresh air (at -30 degrees) but open the window first to hear new mail arrive. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ download, build and distribute -- http://www.A-A-P.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///