]>
Commit | Line | Data |
---|---|---|
21166df1 AG |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 7.1.285 (extra) | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.1.285 (extra) | |
11 | Problem: Mac: dialog hotkeys don't work. | |
12 | Solution: Add hotkey support. (Dan Sandler) | |
13 | Files: src/gui_mac.c | |
14 | ||
15 | ||
16 | *** ../vim-7.1.284/src/gui_mac.c Wed Mar 12 21:47:31 2008 | |
17 | --- src/gui_mac.c Sun Mar 16 15:25:13 2008 | |
18 | *************** | |
19 | *** 153,158 **** | |
20 | --- 153,161 ---- | |
21 | /* Keeping track of which scrollbar is being dragged */ | |
22 | static ControlHandle dragged_sb = NULL; | |
23 | ||
24 | + /* Vector of char_u --> control index for hotkeys in dialogs */ | |
25 | + static short *gDialogHotKeys; | |
26 | + | |
27 | static struct | |
28 | { | |
29 | FMFontFamily family; | |
30 | *************** | |
31 | *** 5519,5524 **** | |
32 | --- 5522,5570 ---- | |
33 | SetDialogItemText(itemHandle, itemName); | |
34 | } | |
35 | ||
36 | + | |
37 | + /* ModalDialog() handler for message dialogs that have hotkey accelerators. | |
38 | + * Expects a mapping of hotkey char to control index in gDialogHotKeys; | |
39 | + * setting gDialogHotKeys to NULL disables any hotkey handling. | |
40 | + */ | |
41 | + static pascal Boolean | |
42 | + DialogHotkeyFilterProc ( | |
43 | + DialogRef theDialog, | |
44 | + EventRecord *event, | |
45 | + DialogItemIndex *itemHit) | |
46 | + { | |
47 | + char_u keyHit; | |
48 | + | |
49 | + if (event->what == keyDown || event->what == autoKey) | |
50 | + { | |
51 | + keyHit = (event->message & charCodeMask); | |
52 | + | |
53 | + if (gDialogHotKeys && gDialogHotKeys[keyHit]) | |
54 | + { | |
55 | + #ifdef DEBUG_MAC_DIALOG_HOTKEYS | |
56 | + printf("user pressed hotkey '%c' --> item %d\n", keyHit, gDialogHotKeys[keyHit]); | |
57 | + #endif | |
58 | + *itemHit = gDialogHotKeys[keyHit]; | |
59 | + | |
60 | + /* When handing off to StdFilterProc, pretend that the user | |
61 | + * clicked the control manually. Note that this is also supposed | |
62 | + * to cause the button to hilite briefly (to give some user | |
63 | + * feedback), but this seems not to actually work (or it's too | |
64 | + * fast to be seen). | |
65 | + */ | |
66 | + event->what = kEventControlSimulateHit; | |
67 | + | |
68 | + return true; /* we took care of it */ | |
69 | + } | |
70 | + | |
71 | + /* Defer to the OS's standard behavior for this event. | |
72 | + * This ensures that Enter will still activate the default button. */ | |
73 | + return StdFilterProc(theDialog, event, itemHit); | |
74 | + } | |
75 | + return false; /* Let ModalDialog deal with it */ | |
76 | + } | |
77 | + | |
78 | + | |
79 | /* TODO: There have been some crashes with dialogs, check your inbox | |
80 | * (Jussi) | |
81 | */ | |
82 | *************** | |
83 | *** 5544,5549 **** | |
84 | --- 5590,5597 ---- | |
85 | GrafPtr oldPort; | |
86 | short itemHit; | |
87 | char_u *buttonChar; | |
88 | + short hotKeys[256]; /* map of hotkey -> control ID */ | |
89 | + char_u aHotKey; | |
90 | Rect box; | |
91 | short button; | |
92 | short lastButton; | |
93 | *************** | |
94 | *** 5571,5576 **** | |
95 | --- 5619,5626 ---- | |
96 | ||
97 | WindowRef theWindow; | |
98 | ||
99 | + ModalFilterUPP dialogUPP; | |
100 | + | |
101 | /* Check 'v' flag in 'guioptions': vertical button placement. */ | |
102 | vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL); | |
103 | ||
104 | *************** | |
105 | *** 5610,5615 **** | |
106 | --- 5660,5668 ---- | |
107 | buttonChar = buttons; | |
108 | button = 0; | |
109 | ||
110 | + /* initialize the hotkey mapping */ | |
111 | + memset(hotKeys, 0, sizeof(hotKeys)); | |
112 | + | |
113 | for (;*buttonChar != 0;) | |
114 | { | |
115 | /* Get the name of the button */ | |
116 | *************** | |
117 | *** 5619,5625 **** | |
118 | --- 5672,5689 ---- | |
119 | { | |
120 | if (*buttonChar != DLG_HOTKEY_CHAR) | |
121 | name[++len] = *buttonChar; | |
122 | + else | |
123 | + { | |
124 | + aHotKey = (char_u)*(buttonChar+1); | |
125 | + if (aHotKey >= 'A' && aHotKey <= 'Z') | |
126 | + aHotKey = (char_u)((int)aHotKey + (int)'a' - (int)'A'); | |
127 | + hotKeys[aHotKey] = button; | |
128 | + #ifdef DEBUG_MAC_DIALOG_HOTKEYS | |
129 | + printf("### hotKey for button %d is '%c'\n", button, aHotKey); | |
130 | + #endif | |
131 | + } | |
132 | } | |
133 | + | |
134 | if (*buttonChar != 0) | |
135 | buttonChar++; | |
136 | name[0] = len; | |
137 | *************** | |
138 | *** 5688,5694 **** | |
139 | --- 5752,5764 ---- | |
140 | (void) C2PascalString(textfield, &name); | |
141 | SetDialogItemText(itemHandle, name); | |
142 | inputItm.width = StringWidth(name); | |
143 | + | |
144 | + /* Hotkeys don't make sense if there's a text field */ | |
145 | + gDialogHotKeys = NULL; | |
146 | } | |
147 | + else | |
148 | + /* Install hotkey table */ | |
149 | + gDialogHotKeys = (short *)&hotKeys; | |
150 | ||
151 | /* Set the <ENTER> and <ESC> button. */ | |
152 | SetDialogDefaultItem(theDialog, dfltbutton); | |
153 | *************** | |
154 | *** 5777,5786 **** | |
155 | dialog_busy = TRUE; | |
156 | #endif | |
157 | ||
158 | /* Hang until one of the button is hit */ | |
159 | do | |
160 | { | |
161 | ! ModalDialog(nil, &itemHit); | |
162 | } while ((itemHit < 1) || (itemHit > lastButton)); | |
163 | ||
164 | #ifdef USE_CARBONKEYHANDLER | |
165 | --- 5847,5859 ---- | |
166 | dialog_busy = TRUE; | |
167 | #endif | |
168 | ||
169 | + /* Prepare the shortcut-handling filterProc for handing to the dialog */ | |
170 | + dialogUPP = NewModalFilterUPP(DialogHotkeyFilterProc); | |
171 | + | |
172 | /* Hang until one of the button is hit */ | |
173 | do | |
174 | { | |
175 | ! ModalDialog(dialogUPP, &itemHit); | |
176 | } while ((itemHit < 1) || (itemHit > lastButton)); | |
177 | ||
178 | #ifdef USE_CARBONKEYHANDLER | |
179 | *************** | |
180 | *** 5803,5808 **** | |
181 | --- 5876,5884 ---- | |
182 | /* Restore the original graphical port */ | |
183 | SetPort(oldPort); | |
184 | ||
185 | + /* Free the modal filterProc */ | |
186 | + DisposeRoutineDescriptor(dialogUPP); | |
187 | + | |
188 | /* Get ride of th edialog (free memory) */ | |
189 | DisposeDialog(theDialog); | |
190 | ||
191 | *** ../vim-7.1.284/src/version.c Thu Mar 20 13:22:47 2008 | |
192 | --- src/version.c Thu Mar 20 14:38:06 2008 | |
193 | *************** | |
194 | *** 668,669 **** | |
195 | --- 668,671 ---- | |
196 | { /* Add new patch number below this line */ | |
197 | + /**/ | |
198 | + 285, | |
199 | /**/ | |
200 | ||
201 | -- | |
202 | hundred-and-one symptoms of being an internet addict: | |
203 | 163. You go outside for the fresh air (at -30 degrees) but open the | |
204 | window first to hear new mail arrive. | |
205 | ||
206 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
207 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
208 | \\\ download, build and distribute -- http://www.A-A-P.org /// | |
209 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |