2 Subject: patch 7.0.232 (extra)
4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
11 Problem: Mac: doesn't support GUI tab page labels.
12 Solution: Add GUI tab page labels. (Nicolas Weber)
13 Files: src/feature.h, src/gui.c, src/gui.h, src/gui_mac.c,
17 *** ../vim-7.0.231/src/feature.h Wed Nov 1 18:10:36 2006
18 --- src/feature.h Thu Mar 15 19:02:15 2007
22 #if defined(FEAT_WINDOWS) && defined(FEAT_NORMAL) \
23 && (defined(FEAT_GUI_GTK) \
24 || (defined(FEAT_GUI_MOTIF) && defined(HAVE_XM_NOTEBOOK_H)) \
25 + || defined(FEAT_GUI_MAC) \
26 || (defined(FEAT_GUI_MSWIN) && (!defined(_MSC_VER) || _MSC_VER > 1020)))
27 # define FEAT_GUI_TABLINE
29 *** ../vim-7.0.231/src/gui.c Tue Oct 10 17:36:50 2006
30 --- src/gui.c Thu Mar 15 19:02:15 2007
35 # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
36 ! || defined(FEAT_GUI_MOTIF))
37 if (gui_has_tabline())
38 text_area_y += gui.tabline_height;
43 # if defined(FEAT_GUI_TABLINE) && (defined(FEAT_GUI_MSWIN) \
44 ! || defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_MAC))
45 if (gui_has_tabline())
46 text_area_y += gui.tabline_height;
48 *** ../vim-7.0.231/src/gui.h Thu Apr 27 01:52:33 2006
49 --- src/gui.h Thu Mar 15 19:02:15 2007
52 #endif /* FEAT_GUI_GTK */
54 #if defined(FEAT_GUI_TABLINE) \
55 ! && (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF))
60 #endif /* FEAT_GUI_GTK */
62 #if defined(FEAT_GUI_TABLINE) \
63 ! && (defined(FEAT_GUI_W32) || defined(FEAT_GUI_MOTIF) \
64 ! || defined(FEAT_GUI_MAC))
68 *** ../vim-7.0.231/src/gui_mac.c Thu Mar 8 20:39:02 2007
69 --- src/gui_mac.c Fri Mar 16 11:26:05 2007
72 * GUI/Motif support by Robert Webb
73 * Macintosh port by Dany St-Amant
75 ! * Port to MPW by Bernhard Pr
\9fmmer
76 * Initial Carbon port by Ammon Skidmore
78 * Do ":help uganda" in Vim to read copying and usage conditions.
80 * GUI/Motif support by Robert Webb
81 * Macintosh port by Dany St-Amant
83 ! * Port to MPW by Bernhard Pruemmer
84 * Initial Carbon port by Ammon Skidmore
86 * Do ":help uganda" in Vim to read copying and usage conditions.
90 OSErr HandleUnusedParms(const AppleEvent *theAEvent);
93 + #ifdef FEAT_GUI_TABLINE
94 + static void initialise_tabline(void);
95 + static WindowRef drawer = NULL; // TODO: put into gui.h
99 * ------------------------------------------------------------
105 thePart = FindWindow(theEvent->where, &whichWindow);
107 + #ifdef FEAT_GUI_TABLINE
108 + /* prevent that the vim window size changes if it's activated by a
109 + click into the tab pane */
110 + if (whichWindow == drawer)
123 + #ifdef FEAT_GUI_TABLINE
125 + * Create the tabline
127 + initialise_tabline();
130 /* TODO: Load bitmap if using TOOLBAR */
135 theCPB.dirInfo.ioFDirIndex = 0;
136 theCPB.dirInfo.ioNamePtr = file.name;
137 theCPB.dirInfo.ioVRefNum = file.vRefNum;
138 ! /*theCPB.hFileInfo.ioDirID = 0;*/
139 theCPB.dirInfo.ioDrDirID = file.parID;
141 /* As ioFDirIndex = 0, get the info of ioNamePtr,
143 theCPB.dirInfo.ioFDirIndex = 0;
144 theCPB.dirInfo.ioNamePtr = file.name;
145 theCPB.dirInfo.ioVRefNum = file.vRefNum;
146 ! /*theCPB.hFileInfo.ioDirID = 0;*/
147 theCPB.dirInfo.ioDrDirID = file.parID;
149 /* As ioFDirIndex = 0, get the info of ioNamePtr,
153 return (script != smRoman
154 && script == GetScriptManagerVariable(smSysScript)) ? 1 : 0;
157 #endif /* defined(USE_IM_CONTROL) || defined(PROTO) */
162 + #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
163 + // drawer implementation
164 + static MenuRef contextMenu = NULL;
167 + kTabContextMenuId = 42,
170 + // the caller has to CFRelease() the returned string
172 + getTabLabel(tabpage_T *page)
174 + get_tabline_label(page, FALSE);
175 + #ifdef MACOS_CONVERT
176 + return mac_enc_to_cfstring(NameBuff, STRLEN(NameBuff));
178 + // TODO: check internal encoding?
179 + return CFStringCreateWithCString(kCFAllocatorDefault, (char *)NameBuff,
180 + kCFStringEncodingMacRoman);
185 + #define DRAWER_SIZE 150
186 + #define DRAWER_INSET 16
188 + static ControlRef dataBrowser = NULL;
190 + // when the tabline is hidden, vim doesn't call update_tabline(). When
191 + // the tabline is shown again, show_tabline() is called before upate_tabline(),
192 + // and because of this, the tab labels and vims internal tabs are out of sync
193 + // for a very short time. to prevent inconsistent state, we store the labels
194 + // of the tabs, not pointers to the tabs (which are invalid for a short time).
195 + static CFStringRef *tabLabels = NULL;
196 + static int tabLabelsSize = 0;
200 + kTabsColumn = 'Tabs'
209 + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
214 + // data browser item display callback
216 + dbItemDataCallback(ControlRef browser,
217 + DataBrowserItemID itemID,
218 + DataBrowserPropertyID property /* column id */,
219 + DataBrowserItemDataRef itemData,
220 + Boolean changeValue)
222 + OSStatus status = noErr;
224 + // assert(property == kTabsColumn); // why is this violated??
226 + // changeValue is true if we have a modifieable list and data was changed.
227 + // In our case, it's always false.
228 + // (that is: if (changeValue) updateInternalData(); else return
234 + assert(itemID - 1 >= 0 && itemID - 1 < tabLabelsSize);
235 + str = tabLabels[itemID - 1];
236 + status = SetDataBrowserItemDataText(itemData, str);
239 + status = errDataBrowserPropertyNotSupported;
244 + // data browser action callback
246 + dbItemNotificationCallback(ControlRef browser,
247 + DataBrowserItemID item,
248 + DataBrowserItemNotification message)
252 + case kDataBrowserItemSelected:
253 + send_tabline_event(item);
258 + // callbacks needed for contextual menu:
260 + dbGetContextualMenuCallback(ControlRef browser,
263 + CFStringRef *helpItemString,
266 + // on mac os 9: kCMHelpItemNoHelp, but it's not the same
267 + *helpType = kCMHelpItemRemoveHelp; // OS X only ;-)
268 + *helpItemString = NULL;
270 + *menu = contextMenu;
274 + dbSelectContextualMenuCallback(ControlRef browser,
276 + UInt32 selectionType,
278 + MenuItemIndex menuItem)
280 + if (selectionType == kCMMenuItemSelected)
282 + MenuCommand command;
283 + GetMenuItemCommandID(menu, menuItem, &command);
285 + // get tab that was selected when the context menu appeared
286 + // (there is always one tab selected). TODO: check if the context menu
287 + // isn't opened on an item but on empty space (has to be possible some
288 + // way, the finder does it too ;-) )
289 + Handle items = NewHandle(0);
294 + GetDataBrowserItems(browser, kDataBrowserNoItem, false,
295 + kDataBrowserItemIsSelected, items);
296 + numItems = GetHandleSize(items) / sizeof(DataBrowserItemID);
300 + DataBrowserItemID *itemsPtr;
303 + itemsPtr = (DataBrowserItemID *)*items;
306 + send_tabline_menu_event(idx, command);
308 + DisposeHandle(items);
313 + // focus callback of the data browser to always leave focus in vim
315 + dbFocusCallback(EventHandlerCallRef handler, EventRef event, void *data)
317 + assert(GetEventClass(event) == kEventClassControl
318 + && GetEventKind(event) == kEventControlSetFocusPart);
324 + // drawer callback to resize data browser to drawer size
326 + drawerCallback(EventHandlerCallRef handler, EventRef event, void *data)
328 + switch (GetEventKind(event))
330 + case kEventWindowBoundsChanged: // move or resize
333 + GetEventParameter(event, kEventParamAttributes, typeUInt32,
334 + NULL, sizeof(attribs), NULL, &attribs);
335 + if (attribs & kWindowBoundsChangeSizeChanged) // resize
338 + GetWindowBounds(drawer, kWindowContentRgn, &r);
339 + SetRect(&r, 0, 0, r.right - r.left, r.bottom - r.top);
340 + SetControlBounds(dataBrowser, &r);
341 + SetDataBrowserTableViewNamedColumnWidth(dataBrowser,
342 + kTabsColumn, r.right);
348 + return eventNotHandledErr;
351 + // Load DataBrowserChangeAttributes() dynamically on tiger (and better).
352 + // This way the code works on 10.2 and 10.3 as well (it doesn't have the
353 + // blue highlights in the list view on these systems, though. Oh well.)
356 + #import <mach-o/dyld.h>
358 + enum { kMyDataBrowserAttributeListViewAlternatingRowColors = (1 << 1) };
361 + myDataBrowserChangeAttributes(ControlRef inDataBrowser,
362 + OptionBits inAttributesToSet,
363 + OptionBits inAttributesToClear)
367 + NSSymbol symbol = NULL;
368 + OSStatus (*dataBrowserChangeAttributes)(ControlRef inDataBrowser,
369 + OptionBits inAttributesToSet, OptionBits inAttributesToClear);
371 + Gestalt(gestaltSystemVersion, &osVersion);
372 + if (osVersion < 0x1040) // only supported for 10.4 (and up)
375 + // C name mangling...
376 + symbolName = "_DataBrowserChangeAttributes";
377 + if (!NSIsSymbolNameDefined(symbolName)
378 + || (symbol = NSLookupAndBindSymbol(symbolName)) == NULL)
381 + dataBrowserChangeAttributes = NSAddressOfSymbol(symbol);
382 + if (dataBrowserChangeAttributes == NULL)
383 + return noErr; // well...
384 + return dataBrowserChangeAttributes(inDataBrowser,
385 + inAttributesToSet, inAttributesToClear);
389 + initialise_tabline(void)
391 + Rect drawerRect = { 0, 0, 0, DRAWER_SIZE };
392 + DataBrowserCallbacks dbCallbacks;
393 + EventTypeSpec focusEvent = {kEventClassControl, kEventControlSetFocusPart};
394 + EventTypeSpec resizeEvent = {kEventClassWindow, kEventWindowBoundsChanged};
395 + DataBrowserListViewColumnDesc colDesc;
397 + // drawers have to have compositing enabled
398 + CreateNewWindow(kDrawerWindowClass,
399 + kWindowStandardHandlerAttribute
400 + | kWindowCompositingAttribute
401 + | kWindowResizableAttribute
402 + | kWindowLiveResizeAttribute,
403 + &drawerRect, &drawer);
405 + SetThemeWindowBackground(drawer, kThemeBrushDrawerBackground, true);
406 + SetDrawerParent(drawer, gui.VimWindow);
407 + SetDrawerOffsets(drawer, kWindowOffsetUnchanged, DRAWER_INSET);
410 + // create list view embedded in drawer
411 + CreateDataBrowserControl(drawer, &drawerRect, kDataBrowserListView,
414 + dbCallbacks.version = kDataBrowserLatestCallbacks;
415 + InitDataBrowserCallbacks(&dbCallbacks);
416 + dbCallbacks.u.v1.itemDataCallback =
417 + NewDataBrowserItemDataUPP(dbItemDataCallback);
418 + dbCallbacks.u.v1.itemNotificationCallback =
419 + NewDataBrowserItemNotificationUPP(dbItemNotificationCallback);
420 + dbCallbacks.u.v1.getContextualMenuCallback =
421 + NewDataBrowserGetContextualMenuUPP(dbGetContextualMenuCallback);
422 + dbCallbacks.u.v1.selectContextualMenuCallback =
423 + NewDataBrowserSelectContextualMenuUPP(dbSelectContextualMenuCallback);
425 + SetDataBrowserCallbacks(dataBrowser, &dbCallbacks);
427 + SetDataBrowserListViewHeaderBtnHeight(dataBrowser, 0); // no header
428 + SetDataBrowserHasScrollBars(dataBrowser, false, true); // only vertical
429 + SetDataBrowserSelectionFlags(dataBrowser,
430 + kDataBrowserSelectOnlyOne | kDataBrowserNeverEmptySelectionSet);
431 + SetDataBrowserTableViewHiliteStyle(dataBrowser,
432 + kDataBrowserTableViewFillHilite);
434 + SetControlData(dataBrowser, kControlEntireControl,
435 + kControlDataBrowserIncludesFrameAndFocusTag, sizeof(b), &b);
437 + // enable blue background in data browser (this is only in 10.4 and vim
438 + // has to support older osx versions as well, so we have to load this
439 + // function dynamically)
440 + myDataBrowserChangeAttributes(dataBrowser,
441 + kMyDataBrowserAttributeListViewAlternatingRowColors, 0);
443 + // install callback that keeps focus in vim and away from the data browser
444 + InstallControlEventHandler(dataBrowser, dbFocusCallback, 1, &focusEvent,
447 + // install callback that keeps data browser at the size of the drawer
448 + InstallWindowEventHandler(drawer, drawerCallback, 1, &resizeEvent,
451 + // add "tabs" column to data browser
452 + colDesc.propertyDesc.propertyID = kTabsColumn;
453 + colDesc.propertyDesc.propertyType = kDataBrowserTextType;
455 + // add if items can be selected (?): kDataBrowserListViewSelectionColumn
456 + colDesc.propertyDesc.propertyFlags = kDataBrowserDefaultPropertyFlags;
458 + colDesc.headerBtnDesc.version = kDataBrowserListViewLatestHeaderDesc;
459 + colDesc.headerBtnDesc.minimumWidth = 100;
460 + colDesc.headerBtnDesc.maximumWidth = 150;
461 + colDesc.headerBtnDesc.titleOffset = 0;
462 + colDesc.headerBtnDesc.titleString = CFSTR("Tabs");
463 + colDesc.headerBtnDesc.initialOrder = kDataBrowserOrderIncreasing;
464 + colDesc.headerBtnDesc.btnFontStyle.flags = 0; // use default font
465 + colDesc.headerBtnDesc.btnContentInfo.contentType = kControlContentTextOnly;
467 + AddDataBrowserListViewColumn(dataBrowser, &colDesc, 0);
469 + // create tabline popup menu required by vim docs (see :he tabline-menu)
470 + CreateNewMenu(kTabContextMenuId, 0, &contextMenu);
471 + AppendMenuItemTextWithCFString(contextMenu, CFSTR("Close"), 0,
472 + TABLINE_MENU_CLOSE, NULL);
473 + AppendMenuItemTextWithCFString(contextMenu, CFSTR("New Tab"), 0,
474 + TABLINE_MENU_NEW, NULL);
475 + AppendMenuItemTextWithCFString(contextMenu, CFSTR("Open Tab..."), 0,
476 + TABLINE_MENU_OPEN, NULL);
481 + * Show or hide the tabline.
484 + gui_mch_show_tabline(int showit)
487 + CloseDrawer(drawer, true);
489 + OpenDrawer(drawer, kWindowEdgeRight, true);
493 + * Return TRUE when tabline is displayed.
496 + gui_mch_showing_tabline(void)
498 + WindowDrawerState state = GetDrawerState(drawer);
500 + return state == kWindowDrawerOpen || state == kWindowDrawerOpening;
504 + * Update the labels of the tabline.
507 + gui_mch_update_tabline(void)
510 + int numTabs = getTabCount();
514 + // adjust data browser
515 + if (tabLabels != NULL)
519 + for (i = 0; i < tabLabelsSize; ++i)
520 + CFRelease(tabLabels[i]);
523 + tabLabels = (CFStringRef *)malloc(numTabs * sizeof(CFStringRef));
524 + tabLabelsSize = numTabs;
526 + for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
530 + tabLabels[nr-1] = getTabLabel(tp);
533 + RemoveDataBrowserItems(dataBrowser, kDataBrowserNoItem, 0, NULL,
534 + kDataBrowserItemNoProperty);
535 + // data browser uses ids 1, 2, 3, ... numTabs per default, so we
536 + // can pass NULL for the id array
537 + AddDataBrowserItems(dataBrowser, kDataBrowserNoItem, numTabs, NULL,
538 + kDataBrowserItemNoProperty);
540 + DataBrowserItemID item = curtabidx;
541 + SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign);
545 + * Set the current tab to "nr". First tab is 1.
548 + gui_mch_set_curtab(nr)
551 + DataBrowserItemID item = nr;
552 + SetDataBrowserSelectedItems(dataBrowser, 1, &item, kDataBrowserItemsAssign);
554 + // TODO: call something like this?: (or restore scroll position, or...)
555 + RevealDataBrowserItem(dataBrowser, item, kTabsColumn,
556 + kDataBrowserRevealOnly);
559 + #endif // FEAT_GUI_TABLINE
560 *** ../vim-7.0.231/src/proto/gui_mac.pro Tue Mar 28 23:01:02 2006
561 --- src/proto/gui_mac.pro Thu Mar 15 20:23:42 2007
565 int gui_mch_dialog __ARGS((int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield));
566 char_u *gui_mch_browse __ARGS((int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter));
567 void gui_mch_set_foreground __ARGS((void));
568 + void gui_mch_show_tabline __ARGS((int showit));
569 + int gui_mch_showing_tabline __ARGS((void));
570 + void gui_mch_update_tabline __ARGS((void));
571 + void gui_mch_set_curtab __ARGS((int nr));
573 char_u *C2Pascal_save __ARGS((char_u *Cstring));
574 char_u *C2Pascal_save_and_remove_backslash __ARGS((char_u *Cstring));
575 *** ../vim-7.0.231/src/version.c Thu Apr 26 17:23:28 2007
576 --- src/version.c Thu Apr 26 18:17:42 2007
580 { /* Add new patch number below this line */
586 hundred-and-one symptoms of being an internet addict:
587 24. You realize there is not a sound in the house and you have no idea where
590 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
591 /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
592 \\\ download, build and distribute -- http://www.A-A-P.org ///
593 \\\ help me help AIDS victims -- http://ICCF-Holland.org ///