From defed109c22cf0e3570fcc2686645ccef8228dfc Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 May 2017 13:55:47 +0000 Subject: On Windows, use Tcl_WinTCharToUtf() in stead of Tcl_NewUnicodeObj(), since Tcl_WinTCharToUtf() works correctly when TCL_UTF_MAX==6 while Tcl_NewUnicodeObj() doesn't. All changes taken over from androwish. Thanks to Christian Werner! And ... on the go ... fixed a few memory leaks correctly detected by Christian. --- win/tkWinClipboard.c | 2 +- win/tkWinDialog.c | 52 ++++++++++++++++++++++++++++++++++++++++++++-------- win/tkWinInit.c | 7 ++++++- win/tkWinSend.c | 42 ++++++++++++++++++++++++++++++++++-------- win/tkWinSendCom.c | 25 ++++++++++++++++++++----- win/tkWinTest.c | 5 ++++- 6 files changed, 109 insertions(+), 24 deletions(-) diff --git a/win/tkWinClipboard.c b/win/tkWinClipboard.c index 929070b..03c0cde 100644 --- a/win/tkWinClipboard.c +++ b/win/tkWinClipboard.c @@ -331,7 +331,7 @@ TkWinClipboardRender( #ifdef UNICODE Tcl_DStringInit(&ds); - Tcl_UtfToUniCharDString(rawText, -1, &ds); + Tcl_WinUtfToTChar(rawText, -1, &ds); ckfree(rawText); handle = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, (unsigned) Tcl_DStringLength(&ds) + 2); diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index a7d8c7d..635b9a3 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -1379,17 +1379,27 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, goto vamoose; if (optsPtr->extObj != NULL) { - wstr = Tcl_GetUnicode(optsPtr->extObj); + Tcl_DString ds; + const char *src; + + src = Tcl_GetString(optsPtr->extObj); + wstr = (LPWSTR) Tcl_WinUtfToTChar(src, optsPtr->extObj->length, &ds); if (wstr[0] == L'.') ++wstr; hr = fdlgIf->lpVtbl->SetDefaultExtension(fdlgIf, wstr); + Tcl_DStringFree(&ds); if (FAILED(hr)) goto vamoose; } if (optsPtr->titleObj != NULL) { - hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, - Tcl_GetUnicode(optsPtr->titleObj)); + Tcl_DString ds; + const char *src; + + src = Tcl_GetString(optsPtr->titleObj); + wstr = (LPWSTR) Tcl_WinUtfToTChar(src, optsPtr->titleObj->length, &ds); + hr = fdlgIf->lpVtbl->SetTitle(fdlgIf, wstr); + Tcl_DStringFree(&ds); if (FAILED(hr)) goto vamoose; } @@ -1464,12 +1474,14 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, SIGDN_FILESYSPATH, &wstr); if (SUCCEEDED(hr)) { Tcl_DString fnds; + ConvertExternalFilename(wstr, &fnds); CoTaskMemFree(wstr); Tcl_ListObjAppendElement( interp, multiObj, Tcl_NewStringObj(Tcl_DStringValue(&fnds), Tcl_DStringLength(&fnds))); + Tcl_DStringFree(&fnds); } itemIf->lpVtbl->Release(itemIf); if (FAILED(hr)) @@ -1490,10 +1502,12 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, &wstr); if (SUCCEEDED(hr)) { Tcl_DString fnds; + ConvertExternalFilename(wstr, &fnds); resultObj = Tcl_NewStringObj(Tcl_DStringValue(&fnds), Tcl_DStringLength(&fnds)); CoTaskMemFree(wstr); + Tcl_DStringFree(&fnds); } resultIf->lpVtbl->Release(resultIf); } @@ -1501,13 +1515,20 @@ static int GetFileNameVista(Tcl_Interp *interp, OFNOpts *optsPtr, if (SUCCEEDED(hr)) { if (filterPtr && optsPtr->typeVariableObj) { UINT ftix; + hr = fdlgIf->lpVtbl->GetFileTypeIndex(fdlgIf, &ftix); if (SUCCEEDED(hr)) { /* Note ftix is a 1-based index */ if (ftix > 0 && ftix <= nfilters) { + Tcl_DString ftds; + Tcl_Obj *ftobj; + + Tcl_WinTCharToUtf(filterPtr[ftix-1].pszName, -1, &ftds); + ftobj = Tcl_NewStringObj(Tcl_DStringValue(&ftds), + Tcl_DStringLength(&ftds)); Tcl_ObjSetVar2(interp, optsPtr->typeVariableObj, NULL, - Tcl_NewUnicodeObj(filterPtr[ftix-1].pszName, -1), - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + ftobj, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG); + Tcl_DStringFree(&ftds); } } } @@ -2786,6 +2807,9 @@ Tk_MessageBoxObjCmd( }; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_DString titleBuf, tmpBuf; + WCHAR *titlePtr, *tmpPtr; + const char *src; defaultBtn = -1; detailObj = NULL; @@ -2896,7 +2920,9 @@ Tk_MessageBoxObjCmd( : Tcl_NewUnicodeObj(NULL, 0); Tcl_IncrRefCount(tmpObj); if (detailObj) { - Tcl_AppendUnicodeToObj(tmpObj, L"\n\n", 2); + const Tcl_UniChar twoNL[] = { '\n', '\n' }; + + Tcl_AppendUnicodeToObj(tmpObj, twoNL, 2); Tcl_AppendObjToObj(tmpObj, detailObj); } @@ -2915,8 +2941,18 @@ Tk_MessageBoxObjCmd( tsdPtr->hBigIcon = TkWinGetIcon(parent, ICON_BIG); tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL, GetCurrentThreadId()); - winCode = MessageBox(hWnd, Tcl_GetUnicode(tmpObj), - titleObj ? Tcl_GetUnicode(titleObj) : L"", flags); + src = Tcl_GetString(tmpObj); + tmpPtr = Tcl_WinUtfToTChar(src, tmpObj->length, &tmpBuf); + if (titleObj != NULL) { + src = Tcl_GetString(titleObj); + titlePtr = Tcl_WinUtfToTChar(src, titleObj->length, &titleBuf); + } else { + titlePtr = L""; + Tcl_DStringInit(&titleBuf); + } + winCode = MessageBox(hWnd, tmpPtr, titlePtr, flags); + Tcl_DStringFree(&titleBuf); + Tcl_DStringFree(&tmpBuf); UnhookWindowsHookEx(tsdPtr->hMsgBoxHook); (void) Tcl_SetServiceMode(oldMode); diff --git a/win/tkWinInit.c b/win/tkWinInit.c index b1b2d6b..4c18399 100644 --- a/win/tkWinInit.c +++ b/win/tkWinInit.c @@ -181,6 +181,9 @@ TkWin32ErrorObj( LPTSTR lpBuffer = NULL, p = NULL; TCHAR sBuffer[30]; Tcl_Obj* errPtr = NULL; +#ifdef _UNICODE + Tcl_DString ds; +#endif FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD)hrError, @@ -196,7 +199,9 @@ TkWin32ErrorObj( } #ifdef _UNICODE - errPtr = Tcl_NewUnicodeObj(lpBuffer, (int)wcslen(lpBuffer)); + Tcl_WinTCharToUtf(lpBuffer, (int)wcslen(lpBuffer) * sizeof (WCHAR), &ds); + errPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); #else errPtr = Tcl_NewStringObj(lpBuffer, (int)strlen(lpBuffer)); #endif /* _UNICODE */ diff --git a/win/tkWinSend.c b/win/tkWinSend.c index 6c4731a..c999c0b 100644 --- a/win/tkWinSend.c +++ b/win/tkWinSend.c @@ -252,8 +252,14 @@ TkGetInterpNames( LPOLESTR p = olestr + wcslen(oleszStub); if (*p) { + Tcl_DString ds; + + Tcl_WinTCharToUtf(p + 1, -1, &ds); result = Tcl_ListObjAppendElement(interp, - objList, Tcl_NewUnicodeObj(p + 1, -1)); + objList, + Tcl_NewStringObj(Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds))); + Tcl_DStringFree(&ds); } } @@ -614,7 +620,7 @@ BuildMoniker( Tcl_DString dString; Tcl_DStringInit(&dString); - Tcl_UtfToUniCharDString(name, -1, &dString); + Tcl_WinUtfToTChar(name, -1, &dString); hr = CreateFileMoniker((LPOLESTR)Tcl_DStringValue(&dString), &pmkItem); Tcl_DStringFree(&dString); if (SUCCEEDED(hr)) { @@ -740,6 +746,8 @@ Send( HRESULT hr = S_OK, ehr = S_OK; Tcl_Obj *cmd = NULL; DISPID dispid; + Tcl_DString ds; + const char *src; cmd = Tcl_ConcatObj(objc, objv); @@ -753,7 +761,10 @@ Send( memset(&ei, 0, sizeof(ei)); vCmd.vt = VT_BSTR; - vCmd.bstrVal = SysAllocString(Tcl_GetUnicode(cmd)); + src = Tcl_GetString(cmd); + Tcl_WinUtfToTChar(src, cmd->length, &ds); + vCmd.bstrVal = SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); dp.cArgs = 1; dp.rgvarg = &vCmd; @@ -774,7 +785,9 @@ Send( ehr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR); if (SUCCEEDED(ehr)) { - Tcl_SetObjResult(interp, Tcl_NewUnicodeObj(vResult.bstrVal, -1)); + Tcl_WinTCharToUtf(vResult.bstrVal, (int) SysStringLen(vResult.bstrVal) * + sizeof (WCHAR), &ds); + Tcl_DStringResult(interp, &ds); } /* @@ -785,8 +798,11 @@ Send( if (hr == DISP_E_EXCEPTION && ei.bstrSource != NULL) { Tcl_Obj *opError, *opErrorCode, *opErrorInfo; - - opError = Tcl_NewUnicodeObj(ei.bstrSource, -1); + Tcl_WinTCharToUtf(ei.bstrSource, (int) SysStringLen(ei.bstrSource) * + sizeof (WCHAR), &ds); + opError = Tcl_NewStringObj(Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); Tcl_ListObjIndex(interp, opError, 0, &opErrorCode); Tcl_SetObjErrorCode(interp, opErrorCode); Tcl_ListObjIndex(interp, opError, 1, &opErrorInfo); @@ -833,6 +849,8 @@ TkWinSend_SetExcepInfo( ICreateErrorInfo *pCEI; IErrorInfo *pEI, **ppEI = &pEI; HRESULT hr; + Tcl_DString ds; + const char *src; if (!pExcepInfo) { return; @@ -851,8 +869,16 @@ TkWinSend_SetExcepInfo( Tcl_ListObjAppendElement(interp, opErrorCode, opErrorInfo); /* TODO: Handle failure to append */ - pExcepInfo->bstrDescription = SysAllocString(Tcl_GetUnicode(opError)); - pExcepInfo->bstrSource = SysAllocString(Tcl_GetUnicode(opErrorCode)); + src = Tcl_GetString(opError); + Tcl_WinUtfToTChar(src, opError->length, &ds); + pExcepInfo->bstrDescription = + SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); + src = Tcl_GetString(opErrorCode); + Tcl_WinUtfToTChar(src, opErrorCode->length, &ds); + pExcepInfo->bstrSource = + SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); Tcl_DecrRefCount(opErrorCode); pExcepInfo->scode = E_FAIL; diff --git a/win/tkWinSendCom.c b/win/tkWinSendCom.c index 83dd56b..9e5b7a0 100644 --- a/win/tkWinSendCom.c +++ b/win/tkWinSendCom.c @@ -370,6 +370,7 @@ Async( { HRESULT hr = S_OK; VARIANT vCmd; + Tcl_DString ds; VariantInit(&vCmd); @@ -382,9 +383,13 @@ Async( } if (SUCCEEDED(hr) && obj->interp) { - Tcl_Obj *scriptPtr = Tcl_NewUnicodeObj(vCmd.bstrVal, - (int) SysStringLen(vCmd.bstrVal)); + Tcl_Obj *scriptPtr; + Tcl_WinTCharToUtf(vCmd.bstrVal, (int) SysStringLen(vCmd.bstrVal) * + sizeof (WCHAR), &ds); + scriptPtr = + Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); TkWinSend_QueueCommand(obj->interp, scriptPtr); } @@ -424,6 +429,7 @@ Send( VARIANT v; register Tcl_Interp *interp = obj->interp; Tcl_Obj *scriptPtr; + Tcl_DString ds; if (interp == NULL) { return S_OK; @@ -434,17 +440,26 @@ Send( return hr; } - scriptPtr = Tcl_NewUnicodeObj(v.bstrVal, (int) SysStringLen(v.bstrVal)); + Tcl_WinTCharToUtf(v.bstrVal, (int) SysStringLen(v.bstrVal) * + sizeof (WCHAR), &ds); + scriptPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); Tcl_Preserve(interp); Tcl_IncrRefCount(scriptPtr); result = Tcl_EvalObjEx(interp, scriptPtr, TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL); Tcl_DecrRefCount(scriptPtr); if (pvResult != NULL) { + Tcl_Obj *obj; + const char *src; + VariantInit(pvResult); pvResult->vt = VT_BSTR; - pvResult->bstrVal = SysAllocString(Tcl_GetUnicode( - Tcl_GetObjResult(interp))); + obj = Tcl_GetObjResult(interp); + src = Tcl_GetString(obj); + Tcl_WinUtfToTChar(src, obj->length, &ds); + pvResult->bstrVal = SysAllocString((WCHAR *) Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); } if (result == TCL_ERROR) { hr = DISP_E_EXCEPTION; diff --git a/win/tkWinTest.c b/win/tkWinTest.c index d824ee4..6e79df3 100644 --- a/win/tkWinTest.c +++ b/win/tkWinTest.c @@ -515,6 +515,7 @@ TestgetwindowinfoObjCmd( Tcl_Obj *childrenObj = NULL; TCHAR buf[512]; int cch, cchBuf = 256; + Tcl_DString ds; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "hwnd"); @@ -542,7 +543,9 @@ TestgetwindowinfoObjCmd( Tcl_NewLongObj(GetWindowLongA(INT2PTR(hwnd), GWL_ID))); cch = GetWindowText(INT2PTR(hwnd), (LPTSTR)buf, cchBuf); - textObj = Tcl_NewUnicodeObj((LPCWSTR)buf, cch); + Tcl_WinTCharToUtf(buf, cch * sizeof (WCHAR), &ds); + textObj = Tcl_NewStringObj(Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); + Tcl_DStringFree(&ds); Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("text", 4), textObj); Tcl_DictObjPut(interp, dictObj, Tcl_NewStringObj("parent", 6), -- cgit v0.12 From f19be0447c6d2d01a10d3881d6f8aab3c87dad5d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 May 2017 15:06:01 +0000 Subject: Constrain test that demands user interaction --- tests/menu.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/menu.test b/tests/menu.test index 05356e3..ebf3fb7 100644 --- a/tests/menu.test +++ b/tests/menu.test @@ -3879,7 +3879,7 @@ test menu-37.1 {menubar menues cannot be posted - bug 2160206} -setup { } -result {1 {a menubar menu cannot be posted}} test menu-38.1 {Can't dismiss ttk::menubutton menu until mouse has hovered over it - bug fa32290898} -setup { -} -constraints {macOrUnix} -body { +} -constraints {userInteraction} -body { toplevel .top ttk::menubutton .top.mb -text "Some menu"; menu .top.mb.m; -- cgit v0.12 From 8a4d0d14da64361e454f103ecd196a53318f1a32 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 6 May 2017 02:14:16 +0000 Subject: Add support for file filters in tk_getSaveFile on macOS/Cocoa --- macosx/tkMacOSXDialog.c | 74 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index cd289d2..9970bc1 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -24,9 +24,11 @@ #define modalOther -1 #define modalError -2 -/*Vars for filtering in "open file" dialog.*/ +/*Vars for filtering in "open file" and "save file" dialogs.*/ NSMutableArray *openFileTypes; +NSMutableArray *saveFileTypes; NSOpenPanel *openpanel; +NSSavePanel *savepanel; static const char *const colorOptionStrings[] = { "-initialcolor", "-parent", "-title", NULL @@ -262,6 +264,16 @@ static NSURL *getFileURL(NSString *directory, NSString *filename) { } +- (void)saveFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + NSInteger selectedItemIndex = [button indexOfSelectedItem]; + saveFileTypes = nil; + saveFileTypes = [NSMutableArray array]; + [saveFileTypes addObject:[button titleOfSelectedItem]]; + [savepanel setAllowedFileTypes:saveFileTypes]; + +} + @end #pragma mark - @@ -410,7 +422,6 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message, *title, *type; NSWindow *parent; - // NSOpenPanel *panel = [NSOpenPanel openPanel]; openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -518,7 +529,6 @@ Tk_GetOpenFileObjCmd( } } - /*Accessory view for file filtering. Adapted from http://codefromabove.com/2015/01/nssavepanel-adding-an-accessory-view/ */ NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; [label setEditable:NO]; @@ -634,7 +644,7 @@ Tk_GetSaveFileObjCmd( NSString *message, *title, *type; NSWindow *parent; NSMutableArray *fileTypes = nil; - NSSavePanel *panel = [NSSavePanel savePanel]; + savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -678,13 +688,13 @@ Tk_GetSaveFileObjCmd( if (len) { filename = [[[NSString alloc] initWithUTF8String:str] autorelease]; - [panel setNameFieldStringValue:filename]; + [savepanel setNameFieldStringValue:filename]; } break; case SAVE_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; + [savepanel setMessage:message]; [message release]; break; case SAVE_PARENT: @@ -698,7 +708,7 @@ Tk_GetSaveFileObjCmd( case SAVE_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; + [savepanel setTitle:title]; [title release]; break; case SAVE_TYPEVARIABLE: @@ -715,8 +725,6 @@ Tk_GetSaveFileObjCmd( } } if (fl.filters || defaultType) { - fileTypes = [NSMutableArray array]; - [fileTypes addObject:defaultType ? defaultType : (id)kUTTypeContent]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -729,19 +737,37 @@ Tk_GetSaveFileObjCmd( } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; + if (![saveFileTypes containsObject:type]) { + [saveFileTypes addObject:type]; } [type release]; } } } } - [panel setAllowedFileTypes:fileTypes]; - [panel setAllowsOtherFileTypes:YES]; + + + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Enable:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:saveFileTypes]; + [popupButton setAction:@selector(saveFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + [savepanel setAllowedFileTypes:saveFileTypes]; + + [savepanel setAccessoryView:accessoryView]; + [savepanel setAllowsOtherFileTypes:YES]; } - [panel setCanSelectHiddenExtension:YES]; - [panel setExtensionHidden:NO]; + [savepanel setCanSelectHiddenExtension:YES]; + [savepanel setExtensionHidden:NO]; if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { @@ -756,7 +782,7 @@ Tk_GetSaveFileObjCmd( if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory + [savepanel beginSheetForDirectory:directory file:filename modalForWindow:parent modalDelegate:NSApp @@ -764,22 +790,22 @@ Tk_GetSaveFileObjCmd( @selector(tkFilePanelDidEnd:returnCode:contextInfo:) contextInfo:callbackInfo]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + [savepanel setDirectoryURL:getFileURL(directory, filename)]; + [savepanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:savepanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; #endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel]; } else { #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory file:filename]; + modalReturnCode = [savepanel runModalForDirectory:directory file:filename]; #else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; + [savepanel setDirectoryURL:getFileURL(directory, filename)]; + modalReturnCode = [savepanel runModal]; #endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; -- cgit v0.12 From cfbabe08a1a584f554365f7387e6c7a59799e0c8 Mon Sep 17 00:00:00 2001 From: Kevin Walzer Date: Sat, 6 May 2017 15:37:27 +0000 Subject: tk_getSaveFile now correctly displays multiple file types with filtering on macOS --- macosx/tkMacOSXDialog.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 9970bc1..ca55c60 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -725,6 +725,7 @@ Tk_GetSaveFileObjCmd( } } if (fl.filters || defaultType) { + saveFileTypes = [NSMutableArray array]; for (FileFilter *filterPtr = fl.filters; filterPtr; filterPtr = filterPtr->next) { for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; @@ -733,8 +734,8 @@ Tk_GetSaveFileObjCmd( globPtr = globPtr->next) { str = globPtr->pattern; while (*str && (*str == '*' || *str == '.')) { - str++; - } + str++; + } if (*str) { type = [[NSString alloc] initWithUTF8String:str]; if (![saveFileTypes containsObject:type]) { -- cgit v0.12 From 83920326ba5851cad594e6a261205a202b75a338 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 May 2017 11:18:52 +0000 Subject: Don't use sizeof(struct) when the structure has a char array as last element: If the size of this array changes, we'll be in trouble. --- generic/tkSelect.c | 4 ++-- generic/tkTextDisp.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/generic/tkSelect.c b/generic/tkSelect.c index ab9018a..d763411 100644 --- a/generic/tkSelect.c +++ b/generic/tkSelect.c @@ -190,8 +190,8 @@ Tk_CreateSelHandler( * should make a copy for this selPtr. */ - unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + - ((CommandInfo *)clientData)->cmdLength + 1; + unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + 1 + + ((CommandInfo *)clientData)->cmdLength; selPtr->clientData = ckalloc(cmdInfoLen); memcpy(selPtr->clientData, clientData, cmdInfoLen); diff --git a/generic/tkTextDisp.c b/generic/tkTextDisp.c index 371e910..03d11e1 100644 --- a/generic/tkTextDisp.c +++ b/generic/tkTextDisp.c @@ -7561,7 +7561,7 @@ TkTextCharLayoutProc( ciPtr = &bciPtr->ci; } else { bciPtr = baseCharChunkPtr->clientData; - ciPtr = ckalloc(sizeof(CharInfo)); + ciPtr = ckalloc(Tk_Offset(CharInfo, chars) + 1); baseString = &bciPtr->baseChars; } -- cgit v0.12 From 39dd1134f379cf247b40c74d68ea6bec62edb33e Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 8 May 2017 12:02:25 +0000 Subject: Remove calls to Tk_FreeXId(), since it's just a NOP. --- generic/tkGC.c | 7 ------- unix/tkUnixCursor.c | 1 - unix/tkUnixXId.c | 1 - 3 files changed, 9 deletions(-) diff --git a/generic/tkGC.c b/generic/tkGC.c index 5663ede..c424e30 100644 --- a/generic/tkGC.c +++ b/generic/tkGC.c @@ -314,7 +314,6 @@ Tk_FreeGC( gcPtr = Tcl_GetHashValue(idHashPtr); gcPtr->refCount--; if (gcPtr->refCount == 0) { - Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(idHashPtr); @@ -351,12 +350,6 @@ TkGCCleanup( entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { gcPtr = Tcl_GetHashValue(entryPtr); - /* - * This call is not needed, as it is only used on Unix to restore the - * Id to the stack pool, and we don't want to use them anymore. - * Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); - */ - XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(entryPtr); diff --git a/unix/tkUnixCursor.c b/unix/tkUnixCursor.c index 5266bde..8afb92d 100644 --- a/unix/tkUnixCursor.c +++ b/unix/tkUnixCursor.c @@ -639,7 +639,6 @@ TkpFreeCursor( TkUnixCursor *unixCursorPtr = (TkUnixCursor *) cursorPtr; XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor); - Tk_FreeXId(unixCursorPtr->display, (XID) unixCursorPtr->info.cursor); } /* diff --git a/unix/tkUnixXId.c b/unix/tkUnixXId.c index 668f228..ec2451c 100644 --- a/unix/tkUnixXId.c +++ b/unix/tkUnixXId.c @@ -96,7 +96,6 @@ Tk_FreePixmap( Pixmap pixmap) /* Identifier for pixmap. */ { XFreePixmap(display, pixmap); - Tk_FreeXId(display, (XID) pixmap); } -- cgit v0.12