summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2019-11-20 18:50:02 (GMT)
committerdgp <dgp@users.sourceforge.net>2019-11-20 18:50:02 (GMT)
commit72ae3baa490baaf69b7359b378361921e532ccde (patch)
tree0ceafbb929cc0ebd5eb08a80288844c8dbad7404
parent83adf45f708233fe1bed74cc67d714c40905dbbd (diff)
parente15390471f6368e52215eb6ff7bd88d3185d66e1 (diff)
downloadtk-72ae3baa490baaf69b7359b378361921e532ccde.zip
tk-72ae3baa490baaf69b7359b378361921e532ccde.tar.gz
tk-72ae3baa490baaf69b7359b378361921e532ccde.tar.bz2
Merge 8.6 except for the broken demo.
-rw-r--r--generic/tkFont.c15
-rw-r--r--library/demos/unicodeout.tcl4
-rw-r--r--macosx/tkMacOSXClipboard.c33
-rw-r--r--macosx/tkMacOSXDraw.c7
-rw-r--r--macosx/tkMacOSXFont.c172
-rw-r--r--macosx/tkMacOSXKeyEvent.c56
-rw-r--r--macosx/tkMacOSXPrivate.h4
-rw-r--r--macosx/tkMacOSXWm.c88
-rw-r--r--macosx/ttkMacOSXTheme.c17
-rw-r--r--tests/wm.test20
-rw-r--r--unix/tkUnixWm.c9
-rw-r--r--win/tkWinWm.c28
12 files changed, 293 insertions, 160 deletions
diff --git a/generic/tkFont.c b/generic/tkFont.c
index 86fdd87..156ebf3 100644
--- a/generic/tkFont.c
+++ b/generic/tkFont.c
@@ -13,7 +13,9 @@
#include "tkInt.h"
#include "tkFont.h"
-
+#if defined(MAC_OSX_TK)
+#include "tkMacOSXInt.h"
+#endif
/*
* The following structure is used to keep track of all the fonts that exist
* in the current application. It must be stored in the TkMainInfo for the
@@ -872,7 +874,18 @@ TheWorldHasChanged(
ClientData clientData) /* Info about application's fonts. */
{
TkFontInfo *fiPtr = clientData;
+#if defined(MAC_OSX_TK)
+ /*
+ * On macOS it is catastrophic to recompute all widgets while the
+ * [NSView drawRect] method is drawing. The best that we can do in
+ * that situation is to abort the recomputation and hope for the best.
+ */
+
+ if (TkpAppIsDrawing()) {
+ return;
+ }
+#endif
fiPtr->updatePending = 0;
RecomputeWidgets(fiPtr->mainPtr->winPtr);
}
diff --git a/library/demos/unicodeout.tcl b/library/demos/unicodeout.tcl
index faa9f90..811d210 100644
--- a/library/demos/unicodeout.tcl
+++ b/library/demos/unicodeout.tcl
@@ -131,6 +131,10 @@ addSample $w Japanese \
addSample $w Korean "\uB300\uD55C\uBBFC\uAD6D\uC758 \uD55C\uAE00"
addSample $w Russian \
"\u0420\u0443\u0441\u0441\u043A\u0438\u0439 \u044F\u0437\u044B\u043A"
+if {[tk windowingsystem] ne "x11"} {
+ addSample $w Emoji \
+ "\uD83D\uDE00\uD83D\uDCA9\uD83D\uDC4D\uD83C\uDDF3\uD83C\uDDF1"
+}
## We're done processing, so change things back to normal running...
destroy $w.wait
diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c
index 696b70e..db45428 100644
--- a/macosx/tkMacOSXClipboard.c
+++ b/macosx/tkMacOSXClipboard.c
@@ -35,10 +35,7 @@ static Tk_Window clipboardOwner = NULL;
targetPtr->type == dispPtr->utf8Atom) {
for (TkClipboardBuffer *cbPtr = targetPtr->firstBufferPtr;
cbPtr; cbPtr = cbPtr->nextPtr) {
- NSString *s = [[NSString alloc] initWithBytesNoCopy:
- cbPtr->buffer length:cbPtr->length
- encoding:NSUTF8StringEncoding freeWhenDone:NO];
-
+ NSString *s = TclUniToNSString(cbPtr->buffer, cbPtr->length);
[string appendString:s];
[s release];
}
@@ -130,7 +127,6 @@ TkSelGetSelection(
&& selection == dispPtr->clipboardAtom
&& (target == XA_STRING || target == dispPtr->utf8Atom)) {
NSString *string = nil;
- NSString *clean;
NSPasteboard *pb = [NSPasteboard generalPasteboard];
NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
NSStringPboardType]];
@@ -139,25 +135,20 @@ TkSelGetSelection(
string = [pb stringForType:type];
}
if (string) {
+
/*
- * Replace all non-BMP characters by the replacement character 0xfffd.
- * This is a workaround until Tcl supports TCL_UTF_MAX > 3.
+ * Encode the string using the encoding which is used in Tcl
+ * when TCL_UTF_MAX = 3. This replaces each UTF-16 surrogate with
+ * a 3-byte sequence generated using the UTF-8 algorithm. (Even
+ * though UTF-8 does not allow encoding surrogates, the algorithm
+ * does produce a 3-byte sequence.)
*/
- int i, j, len = [string length];
- CFRange all = CFRangeMake(0, len);
- UniChar *buffer = ckalloc(len*sizeof(UniChar));
- CFStringGetCharacters((CFStringRef) string, all, buffer);
- for (i = 0, j = 0 ; j < len ; i++, j++) {
- if (CFStringIsSurrogateHighCharacter(buffer[j])) {
- buffer[i] = 0xfffd;
- j++;
- } else {
- buffer[i] = buffer[j];
- }
+
+ char *bytes = NSStringToTclUni(string, NULL);
+ result = proc(clientData, interp, bytes);
+ if (bytes) {
+ ckfree(bytes);
}
- clean = (NSString *)CFStringCreateWithCharacters(NULL, buffer, i);
- ckfree(buffer);
- result = proc(clientData, interp, [clean UTF8String]);
}
} else {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index f4c0107..1bf2572 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -501,9 +501,12 @@ TkMacOSXGetNSImageWithTkImage(
int width,
int height)
{
- Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
+ Pixmap pixmap;
NSImage *nsImage;
-
+ if (width == 0 || height == 0) {
+ return nsImage = [[NSImage alloc] initWithSize:NSMakeSize(0,0)];
+ }
+ pixmap = Tk_GetPixmap(display, None, width, height, 0);
Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
nsImage = CreateNSImageWithPixmap(pixmap, width, height);
Tk_FreePixmap(display, pixmap);
diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c
index 153ce3b..9b2d11c 100644
--- a/macosx/tkMacOSXFont.c
+++ b/macosx/tkMacOSXFont.c
@@ -101,6 +101,148 @@ static void DrawCharsInContext(Display *display, Drawable drawable,
#pragma mark -
#pragma mark Font Helpers:
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclUniToNSString --
+ *
+ * When Tcl is compiled with TCL_UTF_MAX = 3 (the default for 8.6) it cannot
+ * deal directly with UTF-8 encoded non-BMP characters, since their UTF-8
+ * encoding requires 4 bytes.
+ *
+ * As a workaround, these versions of Tcl encode non-BMP characters as a string
+ * of length 6 in which the high and low UTF-16 surrogates have been encoded
+ * using the UTF-8 algorithm. The UTF-8 encoding does not allow encoding
+ * surrogates, so these 6-byte strings are not valid UTF-8, and hence Apple's
+ * NString class will refuse to instantiate an NSString from the 6-byte
+ * encoding. This function allows creating an NSString from a C-string which
+ * has been encoded using this scheme.
+ *
+ * Results:
+ * An NSString, which may be nil.
+ *
+ * Side effects:
+ * None.
+ *---------------------------------------------------------------------------
+ */
+
+MODULE_SCOPE NSString*
+TclUniToNSString(
+ const char *source,
+ int numBytes)
+{
+ NSString *string = [[NSString alloc] initWithBytesNoCopy:(void *)source
+ length:numBytes
+ encoding:NSUTF8StringEncoding
+ freeWhenDone:NO];
+ if (!string) {
+ const unichar *characters = ckalloc(numBytes*sizeof(unichar));
+ const char *in = source;
+ unichar *out = (unichar *) characters;
+ while (in < source + numBytes) {
+ in += Tcl_UtfToUniChar(in, out++);
+ }
+ string = [[NSString alloc] initWithCharacters:characters
+ length:(out - characters)];
+ ckfree(characters);
+ }
+ return string;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclUniAtIndex --
+ *
+ * Write a sequence of bytes up to length 6 which is an encoding of a UTF-16
+ * character in an NSString. Also record the unicode code point of the character.
+ * this may be a non-BMP character constructed by reading two surrogates from
+ * the NSString.
+ *
+ * Results:
+ * Returns the number of bytes written.
+ *
+ * Side effects:
+ * Bytes are written to the char array referenced by the pointer uni and
+ * the unicode code point is written to the integer referenced by the
+ * pointer code.
+ *
+ */
+
+MODULE_SCOPE int
+TclUniAtIndex(
+ NSString *string,
+ int index,
+ char *uni,
+ unsigned int *code)
+{
+ char *ptr = uni;
+ UniChar uniChar = [string characterAtIndex: index];
+ if (CFStringIsSurrogateHighCharacter(uniChar)) {
+ UniChar lowChar = [string characterAtIndex: ++index];
+ *code = CFStringGetLongCharacterForSurrogatePair(
+ uniChar, lowChar);
+ ptr += Tcl_UniCharToUtf(uniChar, ptr);
+ ptr += Tcl_UniCharToUtf(lowChar, ptr);
+ return ptr - uni;
+ } else {
+ *code = (int) uniChar;
+ [[string substringWithRange: NSMakeRange(index, 1)]
+ getCString: uni
+ maxLength: XMaxTransChars
+ encoding: NSUTF8StringEncoding];
+ return strlen(uni);
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NSStringToTclUni --
+ *
+ * Encodes the unicode string represented by an NSString object with the
+ * internal encoding that Tcl uses when TCL_UTF_MAX = 3. This encoding
+ * is similar to UTF-8 except that non-BMP characters are encoded as two
+ * successive 3-byte sequences which are constructed from UTF-16 surrogates
+ * by applying the UTF-8 algorithm. Even though the UTF-8 encoding does not
+ * allow encoding surrogates, the algorithm does produce a well-defined
+ * 3-byte sequence.
+ *
+ * Results:
+ * Returns a pointer to a null-terminated byte array which encodes the
+ * NSString.
+ *
+ * Side effects:
+ * Memory is allocated to hold the byte array, which must be freed with
+ * ckalloc. If the pointer numBytes is not NULL the number of non-null
+ * bytes written to the array is stored in the integer it references.
+ */
+
+MODULE_SCOPE char*
+NSStringToTclUni(
+ NSString *string,
+ int *numBytes)
+{
+ unsigned int code;
+ int i;
+ char *ptr, *bytes = ckalloc(6*[string length] + 1);
+
+ ptr = bytes;
+ if (ptr) {
+ for (i = 0; i < [string length]; i++) {
+ ptr += TclUniAtIndex(string, i, ptr, &code);
+ if (code > 0xffff){
+ i++;
+ }
+ }
+ *ptr = '\0';
+ }
+ if (numBytes) {
+ *numBytes = ptr - bytes;
+ }
+ return bytes;
+}
+
#define GetNSFontTraitsFromTkFontAttributes(faPtr) \
((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \
((faPtr)->slant == TK_FS_ITALIC ? NSItalicFontMask : NSUnitalicFontMask)
@@ -176,6 +318,18 @@ FindNSFont(
size = [defaultFont pointSize];
}
nsFont = [fm fontWithFamily:family traits:traits weight:weight size:size];
+
+ /*
+ * A second bug in NSFontManager that Apple created for the Catalina OS
+ * causes requests as above to sometimes return fonts with additional
+ * traits that were not requested, even though fonts without those unwanted
+ * traits exist on the system. See bug [90d555e088]. As a workaround
+ * we ask the font manager to remove any unrequested traits.
+ */
+
+ if (nsFont) {
+ nsFont = [fm convertFont:nsFont toNotHaveTrait:~traits];
+ }
if (!nsFont) {
NSArray *availableFamilies = [fm availableFontFamilies];
NSString *caseFamily = nil;
@@ -395,12 +549,15 @@ TkpFontPkgInit(
}
TkInitFontAttributes(&fa);
#if 0
+
/*
- * In macOS 10.15.1 Apple introduced a bug which caused the call below to
- * return a font with the invalid familyName ".SF NSMono" instead of the
- * valid familyName "NSMono". Calling [NSFont userFixedPitchFontOfSize:11]
- * returns a font in the "Menlo" family which has a valid familyName.
+ * In macOS 10.15.1 Apple introduced a bug in NSFontManager which caused
+ * it to not recognize the familyName ".SF NSMono" which is the familyName
+ * of the default fixed pitch system fault on that system. See bug [855049e799].
+ * As a workaround we call [NSFont userFixedPitchFontOfSize:11] instead.
+ * This returns a user font in the "Menlo" family.
*/
+
nsFont = (NSFont*) CTFontCreateUIFontForLanguage(fixedPitch, 11, NULL);
#else
nsFont = [NSFont userFixedPitchFontOfSize:11];
@@ -829,8 +986,7 @@ TkpMeasureCharsInContext(
if (maxLength > 32767) {
maxLength = 32767;
}
- string = [[NSString alloc] initWithBytesNoCopy:(void*)source
- length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
+ string = TclUniToNSString((const char *)source, numBytes);
if (!string) {
length = 0;
fit = rangeLength;
@@ -1109,12 +1265,10 @@ DrawCharsInContext(
!TkMacOSXSetupDrawingContext(drawable, gc, 1, &drawingContext)) {
return;
}
- string = [[NSString alloc] initWithBytesNoCopy:(void*)source
- length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
+ string = TclUniToNSString((const char *)source, numBytes);
if (!string) {
return;
}
-
context = drawingContext.context;
fg = TkMacOSXCreateCGColor(gc, gc->foreground);
attributes = [fontPtr->nsAttributes mutableCopy];
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index 677f77e..7ea085b 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -14,7 +14,7 @@
*/
#include "tkMacOSXPrivate.h"
-#include "tkMacOSXEvent.h"
+#include "tkMacOSXInt.h"
#include "tkMacOSXConstants.h"
/*
@@ -293,7 +293,7 @@ static unsigned isFunctionKey(unsigned int code);
NSString *str;
str = ([aString isKindOfClass: [NSAttributedString class]]) ?
- str = [aString string] : aString;
+ [aString string] : aString;
len = [str length];
if (NS_KEYLOG) {
@@ -331,42 +331,30 @@ static unsigned isFunctionKey(unsigned int code);
}
/*
- * NSString represents a non-BMP character as a string of length 2 where
- * the first character is the high surrogate and the second character is
- * the low surrogate. We could record this in the XEvent by setting the
- * keycode to the unicode code point and setting the trans_chars to the
- * 4-byte UTF-8 string. However, that will not help as long as TCL_UTF_MAX
- * is set to 3. Until that changes, we just replace non-BMP characters by
- * the "replacement character" U+FFFD.
+ * Next we generate an XEvent for each unicode character in our string.
+ *
+ * NSString uses UTF-16 internally, which means that a non-BMP character is
+ * represented by a sequence of two 16-bit "surrogates". In principle we
+ * could record this in the XEvent by setting the keycode to the 32-bit
+ * unicode code point and setting the trans_chars string to the 4-byte
+ * UTF-8 string for the non-BMP character. However, that will not work
+ * when TCL_UTF_MAX is set to 3, as is the case for Tcl 8.6. A workaround
+ * used internally by Tcl 8.6 is to encode each surrogate as a 3-byte
+ * sequence using the UTF-8 algorithm (ignoring the fact that the UTF-8
+ * encoding specification does not allow encoding UTF-16 surrogates).
+ * This gives a 6-byte encoding of the non-BMP character which we write into
+ * the trans_chars field of the XEvent.
*/
for (i = 0; i < len; i++) {
- UniChar nextChar = [str characterAtIndex: i];
- if (CFStringIsSurrogateHighCharacter(nextChar)) {
-#if 0
- UniChar lowChar = [str characterAtIndex: ++i];
- xEvent.xkey.keycode = CFStringGetLongCharacterForSurrogatePair(
- nextChar, lowChar);
- xEvent.xkey.nbytes = TkUniCharToUtf(xEvent.xkey.keycode,
- &xEvent.xkey.trans_chars);
-#else
+ xEvent.xkey.nbytes = TclUniAtIndex(str, i, xEvent.xkey.trans_chars,
+ &xEvent.xkey.keycode);
+ if (xEvent.xkey.keycode > 0xffff){
i++;
- xEvent.xkey.keycode = 0xfffd;
- strcpy(xEvent.xkey.trans_chars, "\xef\xbf\xbd");
- xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);
-#endif
- } else {
- xEvent.xkey.keycode = (int) nextChar;
- [[str substringWithRange: NSMakeRange(i,1)]
- getCString: xEvent.xkey.trans_chars
- maxLength: XMaxTransChars encoding: NSUTF8StringEncoding];
- xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);
}
- xEvent.xany.type = KeyPress;
- releaseCode = (UInt16) nextChar;
- Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
+ xEvent.xany.type = KeyPress;
+ Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
}
-
releaseCode = (UInt16) [str characterAtIndex: 0];
}
@@ -396,7 +384,7 @@ static unsigned isFunctionKey(unsigned int code);
NSString *str;
str = ([aString isKindOfClass: [NSAttributedString class]]) ?
- str = [aString string] : aString;
+ [aString string] : aString;
if (focusWin) {
@@ -642,7 +630,7 @@ XGrabKeyboard(
Time time)
{
keyboardGrabWinPtr = Tk_IdToWindow(display, grab_window);
- TkWindow *captureWinPtr = (TkWindow *) TkMacOSXGetCapture();
+ TkWindow *captureWinPtr = (TkWindow *) TkpGetCapture();
if (keyboardGrabWinPtr && captureWinPtr) {
NSWindow *w = TkMacOSXDrawableWindow(grab_window);
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 68bad41..9417b62 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -239,6 +239,10 @@ MODULE_SCOPE int TkMacOSXServices_Init(Tcl_Interp *interp);
MODULE_SCOPE int TkMacOSXRegisterServiceWidgetObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE NSString* TclUniToNSString(const char *source, int numBytes);
+MODULE_SCOPE int TclUniAtIndex(NSString *string, int index, char *uni,
+ unsigned int *code);
+MODULE_SCOPE char* NSStringToTclUni(NSString *string, int *numBytes);
#pragma mark Private Objective-C Classes
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index c2b67f6..ceb3f3f 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -2518,6 +2518,7 @@ WmIconphotoCmd(
{
Tk_Image tk_icon;
int width, height, isDefault = 0;
+ NSImage *newIcon = NULL;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 2, objv,
@@ -2563,12 +2564,16 @@ WmIconphotoCmd(
return TCL_ERROR;
}
- NSImage *newIcon;
Tk_SizeOfImage(tk_icon, &width, &height);
- newIcon = TkMacOSXGetNSImageWithTkImage(winPtr->display, tk_icon,
- width, height);
+ if (width != 0 && height != 0) {
+ newIcon = TkMacOSXGetNSImageWithTkImage(winPtr->display, tk_icon,
+ width, height);
+ }
Tk_FreeImage(tk_icon);
if (newIcon == NULL) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "failed to create an iconphoto with image \"%s\"", icon));
+ Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
return TCL_ERROR;
}
[NSApp setApplicationIconImage: newIcon];
@@ -3309,18 +3314,18 @@ WmStackorderCmd(
if (objc == 3) {
windows = TkWmStackorderToplevel(winPtr);
- if (windows == NULL) {
- Tcl_Panic("TkWmStackorderToplevel failed");
- }
-
- resultObj = Tcl_NewObj();
- for (windowPtr = windows; *windowPtr ; windowPtr++) {
- Tcl_ListObjAppendElement(NULL, resultObj,
+ if (windows != NULL) {
+ resultObj = Tcl_NewObj();
+ for (windowPtr = windows; *windowPtr ; windowPtr++) {
+ Tcl_ListObjAppendElement(NULL, resultObj,
TkNewWindowObj((Tk_Window) *windowPtr));
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ ckfree(windows);
+ return TCL_OK;
+ } else {
+ return TCL_ERROR;
}
- Tcl_SetObjResult(interp, resultObj);
- ckfree(windows);
- return TCL_OK;
} else {
TkWindow *winPtr2;
int index1 = -1, index2 = -1, result;
@@ -6621,7 +6626,7 @@ WmStackorderToplevelWrapperMap(
Tcl_HashEntry *hPtr;
int newEntry;
- if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr)
+ if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)
&& (winPtr->display == display)) {
hPtr = Tcl_CreateHashEntry(table,
(char*) TkMacOSXDrawableWindow(winPtr->window), &newEntry);
@@ -6642,8 +6647,8 @@ WmStackorderToplevelWrapperMap(
* This procedure returns the stack order of toplevel windows.
*
* Results:
- * An array of pointers to tk window objects in stacking order or else
- * NULL if there was an error.
+ * A NULL terminated array of pointers to tk window objects in stacking
+ * order or else NULL if there was an error.
*
* Side effects:
* None.
@@ -6658,57 +6663,24 @@ TkWmStackorderToplevel(
TkWindow *childWinPtr, **windows, **windowPtr;
Tcl_HashTable table;
Tcl_HashEntry *hPtr;
- Tcl_HashSearch search;
-
- /*
- * Map mac windows to a TkWindow of the wrapped toplevel.
- */
-
- Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
- WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
-
- windows = ckalloc((table.numEntries+1) * sizeof(TkWindow *));
-
- /*
- * Special cases: If zero or one toplevels were mapped there is no need to
- * enumerate Windows.
- */
-
- switch (table.numEntries) {
- case 0:
- windows[0] = NULL;
- goto done;
- case 1:
- hPtr = Tcl_FirstHashEntry(&table, &search);
- windows[0] = Tcl_GetHashValue(hPtr);
- windows[1] = NULL;
- goto done;
- }
-
NSArray *macWindows = [NSApp orderedWindows];
+ NSArray* backToFront = [[macWindows reverseObjectEnumerator] allObjects];
NSInteger windowCount = [macWindows count];
- if (!windowCount) {
- ckfree(windows);
- windows = NULL;
- } else {
- windowPtr = windows + table.numEntries;
- *windowPtr-- = NULL;
- for (NSWindow *w in macWindows) {
+ windows = windowPtr = ckalloc((windowCount + 1) * sizeof(TkWindow *));
+ if (windows != NULL) {
+ Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
+ WmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
+ for (NSWindow *w in backToFront) {
hPtr = Tcl_FindHashEntry(&table, (char*) w);
if (hPtr != NULL) {
childWinPtr = Tcl_GetHashValue(hPtr);
- *windowPtr-- = childWinPtr;
+ *windowPtr++ = childWinPtr;
}
}
- if (windowPtr != windows-1) {
- Tcl_Panic("num matched toplevel windows does not equal num "
- "children");
- }
+ *windowPtr = NULL;
+ Tcl_DeleteHashTable(&table);
}
-
- done:
- Tcl_DeleteHashTable(&table);
return windows;
}
diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c
index 952aa20..7e8377e 100644
--- a/macosx/ttkMacOSXTheme.c
+++ b/macosx/ttkMacOSXTheme.c
@@ -1409,8 +1409,10 @@ static void ButtonElementDraw(
} else if (info.kind == kThemePushButton &&
(state & TTK_STATE_PRESSED)) {
bounds.size.height += 2;
- GradientFillRoundedRectangle(dc.context, bounds, 4,
- pressedPushButtonGradient, 2);
+ if ([NSApp macMinorVersion] > 8) {
+ GradientFillRoundedRectangle(dc.context, bounds, 4,
+ pressedPushButtonGradient, 2);
+ }
} else {
/*
@@ -1859,18 +1861,17 @@ static void ComboboxElementDraw(
BEGIN_DRAWING(d)
bounds.origin.y += 1;
if (TkMacOSXInDarkMode(tkwin)) {
- bounds.size.height += 1;
+ bounds.size.height += 1;
DrawDarkButton(bounds, info.kind, state, dc.context);
- } else if ([NSApp macMinorVersion] > 8) {
- if ((state & TTK_STATE_BACKGROUND) &&
- !(state & TTK_STATE_DISABLED)) {
+ } else if ([NSApp macMinorVersion] > 8) {
+ if ((state & TTK_STATE_BACKGROUND) &&
+ !(state & TTK_STATE_DISABLED)) {
NSColor *background = [NSColor textBackgroundColor];
CGRect innerBounds = CGRectInset(bounds, 1, 2);
SolidFillRoundedRectangle(dc.context, innerBounds, 4, background);
}
- ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
- NULL);
}
+ ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
END_DRAWING
}
diff --git a/tests/wm.test b/tests/wm.test
index c2bc385..4d0d73b 100644
--- a/tests/wm.test
+++ b/tests/wm.test
@@ -873,6 +873,12 @@ test wm-iconphoto-1.4 {usage} -returnCodes error -body {
# we currently have no return info
wm iconphoto . -default
} -result {wrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"}
+test wm-iconphoto-1.5.1 {usage} -constraints aquaOrWin32 -returnCodes error -body {
+ wm iconphoto . -default [image create photo -file {}]
+} -match {glob} -result {failed to create an iconphoto with image *}
+test wm-iconphoto-1.5.2 {usage} -constraints x11 -body {
+ wm iconphoto . -default [image create photo -file {}]
+} -result {}
# All other iconphoto tests are platform specific
@@ -1553,8 +1559,8 @@ test wm-stackorder-5.3 {An overrideredirect window\
destroy .t
} -result 1
-test wm-stackorder-6.1 {An embedded toplevel does not\
- appear in the stacking order on unix or win} -constraints notAqua -body {
+test wm-stackorder-6.1 {An embedded toplevel does not appear in the \
+ stacking order} -body {
toplevel .real -container 1
toplevel .embd -bg blue -use [winfo id .real]
update
@@ -1562,16 +1568,6 @@ test wm-stackorder-6.1 {An embedded toplevel does not\
} -cleanup {
deleteWindows
} -result {. .real}
-test wm-stackorder-6.1.1 {An embedded toplevel does\
- appear in the stacking order on macOS} -constraints aqua -body {
- toplevel .real -container 1
- toplevel .embd -bg blue -use [winfo id .real]
- update
- wm stackorder .
-} -cleanup {
- deleteWindows
-} -result {. .embd}
-
stdWindow
diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c
index bc7f1cb..2c9e9dd 100644
--- a/unix/tkUnixWm.c
+++ b/unix/tkUnixWm.c
@@ -2447,6 +2447,10 @@ WmIconphotoCmd(
photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
if (photo == NULL) {
ckfree((char *) iconPropertyData);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "failed to create an iconphoto with image \"%s\"",
+ Tcl_GetString(objv[i])));
+ Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
return TCL_ERROR;
}
Tk_PhotoGetSize(photo, &width, &height);
@@ -3268,6 +3272,8 @@ WmStackorderCmd(
ckfree(windows);
Tcl_SetObjResult(interp, resultObj);
return TCL_OK;
+ } else {
+ return TCL_ERROR;
}
} else {
Tk_Window relWin;
@@ -6432,6 +6438,9 @@ TkWmStackorderToplevel(
TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
window_ptr = windows = ckalloc((table.numEntries+1) * sizeof(TkWindow *));
+ if (windows == NULL) {
+ return NULL;
+ }
/*
* Special cases: If zero or one toplevels were mapped there is no need to
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 117b539..bddbe05 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -4384,9 +4384,9 @@ WmIconphotoCmd(
if (!iconInfo.hbmColor) {
ckfree(lpIR);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "failed to create color bitmap for \"%s\"",
+ "failed to create an iconphoto with image \"%s\"",
Tcl_GetString(objv[i])));
- Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "BITMAP", NULL);
+ Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "IMAGE", NULL);
return TCL_ERROR;
}
@@ -5195,18 +5195,18 @@ WmStackorderCmd(
if (objc == 3) {
windows = TkWmStackorderToplevel(winPtr);
- if (windows == NULL) {
- Tcl_Panic("TkWmStackorderToplevel failed");
- }
-
- resultObj = Tcl_NewObj();
- for (windowPtr = windows; *windowPtr ; windowPtr++) {
- Tcl_ListObjAppendElement(NULL, resultObj,
- TkNewWindowObj((Tk_Window) *windowPtr));
+ if (windows != NULL) {
+ resultObj = Tcl_NewObj();
+ for (windowPtr = windows; *windowPtr ; windowPtr++) {
+ Tcl_ListObjAppendElement(NULL, resultObj,
+ TkNewWindowObj((Tk_Window) *windowPtr));
+ }
+ Tcl_SetObjResult(interp, resultObj);
+ ckfree(windows);
+ return TCL_OK;
+ } else {
+ return TCL_ERROR;
}
- Tcl_SetObjResult(interp, resultObj);
- ckfree(windows);
- return TCL_OK;
} else {
TkWindow *winPtr2, **winPtr2Ptr = &winPtr2;
int index1 = -1, index2 = -1, result;
@@ -6812,8 +6812,6 @@ TkWmStackorderToplevel(
(LPARAM) &pair) == 0) {
ckfree(windows);
windows = NULL;
- } else if (pair.windowPtr != (windows-1)) {
- Tcl_Panic("num matched toplevel windows does not equal num children");
}
done: