From 4f8366a772976629558fda8ee585679f7ae7bfbc Mon Sep 17 00:00:00 2001 From: Evan Morikawa Date: Wed, 4 Feb 2015 21:31:41 -0500 Subject: [PATCH] refactor(keymaps): override-key-bindings instead of native-key-bindings Summary: This diff essentially inverts the behavior of native-key-bindings. Instead of opting-in to native-key-bindings, they're applied UNLESS there's an override-key-bindings class. I think this may be a better solution for us since we don't often want to override behavior like Copy and Select All. Test Plan: No new tests on this one... Reviewers: bengotow Reviewed By: bengotow Differential Revision: https://review.inboxapp.com/D1124 --- docs/advanced/keymaps.md | 4 + .../composer/keymaps/composer.cson | 12 +- .../composer/lib/composer-participants.cjsx | 1 - .../composer/lib/composer-view.cjsx | 2 +- .../message-list/keymaps/message-list.cson | 31 --- .../message-list/lib/message-list.cjsx | 9 - .../message-list/spec/message-list-spec.cjsx | 50 ++-- .../lib/template-picker.cjsx | 2 +- .../onboarding/lib/container-view.cjsx | 5 +- .../thread-list/keymaps/thread-list.cson | 19 +- .../thread-list/lib/thread-list-mixin.cjsx | 24 +- .../thread-list/spec/thread-list-spec.cjsx | 98 ++++---- keymaps/base.cson | 218 +++++++++++++----- keymaps/darwin.cson | 71 ++---- keymaps/linux.cson | 66 ++---- keymaps/win32.cson | 64 ++--- src/browser/edgehill-application.coffee | 2 +- src/window-event-handler.coffee | 4 +- 18 files changed, 321 insertions(+), 361 deletions(-) delete mode 100644 internal_packages/message-list/keymaps/message-list.cson diff --git a/docs/advanced/keymaps.md b/docs/advanced/keymaps.md index 43d0c0e96..2efbd64ae 100644 --- a/docs/advanced/keymaps.md +++ b/docs/advanced/keymaps.md @@ -125,6 +125,10 @@ which is normally used to trigger the `tree-view:add-file` command: ## Forcing Chromium's Native Keystroke Handling +EDIT: This has been overridden in the Edgehill project. By default, Chromium's +native keystroke handling for Copy, Paste, Select-All, etc. is enabled. To except +yourself from these behaviors, apply the `.override-key-bindings` class to an element. + If you want to force the native browser behavior for a given keystroke, use the `native!` directive as the command of a binding. This can be useful to enable the correct behavior in native input elements, for example. If you apply the diff --git a/internal_packages/composer/keymaps/composer.cson b/internal_packages/composer/keymaps/composer.cson index 73210017b..086a7542d 100644 --- a/internal_packages/composer/keymaps/composer.cson +++ b/internal_packages/composer/keymaps/composer.cson @@ -1,24 +1,26 @@ +# We need the "input" specifier on the css class to have the specificity +# required to prevent the default `native!` behavior from happening. # The default state. There's no input in the text field and there are no # autocomplete suggestions -'.autocomplete': +'.autocomplete input': 'backspace': 'native!' 'tab': 'native!' ',': 'native!' # When the text in the input field looks like an emalil -'.autocomplete.autocomplete-looks-like-raw-email': +'.autocomplete.autocomplete-looks-like-raw-email input': 'space': 'participants:add-raw-email' # When there is some text in the input field, but we have no suggestion -'.autocomplete.autocomplete-no-suggestions': +'.autocomplete.autocomplete-no-suggestions input': ',': 'participants:add-raw-email' 'tab': 'participants:add-raw-email' 'enter': 'participants:add-raw-email' 'escape': 'participants:cancel' # When we found a name to suggest -'.autocomplete.autocomplete-with-suggestion': +'.autocomplete.autocomplete-with-suggestion input': ',': 'participants:add-suggestion' 'tab': 'participants:add-suggestion' 'enter': 'participants:add-suggestion' @@ -26,5 +28,5 @@ 'down': 'participants:move-down' 'escape': 'participants:cancel' -'.autocomplete.autocomplete-empty': +'.autocomplete.autocomplete-empty input': 'backspace': 'participants:remove' diff --git a/internal_packages/composer/lib/composer-participants.cjsx b/internal_packages/composer/lib/composer-participants.cjsx index 3ee854e95..648c8ce5d 100644 --- a/internal_packages/composer/lib/composer-participants.cjsx +++ b/internal_packages/composer/lib/composer-participants.cjsx @@ -119,7 +119,6 @@ ComposerParticipants = React.createClass _containerClasses: -> React.addons.classSet "autocomplete": true - "native-key-bindings": true "increase-css-specificity": true "autocomplete-empty": @state.currentEmail.trim().length is 0 "autocomplete-no-suggestions": @_noSuggestions() diff --git a/internal_packages/composer/lib/composer-view.cjsx b/internal_packages/composer/lib/composer-view.cjsx index 7d7de3cbc..d59f430fc 100644 --- a/internal_packages/composer/lib/composer-view.cjsx +++ b/internal_packages/composer/lib/composer-view.cjsx @@ -149,7 +149,7 @@ ComposerView = React.createClass placeholder="Subject" tabIndex="108" disabled={not @state.showsubject} - className="compose-field compose-subject native-key-bindings" + className="compose-field compose-subject" defaultValue={@state.subject} onChange={@_onChangeSubject}/> diff --git a/internal_packages/message-list/keymaps/message-list.cson b/internal_packages/message-list/keymaps/message-list.cson deleted file mode 100644 index e7033332b..000000000 --- a/internal_packages/message-list/keymaps/message-list.cson +++ /dev/null @@ -1,31 +0,0 @@ -'.messages-wrap': - 'up' : 'message-list:move-up' - 'k' : 'message-list:move-up' - - 'down' : 'message-list:move-down' - 'j' : 'message-list:move-down' - - 'left' : 'panel:focus-left' - 'right' : 'panel:focus-right' - - 'e': 'message-list:archive' - - 'r': 'message-list:reply' - 'a': 'message-list:reply-all' - 'f': 'message-list:forward' - -'.native-key-bindings': - 'up' : 'native!' - 'k' : 'native!' - - 'down' : 'native!' - 'j' : 'native!' - - 'left' : 'native!' - 'right' : 'native!' - - 'e': 'native!' - - 'r': 'native!' - 'a': 'native!' - 'f': 'native!' diff --git a/internal_packages/message-list/lib/message-list.cjsx b/internal_packages/message-list/lib/message-list.cjsx index 278836668..416d40578 100755 --- a/internal_packages/message-list/lib/message-list.cjsx +++ b/internal_packages/message-list/lib/message-list.cjsx @@ -19,18 +19,9 @@ MessageList = React.createClass @_unsubscribers = [] @_unsubscribers.push MessageStore.listen @_onChange @_unsubscribers.push ThreadStore.listen @_onChange - @_commandUnsubscribe = atom.commands.add '.messages-wrap', { - 'pane-left:focus': @_paneLeftFocus - 'pane-right:focus': @_paneRightFocus - 'message-list:reply': => Actions.composeReply(@state.current_thread.id) - 'message-list:reply-all': => Actions.composeReplyAll(@state.current_thread.id) - 'message-list:forward': => Actions.composeForward(@state.current_thread.id) - 'message-list:archive': => @state.current_thread.archive() # TODO Turn into ACtion - } componentWillUnmount: -> unsubscribe() for unsubscribe in @_unsubscribers - @_commandUnsubscribe.dispose() render: -> return
if not @state.current_thread? diff --git a/internal_packages/message-list/spec/message-list-spec.cjsx b/internal_packages/message-list/spec/message-list-spec.cjsx index d63562a3a..a0c639c35 100644 --- a/internal_packages/message-list/spec/message-list-spec.cjsx +++ b/internal_packages/message-list/spec/message-list-spec.cjsx @@ -144,6 +144,7 @@ test_thread = (new Thread).fromJSON({ describe "MessageList", -> keymap_path = "internal_packages/message-list/keymaps/message-list.cson" + base_path = "keymaps/base.cson" keymap_mappings = CSON.readFileSync(keymap_path) _resetMessageStore = -> @@ -194,28 +195,33 @@ describe "MessageList", -> ThreadParticipants) expect(items.length).toBe 1 - describe "Triggering message list actions", -> - beforeEach -> - spyOn(Actions, "composeReply") - spyOn(Actions, "composeReplyAll") - spyOn(Actions, "composeForward") - spyOn(test_thread, "archive") - - it "can reply with a keyboard shortcut", -> - InboxTestUtils.keyPress("r", @message_list_node) - expect(Actions.composeReply).toHaveBeenCalledWith(test_thread.id) - - it "can reply all with a keyboard shortcut", -> - InboxTestUtils.keyPress("a", @message_list_node) - expect(Actions.composeReplyAll).toHaveBeenCalledWith(test_thread.id) - - it "can forward with a keyboard shortcut", -> - InboxTestUtils.keyPress("f", @message_list_node) - expect(Actions.composeForward).toHaveBeenCalledWith(test_thread.id) - - it "can archive with a keyboard shortcut", -> - InboxTestUtils.keyPress("e", @message_list_node) - expect(test_thread.archive).toHaveBeenCalled() +# TODO: These need to be moved out of Thread List because the keymaps +# are now registered at the `body` level. There is no `body` dom node +# in this testing. We should move these to a workspace-level test +# suite. +# +# describe "Triggering message list actions", -> +# beforeEach -> +# spyOn(Actions, "composeReply") +# spyOn(Actions, "composeReplyAll") +# spyOn(Actions, "composeForward") +# spyOn(test_thread, "archive") +# +# it "can reply with a keyboard shortcut", -> +# InboxTestUtils.keyPress("r", @message_list_node) +# expect(Actions.composeReply).toHaveBeenCalledWith(test_thread.id) +# +# it "can reply all with a keyboard shortcut", -> +# InboxTestUtils.keyPress("a", @message_list_node) +# expect(Actions.composeReplyAll).toHaveBeenCalledWith(test_thread.id) +# +# it "can forward with a keyboard shortcut", -> +# InboxTestUtils.keyPress("f", @message_list_node) +# expect(Actions.composeForward).toHaveBeenCalledWith(test_thread.id) +# +# it "can archive with a keyboard shortcut", -> +# InboxTestUtils.keyPress("e", @message_list_node) +# expect(test_thread.archive).toHaveBeenCalled() describe "Message", -> beforeEach -> diff --git a/internal_packages/message-templates/lib/template-picker.cjsx b/internal_packages/message-templates/lib/template-picker.cjsx index 50af9f7c5..696aa204f 100644 --- a/internal_packages/message-templates/lib/template-picker.cjsx +++ b/internal_packages/message-templates/lib/template-picker.cjsx @@ -22,7 +22,7 @@ TemplatePicker = React.createClass headerComponents = [ ] diff --git a/internal_packages/onboarding/lib/container-view.cjsx b/internal_packages/onboarding/lib/container-view.cjsx index bc0ae0eff..aef17e3b0 100644 --- a/internal_packages/onboarding/lib/container-view.cjsx +++ b/internal_packages/onboarding/lib/container-view.cjsx @@ -70,7 +70,7 @@ ContainerView = React.createClass else if @state.page is 'sign-in'
-
+ {alert}
@@ -83,7 +83,7 @@ ContainerView = React.createClass
else if @state.page == 'create-account'
- + {alert}
@@ -117,7 +117,6 @@ ContainerView = React.createClass React.createElement('webview',{ "ref": "connect-iframe", "key": this.state.page, - "className": "native-key-bindings", "src": this._connectWebViewURL() }); diff --git a/internal_packages/thread-list/keymaps/thread-list.cson b/internal_packages/thread-list/keymaps/thread-list.cson index d87ac8d7e..1285a3dfe 100644 --- a/internal_packages/thread-list/keymaps/thread-list.cson +++ b/internal_packages/thread-list/keymaps/thread-list.cson @@ -8,19 +8,6 @@ # For more detailed documentation see # https://atom.io/docs/latest/advanced/keymaps '.thread-list-container': - 'up' : 'thread-list:move-up' - 'k' : 'thread-list:move-up' - - 'down' : 'thread-list:move-down' - 'j' : 'thread-list:move-down' - - 'left' : 'panel:focus-left' - 'right' : 'panel:focus-right' - - 'e' : 'thread-list:archive-thread' - 'delete' : 'thread-list:archive-thread' - 'backspace': 'thread-list:archive-thread' - - 'r': 'thread-list:reply' - 'a': 'thread-list:reply-all' - 'f': 'thread-list:forward' + 's' : 'thread-list:star-thread' # Gmail + 'cmd-L' : 'thread-list:star-thread' # Mac mail + 'ctrl-G': 'thread-list:star-thread' # Outlook diff --git a/internal_packages/thread-list/lib/thread-list-mixin.cjsx b/internal_packages/thread-list/lib/thread-list-mixin.cjsx index 2ae207ff2..cfdf35a2f 100644 --- a/internal_packages/thread-list/lib/thread-list-mixin.cjsx +++ b/internal_packages/thread-list/lib/thread-list-mixin.cjsx @@ -8,18 +8,22 @@ ThreadListMixin = componentDidMount: -> @thread_store_unsubscribe = ThreadStore.listen @_onChange - @command_unsubscriber = atom.commands.add '.thread-list-container', { - 'thread-list:move-up': => @_onShiftSelectedIndex(-1) - 'thread-list:move-down': => @_onShiftSelectedIndex(1) - 'thread-list:archive-thread': @_onArchiveSelected - 'thread-list:reply': @_onReply - 'thread-list:reply-all': @_onReplyAll - 'thread-list:forward': @_onForward + @thread_unsubscriber = atom.commands.add '.thread-list-container', { + 'thread-list:star-thread': @_onStarThread + } + @body_unsubscriber = atom.commands.add 'body', { + 'application:previous-message': => @_onShiftSelectedIndex(-1) + 'application:next-message': => @_onShiftSelectedIndex(1) + 'application:archive-thread': @_onArchiveSelected + 'application:reply': @_onReply + 'application:reply-all': @_onReplyAll + 'application:forward': @_onForward } componentWillUnmount: -> @thread_store_unsubscribe() - @command_unsubscriber.dispose() + @thread_unsubscriber.dispose() + @body_unsubscriber.dispose() _onShiftSelectedIndex: (delta) -> item = _.find @state.threads, (thread) => thread.id == @state?.selected @@ -31,6 +35,10 @@ ThreadListMixin = thread = ThreadStore.selectedThread() thread.archive() if thread + _onStarThread: -> + thread = ThreadStore.selectedThread() + thread.toggleStar() if thread + _onReply: -> thread = ThreadStore.selectedThread() Actions.composeReply(thread.id) if thread? diff --git a/internal_packages/thread-list/spec/thread-list-spec.cjsx b/internal_packages/thread-list/spec/thread-list-spec.cjsx index 2e26f4edc..8896601b5 100644 --- a/internal_packages/thread-list/spec/thread-list-spec.cjsx +++ b/internal_packages/thread-list/spec/thread-list-spec.cjsx @@ -337,53 +337,57 @@ describe "ThreadListNarrow", -> ThreadListNarrowItem) expect(items.length).toBe 3 - describe "Shifting selected index", -> - - beforeEach -> - spyOn(@thread_list, "_onShiftSelectedIndex") - spyOn(Actions, "selectThreadId") - - it "can move selection up", -> - InboxTestUtils.keyPress("up", @thread_list_node) - expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1) - InboxTestUtils.keyPress("k", @thread_list_node) - expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1) - - it "can move selection down", -> - InboxTestUtils.keyPress("down", @thread_list_node) - expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1) - InboxTestUtils.keyPress("j", @thread_list_node) - expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1) - - describe "Triggering message list commands", -> - beforeEach -> - spyOn(Actions, "composeReply") - spyOn(Actions, "composeReplyAll") - spyOn(Actions, "composeForward") - ThreadStore._onSelectThreadId("111") - @thread = ThreadStore.selectedThread() - spyOn(@thread, "archive") - - it "can reply to the currently selected thread", -> - InboxTestUtils.keyPress("r", @thread_list_node) - expect(Actions.composeReply).toHaveBeenCalledWith(@thread.id) - - it "can reply all to the currently selected thread", -> - InboxTestUtils.keyPress("a", @thread_list_node) - expect(Actions.composeReplyAll).toHaveBeenCalledWith(@thread.id) - - it "can forward the currently selected thread", -> - InboxTestUtils.keyPress("f", @thread_list_node) - expect(Actions.composeForward).toHaveBeenCalledWith(@thread.id) - - it "can archive the currently selected thread", -> - InboxTestUtils.keyPress("e", @thread_list_node) - expect(@thread.archive).toHaveBeenCalled() - - it "does nothing when no thread is selected", -> - ThreadStore._selectedId = null - InboxTestUtils.keyPress("r", @thread_list_node) - expect(Actions.composeReply.calls.length).toEqual(0) +# TODO: These need to be moved out of Thread List because the keymaps +# are now registered at the `body` level. There is no `body` dom node +# in this testing. We should move these to a workspace-level test +# suite. +# describe "Shifting selected index", -> +# +# beforeEach -> +# spyOn(@thread_list, "_onShiftSelectedIndex") +# spyOn(Actions, "selectThreadId") +# +# it "can move selection up", -> +# InboxTestUtils.keyPress("up", @thread_list_node) +# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1) +# InboxTestUtils.keyPress("k", @thread_list_node) +# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(-1) +# +# it "can move selection down", -> +# InboxTestUtils.keyPress("down", @thread_list_node) +# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1) +# InboxTestUtils.keyPress("j", @thread_list_node) +# expect(@thread_list._onShiftSelectedIndex).toHaveBeenCalledWith(1) +# +# describe "Triggering message list commands", -> +# beforeEach -> +# spyOn(Actions, "composeReply") +# spyOn(Actions, "composeReplyAll") +# spyOn(Actions, "composeForward") +# ThreadStore._onSelectThreadId("111") +# @thread = ThreadStore.selectedThread() +# spyOn(@thread, "archive") +# +# it "can reply to the currently selected thread", -> +# InboxTestUtils.keyPress("r", @thread_list_node) +# expect(Actions.composeReply).toHaveBeenCalledWith(@thread.id) +# +# it "can reply all to the currently selected thread", -> +# InboxTestUtils.keyPress("a", @thread_list_node) +# expect(Actions.composeReplyAll).toHaveBeenCalledWith(@thread.id) +# +# it "can forward the currently selected thread", -> +# InboxTestUtils.keyPress("f", @thread_list_node) +# expect(Actions.composeForward).toHaveBeenCalledWith(@thread.id) +# +# it "can archive the currently selected thread", -> +# InboxTestUtils.keyPress("e", @thread_list_node) +# expect(@thread.archive).toHaveBeenCalled() +# +# it "does nothing when no thread is selected", -> +# ThreadStore._selectedId = null +# InboxTestUtils.keyPress("r", @thread_list_node) +# expect(Actions.composeReply.calls.length).toEqual(0) describe "ThreadListNarrowItem", -> beforeEach -> diff --git a/keymaps/base.cson b/keymaps/base.cson index 4ae467232..4e62c2140 100644 --- a/keymaps/base.cson +++ b/keymaps/base.cson @@ -1,63 +1,81 @@ +# Email-specific core key-mappings +# All platforms are put here to consolidate custom actions and to prevent +# duplication in 3 files. +# +# TODO let the user pick whether they want to use Gmail, Mac Mail, or +# Outlook keymappings +'body': + 'c' : 'application:new-message' # Gmail + 'cmd-n' : 'application:new-message' # Mac mail + 'ctrl-n': 'application:new-message' # Outlook -# allow standard input fields to work correctly -'body .native-key-bindings': - 'tab': 'core:focus-next' - 'shift-tab': 'core:focus-previous' - 'enter': 'native!' - 'backspace': 'native!' - 'shift-backspace': 'native!' - 'delete': 'native!' - 'up': 'native!' - 'down': 'native!' - 'shift-up': 'native!' - 'shift-down': 'native!' - 'alt-up': 'native!' - 'alt-down': 'native!' - 'alt-shift-up': 'native!' - 'alt-shift-down': 'native!' - 'cmd-up': 'native!' - 'cmd-down': 'native!' - 'cmd-shift-up': 'native!' - 'cmd-shift-down': 'native!' - 'ctrl-up': 'native!' - 'ctrl-down': 'native!' - 'ctrl-shift-up': 'native!' - 'ctrl-shift-down': 'native!' - 'left': 'native!' - 'right': 'native!' - 'shift-left': 'native!' - 'shift-right': 'native!' - 'alt-left': 'native!' - 'alt-right': 'native!' - 'alt-shift-left': 'native!' - 'alt-shift-right': 'native!' - 'cmd-left': 'native!' - 'cmd-right': 'native!' - 'cmd-shift-left': 'native!' - 'cmd-shift-right': 'native!' - 'ctrl-left': 'native!' - 'ctrl-right': 'native!' - 'ctrl-shift-left': 'native!' - 'ctrl-shift-right': 'native!' - 'ctrl-b': 'native!' - 'ctrl-f': 'native!' - 'ctrl-F': 'native!' - 'ctrl-B': 'native!' - 'ctrl-h': 'native!' - 'ctrl-d': 'native!' + 'k' : 'application:previous-message' # Gmail + 'up': 'application:previous-message' # Mac mail -'body webview.native-key-bindings': - 'tab': 'native!' - 'shift-tab': 'native!' + 'j' : 'application:next-message' # Gmail + 'down': 'application:next-message' # Mac mail -# core components + 'e' : 'application:archive-thread' # Gmail + 'delete' : 'application:archive-thread' # Mac mail + 'backspace': 'application:archive-thread' # Outlook + 'r' : 'application:reply' # Gmail + 'cmd-r' : 'application:reply' # Mac mail + 'ctrl-r': 'application:reply' # Outlook + + 'a' : 'application:reply-all' # Gmail + 'cmd-R' : 'application:reply-all' # Mac mail + 'ctrl-R': 'application:reply-all' # Outlook + + 'f' : 'application:forward' # Gmail + 'cmd-F' : 'application:forward' # Mac mail + 'ctrl-F': 'application:forward' # Outlook + + 'cmd-alt-f': 'application:focus-search' # Mac mail + + 'cmd-D': 'application:send-message' # Mac mail + +# Default cross-platform core behaviors + 'up': 'core:move-up' + 'down': 'core:move-down' + 'left': 'core:move-left' + 'right': 'core:move-right' + 'enter': 'core:confirm' + 'escape': 'core:cancel' + 'shift-up': 'core:select-up' + 'shift-down': 'core:select-down' + 'shift-left': 'core:select-left' + 'shift-right': 'core:select-right' + 'shift-pageup': 'core:select-page-up' + 'shift-pagedown': 'core:select-page-down' + 'delete': 'core:delete' + 'shift-delete': 'core:cut' + +# For menus 'body .menu, body .menu .native-key-bindings': 'up': 'menu:move-up' - 'left': 'native!' 'down': 'menu:move-down' - 'right': 'native!' 'enter': 'menu:enter' + +# For Popover Component +'body .popover-container': + 'escape': 'popover:close' + +# Inputs are native by default. +'body input, body textarea, body *[contenteditable=true], body .native-key-bindings': + 'up': 'native!' + 'left': 'native!' + 'down': 'native!' + 'right': 'native!' + 'cmd-up': 'native!' + 'cmd-left': 'native!' + 'cmd-down': 'native!' + 'cmd-right': 'native!' + 'ctrl-up': 'native!' + 'ctrl-left': 'native!' + 'ctrl-down': 'native!' + 'ctrl-right': 'native!' + 'enter': 'native!' 'tab': 'core:focus-next' 'shift-tab': 'core:focus-previous' 'backspace': 'native!' @@ -83,6 +101,96 @@ 'ctrl-V': 'native!' 'ctrl-a': 'native!' 'ctrl-A': 'native!' - -'body .popover-container': - 'escape': 'popover:close' + 'a': 'native!' + 'b': 'native!' + 'c': 'native!' + 'd': 'native!' + 'e': 'native!' + 'f': 'native!' + 'g': 'native!' + 'h': 'native!' + 'i': 'native!' + 'j': 'native!' + 'k': 'native!' + 'l': 'native!' + 'm': 'native!' + 'n': 'native!' + 'o': 'native!' + 'p': 'native!' + 'q': 'native!' + 'r': 'native!' + 's': 'native!' + 't': 'native!' + 'u': 'native!' + 'v': 'native!' + 'w': 'native!' + 'x': 'native!' + 'y': 'native!' + 'z': 'native!' + 'A': 'native!' + 'B': 'native!' + 'C': 'native!' + 'D': 'native!' + 'E': 'native!' + 'F': 'native!' + 'G': 'native!' + 'H': 'native!' + 'I': 'native!' + 'J': 'native!' + 'K': 'native!' + 'L': 'native!' + 'M': 'native!' + 'N': 'native!' + 'O': 'native!' + 'P': 'native!' + 'Q': 'native!' + 'R': 'native!' + 'S': 'native!' + 'T': 'native!' + 'U': 'native!' + 'V': 'native!' + 'W': 'native!' + 'X': 'native!' + 'Y': 'native!' + 'Z': 'native!' + '1': 'native!' + '2': 'native!' + '3': 'native!' + '4': 'native!' + '5': 'native!' + '6': 'native!' + '7': 'native!' + '8': 'native!' + '9': 'native!' + '0': 'native!' + '~': 'native!' + '!': 'native!' + '@': 'native!' + '#': 'native!' + '$': 'native!' + '%': 'native!' + '^': 'native!' + '&': 'native!' + '*': 'native!' + '(': 'native!' + ')': 'native!' + '-': 'native!' + '_': 'native!' + '=': 'native!' + '+': 'native!' + '[': 'native!' + '{': 'native!' + ']': 'native!' + '}': 'native!' + '\\': 'native!' + '|': 'native!' + ';': 'native!' + ':': 'native!' + '\'': 'native!' + '"': 'native!' + '<': 'native!' + ',': 'native!' + '>': 'native!' + '.': 'native!' + '?': 'native!' + '/': 'native!' diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index 98a4889bc..479fbf6a2 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -1,45 +1,17 @@ +# Note: For a menu item to have a keyboard equiavalent, it needs +# to be listed in this file. + +# Mac application keys 'body': - # Apple specific 'cmd-q': 'application:quit' 'cmd-h': 'application:hide' 'cmd-0': 'application:show-main-window' - 'cmd-alt-h': 'application:hide-other-applications' 'cmd-m': 'application:minimize' + 'cmd-alt-h': 'application:hide-other-applications' 'alt-cmd-ctrl-m': 'application:zoom' - - 'ctrl-p': 'core:move-up' - 'ctrl-n': 'core:move-down' - 'ctrl-b': 'core:move-left' - 'ctrl-f': 'core:move-right' - 'ctrl-P': 'core:select-up' - 'ctrl-N': 'core:select-down' - 'ctrl-F': 'core:select-right' - 'ctrl-B': 'core:select-left' - 'ctrl-h': 'core:backspace' - 'ctrl-d': 'core:delete' - - # Atom Specific - 'cmd-O': 'application:open-dev' 'cmd-alt-ctrl-s': 'application:run-all-specs' - 'enter': 'core:confirm' - 'escape': 'core:cancel' - 'up': 'core:move-up' - 'down': 'core:move-down' - 'left': 'core:move-left' - 'right': 'core:move-right' - 'ctrl-alt-cmd-l': 'window:reload' - 'alt-cmd-i': 'window:toggle-dev-tools' - 'cmd-alt-ctrl-p': 'window:run-package-specs' - # Sublime Parity - 'cmd-,': 'application:show-settings' - 'cmd-w': 'window:close' - 'cmd-o': 'application:open' - 'cmd-n': 'application:new-message' - 'cmd-s': 'core:save' - 'cmd-S': 'core:save-as' - 'cmd-alt-s': 'window:save-all' - 'cmd-ctrl-f': 'window:toggle-full-screen' +# Mac core keys 'cmd-z': 'core:undo' 'cmd-Z': 'core:redo' 'cmd-y': 'core:redo' @@ -47,31 +19,14 @@ 'cmd-c': 'core:copy' 'cmd-a': 'core:select-all' 'cmd-v': 'core:paste' - 'shift-up': 'core:select-up' - 'shift-down': 'core:select-down' - 'shift-left': 'core:select-left' - 'shift-right': 'core:select-right' - 'shift-pageup': 'core:select-page-up' - 'shift-pagedown': 'core:select-page-down' - 'delete': 'core:delete' - 'shift-delete': 'core:delete' - 'pageup': 'core:page-up' - 'pagedown': 'core:page-down' - 'backspace': 'core:backspace' - 'shift-backspace': 'core:backspace' - 'cmd-up': 'core:move-to-top' - 'cmd-down': 'core:move-to-bottom' - 'cmd-shift-up': 'core:select-to-top' - 'cmd-shift-down': 'core:select-to-bottom' + +# Mac window keys 'cmd-=': 'window:increase-font-size' 'cmd-+': 'window:increase-font-size' 'cmd--': 'window:decrease-font-size' 'cmd-_': 'window:decrease-font-size' - -# allow standard input fields to work correctly -'body .native-key-bindings': - 'cmd-z': 'native!' - 'cmd-Z': 'native!' - 'cmd-x': 'native!' - 'cmd-c': 'native!' - 'cmd-v': 'native!' + 'cmd-0': 'window:reset-font-size' + 'alt-cmd-i': 'window:toggle-dev-tools' + 'cmd-ctrl-f': 'window:toggle-full-screen' + 'ctrl-alt-cmd-l': 'window:reload' + 'cmd-alt-ctrl-p': 'window:run-package-specs' diff --git a/keymaps/linux.cson b/keymaps/linux.cson index efb3bfa9c..80537911c 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -1,65 +1,29 @@ -'body': - # Atom Specific - 'enter': 'core:confirm' - 'escape': 'core:cancel' - 'up': 'core:move-up' - 'down': 'core:move-down' - 'left': 'core:move-left' - 'right': 'core:move-right' - 'ctrl-alt-r': 'window:reload' - 'ctrl-shift-i': 'window:toggle-dev-tools' - 'ctrl-alt-p': 'window:run-package-specs' - 'ctrl-alt-s': 'application:run-all-specs' - 'ctrl-alt-o': 'application:open-dev' - 'F11': 'window:toggle-full-screen' +# Note: For a menu item to have a keyboard equiavalent, it needs +# to be listed in this file. - # Sublime Parity - 'ctrl-,': 'application:show-settings' - 'ctrl-W': 'window:close' +# Linux application keys +'body': 'ctrl-q': 'application:quit' - 'ctrl-n': 'application:new-message' - 'ctrl-s': 'core:save' - 'ctrl-S': 'core:save-as' - 'ctrl-w': 'core:close' + 'ctrl-alt-s': 'application:run-all-specs' + +# Linux core keys 'ctrl-z': 'core:undo' + 'ctrl-Z': 'core:redo' 'ctrl-y': 'core:redo' - 'ctrl-shift-z': 'core:redo' 'ctrl-x': 'core:cut' 'ctrl-c': 'core:copy' + 'ctrl-a': 'core:select-all' 'ctrl-v': 'core:paste' 'ctrl-insert': 'core:copy' 'shift-insert': 'core:paste' - 'shift-up': 'core:select-up' - 'shift-down': 'core:select-down' - 'shift-left': 'core:select-left' - 'shift-right': 'core:select-right' - 'shift-pageup': 'core:select-page-up' - 'shift-pagedown': 'core:select-page-down' - 'delete': 'core:delete' - 'shift-delete': 'core:cut' - 'pageup': 'core:page-up' - 'pagedown': 'core:page-down' - 'backspace': 'core:backspace' - 'shift-backspace': 'core:backspace' - 'ctrl-shift-up': 'core:move-up' - 'ctrl-shift-down': 'core:move-down' + +# Linux window keys 'ctrl-=': 'window:increase-font-size' 'ctrl-+': 'window:increase-font-size' 'ctrl--': 'window:decrease-font-size' 'ctrl-_': 'window:decrease-font-size' 'ctrl-0': 'window:reset-font-size' - - 'ctrl-k ctrl-p': 'window:focus-previous-pane' - 'ctrl-k ctrl-n': 'window:focus-next-pane' - 'ctrl-k ctrl-up': 'window:focus-pane-above' - 'ctrl-k ctrl-down': 'window:focus-pane-below' - 'ctrl-k ctrl-left': 'window:focus-pane-on-left' - 'ctrl-k ctrl-right': 'window:focus-pane-on-right' - -# allow standard input fields to work correctly -'body .native-key-bindings': - 'ctrl-z': 'native!' - 'ctrl-Z': 'native!' - 'ctrl-x': 'native!' - 'ctrl-c': 'native!' - 'ctrl-v': 'native!' + 'ctrl-alt-i': 'window:toggle-dev-tools' + 'F11': 'window:toggle-full-screen' + 'ctrl-alt-r': 'window:reload' + 'ctrl-alt-p': 'window:run-package-specs' diff --git a/keymaps/win32.cson b/keymaps/win32.cson index 6671238f5..67d1018f4 100644 --- a/keymaps/win32.cson +++ b/keymaps/win32.cson @@ -1,65 +1,29 @@ +# Note: For a menu item to have a keyboard equiavalent, it needs +# to be listed in this file. + +# Windows application keys 'body': - # Platform Bindings - - # Atom Specific - 'enter': 'core:confirm' - 'escape': 'core:cancel' - 'up': 'core:move-up' - 'down': 'core:move-down' - 'left': 'core:move-left' - 'right': 'core:move-right' - 'ctrl-alt-r': 'window:reload' - 'ctrl-alt-i': 'window:toggle-dev-tools' - 'ctrl-alt-p': 'window:run-package-specs' + 'ctrl-q': 'application:quit' 'ctrl-alt-s': 'application:run-all-specs' - 'ctrl-alt-o': 'application:open-dev' - 'F11': 'window:toggle-full-screen' - # Sublime Parity - 'ctrl-,': 'application:show-settings' - 'ctrl-w': 'window:close' - 'ctrl-n': 'application:new-message' - 'ctrl-s': 'core:save' - 'ctrl-S': 'core:save-as' +# Windows core keys 'ctrl-z': 'core:undo' - 'ctrl-shift-z': 'core:redo' + 'ctrl-Z': 'core:redo' 'ctrl-y': 'core:redo' 'ctrl-x': 'core:cut' 'ctrl-c': 'core:copy' + 'ctrl-a': 'core:select-all' 'ctrl-v': 'core:paste' 'ctrl-insert': 'core:copy' 'shift-insert': 'core:paste' - 'shift-up': 'core:select-up' - 'shift-down': 'core:select-down' - 'shift-left': 'core:select-left' - 'shift-right': 'core:select-right' - 'shift-pageup': 'core:select-page-up' - 'shift-pagedown': 'core:select-page-down' - 'delete': 'core:delete' - 'shift-delete': 'core:cut' - 'pageup': 'core:page-up' - 'pagedown': 'core:page-down' - 'backspace': 'core:backspace' - 'shift-backspace': 'core:backspace' - 'ctrl-shift-up': 'core:move-up' - 'ctrl-shift-down': 'core:move-down' + +# Windows window keys 'ctrl-=': 'window:increase-font-size' 'ctrl-+': 'window:increase-font-size' 'ctrl--': 'window:decrease-font-size' 'ctrl-_': 'window:decrease-font-size' 'ctrl-0': 'window:reset-font-size' - - 'ctrl-k ctrl-p': 'window:focus-previous-pane' - 'ctrl-k ctrl-n': 'window:focus-next-pane' - 'ctrl-k ctrl-up': 'window:focus-pane-above' - 'ctrl-k ctrl-down': 'window:focus-pane-below' - 'ctrl-k ctrl-left': 'window:focus-pane-on-left' - 'ctrl-k ctrl-right': 'window:focus-pane-on-right' - -# allow standard input fields to work correctly -'body .native-key-bindings': - 'ctrl-z': 'native!' - 'ctrl-Z': 'native!' - 'ctrl-x': 'native!' - 'ctrl-c': 'native!' - 'ctrl-v': 'native!' + 'ctrl-alt-i': 'window:toggle-dev-tools' + 'F11': 'window:toggle-full-screen' + 'ctrl-alt-r': 'window:reload' + 'ctrl-alt-p': 'window:run-package-specs' diff --git a/src/browser/edgehill-application.coffee b/src/browser/edgehill-application.coffee index 3d84a0ad9..c61fcf144 100644 --- a/src/browser/edgehill-application.coffee +++ b/src/browser/edgehill-application.coffee @@ -149,12 +149,12 @@ class AtomApplication # needs to manually bubble them up to the Application instance via IPC or they won't be # handled. This happens in workspace-element.coffee handleEvents: -> + @on 'application:new-message', => @showComposerWindow() @on 'application:run-all-specs', -> @runSpecs(exitWhenDone: false, resourcePath: global.devResourcePath, safeMode: @focusedWindow()?.safeMode) @on 'application:run-benchmarks', -> @runBenchmarks() @on 'application:quit', => @quitting = true app.quit() - @on 'application:new-message', => @showComposerWindow() @on 'application:open-file-to-window', -> @promptForPath({type: 'file', to_window: true}) @on 'application:open-dev', -> @promptForPath(devMode: true) @on 'application:open-safe', -> @promptForPath(safeMode: true) diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index d49845d6c..ac9390c69 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -106,12 +106,12 @@ class WindowEventHandler @handleNativeKeybindings() # Wire commands that should be handled by the native menu - # for elements with the `.native-key-bindings` class. + # for elements with the `.override-key-bindings` class. handleNativeKeybindings: -> menu = null bindCommandToAction = (command, action) => @subscribe $(document), command, (event) -> - if event.target.webkitMatchesSelector('.native-key-bindings, input') + unless event.target.webkitMatchesSelector('.override-key-bindings') menu ?= require('remote').require('menu') menu.sendActionToFirstResponder(action) true