< prev index next >

src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m

Print this page
rev 52276 : 8213292 Input freezes after MacOS key-selector (press&hold) usage on macOS Mojave

Call abandonInput to reset input methods after entering accented symbols


  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #import "jni_util.h"
  27 #import "CGLGraphicsConfig.h"
  28 #import "AWTView.h"
  29 #import "AWTWindow.h"
  30 #import "JavaComponentAccessibility.h"
  31 #import "JavaTextAccessibility.h"
  32 #import "JavaAccessibilityUtilities.h"
  33 #import "GeomUtilities.h"
  34 #import "OSVersion.h"
  35 #import "ThreadUtilities.h"
  36 

  37 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  38 
  39 @interface AWTView()
  40 @property (retain) CDropTarget *_dropTarget;
  41 @property (retain) CDragSource *_dragSource;
  42 
  43 -(void) deliverResize: (NSRect) rect;
  44 -(void) resetTrackingArea;
  45 -(void) deliverJavaKeyEventHelper: (NSEvent*) event;
  46 -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint;
  47 -(NSMutableString *) parseString : (id) complexString;
  48 @end
  49 
  50 // Uncomment this line to see fprintfs of each InputMethod API being called on this View
  51 //#define IM_DEBUG TRUE
  52 //#define EXTRA_DEBUG
  53 
  54 static BOOL shouldUsePressAndHold() {
  55     static int shouldUsePressAndHold = -1;
  56     if (shouldUsePressAndHold != -1) return shouldUsePressAndHold;
  57     shouldUsePressAndHold = !isSnowLeopardOrLower();
  58     return shouldUsePressAndHold;
  59 }
  60 







  61 @implementation AWTView
  62 
  63 @synthesize _dropTarget;
  64 @synthesize _dragSource;
  65 @synthesize cglLayer;
  66 @synthesize mouseIsOver;
  67 
  68 // Note: Must be called on main (AppKit) thread only
  69 - (id) initWithRect: (NSRect) rect
  70        platformView: (jobject) cPlatformView
  71         windowLayer: (CALayer*) windowLayer
  72 {
  73     AWT_ASSERT_APPKIT_THREAD;
  74     // Initialize ourselves
  75     self = [super initWithFrame: rect];
  76     if (self == nil) return self;
  77 
  78     m_cPlatformView = cPlatformView;
  79     fInputMethodLOCKABLE = NULL;
  80     fKeyEventsNeeded = NO;


 264     [self deliverJavaMouseEvent: event];
 265     //Restore the cursor back.
 266     //[CCursorManager _setCursor: [NSCursor arrowCursor]];
 267 }
 268 
 269 - (void) scrollWheel: (NSEvent*) event {
 270     [self deliverJavaMouseEvent: event];
 271 }
 272 
 273 /*
 274  * KeyEvents support
 275  */
 276 
 277 - (void) keyDown: (NSEvent *)event {
 278     fProcessingKeystroke = YES;
 279     fKeyEventsNeeded = YES;
 280 
 281     // Allow TSM to look at the event and potentially send back NSTextInputClient messages.
 282     [self interpretKeyEvents:[NSArray arrayWithObject:event]];
 283 
 284     if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod] && fInputMethodLOCKABLE) {


 285         fProcessingKeystroke = NO;
 286         if (!fInPressAndHold) {
 287             fInPressAndHold = YES;
 288             fPAHNeedsToSelect = YES;


















 289         }
 290         return;
 291     }
 292 
 293     NSString *eventCharacters = [event characters];
 294     BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
 295 
 296     if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
 297         [self deliverJavaKeyEventHelper: event];
 298     }
 299 
 300     fProcessingKeystroke = NO;
 301 }
 302 
 303 - (void) keyUp: (NSEvent *)event {
 304     [self deliverJavaKeyEventHelper: event];
 305 }
 306 
 307 - (void) flagsChanged: (NSEvent *)event {
 308     [self deliverJavaKeyEventHelper: event];


 961             fPAHNeedsToSelect = NO;
 962         }
 963 
 964         static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V");
 965         jstring insertedText =  JNFNSToJavaString(env, useString);
 966         JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode)
 967         (*env)->DeleteLocalRef(env, insertedText);
 968 
 969         // The input method event will create psuedo-key events for each character in the committed string.
 970         // We also don't want to send the character that triggered the insertText, usually a return. [3337563]
 971         fKeyEventsNeeded = NO;
 972     }
 973     else {
 974         // Need to set back the fKeyEventsNeeded flag so that the string following the
 975         // marked text is not ignored by keyDown
 976         if ([useString length] > 0) {
 977             fKeyEventsNeeded = YES;
 978         }
 979     }
 980     fPAHNeedsToSelect = NO;







 981 }
 982 
 983 - (void) doCommandBySelector:(SEL)aSelector
 984 {
 985 #ifdef IM_DEBUG
 986     fprintf(stderr, "AWTView InputMethod Selector Called : [doCommandBySelector]\n");
 987     NSLog(@"%@", NSStringFromSelector(aSelector));
 988 #endif // IM_DEBUG
 989     if (@selector(insertNewline:) == aSelector || @selector(insertTab:) == aSelector || @selector(deleteBackward:) == aSelector)
 990     {
 991         fKeyEventsNeeded = YES;
 992     }
 993 }
 994 
 995 // setMarkedText: cannot take a nil first argument. aString can be NSString or NSAttributedString
 996 - (void) setMarkedText:(id)aString selectedRange:(NSRange)selectionRange replacementRange:(NSRange)replacementRange
 997 {
 998     if (!fInputMethodLOCKABLE)
 999         return;
1000 




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 #import "jni_util.h"
  27 #import "CGLGraphicsConfig.h"
  28 #import "AWTView.h"
  29 #import "AWTWindow.h"
  30 #import "JavaComponentAccessibility.h"
  31 #import "JavaTextAccessibility.h"
  32 #import "JavaAccessibilityUtilities.h"
  33 #import "GeomUtilities.h"
  34 #import "OSVersion.h"
  35 #import "ThreadUtilities.h"
  36 
  37 #import <Carbon/Carbon.h>
  38 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  39 
  40 @interface AWTView()
  41 @property (retain) CDropTarget *_dropTarget;
  42 @property (retain) CDragSource *_dragSource;
  43 
  44 -(void) deliverResize: (NSRect) rect;
  45 -(void) resetTrackingArea;
  46 -(void) deliverJavaKeyEventHelper: (NSEvent*) event;
  47 -(BOOL) isCodePointInUnicodeBlockNeedingIMEvent: (unichar) codePoint;
  48 -(NSMutableString *) parseString : (id) complexString;
  49 @end
  50 
  51 // Uncomment this line to see fprintfs of each InputMethod API being called on this View
  52 //#define IM_DEBUG TRUE
  53 //#define EXTRA_DEBUG
  54 
  55 static BOOL shouldUsePressAndHold() {
  56     static int shouldUsePressAndHold = -1;
  57     if (shouldUsePressAndHold != -1) return shouldUsePressAndHold;
  58     shouldUsePressAndHold = !isSnowLeopardOrLower();
  59     return shouldUsePressAndHold;
  60 }
  61 
  62 #ifndef kCFCoreFoundationVersionNumber10_13_Max
  63 #define kCFCoreFoundationVersionNumber10_13_Max 1499
  64 #endif
  65 
  66 #define IS_OSX_GT10_13 (floor(kCFCoreFoundationVersionNumber) > \
  67     kCFCoreFoundationVersionNumber10_13_Max)
  68 
  69 @implementation AWTView
  70 
  71 @synthesize _dropTarget;
  72 @synthesize _dragSource;
  73 @synthesize cglLayer;
  74 @synthesize mouseIsOver;
  75 
  76 // Note: Must be called on main (AppKit) thread only
  77 - (id) initWithRect: (NSRect) rect
  78        platformView: (jobject) cPlatformView
  79         windowLayer: (CALayer*) windowLayer
  80 {
  81     AWT_ASSERT_APPKIT_THREAD;
  82     // Initialize ourselves
  83     self = [super initWithFrame: rect];
  84     if (self == nil) return self;
  85 
  86     m_cPlatformView = cPlatformView;
  87     fInputMethodLOCKABLE = NULL;
  88     fKeyEventsNeeded = NO;


 272     [self deliverJavaMouseEvent: event];
 273     //Restore the cursor back.
 274     //[CCursorManager _setCursor: [NSCursor arrowCursor]];
 275 }
 276 
 277 - (void) scrollWheel: (NSEvent*) event {
 278     [self deliverJavaMouseEvent: event];
 279 }
 280 
 281 /*
 282  * KeyEvents support
 283  */
 284 
 285 - (void) keyDown: (NSEvent *)event {
 286     fProcessingKeystroke = YES;
 287     fKeyEventsNeeded = YES;
 288 
 289     // Allow TSM to look at the event and potentially send back NSTextInputClient messages.
 290     [self interpretKeyEvents:[NSArray arrayWithObject:event]];
 291 
 292     if (fEnablePressAndHold && [event willBeHandledByComplexInputMethod] && 
 293         fInputMethodLOCKABLE)
 294     {
 295         fProcessingKeystroke = NO;
 296         if (!fInPressAndHold) {
 297             fInPressAndHold = YES;
 298             fPAHNeedsToSelect = YES;
 299         } else if (IS_OSX_GT10_13) {
 300             // Abandon input to reset IM and unblock input after canceling 
 301             // input accented symbols (macOS 10.14+ only)
 302 
 303             switch([event keyCode]) {
 304                 case kVK_Escape:
 305                 case kVK_Delete:
 306                 case kVK_Return:
 307                 case kVK_ForwardDelete:
 308                 case kVK_PageUp:
 309                 case kVK_PageDown:
 310                 case kVK_DownArrow:
 311                 case kVK_UpArrow:
 312                 case kVK_Home:
 313                 case kVK_End:
 314                    [self abandonInput];
 315                    break;
 316             }
 317         }
 318         return;
 319     }
 320 
 321     NSString *eventCharacters = [event characters];
 322     BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
 323 
 324     if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
 325         [self deliverJavaKeyEventHelper: event];
 326     }
 327 
 328     fProcessingKeystroke = NO;
 329 }
 330 
 331 - (void) keyUp: (NSEvent *)event {
 332     [self deliverJavaKeyEventHelper: event];
 333 }
 334 
 335 - (void) flagsChanged: (NSEvent *)event {
 336     [self deliverJavaKeyEventHelper: event];


 989             fPAHNeedsToSelect = NO;
 990         }
 991 
 992         static JNF_MEMBER_CACHE(jm_insertText, jc_CInputMethod, "insertText", "(Ljava/lang/String;)V");
 993         jstring insertedText =  JNFNSToJavaString(env, useString);
 994         JNFCallVoidMethod(env, fInputMethodLOCKABLE, jm_insertText, insertedText); // AWT_THREADING Safe (AWTRunLoopMode)
 995         (*env)->DeleteLocalRef(env, insertedText);
 996 
 997         // The input method event will create psuedo-key events for each character in the committed string.
 998         // We also don't want to send the character that triggered the insertText, usually a return. [3337563]
 999         fKeyEventsNeeded = NO;
