JDK-8094601 : Mac: Command-period generates spurious KeyEvents on Mac OS
  • Type: Bug
  • Component: javafx
  • Sub-Component: window-toolkit
  • Affected Version: 8u5
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-06-04
  • Updated: 2025-06-30
  • Resolved: 2015-01-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8u60Fixed
Related Reports
Relates :  
Relates :  
Description
Pressing meta-. on Mac OS generates spurious events in addition to the normal events.

Pressing meta-, shows the expected sequence of events:
type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0)
type=KEY_PRESSED code=COMMA mods=[meta] char='' ( 0)
type=KEY_TYPED code=UNDEFINED mods=[meta] char=',' ( 44)
type=KEY_RELEASED code=COMMA mods=[meta] char='' ( 0)
type=KEY_RELEASED code=COMMAND mods=[] char='' ( 0)

Pressing meta-. generates two additional events:
type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0)
type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0)
type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46)
type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0)
type=KEY_PRESSED code=A mods=[] char='' ( 0)
type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27)
type=KEY_RELEASED code=COMMAND mods=[] char='' ( 0)

A KEY_PRESSED with keycode 'A' followed by a KEY_TYPED with the ASCII escape character as its character value.

The spurious events are not generated when running the same program in Ubuntu Linux 12.04.

On Windows 8 the right Windows key generates no events whatsoever, and the left Windows key generates PRESSED and RELEASED for the WINDOWS key itself, and only RELEASED for the PERIOD key. No PRESSED or TYPED are generated for the PERIOD. Presumably this is because Windows-. means something to Windows 8, because Windows-/ for example generates the normal sequence of events (WINDOWS PRESSED, SLASH PRESSED, '/' TYPED, SLASH RELEASED, WINDOWS RELEASED). In any case, no spurious events are generated on Windows either.

Comments
Fixed with this change set: Changeset: 2d040d3f8165 Author: Morris Meyer <morris.meyer@oracle.com> Date: 2015-01-13 14:49 -0500 URL: http://hg.openjdk.java.net/openjfx/8u-dev/rt/rev/2d040d3f8165
13-01-2015

Looks good, +1
13-01-2015

Looks good to me. I haven't tested it but I assume you have. +1
13-01-2015

Updated review with the redundant test and proper release. http://cr.openjdk.java.net/~morris/RT-37399.02a
13-01-2015

Oh, wait. I just noticed one more thing: you will leak the fsWindow since you don't release it in the new block before returning.
13-01-2015

+1 (but I recommend removing the redundant test)
13-01-2015

The check for modiferFlag containing NSCommandKeyMask is done twice, so one of them is redundant: + if ([theEvent modifierFlags] & NSCommandKeyMask) + { + if ([theEvent modifierFlags] & NSCommandKeyMask && + uch == com_sun_glass_events_KeyEvent_VK_PERIOD) + { ... Looks good other than that. I tested it on two different Mac systems: 10.9.5 and 10.7.5 (the latter matches our build/test environment even though 10.8.3 is our minimum supported version).
13-01-2015

Thanks for testing Michael Bayne.
10-01-2015

I noticed it was complaining about GetJavaKeyChars not being defined, and realized that I had failed to add the import of GlassKey.h. It works fine now, nothing to see here. Move it along. :)
10-01-2015

Here's the crash trace if it's useful: Thread 0 Crashed:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x00007fff89ab4282 __pthread_kill + 10 1 libsystem_c.dylib 0x00007fff81512b73 abort + 129 2 libjvm.dylib 0x000000010545d02b os::abort(bool) + 25 3 libjvm.dylib 0x0000000105579b16 VMError::report_and_die() + 2260 4 libjvm.dylib 0x000000010545eb9e JVM_handle_bsd_signal + 1131 5 libjvm.dylib 0x000000010545b05f signalHandler(int, __siginfo*, void*) + 47 6 libsystem_platform.dylib 0x00007fff8ac6ff1a _sigtramp + 26 7 libjvm.dylib 0x00000001052d3d87 JavaCallArguments::parameters() + 39 8 libjvm.dylib 0x00000001052d44e5 JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*) + 1661 9 libjvm.dylib 0x000000010530993b jni_invoke_nonstatic(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, Thread*) + 773 10 libjvm.dylib 0x00000001052fc576 jni_CallVoidMethod + 363 11 libglass.dylib 0x00000001242fec6f -[GlassView3D performKeyEquivalent:] + 463 12 com.apple.AppKit 0x00007fff838e9a8b -[NSView _performKeyEquivalent:conditionally:] + 189 13 com.apple.AppKit 0x00007fff838e9b3f -[NSView performKeyEquivalent:] + 150 14 com.apple.AppKit 0x00007fff838e9a8b -[NSView _performKeyEquivalent:conditionally:] + 189 15 com.apple.AppKit 0x00007fff838e9b3f -[NSView performKeyEquivalent:] + 150 16 com.apple.AppKit 0x00007fff838e9a8b -[NSView _performKeyEquivalent:conditionally:] + 189 17 com.apple.AppKit 0x00007fff838e9959 -[NSWindow performKeyEquivalent:] + 61 18 libglass.dylib 0x0000000124306810 -[GlassWindow_Normal performKeyEquivalent:] + 64 19 com.apple.AppKit 0x00007fff838e9736 -[NSApplication _handleKeyEquivalent:] + 521 20 com.apple.AppKit 0x00007fff8386c79b -[NSApplication sendEvent:] + 4035 21 com.apple.AppKit 0x00007fff836f8e98 -[NSApplication run] + 711 22 libglass.dylib 0x00000001242e7844 -[GlassApplication runLoop:] + 1860 23 com.apple.Foundation 0x00007fff89044f4c __NSThreadPerformPerform + 293 24 com.apple.CoreFoundation 0x00007fff87119661 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 25 com.apple.CoreFoundation 0x00007fff8710b7ed __CFRunLoopDoSources0 + 269 26 com.apple.CoreFoundation 0x00007fff8710ae1f __CFRunLoopRun + 927 27 com.apple.CoreFoundation 0x00007fff8710a838 CFRunLoopRunSpecific + 296 28 java 0x0000000103d246cc CreateExecutionEnvironment + 871 29 java 0x0000000103d2065c JLI_Launch + 1952 30 java 0x0000000103d2668a main + 101 31 java 0x0000000103d1feb4 start + 52
09-01-2015

