diff --git a/browser/default_app/main.js b/browser/default_app/main.js index 3bfb5b510..2aff83e30 100644 --- a/browser/default_app/main.js +++ b/browser/default_app/main.js @@ -1,6 +1,7 @@ var app = require('app'); var dialog = require('dialog'); var path = require('path'); +var optimist = require('optimist'); // Quit when all windows are closed and no other one is listening to this. app.on('window-all-closed', function() { @@ -8,8 +9,7 @@ app.on('window-all-closed', function() { app.quit(); }); -process.argv.splice(1, 0, 'dummyScript'); -var argv = require('optimist').argv; +var argv = optimist(process.argv.slice(1)).argv; // Start the specified app if there is one specified in command line, otherwise // start the default app. diff --git a/browser/ui/accelerator_util.cc b/browser/ui/accelerator_util.cc index fe1b7a962..c1563ca12 100644 --- a/browser/ui/accelerator_util.cc +++ b/browser/ui/accelerator_util.cc @@ -4,6 +4,8 @@ #include "browser/ui/accelerator_util.h" +#include + #include #include "base/string_util.h" @@ -15,27 +17,79 @@ namespace accelerator_util { namespace { -// Convert "Command" to "Ctrl" on non-Mac -std::string NormalizeShortcutSuggestion(const std::string& suggestion) { -#if defined(OS_MACOSX) - return suggestion; -#endif +// Return key code of the char. +ui::KeyboardCode KeyboardCodeFromCharCode(char c, bool* shifted) { + *shifted = false; + switch (c) { + case 8: case 0x7F: return ui::VKEY_BACK; + case 9: return ui::VKEY_TAB; + case 0xD: case 3: return ui::VKEY_RETURN; + case 0x1B: return ui::VKEY_ESCAPE; + case ' ': return ui::VKEY_SPACE; - std::string key; - std::vector tokens; - base::SplitString(suggestion, '+', &tokens); - for (size_t i = 0; i < tokens.size(); i++) { - if (tokens[i] == "Command") - tokens[i] = "Ctrl"; + case 'a': return ui::VKEY_A; + case 'b': return ui::VKEY_B; + case 'c': return ui::VKEY_C; + case 'd': return ui::VKEY_D; + case 'e': return ui::VKEY_E; + case 'f': return ui::VKEY_F; + case 'g': return ui::VKEY_G; + case 'h': return ui::VKEY_H; + case 'i': return ui::VKEY_I; + case 'j': return ui::VKEY_J; + case 'k': return ui::VKEY_K; + case 'l': return ui::VKEY_L; + case 'm': return ui::VKEY_M; + case 'n': return ui::VKEY_N; + case 'o': return ui::VKEY_O; + case 'p': return ui::VKEY_P; + case 'q': return ui::VKEY_Q; + case 'r': return ui::VKEY_R; + case 's': return ui::VKEY_S; + case 't': return ui::VKEY_T; + case 'u': return ui::VKEY_U; + case 'v': return ui::VKEY_V; + case 'w': return ui::VKEY_W; + case 'x': return ui::VKEY_X; + case 'y': return ui::VKEY_Y; + case 'z': return ui::VKEY_Z; + + case ')': *shifted = true; case '0': return ui::VKEY_0; + case '!': *shifted = true; case '1': return ui::VKEY_1; + case '@': *shifted = true; case '2': return ui::VKEY_2; + case '#': *shifted = true; case '3': return ui::VKEY_3; + case '$': *shifted = true; case '4': return ui::VKEY_4; + case '%': *shifted = true; case '5': return ui::VKEY_5; + case '^': *shifted = true; case '6': return ui::VKEY_6; + case '&': *shifted = true; case '7': return ui::VKEY_7; + case '*': *shifted = true; case '8': return ui::VKEY_8; + case '(': *shifted = true; case '9': return ui::VKEY_9; + + case ':': *shifted = true; case ';': return ui::VKEY_OEM_1; + case '+': *shifted = true; case '=': return ui::VKEY_OEM_PLUS; + case '<': *shifted = true; case ',': return ui::VKEY_OEM_COMMA; + case '_': *shifted = true; case '-': return ui::VKEY_OEM_MINUS; + case '>': *shifted = true; case '.': return ui::VKEY_OEM_PERIOD; + case '?': *shifted = true; case '/': return ui::VKEY_OEM_2; + case '~': *shifted = true; case '`': return ui::VKEY_OEM_3; + case '{': *shifted = true; case '[': return ui::VKEY_OEM_4; + case '|': *shifted = true; case '\\': return ui::VKEY_OEM_5; + case '}': *shifted = true; case ']': return ui::VKEY_OEM_6; + case '"': *shifted = true; case '\'': return ui::VKEY_OEM_7; + + default: return ui::VKEY_UNKNOWN; } - return JoinString(tokens, '+'); } } // namespace bool StringToAccelerator(const std::string& description, ui::Accelerator* accelerator) { - std::string shortcut(NormalizeShortcutSuggestion(description)); + if (!IsStringASCII(description)) { + LOG(ERROR) << "The accelerator string can only contain ASCII characters"; + return false; + } + std::string shortcut(StringToLowerASCII(description)); std::vector tokens; base::SplitString(shortcut, '+', &tokens); @@ -48,65 +102,77 @@ bool StringToAccelerator(const std::string& description, int modifiers = ui::EF_NONE; ui::KeyboardCode key = ui::VKEY_UNKNOWN; for (size_t i = 0; i < tokens.size(); i++) { - if (tokens[i] == "Ctrl") { + // We use straight comparing instead of map because the accelerator tends + // to be correct and usually only uses few special tokens. + if (tokens[i].size() == 1) { + bool shifted = false; + key = KeyboardCodeFromCharCode(tokens[i][0], &shifted); + if (shifted) + modifiers |= ui::EF_SHIFT_DOWN; + } else if (tokens[i] == "ctrl") { modifiers |= ui::EF_CONTROL_DOWN; - } else if (tokens[i] == "Command") { + } else if (tokens[i] == "command") { + // The "Command" would be translated to "Ctrl" on platforms other than + // OS X. +#if defined(OS_MACOSX) modifiers |= ui::EF_COMMAND_DOWN; - } else if (tokens[i] == "Alt") { +#else + modifiers |= ui::EF_CONTROL_DOWN; +#endif + } else if (tokens[i] == "alt") { modifiers |= ui::EF_ALT_DOWN; - } else if (tokens[i] == "Shift") { + } else if (tokens[i] == "shift") { modifiers |= ui::EF_SHIFT_DOWN; - } else if (tokens[i].size() == 1) { - char token = tokens[i][0]; - - if (key != ui::VKEY_UNKNOWN) { - // Multiple key assignments. - key = ui::VKEY_UNKNOWN; - return false; - } - if (token >= 'A' && token <= 'Z') { - key = static_cast(ui::VKEY_A + (token - 'A')); - } else if (token >= '0' && token <= '9') { - key = static_cast(ui::VKEY_0 + (token - '0')); - } else if (token >= '*' && token <= '/') { - // *+,-./ - key = static_cast( - ui::VKEY_MULTIPLY + (token - '*')); + } else if (tokens[i] == "tab") { + key = ui::VKEY_TAB; + } else if (tokens[i] == "space") { + key = ui::VKEY_SPACE; + } else if (tokens[i] == "backspace") { + key = ui::VKEY_BACK; + } else if (tokens[i] == "delete") { + key = ui::VKEY_DELETE; + } else if (tokens[i] == "enter" || tokens[i] == "return") { + key = ui::VKEY_RETURN; + } else if (tokens[i] == "up") { + key = ui::VKEY_UP; + } else if (tokens[i] == "down") { + key = ui::VKEY_DOWN; + } else if (tokens[i] == "left") { + key = ui::VKEY_LEFT; + } else if (tokens[i] == "right") { + key = ui::VKEY_RIGHT; + } else if (tokens[i] == "home") { + key = ui::VKEY_HOME; + } else if (tokens[i] == "end") { + key = ui::VKEY_END; + } else if (tokens[i] == "pagedown") { + key = ui::VKEY_PRIOR; + } else if (tokens[i] == "pageup") { + key = ui::VKEY_NEXT; + } else if (tokens[i] == "esc") { + key = ui::VKEY_ESCAPE; + } else if (tokens[i] == "volumemute") { + key = ui::VKEY_VOLUME_MUTE; + } else if (tokens[i] == "volumeup") { + key = ui::VKEY_VOLUME_UP; + } else if (tokens[i] == "volumedown") { + key = ui::VKEY_VOLUME_DOWN; + } else if (tokens[i] == "medianexttrack") { + key = ui::VKEY_MEDIA_NEXT_TRACK; + } else if (tokens[i] == "mediaprevioustrack") { + key = ui::VKEY_MEDIA_PREV_TRACK; + } else if (tokens[i] == "mediastop") { + key = ui::VKEY_MEDIA_STOP; + } else if (tokens[i] == "mediaplaypause") { + key = ui::VKEY_MEDIA_PLAY_PAUSE; + } else if (tokens[i].size() > 1 && tokens[i][0] == 'f') { + // F1 - F24. + int n; + if (base::StringToInt(tokens[i].c_str() + 1, &n)) { + key = static_cast(ui::VKEY_F1 + n - 1); } else { - switch (token) { - case ':': - case ';': - key = ui::VKEY_OEM_1; - break; - case '?': - case '/': - key = ui::VKEY_OEM_2; - break; - case '~': - case '`': - key = ui::VKEY_OEM_3; - break; - case '{': - case '[': - key = ui::VKEY_OEM_4; - break; - case '|': - case '\\': - key = ui::VKEY_OEM_5; - break; - case '}': - case ']': - key = ui::VKEY_OEM_6; - break; - case '\"': - case '\'': - key = ui::VKEY_OEM_7; - break; - default: - LOG(WARNING) << "Invalid accelerator character: " << tokens[i]; - key = ui::VKEY_UNKNOWN; - return false; - } + LOG(WARNING) << tokens[i] << "is not available on keyboard"; + return false; } } else { LOG(WARNING) << "Invalid accelerator token: " << tokens[i]; @@ -114,6 +180,11 @@ bool StringToAccelerator(const std::string& description, } } + if (key == ui::VKEY_UNKNOWN) { + LOG(WARNING) << "The accelerator doesn't contain a valid key"; + return false; + } + *accelerator = ui::Accelerator(key, modifiers); SetPlatformAccelerator(accelerator); return true;