From 41617cb3f6dc92eeb21c55eb776e0135bfa6e935 Mon Sep 17 00:00:00 2001 From: culler Date: Thu, 14 May 2020 21:46:39 +0000 Subject: Add the macOS support, using the TkWheelEvent but not the TkKeyEvent since macOS no longer needs trans_chars. --- generic/tkBind.c | 6 +++--- generic/tkInt.h | 28 ++++++++++++++-------------- macosx/tkMacOSXKeyEvent.c | 25 ++----------------------- macosx/tkMacOSXKeyboard.c | 36 ++++++++++++++++++------------------ macosx/tkMacOSXMouseEvent.c | 34 +++++++++++++++++----------------- 5 files changed, 54 insertions(+), 75 deletions(-) diff --git a/generic/tkBind.c b/generic/tkBind.c index 48f51e3..79f6cb1 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -3139,7 +3139,7 @@ ExpandPercents( break; case 'D': if (flags & WHEEL) { - SET_NUMBER((int)evPtr->xbutton.button); /* mis-use button field for this */ + SET_NUMBER(((TkWheelEvent *)evPtr)->delta); } break; case 'E': @@ -3796,7 +3796,7 @@ HandleEventGenerate( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - union { XEvent general; XVirtualEvent virtual; } event; + union { XEvent general; XVirtualEvent virtual; TkWheelEvent wheel;} event; const char *p; const char *name; @@ -4022,7 +4022,7 @@ HandleEventGenerate( return TCL_ERROR; } if (flags & WHEEL) { - event.general.xbutton.button = (unsigned)number; /* mis-use button field for this */ + event.wheel.delta = number; } else { badOpt = 1; } diff --git a/generic/tkInt.h b/generic/tkInt.h index fd124d5..64e7947 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -854,7 +854,7 @@ typedef struct TkWindow { typedef struct { XKeyEvent keyEvent; /* The real event from X11. */ -#if defined(_WIN32) || defined(MAC_OSX_TK) +#if defined(_WIN32) char trans_chars[XMaxTransChars]; /* translated characters */ unsigned char nbytes; /* Length of trans_chars. */ @@ -872,19 +872,19 @@ typedef struct { } TkKeyEvent; typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window it is reported relative to */ - Window root; /* root window that the event occured on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - int delta; /* delta */ - unsigned int button; /* detail */ - Bool same_screen; /* same screen flag */ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occured on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + int delta; /* delta */ + unsigned int state; /* detail */ + Bool same_screen; /* same screen flag */ } TkWheelEvent; /* 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..5952fa3 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 - * event does not cause text to be inserted but a following 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 event does not cause text + * to be inserted but a following 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); } /* @@ -667,7 +672,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 +723,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; - } } } diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index dd50d0a..36544ec 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -275,34 +275,34 @@ enum { CGFloat delta; int coarseDelta; - XEvent xEvent; + TkWheelEvent wheelEvent; - xEvent.type = MouseWheelEvent; - xEvent.xbutton.x = local.x; - xEvent.xbutton.y = local.y; - xEvent.xbutton.x_root = global.x; - xEvent.xbutton.y_root = global.y; - xEvent.xany.send_event = false; - xEvent.xany.display = Tk_Display(tkwin); - xEvent.xany.window = Tk_WindowId(tkwin); + wheelEvent.type = MouseWheelEvent; + wheelEvent.x = local.x; + wheelEvent.y = local.y; + wheelEvent.x_root = global.x; + wheelEvent.y_root = global.y; + wheelEvent.send_event = false; + wheelEvent.display = Tk_Display(tkwin); + wheelEvent.window = Tk_WindowId(tkwin); delta = [theEvent deltaY]; if (delta != 0.0) { coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta); - xEvent.xbutton.state = state; - xEvent.xkey.keycode = coarseDelta; - xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + wheelEvent.state = state; + wheelEvent.delta = coarseDelta; + wheelEvent.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + Tk_QueueWindowEvent((XEvent *) &wheelEvent, TCL_QUEUE_TAIL); } delta = [theEvent deltaX]; if (delta != 0.0) { coarseDelta = (delta > -1.0 && delta < 1.0) ? (signbit(delta) ? -1 : 1) : lround(delta); - xEvent.xbutton.state = state | ShiftMask; - xEvent.xkey.keycode = coarseDelta; - xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + wheelEvent.state = state | ShiftMask; + wheelEvent.delta = coarseDelta; + wheelEvent.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + Tk_QueueWindowEvent((XEvent *) &wheelEvent, TCL_QUEUE_TAIL); } } return theEvent; -- cgit v0.12