summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorculler <culler>2019-10-24 23:56:43 (GMT)
committerculler <culler>2019-10-24 23:56:43 (GMT)
commitc9c3c73d09cd696f710a5c6bfd731d9cdb243276 (patch)
tree97fe5c8f77496aea79aedaaf8585bfc7946269e6
parent2b66c3ae4d05b4f4c64b795fb6e276c24c44f37e (diff)
downloadtk-c9c3c73d09cd696f710a5c6bfd731d9cdb243276.zip
tk-c9c3c73d09cd696f710a5c6bfd731d9cdb243276.tar.gz
tk-c9c3c73d09cd696f710a5c6bfd731d9cdb243276.tar.bz2
Make Apple's press-and-hold accent menu work with Tk entry and text widgets.
-rw-r--r--library/entry.tcl5
-rw-r--r--library/text.tcl3
-rw-r--r--library/ttk/entry.tcl3
-rw-r--r--macosx/tkMacOSXKeyEvent.c86
4 files changed, 62 insertions, 35 deletions
diff --git a/library/entry.tcl b/library/entry.tcl
index 36c331d..2c72fee 100644
--- a/library/entry.tcl
+++ b/library/entry.tcl
@@ -272,7 +272,7 @@ bind Entry <Meta-Delete> {
}
}
-# Bindings for IME text input.
+# Bindings for IME text input and accents.
bind Entry <<TkStartIMEMarkedText>> {
dict set ::tk::Priv(IMETextMark) "%W" [%W index insert]
@@ -283,6 +283,9 @@ bind Entry <<TkEndIMEMarkedText>> {
bind Entry <<TkClearIMEMarkedText>> {
%W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
+bind Entry <<TkAccentBackspace>> {
+ tk::EntryBackspace %W
+}
# A few additional bindings of my own.
diff --git a/library/text.tcl b/library/text.tcl
index 24f8428..e1130a4 100644
--- a/library/text.tcl
+++ b/library/text.tcl
@@ -403,6 +403,9 @@ bind Text <<TkEndIMEMarkedText>> {
bind Text <<TkClearIMEMarkedText>> {
%W delete IMEmarkedtext.first IMEmarkedtext.last
}
+bind Text <<TkAccentBackspace>> {
+ %W delete insert-1c
+}
# Macintosh only bindings:
diff --git a/library/ttk/entry.tcl b/library/ttk/entry.tcl
index 6a34488..7bca47f 100644
--- a/library/ttk/entry.tcl
+++ b/library/ttk/entry.tcl
@@ -156,6 +156,9 @@ bind TEntry <<TkEndIMEMarkedText>> {
bind TEntry <<TkClearIMEMarkedText>> {
%W delete [dict get $::tk::Priv(IMETextMark) "%W"] [%W index insert]
}
+bind Entry <<TkAccentBackspace>> {
+ tk::EntryBackspace %W
+}
### Clipboard procedures.
#
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index 19be7cf..09abb01 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -285,7 +285,7 @@ static unsigned isFunctionKey(unsigned int code);
return self;
}
-/*
+/*
* Implementation of the NSTextInputClient protocol.
*/
@@ -297,9 +297,14 @@ static unsigned isFunctionKey(unsigned int code);
- (void)insertText: (id)aString
replacementRange: (NSRange)repRange
{
- int i, len = [(NSString *) aString length];
+ int i, len;
XEvent xEvent;
-
+ NSString *str;
+
+ str = ([aString isKindOfClass: [NSAttributedString class]]) ?
+ str = [aString string] : aString;
+ len = [str length];
+
if (NS_KEYLOG) {
TKLog(@"insertText '%@'\tlen = %d", aString, len);
}
@@ -322,6 +327,19 @@ static unsigned isFunctionKey(unsigned int code);
xEvent.xany.type = KeyPress;
/*
+ * Apple evidently sets location to 0 to signal that an accented letter has
+ * been selected from the accent menu. An unaccented letter has already
+ * been displayed and we need to erase it before displaying the accented
+ * letter.
+ */
+
+ if (repRange.location == 0) {
+ TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
+ Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
+ TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
+ }
+
+ /*
* 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
@@ -332,10 +350,10 @@ static unsigned isFunctionKey(unsigned int code);
*/
for (i = 0; i < len; i++) {
- UniChar nextChar = [aString characterAtIndex: i];
+ UniChar nextChar = [str characterAtIndex: i];
if (CFStringIsSurrogateHighCharacter(nextChar)) {
#if 0
- UniChar lowChar = [aString characterAtIndex: ++i];
+ UniChar lowChar = [str characterAtIndex: ++i];
xEvent.xkey.keycode = CFStringGetLongCharacterForSurrogatePair(
nextChar, lowChar);
xEvent.xkey.nbytes = TkUniCharToUtf(xEvent.xkey.keycode,
@@ -348,7 +366,7 @@ static unsigned isFunctionKey(unsigned int code);
#endif
} else {
xEvent.xkey.keycode = (int) nextChar;
- [[aString substringWithRange: NSMakeRange(i,1)]
+ [[str substringWithRange: NSMakeRange(i,1)]
getCString: xEvent.xkey.trans_chars
maxLength: XMaxTransChars encoding: NSUTF8StringEncoding];
xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);
@@ -358,20 +376,20 @@ static unsigned isFunctionKey(unsigned int code);
Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
}
- releaseCode = (UInt16) [aString characterAtIndex: 0];
+ releaseCode = (UInt16) [str characterAtIndex: 0];
}
/*
* This required method is allowed to return nil.
*/
-- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)theRange
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)theRange
actualRange:(NSRangePointer)thePointer
{
return nil;
}
-/*
+/*
* This method is supposed to insert (or replace selected text with) the string
* argument. If the argument is an NSString, it should be displayed with a
* distinguishing appearance, e.g underlined.
@@ -384,11 +402,13 @@ static unsigned isFunctionKey(unsigned int code);
TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
NSString *temp;
- NSString *str = [aString respondsToSelector:@selector (string)] ?
- [aString string] : aString;
+ NSString *str;
+
+ str = ([aString isKindOfClass: [NSAttributedString class]]) ?
+ str = [aString string] : aString;
if (focusWin) {
-
+
/*
* Remember the widget where the composition is happening, in case it
* gets defocussed during the composition.
@@ -415,7 +435,7 @@ static unsigned isFunctionKey(unsigned int code);
/*
* Use our insertText method to display the marked text.
*/
-
+
TkSendVirtualEvent(focusWin, "TkStartIMEMarkedText", NULL);
temp = [str copy];
[self insertText: temp replacementRange:repRange];
@@ -424,7 +444,6 @@ static unsigned isFunctionKey(unsigned int code);
TkSendVirtualEvent(focusWin, "TkEndIMEMarkedText", NULL);
}
-
- (BOOL)hasMarkedText
{
return privateWorkingText != nil;
@@ -443,11 +462,19 @@ static unsigned isFunctionKey(unsigned int code);
return rng;
}
+- (void)cancelComposingText
+{
+ if (NS_KEYLOG) {
+ TKLog(@"cancelComposingText");
+ }
+ [self deleteWorkingText];
+ processingCompose = NO;
+}
- (void)unmarkText
{
if (NS_KEYLOG) {
- TKLog(@"unmark (accept) text");
+ TKLog(@"unmarkText");
}
[self deleteWorkingText];
processingCompose = NO;
@@ -489,31 +516,22 @@ static unsigned isFunctionKey(unsigned int code);
}
processingCompose = NO;
if (aSelector == @selector (deleteBackward:)) {
- /*
- * Happens when user backspaces over an ongoing composition:
- * throw a 'delete' into the event queue.
- */
-
- XEvent xEvent;
-
- setupXEvent(&xEvent, [self window], 0);
- xEvent.xany.type = KeyPress;
- xEvent.xkey.nbytes = 1;
- xEvent.xkey.keycode = (0x33 << 16) | 0x7F;
- xEvent.xkey.trans_chars[0] = 0x7F;
- xEvent.xkey.trans_chars[1] = 0x0;
- Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
+ TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
+ Tk_Window focusWin = (Tk_Window) winPtr->dispPtr->focusPtr;
+ TkSendVirtualEvent(focusWin, "TkAccentBackspace", NULL);
}
}
- (NSArray *)validAttributesForMarkedText
{
static NSArray *arr = nil;
-
if (arr == nil) {
- arr = [NSArray new];
+ arr = [[NSArray alloc] initWithObjects:
+ NSUnderlineStyleAttributeName,
+ NSUnderlineColorAttributeName,
+ nil];
+ [arr retain];
}
- /* [[NSArray arrayWithObject: NSUnderlineStyleAttributeName] retain]; */
return arr;
}
@@ -522,7 +540,7 @@ static unsigned isFunctionKey(unsigned int code);
if (NS_KEYLOG) {
TKLog(@"selectedRange request");
}
- return NSMakeRange(NSNotFound, 0);
+ return NSMakeRange(0, 0);
}
- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
@@ -530,7 +548,7 @@ static unsigned isFunctionKey(unsigned int code);
if (NS_KEYLOG) {
TKLog(@"characterIndexForPoint request");
}
- return 0;
+ return NSNotFound;
}
- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange