Handle missing keyup events for keys pressed while Command key is down on Mac.

Closes #630.
This commit is contained in:
Jürg Lehni 2015-08-21 13:56:44 +02:00
parent 3dd0f1fc1b
commit eb3628063c
2 changed files with 36 additions and 6 deletions

View file

@ -74,14 +74,22 @@ var PaperScope = Base.extend(/** @lends PaperScope# */{
/*#*/ if (__options.environment == 'browser') {
if (!this.browser) {
var browser = proto.browser = {};
var agent = navigator.userAgent.toLowerCase(),
// Detect basic platforms, only mac internally required for now.
platform = (/(win)/.exec(agent)
|| /(mac)/.exec(agent)
|| /(linux)/.exec(agent)
|| [])[0],
browser = proto.browser = { platform: platform };
if (platform)
browser[platform] = true;
// Use replace() to get all matches, and deal with Chrome/Webkit
// overlap:
// TODO: Do we need Mozilla next to Firefox? Other than the
// different treatment of the Chrome/Webkit overlap
// here: { chrome: true, webkit: false }, mozilla missing is the
// here: { chrome: true, webkit: false }, Mozilla missing is the
// only difference to jQuery.browser
navigator.userAgent.toLowerCase().replace(
agent.replace(
/(opera|chrome|safari|webkit|firefox|msie|trident|atom)\/?\s*([.\d]+)(?:.*version\/([.\d]+))?(?:.*rv\:([.\d]+))?/g,
function(all, n, v1, v2, rv) {
// Do not set additional browsers once chrome is detected.

View file

@ -65,6 +65,7 @@ var Key = new function() {
// charCode so keyup can do the right.
charCodeMap = {}, // keyCode -> charCode mappings for pressed keys
keyMap = {}, // Map for currently pressed keys
commandFixMap, // Keys that will not receive keyup events due to Mac bug
downCode; // The last keyCode from keydown
function handleKey(down, keyCode, charCode, event) {
@ -77,9 +78,6 @@ var Key = new function() {
tool = scope && scope.tool,
name;
keyMap[key] = down;
// Detect modifiers and mark them as pressed / released
if (specialKey && (name = Base.camelize(specialKey)) in modifiers)
modifiers[name] = down;
// Link the keyCode from keydown with the charCode form keypress,
// so keyup can retrieve the charCode again.
// Use delete instead of setting to null, so charCodeMap only contains
@ -91,6 +89,30 @@ var Key = new function() {
} else {
delete charCodeMap[keyCode];
}
// Detect modifiers and mark them as pressed / released
if (specialKey && (name = Base.camelize(specialKey)) in modifiers) {
modifiers[name] = down;
var browser = paper.browser;
if (name === 'command' && browser && browser.mac) {
// Fix a strange behavior on Mac where no keyup events are
// received for any keys pressed while the command key is down.
// Keep track of the normal keys being pressed and trigger keyup
// events for all these keys when command is released:
if (down) {
commandFixMap = {};
} else {
for (var code in commandFixMap) {
// Make sure it wasn't released already in the meantime:
if (code in charCodeMap)
handleKey(false, code, commandFixMap[code], event);
}
commandFixMap = null;
}
}
} else if (down && commandFixMap) {
// A normal key, add it to commandFixMap if that's defined.
commandFixMap[keyCode] = charCode;
}
if (tool && tool.responds(type)) {
// Update global reference to this scope.
paper = scope;