diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-05-18 22:01:28 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2020-05-18 22:01:28 (GMT) |
commit | 742aa6e5578759ae3d318aa05164df0b9e3982d3 (patch) | |
tree | 638c96b8b121ba515a09b85a3dbaa69c26cb136b | |
parent | 6fa16c680c6af311355e3c43f9123007c5fa565b (diff) | |
parent | 1d435ce1f0cd4775332957c719ee82d78bf926b7 (diff) | |
download | tk-742aa6e5578759ae3d318aa05164df0b9e3982d3.zip tk-742aa6e5578759ae3d318aa05164df0b9e3982d3.tar.gz tk-742aa6e5578759ae3d318aa05164df0b9e3982d3.tar.bz2 |
Merge 8.6
-rw-r--r-- | generic/tkBind.c | 4 | ||||
-rw-r--r-- | generic/tkEvent.c | 4 | ||||
-rw-r--r-- | generic/tkInt.h | 6 | ||||
-rw-r--r-- | macosx/tkMacOSXButton.c | 19 | ||||
-rw-r--r-- | macosx/tkMacOSXClipboard.c | 25 | ||||
-rw-r--r-- | macosx/tkMacOSXColor.c | 9 | ||||
-rw-r--r-- | macosx/tkMacOSXConstants.h | 4 | ||||
-rw-r--r-- | macosx/tkMacOSXFont.c | 145 | ||||
-rw-r--r-- | macosx/tkMacOSXInit.c | 40 | ||||
-rw-r--r-- | macosx/tkMacOSXKeyEvent.c | 25 | ||||
-rw-r--r-- | macosx/tkMacOSXKeyboard.c | 55 | ||||
-rw-r--r-- | macosx/tkMacOSXMouseEvent.c | 4 | ||||
-rw-r--r-- | macosx/tkMacOSXNotify.c | 20 | ||||
-rw-r--r-- | macosx/tkMacOSXPrivate.h | 31 | ||||
-rw-r--r-- | macosx/tkMacOSXTest.c | 2 | ||||
-rw-r--r-- | win/tkWinKey.c | 5 | ||||
-rw-r--r-- | win/tkWinMenu.c | 15 | ||||
-rw-r--r-- | win/tkWinX.c | 146 | ||||
-rw-r--r-- | xlib/X11/Xlib.h | 3 |
19 files changed, 241 insertions, 321 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c index 48f51e3..e9d5b3a 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -567,7 +567,7 @@ static int eventArrayIndex[TK_LASTEVENT]; #define HAS_XKEY_HEAD (KEY|BUTTON|MOTION|VIRTUAL|CROSSING|WHEEL) -/* +/* * The xcrossing struct puts the state field in a different location, but the other * events above agree on where state is located. */ @@ -3218,7 +3218,7 @@ ExpandPercents( } #undef SET_NUMBER -#undef SET_UNUMBER +#undef SET_UNUMBER Tcl_DStringFree(&buf); } diff --git a/generic/tkEvent.c b/generic/tkEvent.c index 0beb8b6..a2fa293 100644 --- a/generic/tkEvent.c +++ b/generic/tkEvent.c @@ -1751,13 +1751,15 @@ CleanUpTkEvent( switch (eventPtr->type) { case KeyPress: case KeyRelease: { - TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr; +#if !defined(_WIN32) && !defined(MAC_OSX_TK) + TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr; if (kePtr->charValuePtr != NULL) { ckfree(kePtr->charValuePtr); kePtr->charValuePtr = NULL; kePtr->charValueLen = 0; } +#endif break; } diff --git a/generic/tkInt.h b/generic/tkInt.h index f638c56..c63748a 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -852,6 +852,11 @@ typedef struct TkWindow { typedef struct { XKeyEvent keyEvent; /* The real event from X11. */ +#ifdef _WIN32 + char trans_chars[XMaxTransChars]; + /* translated characters */ + unsigned char nbytes; +#elif !defined(MAC_OSC_TK) char *charValuePtr; /* A pointer to a string that holds the key's * %A substitution text (before backslash * adding), or NULL if that has not been @@ -861,6 +866,7 @@ typedef struct { * is non-NULL. */ KeySym keysym; /* Key symbol computed after input methods * have been invoked */ +#endif } TkKeyEvent; /* diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c index f869350..721dd03 100644 --- a/macosx/tkMacOSXButton.c +++ b/macosx/tkMacOSXButton.c @@ -186,9 +186,6 @@ TkpDisplayButton( DrawParams* dpPtr = &macButtonPtr->drawParams; int needhighlight = 0; - if (butPtr->flags & BUTTON_DELETED) { - return; - } butPtr->flags &= ~REDRAW_PENDING; if ((butPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { return; @@ -1048,7 +1045,14 @@ TkMacOSXComputeButtonParams( if (drawinfo->state != kThemeStatePressed) { drawinfo->adornment |= kThemeAdornmentDefault; } - if (!mbPtr->defaultPulseHandler) { + + /* + * Older macOS systems (10.9 and earlier) use an animation to + * indicate the active button. This is simulated by redrawing + * the button periodically. + */ + + if (!mbPtr->defaultPulseHandler && ([NSApp macMinorVersion] <= 9)) { mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler( PULSE_TIMER_MSECS, PulseDefaultButtonProc, butPtr); } @@ -1178,6 +1182,13 @@ PulseDefaultButtonProc(ClientData clientData) MacButton *mbPtr = clientData; TkpDisplayButton(clientData); + /* + * Fix 40ada90762: any idle calls to TkpDisplayButton need to be canceled + * in case the button is destroyed and has its data freed before the idle + * event is handled (DestroyButton only cancels calls when REDRAW_PENDING + * is set, which is not the case after calling TkpDisplayButton directly). + */ + Tcl_CancelIdleCall(TkpDisplayButton, clientData); mbPtr->defaultPulseHandler = Tcl_CreateTimerHandler( PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData); } diff --git a/macosx/tkMacOSXClipboard.c b/macosx/tkMacOSXClipboard.c index 529b5fa..be1f16c 100644 --- a/macosx/tkMacOSXClipboard.c +++ b/macosx/tkMacOSXClipboard.c @@ -137,26 +137,19 @@ TkSelGetSelection( string = [pb stringForType:type]; } if (string) { - - /* - * 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.) - */ - - char *bytes = TkNSStringToUtf(string, NULL); - result = proc(clientData, interp, bytes); - if (bytes) { - ckfree(bytes); + if (target == dispPtr->utf8Atom) { + result = proc(clientData, interp, string.UTF8String); + } else if (target == XA_STRING) { + const char *latin1 = [string + cStringUsingEncoding:NSISOLatin1StringEncoding]; + result = proc(clientData, interp, latin1); } } } else { Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s selection doesn't exist or form \"%s\" not defined", - Tk_GetAtomName(tkwin, selection), - Tk_GetAtomName(tkwin, target))); + "%s selection doesn't exist or form \"%s\" not defined", + Tk_GetAtomName(tkwin, selection), + Tk_GetAtomName(tkwin, target))); Tcl_SetErrorCode(interp, "TK", "SELECTION", "EXISTS", NULL); } return result; diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c index 924eebf..7694b1d 100644 --- a/macosx/tkMacOSXColor.c +++ b/macosx/tkMacOSXColor.c @@ -280,11 +280,6 @@ SetCGColorComponents( OSStatus err = noErr; NSColor *bgColor, *color = nil; CGFloat rgba[4] = {0, 0, 0, 1}; -#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400 - NSInteger colorVariant; - static CGFloat graphiteAccentRGBA[4] = - {152.0 / 255, 152.0 / 255, 152.0 / 255, 1.0}; -#endif if (!sRGB) { sRGB = [NSColorSpace sRGBColorSpace]; @@ -372,10 +367,10 @@ SetCGColorComponents( case 8: #if MAC_OS_X_VERSION_MAX_ALLOWED >= 101400 if (@available(macOS 14, *)) { + color = [[NSColor controlAccentColor] colorUsingColorSpace:sRGB]; #else - if (false) { + if(false) { #endif - color = [[NSColor controlAccentColor] colorUsingColorSpace:sRGB]; } else { color = [[NSColor colorForControlTint:[NSColor currentControlTint]] diff --git a/macosx/tkMacOSXConstants.h b/macosx/tkMacOSXConstants.h index 8ef535c..e019ea1 100644 --- a/macosx/tkMacOSXConstants.h +++ b/macosx/tkMacOSXConstants.h @@ -19,6 +19,10 @@ #define NSFullScreenWindowMask (1 << 14) #endif +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1090 +typedef NSInteger NSModalResponse; +#endif + /* * Let's raise a glass for the project manager who improves our lives by * generating deprecation warnings about pointless changes of the names diff --git a/macosx/tkMacOSXFont.c b/macosx/tkMacOSXFont.c index 89df102..7fc0113 100644 --- a/macosx/tkMacOSXFont.c +++ b/macosx/tkMacOSXFont.c @@ -103,7 +103,9 @@ static void DrawCharsInContext(Display *display, Drawable drawable, /* * To avoid an extra copy, a TKNSString object wraps a Tcl_DString with an - * NSString that uses the DString's buffer as its character buffer. + * NSString that uses the DString's buffer as its character buffer. It can be + * constructed from a Tcl_DString and it has a DString property that handles + * converting from an NSString to a Tcl_DString */ @implementation TKNSString @@ -111,7 +113,8 @@ static void DrawCharsInContext(Display *display, Drawable drawable, - (instancetype)initWithTclUtfBytes:(const void *)bytes length:(NSUInteger)len { - if (self = [self init]) { + self = [self init]; + if (self) { Tcl_DStringInit(&_ds); Tcl_UtfToUniCharDString(bytes, len, &_ds); _string = [[NSString alloc] @@ -123,6 +126,17 @@ static void DrawCharsInContext(Display *display, Drawable drawable, return self; } +- (instancetype)initWithString:(NSString *)aString +{ + self = [self init]; + if (self) { + _string = [[NSString alloc] initWithString:aString]; + self.UTF8String = _string.UTF8String; + } + printf("Initialized with string %s\n", self.UTF8String); + return self; +} + - (void)dealloc { Tcl_DStringFree(&_ds); @@ -140,101 +154,52 @@ static void DrawCharsInContext(Display *display, Drawable drawable, return [_string characterAtIndex:index]; } -@end - -/* - *--------------------------------------------------------------------------- - * - * TkUtfAtIndex -- - * - * 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. See the documentation for TKNSString in tkMacOSXPrivate.h. - * - * 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. - * - */ +# ifndef __clang__ +@synthesize DString = _ds; +#endif -MODULE_SCOPE int -TkUtfAtIndex( - NSString *string, - int index, - char *uni, - unsigned int *code) +- (Tcl_DString)DString { - 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); - } -} - -/* - *--------------------------------------------------------------------------- - * - * TkNSStringToUtf -- - * - * 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. - */ + if ( _ds.string == NULL) { -MODULE_SCOPE char* -TkNSStringToUtf( - 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 += TkUtfAtIndex(string, i, ptr, &code); - if (code > 0xffff){ - i++; + /* + * The DString has not been initialized. Construct it from + * our string's unicode characters. + */ + + char buffer[2*TCL_UTF_MAX]; + unsigned int index, length, ch; + + Tcl_DStringInit(&_ds); +#if TCL_UTF_MAX == 3 + for (index = 0; index < [_string length]; index++) { + UniChar uni = [_string characterAtIndex: index]; + + if (CFStringIsSurrogateHighCharacter(uni)) { + UniChar low = [_string characterAtIndex: ++index]; + ch = CFStringGetLongCharacterForSurrogatePair(uni, low); + } else { + ch = uni; } + length = TkUniCharToUtf(ch, buffer); + Tcl_DStringAppend(&_ds, buffer, length); } - *ptr = '\0'; - } - if (numBytes) { - *numBytes = ptr - bytes; +#else + for (index = 0; index < [_string length]; index++) { + ch = (int) [_string characterAtIndex: index]; + length = Tcl_UniCharToUtf(ch, buffer); + Tcl_DStringAppend(&_ds, buffer, length); + } + +#endif } - return bytes; + return _ds; } + +#ifndef __clang__ +@synthesize UTF8String = _UTF8String; +#endif +@end #define GetNSFontTraitsFromTkFontAttributes(faPtr) \ ((faPtr)->weight == TK_FW_BOLD ? NSBoldFontMask : NSUnboldFontMask) | \ diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index b13b855..e806b24 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -623,46 +623,6 @@ TkMacOSXGetNamedSymbol( } /* - *---------------------------------------------------------------------- - * - * TkMacOSXGetStringObjFromCFString -- - * - * Get a string object from a CFString as efficiently as possible. - * - * Results: - * New string object or NULL if conversion failed. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -MODULE_SCOPE Tcl_Obj* -TkMacOSXGetStringObjFromCFString( - CFStringRef str) -{ - Tcl_Obj *obj = NULL; - const char *c = CFStringGetCStringPtr(str, kCFStringEncodingUTF8); - - if (c) { - obj = Tcl_NewStringObj(c, -1); - } else { - CFRange all = CFRangeMake(0, CFStringGetLength(str)); - CFIndex len; - - if (CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false, NULL, - 0, &len) > 0 && len < INT_MAX) { - obj = Tcl_NewObj(); - Tcl_SetObjLength(obj, len); - CFStringGetBytes(str, all, kCFStringEncodingUTF8, 0, false, - (UInt8*) obj->bytes, len, NULL); - } - } - return obj; -} - -/* * Local Variables: * mode: objc * c-basic-offset: 4 diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c index ee69c35..e0b0094 100644 --- a/macosx/tkMacOSXKeyEvent.c +++ b/macosx/tkMacOSXKeyEvent.c @@ -247,16 +247,7 @@ static NSUInteger textInputModifiers; } macKC.v.keychar = keychar; xEvent.xkey.keycode = macKC.uint; - - /* - * Set the trans_chars for keychars outside of the private-use range. - */ - setXEventPoint(&xEvent, tkwin, w); - if (IS_PRINTABLE(keychar)) { - int length = TkUniCharToUtf(keychar, xEvent.xkey.trans_chars); - xEvent.xkey.trans_chars[length] = 0; - } /* * Finally we can queue the XEvent, inserting a KeyRelease before a @@ -351,26 +342,18 @@ static NSUInteger textInputModifiers; * represented by a sequence of two 16-bit "surrogates". We record this in * the XEvent by setting the low order 21-bits of the keycode to the UCS-32 * value value of the character and the virtual keycode in the high order - * byte to the special value NON_BMP. In principle we could set the - * trans_chars string to the 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. + * byte to the special value NON_BMP. */ state = xEvent.xkey.state; for (i = 0; i < len; i++) { - unsigned int code; UniChar keychar; MacKeycode macKC = {0}; keychar = [str characterAtIndex:i]; macKC.v.keychar = keychar; if (CFStringIsSurrogateHighCharacter(keychar)) { - UniChar lowChar = [str characterAtIndex:i+1]; + UniChar lowChar = [str characterAtIndex:++i]; macKC.v.keychar = CFStringGetLongCharacterForSurrogatePair( (UniChar)keychar, lowChar); macKC.v.virtual = NON_BMP_VIRTUAL; @@ -389,10 +372,6 @@ static NSUInteger textInputModifiers; if (xEvent.xkey.state & Mod2Mask) { macKC.v.o_s |= INDEX_OPTION; } - TkUtfAtIndex(str, i, xEvent.xkey.trans_chars, &code); - if (code > 0xFFFF){ - i++; - } xEvent.xkey.keycode = macKC.uint; xEvent.xany.type = KeyPress; Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); diff --git a/macosx/tkMacOSXKeyboard.c b/macosx/tkMacOSXKeyboard.c index db693ea..8381aa7 100644 --- a/macosx/tkMacOSXKeyboard.c +++ b/macosx/tkMacOSXKeyboard.c @@ -62,15 +62,13 @@ * * When the keyboard focus is on a Tk widget which provides text input, there * are some X11 KeyPress events which cause text to be inserted. We will call - * these "printable" events. On macOS the text which should be inserted is - * contained in the xkeys.trans_chars field of a key XEvent as a - * null-terminated unicode string encoded with a special Tcl encoding. The - * value of the trans_chars string in an Xevent depends on more than the three - * items above. It may also depend on the sequence of keypresses that preceded - * the one being reported by the XEvent. For example, on macOS an <Alt-e> - * event does not cause text to be inserted but a following <a> event causes an - * accented 'a' to be inserted. The events in such a composition sequence, - * other than the final one, are known as "dead-key" events. + * these "printable" events. The UCS-32 character stored in the keycode field + * of an XKeyEvent depends on more than the three items above. It may also + * depend on the sequence of keypresses that preceded the one being reported by + * the XKeyEvent. For example, on macOS an <Alt-e> event does not cause text + * to be inserted but a following <a> event causes an accented 'a' to be + * inserted. The events in such a composition sequence, other than the final + * one, are known as "dead-key" events. * * MacOS packages the information described above in a different way. Every * meaningful effect from a key action *other than changing the state of @@ -488,11 +486,18 @@ TkpGetString( * result. */ { (void) winPtr; /*unused*/ - int ch; + MacKeycode macKC; + char utfChars[8]; + int length = 0; + + macKC.uint = eventPtr->xkey.keycode; + if (IS_PRINTABLE(macKC.v.keychar)) { + length = TkUniCharToUtf(macKC.v.keychar, utfChars); + } + utfChars[length] = 0; Tcl_DStringInit(dsPtr); - return Tcl_DStringAppend(dsPtr, eventPtr->xkey.trans_chars, - TkUtfToUniChar(eventPtr->xkey.trans_chars, &ch)); + return Tcl_DStringAppend(dsPtr, utfChars, length); } /* @@ -623,7 +628,7 @@ XKeysymToKeycode( hPtr = Tcl_FindHashEntry(&keysym2keycode, INT2PTR(keysym)); if (hPtr != NULL) { - return (unsigned int) Tcl_GetHashValue(hPtr); + return (KeyCode) Tcl_GetHashValue(hPtr); } /* @@ -640,15 +645,18 @@ XKeysymToKeycode( * xvirtual field if the key exists on the current keyboard. */ - hPtr = Tcl_FindHashEntry(&keysym2unichar, INT2PTR(keysym)); + hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&keysym2unichar, + INT2PTR(keysym)); if (hPtr != NULL) { - macKC.x.keychar = (unsigned int) Tcl_GetHashValue(hPtr); + unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr); + macKC.x.keychar = (unsigned int) data; hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.x.keychar)); if (hPtr != NULL) { - macKC.x.xvirtual = (unsigned int) Tcl_GetHashValue(hPtr); + unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr); + macKC.x.xvirtual = (unsigned int) data; } } - return macKC.uint; + return (KeyCode) macKC.uint; } /* @@ -667,7 +675,7 @@ XKeysymToKeycode( * Modifies the XEvent. Sets the xkey.keycode to a keycode value formatted * by XKeysymToKeycode and updates the shift and option flags in * xkey.state if either of those modifiers is required to generate the - * keysym. Also fills in xkey.trans_chars for printable events. + * keysym. * *---------------------------------------------------------------------- */ @@ -718,11 +726,6 @@ TkpSetKeycodeAndState( } eventPtr->xkey.keycode = macKC.uint; eventPtr->xkey.state |= INDEX2STATE(macKC.v.o_s); - if (IS_PRINTABLE(macKC.v.keychar)) { - int length = TkUniCharToUtf(macKC.v.keychar, - eventPtr->xkey.trans_chars); - eventPtr->xkey.trans_chars[length] = 0; - } } } @@ -935,9 +938,11 @@ TkMacOSXAddVirtual( InitHashTables(); } - hPtr = Tcl_FindHashEntry(&unichar2xvirtual, INT2PTR(macKC.v.keychar)); + hPtr = (Tcl_HashEntry *) Tcl_FindHashEntry(&unichar2xvirtual, + INT2PTR(macKC.v.keychar)); if (hPtr != NULL) { - macKC.x.xvirtual = (unsigned int) Tcl_GetHashValue(hPtr); + unsigned long data = (unsigned long) Tcl_GetHashValue(hPtr); + macKC.x.xvirtual = (unsigned int) data; } else { macKC.v.virtual = NO_VIRTUAL; } diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index dd50d0a..435caf9 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -103,8 +103,8 @@ enum { * ticket [d72abe6b54]. */ - if (eventType == NSEventTypeLeftMouseDown && - ([eventWindow styleMask] & NSWindowStyleMaskResizable) && + if (eventType == NSLeftMouseDown && + ([eventWindow styleMask] & NSResizableWindowMask) && [NSApp macMinorVersion] > 6) { NSRect frame = [eventWindow frame]; if (local.x < 3 || local.x > frame.size.width - 3 || local.y < 3) { diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c index 77e9e74..96c9a7a 100644 --- a/macosx/tkMacOSXNotify.c +++ b/macosx/tkMacOSXNotify.c @@ -145,18 +145,18 @@ void DebugPrintQueue(void) /* * Workaround for an Apple bug. When an accented character is selected * from an NSTextInputClient popup character viewer with the mouse, Apple - * sends an event of type NSEventTypeAppKitDefined and subtype 21. If that - * event is sent up the responder chain it causes Apple to print a warning - * to the console log and, extremely obnoxiously, also to stderr, which - * says "Window move completed without beginning." Apparently they are - * sending the "move completed" event without having sent the "move began" - * event of subtype 20, and then announcing their error on our stderr. - * Also, of course, no movement is occurring. The popup is not movable and - * is just being closed. The bug has been reported to Apple. If they ever - * fix it, this block should be removed. + * sends an event of type NSAppKitDefined and subtype 21. If that event is + * sent up the responder chain it causes Apple to print a warning to the + * console log and, extremely obnoxiously, also to stderr, which says + * "Window move completed without beginning." Apparently they are sending + * the "move completed" event without having sent the "move began" event of + * subtype 20, and then announcing their error on our stderr. Also, of + * course, no movement is occurring. The popup is not movable and is just + * being closed. The bug has been reported to Apple. If they ever fix it, + * this block should be removed. */ - if ([theEvent type] == NSEventTypeAppKitDefined) { + if ([theEvent type] == NSAppKitDefined) { static Bool aWindowIsMoving = NO; switch([theEvent subtype]) { case 20: diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index b5b93d5..a0645f7 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -19,6 +19,10 @@ #error Objective-C compiler required #endif +#ifndef __clang__ +#define instancetype id +#endif + #define TextStyle MacTextStyle #import <ApplicationServices/ApplicationServices.h> #import <Cocoa/Cocoa.h> @@ -283,7 +287,6 @@ MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithBitmap(Display *display, Pixmap bitmap, GC gc, int width, int height); MODULE_SCOPE CGColorRef TkMacOSXCreateCGColor(GC gc, unsigned long pixel); MODULE_SCOPE NSColor* TkMacOSXGetNSColor(GC gc, unsigned long pixel); -MODULE_SCOPE Tcl_Obj * TkMacOSXGetStringObjFromCFString(CFStringRef str); MODULE_SCOPE TkWindow* TkMacOSXGetTkWindow(NSWindow *w); MODULE_SCOPE NSFont* TkMacOSXNSFontForFont(Tk_Font tkfont); MODULE_SCOPE NSDictionary* TkMacOSXNSFontAttributesForFont(Tk_Font tkfont); @@ -303,10 +306,6 @@ 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* TkUtfToNSString(const char *source, size_t numBytes); -MODULE_SCOPE int TkUtfAtIndex(NSString *string, int index, char *uni, - unsigned int *code); -MODULE_SCOPE char* TkNSStringToUtf(NSString *string, int *numBytes); MODULE_SCOPE unsigned TkMacOSXAddVirtual(unsigned int keycode); #pragma mark Private Objective-C Classes @@ -519,17 +518,16 @@ VISIBILITY_HIDDEN * * 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 subclass of NSString adds a new initialization method which accepts - * a C string encoded with the scheme described above. + * encoding requires 4 bytes. Instead, when using these versions of Tcl, Tk + * uses the CESU-8 encoding internally. This encoding is similar to UTF-8 + * except that it allows encoding surrogate characters as 3-byte sequences + * using the same algorithm which UTF-8 uses for non-surrogates. This means + * that a non-BMP character is encoded as a string of length 6. Apple's + * NSString class does not provide a constructor which accepts a CESU-8 encoded + * byte sequence as initial data. So we add a new class which does provide + * such a constructor. It also has a DString property which is a DString whose + * string pointer is a byte sequence encoding the NSString with the current Tk + * encoding, namely UTF-8 if TCL_MAX >= 4 or CESU-8 if TCL_MAX = 3. * *--------------------------------------------------------------------------- */ @@ -540,6 +538,7 @@ VISIBILITY_HIDDEN NSString *_string; } @property const char *UTF8String; +@property (readonly) Tcl_DString DString; - (instancetype)initWithTclUtfBytes:(const void *)bytes length:(NSUInteger)len; @end diff --git a/macosx/tkMacOSXTest.c b/macosx/tkMacOSXTest.c index 902bf9e..0a739a1 100644 --- a/macosx/tkMacOSXTest.c +++ b/macosx/tkMacOSXTest.c @@ -153,7 +153,7 @@ PressButtonObjCmd( int objc, Tcl_Obj *const objv[]) { - int x, y, i, value, wNum; + int x = 0, y = 0, i, value, wNum; CGPoint pt; NSPoint loc; NSEvent *motion, *press, *release; diff --git a/win/tkWinKey.c b/win/tkWinKey.c index c7fa20c..4451296 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -102,9 +102,10 @@ TkpGetString( Tcl_DStringInit(dsPtr); if (keyEv->send_event == -1) { - if (keyEv->nbytes > 0) { + TkKeyEvent *ev = (TkKeyEvent *)keyEv; + if (ev->nbytes > 0) { Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(), - keyEv->trans_chars, keyEv->nbytes, dsPtr); + ev->trans_chars, ev->nbytes, dsPtr); } } else if (keyEv->send_event == -3) { diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index 8bcc826..1f345ff 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -2231,17 +2231,16 @@ TkWinMenuKeyObjCmd( virtualKey = XKeysymToKeycode(winPtr->display, keySym); scanCode = MapVirtualKeyW(virtualKey, 0); if (0 != scanCode) { - XKeyEvent xkey = eventPtr->xkey; + TkKeyEvent xkey; + memcpy(&xkey, eventPtr, sizeof(xkey)); CallWindowProcW(DefWindowProcW, Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSKEYDOWN, virtualKey, (int) ((scanCode << 16) | (1 << 29))); - if (xkey.nbytes > 0) { - for (i = 0; i < xkey.nbytes; i++) { - CallWindowProcW(DefWindowProcW, - Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR, - xkey.trans_chars[i], - (int) ((scanCode << 16) | (1 << 29))); - } + for (i = 0; i < xkey.nbytes; i++) { + CallWindowProcW(DefWindowProcW, + Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR, + xkey.trans_chars[i], + (int) ((scanCode << 16) | (1 << 29))); } } } diff --git a/win/tkWinX.c b/win/tkWinX.c index 689268d..f445fce 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -104,7 +104,7 @@ static Tcl_ThreadDataKey dataKey; static void GenerateXEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); static unsigned int GetState(UINT message, WPARAM wParam, LPARAM lParam); -static void GetTranslatedKey(XKeyEvent *xkey, UINT type); +static void GetTranslatedKey(TkKeyEvent *xkey, UINT type); static void UpdateInputLanguage(int charset); static int HandleIMEComposition(HWND hwnd, LPARAM lParam); @@ -994,7 +994,7 @@ GenerateXEvent( WPARAM wParam, LPARAM lParam) { - XEvent event; + union {XEvent x; TkKeyEvent key;} event; TkWindow *winPtr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -1020,33 +1020,33 @@ GenerateXEvent( return; } - memset(&event, 0, sizeof(XEvent)); - event.xany.serial = winPtr->display->request++; - event.xany.send_event = False; - event.xany.display = winPtr->display; - event.xany.window = winPtr->window; + memset(&event.x, 0, sizeof(XEvent)); + event.x.xany.serial = winPtr->display->request++; + event.x.xany.send_event = False; + event.x.xany.display = winPtr->display; + event.x.xany.window = winPtr->window; switch (message) { case WM_PAINT: { PAINTSTRUCT ps; - event.type = Expose; + event.x.type = Expose; BeginPaint(hwnd, &ps); - event.xexpose.x = ps.rcPaint.left; - event.xexpose.y = ps.rcPaint.top; - event.xexpose.width = ps.rcPaint.right - ps.rcPaint.left; - event.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top; + event.x.xexpose.x = ps.rcPaint.left; + event.x.xexpose.y = ps.rcPaint.top; + event.x.xexpose.width = ps.rcPaint.right - ps.rcPaint.left; + event.x.xexpose.height = ps.rcPaint.bottom - ps.rcPaint.top; EndPaint(hwnd, &ps); - event.xexpose.count = 0; + event.x.xexpose.count = 0; break; } case WM_CLOSE: - event.type = ClientMessage; - event.xclient.message_type = + event.x.type = ClientMessage; + event.x.xclient.message_type = Tk_InternAtom((Tk_Window) winPtr, "WM_PROTOCOLS"); - event.xclient.format = 32; - event.xclient.data.l[0] = + event.x.xclient.format = 32; + event.x.xclient.data.l[0] = Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW"); break; @@ -1082,10 +1082,10 @@ GenerateXEvent( return; } - event.xany.window = winPtr->window; - event.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut; - event.xfocus.mode = NotifyNormal; - event.xfocus.detail = NotifyNonlinear; + event.x.xany.window = winPtr->window; + event.x.type = (message == WM_SETFOCUS) ? FocusIn : FocusOut; + event.x.xfocus.mode = NotifyNormal; + event.x.xfocus.detail = NotifyNonlinear; /* * Destroy the caret if we own it. If we are moving to another Tk @@ -1107,10 +1107,10 @@ GenerateXEvent( return; } - event.type = SelectionClear; - event.xselectionclear.selection = + event.x.type = SelectionClear; + event.x.xselectionclear.selection = Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD"); - event.xselectionclear.time = TkpGetMS(); + event.x.xselectionclear.time = TkpGetMS(); break; case WM_MOUSEWHEEL: @@ -1139,15 +1139,15 @@ GenerateXEvent( * Set up the common event fields. */ - event.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum); - event.xbutton.subwindow = None; - event.xbutton.x = clientPoint.x; - event.xbutton.y = clientPoint.y; - event.xbutton.x_root = root.point.x; - event.xbutton.y_root = root.point.y; - event.xbutton.state = state; - event.xbutton.time = time; - event.xbutton.same_screen = True; + event.x.xbutton.root = RootWindow(winPtr->display, winPtr->screenNum); + event.x.xbutton.subwindow = None; + event.x.xbutton.x = clientPoint.x; + event.x.xbutton.y = clientPoint.y; + event.x.xbutton.x_root = root.point.x; + event.x.xbutton.y_root = root.point.y; + event.x.xbutton.state = state; + event.x.xbutton.time = time; + event.x.xbutton.same_screen = True; /* * Now set up event specific fields. @@ -1179,10 +1179,10 @@ GenerateXEvent( * TkpGetString. [Bug 1118340]. */ - event.type = MouseWheelEvent; - event.xany.send_event = -1; - event.xkey.nbytes = 0; - event.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA; + event.x.type = MouseWheelEvent; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.keycode = tsdPtr->vWheelAcc / WHEEL_DELTA * WHEEL_DELTA; tsdPtr->vWheelAcc = tsdPtr->vWheelAcc % WHEEL_DELTA; break; } @@ -1211,11 +1211,11 @@ GenerateXEvent( * TkpGetString. [Bug 1118340]. */ - event.type = MouseWheelEvent; - event.xany.send_event = -1; - event.xkey.nbytes = 0; - event.xkey.state |= ShiftMask; - event.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA; + event.x.type = MouseWheelEvent; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.state |= ShiftMask; + event.x.xkey.keycode = tsdPtr->hWheelAcc / WHEEL_DELTA * WHEEL_DELTA; tsdPtr->hWheelAcc = tsdPtr->hWheelAcc % WHEEL_DELTA; break; } @@ -1229,10 +1229,10 @@ GenerateXEvent( * MBCS characters that came from the TranslateMessage call. */ - event.type = KeyPress; - event.xany.send_event = -1; - event.xkey.keycode = wParam; - GetTranslatedKey(&event.xkey, (message == WM_KEYDOWN) ? WM_CHAR : + event.x.type = KeyPress; + event.x.xany.send_event = -1; + event.x.xkey.keycode = wParam; + GetTranslatedKey(&event.key, (message == WM_KEYDOWN) ? WM_CHAR : WM_SYSCHAR); break; @@ -1244,9 +1244,9 @@ GenerateXEvent( * WM_CHAR messages which will follow. */ - event.type = KeyRelease; - event.xkey.keycode = wParam; - event.xkey.nbytes = 0; + event.x.type = KeyRelease; + event.x.xkey.keycode = wParam; + event.key.nbytes = 0; break; case WM_CHAR: @@ -1280,9 +1280,9 @@ GenerateXEvent( * character. */ - event.type = KeyPress; - event.xany.send_event = -1; - event.xkey.keycode = 0; + event.x.type = KeyPress; + event.x.xany.send_event = -1; + event.x.xkey.keycode = 0; if ((int)wParam & 0xff00) { int ch1 = wParam & 0xffff; @@ -1295,12 +1295,12 @@ GenerateXEvent( (ch1 & 0x3ff) | 0x10000; tsdPtr->surrogateBuffer = 0; } - event.xany.send_event = -3; - event.xkey.nbytes = 0; - event.xkey.keycode = ch1; + event.x.xany.send_event = -3; + event.key.nbytes = 0; + event.x.xkey.keycode = ch1; } else { - event.xkey.nbytes = 1; - event.xkey.trans_chars[0] = (char) wParam; + event.key.nbytes = 1; + event.key.trans_chars[0] = (char) wParam; if (IsDBCSLeadByte((BYTE) wParam)) { MSG msg; @@ -1309,22 +1309,22 @@ GenerateXEvent( PM_NOREMOVE) != 0) && (msg.message == WM_CHAR)) { GetMessageW(&msg, NULL, WM_CHAR, WM_CHAR); - event.xkey.nbytes = 2; - event.xkey.trans_chars[1] = (char) msg.wParam; + event.key.nbytes = 2; + event.key.trans_chars[1] = (char) msg.wParam; } } } - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - event.type = KeyRelease; + Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL); + event.x.type = KeyRelease; break; case WM_UNICHAR: { - event.type = KeyPress; - event.xany.send_event = -3; - event.xkey.keycode = wParam; - event.xkey.nbytes = 0; - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - event.type = KeyRelease; + event.x.type = KeyPress; + event.x.xany.send_event = -3; + event.x.xkey.keycode = wParam; + event.key.nbytes = 0; + Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL); + event.x.type = KeyRelease; break; } @@ -1345,7 +1345,7 @@ GenerateXEvent( * Post the translated event to the main Tk event queue. */ - Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL); } /* @@ -1447,7 +1447,7 @@ GetState( static void GetTranslatedKey( - XKeyEvent *xkey, + TkKeyEvent *xkey, UINT type) { MSG msg; @@ -1470,7 +1470,7 @@ GetTranslatedKey( */ if ((msg.message == WM_CHAR) && (msg.lParam & 0x20000000)) { - xkey->state = 0; + xkey->keyEvent.state = 0; } xkey->trans_chars[xkey->nbytes++] = (char) msg.wParam; @@ -1529,7 +1529,11 @@ UpdateInputLanguage( return; } - sprintf(codepage, "cp%d", charsetInfo.ciACP); + if (charsetInfo.ciACP == CP_UTF8) { + strcpy(codepage, "utf-8"); + } else { + sprintf(codepage, "cp%d", charsetInfo.ciACP); + } if ((encoding = Tcl_GetEncoding(NULL, codepage)) == NULL) { /* diff --git a/xlib/X11/Xlib.h b/xlib/X11/Xlib.h index af8f706..7969ff5 100644 --- a/xlib/X11/Xlib.h +++ b/xlib/X11/Xlib.h @@ -549,9 +549,6 @@ typedef struct { unsigned int state; /* key or button mask */ unsigned int keycode; /* detail */ Bool same_screen; /* same screen flag */ - char trans_chars[XMaxTransChars]; - /* translated characters */ - unsigned char nbytes; } XKeyEvent; typedef XKeyEvent XKeyPressedEvent; typedef XKeyEvent XKeyReleasedEvent; |