1000     }
1001     else {
1002         // Need to set back the fKeyEventsNeeded flag so that the string following the
1003         // marked text is not ignored by keyDown
1004         if ([useString length] > 0) {
1005             fKeyEventsNeeded = YES;
1006         }
1007     }
1008     fPAHNeedsToSelect = NO;
1009 
1010     // Abandon input to reset IM and unblock input after entering accented
1011     // symbols (macOS 10.14+ only)
1012 
1013     if (IS_OSX_GT10_13) {
1014         [self abandonInput];
1015     }
1016 }
1017 
1018 - (void) doCommandBySelector:(SEL)aSelector
1019 {
1020 #ifdef IM_DEBUG
1021     fprintf(stderr, "AWTView InputMethod Selector Called : [doCommandBySelector]\n");
1022     NSLog(@"%@", NSStringFromSelector(aSelector));
1023 #endif // IM_DEBUG
1024     if (@selector(insertNewline:) == aSelector || @selector(insertTab:) == aSelector || @selector(deleteBackward:) == aSelector)
1025     {
1026         fKeyEventsNeeded = YES;
1027     }
1028 }
1029 
1030 // setMarkedText: cannot take a nil first argument. aString can be NSString or NSAttributedString
1031 - (void) setMarkedText:(id)aString selectedRange:(NSRange)selectionRange replacementRange:(NSRange)replacementRange
1032 {
1033     if (!fInputMethodLOCKABLE)
1034         return;
1035 


< prev index next >