FWIW: when I apply your patch and test MetaDot, it segfaults when I press CMD-.. Not entirely sure what the bug is, getting a debugger wired up will probably not be quite as easy as building and testing. :)
09-01-2015

Incidentally, kudos to the build team on the OpenJFX build. That was easily the least painful "decide I want to build and test some really complex system that involves multiple cross-platform builds" experience I've ever had. From "hg clone" to "java -Djava.ext.dirs=..." was less than ten minutes.
09-01-2015

Well, I stand corrected. With the performKeyEquivalent processing eliminated (just returning NO), I get nothing for the . key press. Just COMMAND down, and COMMAND up. Alas. I suppose that something else must be "recognizing" that key equivalent, and preventing the OS from dispatching it as a normal NSKeyDown.
09-01-2015

I'm no Mac OS event dispatch expert, but this documentation: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html indicates: "Note: Beginning with OS X v10.5, if a key equivalent is not recognized, NSWindow sends it as an NSKeyDown event to the first responder. This behavior enables custom key-binding entries with Command-key modifiers. In addition, NSApplication sends a Control-key event to the key window via performKeyEquivalent: before sending it as an NSKeyDown event through the responder chain. This behavior allows more reliable use of Control-key events as menu key equivalents." which makes me think that you could just not dispatch anything in performKeyEquivalent and you'd get a subsequent keyDown notification. Perhaps I should build OpenJFX and test that hypothesis.
09-01-2015

Please review - http://cr.openjdk.java.net/~morris/RT-37399.01/
09-01-2015

Testing on Windows. Here is CTRL-k : type=KEY_PRESSED code=CONTROL mods=[ctrl] char=' ' ( 0) type=KEY_PRESSED code=K mods=[ctrl] char=' ' ( 0) type=KEY_TYPED code=UNDEFINED mods=[ctrl] char='♂' ( 11) type=KEY_RELEASED code=K mods=[ctrl] char=' ' ( 0) type=KEY_RELEASED code=CONTROL mods=[] char=' ' ( 0) Here is WINDOWS- dot type=KEY_PRESSED code=WINDOWS mods=[meta] char=' ' ( 0) type=KEY_PRESSED code=PERIOD mods=[meta] char=' ' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char=' ' ( 0) type=KEY_RELEASED code=WINDOWS mods=[] char=' ' ( 0)
08-01-2015

I can reproduce this bug in Mac OS X 10.10.1 using the program listed above. When I press COMMAND . this output results: type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0) type=KEY_PRESSED code=A mods=[] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27) type=KEY_RELEASED code=COMMAND mods=[] char='' ( 0)
05-01-2015

I still can't reproduce the issue on my system consistently. Yesterday I managed to make it happen, but today to no avail. The same for RT-37093. I suspect that this may somehow be related to the fact that I use VNC to connect to my Mac (and I can't access its console physically atm). I'm reassigning both bugs to Petr as he says he's able to reproduce the bugs consistently.
18-06-2014

Petr can reproduce the bug on his OS X 10.9 consistently. I'll try a few more times later, and if I can't replicate it on my system, I'll reassign the bug to Petr.
06-06-2014

Lucky you! :) The version of the OS may matter here, however, I *did* reproduce it on my system once. But the second and all subsequent runs don't reveal the bug (and yes, I've tried rebooting my system, too.) That's really puzzling me now...
06-06-2014

Sorry, the second two runs, I had the CMD key down before the app fully started (so there's no KEY_PRESSED for COMMAND). But it still happens consistently even if I take care not to press any keys until the app is running: [6:56am] usui:bugs/javafx/meta-dot % java MetaDot type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0) type=KEY_PRESSED code=A mods=[] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27) type=KEY_RELEASED code=COMMAND mods=[] char='' ( 0) type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=Q mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='q' ( 113) type=KEY_RELEASED code=Q mods=[meta] char='' ( 0) [6:57am] usui:bugs/javafx/meta-dot % java MetaDot type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0) type=KEY_PRESSED code=A mods=[] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27) type=KEY_RELEASED code=COMMAND mods=[] char='' ( 0) type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=Q mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='q' ( 113) type=KEY_RELEASED code=Q mods=[meta] char='' ( 0)
06-06-2014

I can. :) [6:53am] usui:bugs/javafx/meta-dot % java MetaDot type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0) type=KEY_PRESSED code=A mods=[] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27) type=KEY_RELEASED code=COMMAND mods=[] char='' ( 0) type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=Q mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='q' ( 113) type=KEY_RELEASED code=Q mods=[meta] char='' ( 0) [6:55am] usui:bugs/javafx/meta-dot % java MetaDot type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0) type=KEY_PRESSED code=A mods=[] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27) type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=Q mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='q' ( 113) type=KEY_RELEASED code=Q mods=[meta] char='' ( 0) [6:55am] usui:bugs/javafx/meta-dot % java MetaDot type=KEY_PRESSED code=PERIOD mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='.' ( 46) type=KEY_RELEASED code=PERIOD mods=[meta] char='' ( 0) type=KEY_PRESSED code=A mods=[] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[] char=' ( 27) type=KEY_PRESSED code=COMMAND mods=[meta] char='' ( 0) type=KEY_PRESSED code=Q mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='q' ( 113) type=KEY_RELEASED code=Q mods=[meta] char='' ( 0) I'm running OS X 10.9.3, so maybe you have a different OS version?
06-06-2014

Can you reproduce the Cmd+. bug consistently? I.e., if you restart the test multiple times (literally restart, Cmd+q and then run again), is it reproducible always?
06-06-2014

Whereas if I use the "Key Codes" app (http://manytricks.com/keycodes/), I see only: Modifier Change Keys: ⌘ Key Code: 65535 / 0xffff Modifiers: 1048848 / 0x100110 Key Down Characters: = Unicode: 61 / 0x3d Keys: ⌘= Key Code: 24 / 0x18 Modifiers: 1048848 / 0x100110 Key Up Characters: = Unicode: 61 / 0x3d Keys: ⌘= Key Code: 24 / 0x18 Modifiers: 1048848 / 0x100110 Modifier Change Keys: Key Code: 65535 / 0xffff Modifiers: 256 / 0x100 Unfortunately the source to the Key Codes app is not available AFAIK, otherwise you could compare their event handling to JavaFX's.
06-06-2014

FWIW: I just tried RT-37093 and I also get the spurious behavior it describes: type=KEY_PRESSED code=EQUALS mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='=' ( 61) type=KEY_RELEASED code=EQUALS mods=[meta] char='' ( 0) type=KEY_PRESSED code=EQUALS mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='+' ( 43) type=KEY_RELEASED code=EQUALS mods=[meta] char='' ( 0) type=KEY_PRESSED code=EQUALS mods=[meta] char='' ( 0) type=KEY_TYPED code=UNDEFINED mods=[meta] char='=' ( 61) type=KEY_RELEASED code=EQUALS mods=[meta] char='' ( 0)
06-06-2014

I've tried 8 GA, 8u5 GA, and my developer build of 8u20, and I can no longer reproduce either this bug, or RT-37093.
06-06-2014

RT-37093 is also tracking a Cmd+key issue on Mac. They may be related.
06-06-2014

I mean I could. Just now I've reproduced the bug exactly once on the first run. All subsequent runs do not exhibit the behavior, Cmd+. works as expected. I've tested with both a developer build of 8u20 and also JDK/FX 8 GA. I'll test this further tomorrow.
05-06-2014

I can reproduce this bug on my OS X 10.8.2 system.
05-06-2014

I can't seem to attach a file, so here's the test program that generates the behavior: import java.util.Arrays; import java.util.Set; import java.util.HashSet; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.input.KeyEvent; import javafx.scene.control.Label; import javafx.scene.layout.StackPane; import javafx.stage.Stage; public class MetaDot extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) { primaryStage.setTitle("Meta Dot!"); StackPane root = new StackPane(); root.getChildren().add(new Label("Press Meta Dot.")); primaryStage.addEventHandler(KeyEvent.ANY, ev -> System.out.println(toDebugString(ev))); primaryStage.setScene(new Scene(root, 300, 250)); primaryStage.show(); } private String toDebugString (KeyEvent ev) { StringBuilder sb = new StringBuilder(); sb.append("type=").append(ev.getEventType()); sb.append(" code=").append(ev.getCode()); sb.append(" mods=").append(getModifiers(ev)); sb.append(" char='").append(ev.getCharacter()); sb.append("' ("); for (char c : ev.getCharacter().toCharArray()) sb.append(" ").append((int)c); sb.append(")"); return sb.toString(); } private Set<String> getModifiers (KeyEvent ev) { Set<String> set = new HashSet<>(); if (ev.isAltDown()) set.add("alt"); if (ev.isControlDown()) set.add("ctrl"); if (ev.isMetaDown()) set.add("meta"); if (ev.isShiftDown()) set.add("shift"); return set; } }
04-06-2014