diff options
| author | Stephen Blott | 2015-04-23 11:07:36 +0100 | 
|---|---|---|
| committer | Stephen Blott | 2015-04-23 11:07:36 +0100 | 
| commit | bfa6c88b41acac4c98d06f324f25f8bb7b328614 (patch) | |
| tree | c624300290dfa3d9506e40e17a2b8fddf5f2c407 | |
| parent | 9eaa7330b1e4952e171cf53db855cf447c8e1e49 (diff) | |
| download | vimium-bfa6c88b41acac4c98d06f324f25f8bb7b328614.tar.bz2 | |
Activate vomnibar in window.top; no flicker and tidy up.
1. Rework event handling to eliminate frame flicker (a la #1485).
2. Tidy up logic.  Which should make this more robust.
| -rw-r--r-- | background_scripts/main.coffee | 2 | ||||
| -rw-r--r-- | content_scripts/ui_component.coffee | 23 | ||||
| -rw-r--r-- | content_scripts/vimium_frontend.coffee | 10 | ||||
| -rw-r--r-- | content_scripts/vomnibar.coffee | 8 | ||||
| -rw-r--r-- | pages/vomnibar.coffee | 9 | 
5 files changed, 36 insertions, 16 deletions
| diff --git a/background_scripts/main.coffee b/background_scripts/main.coffee index a64c7e37..0c7d9343 100644 --- a/background_scripts/main.coffee +++ b/background_scripts/main.coffee @@ -658,7 +658,7 @@ handleFrameFocused = (request, sender) ->      frameIdsForTab[tabId] =        [request.frameId, (frameIdsForTab[tabId].filter (id) -> id != request.frameId)...]    # Inform all frames that a frame has received the focus. -  chrome.tabs.sendMessage sender.tab.id,  +  chrome.tabs.sendMessage sender.tab.id,      name: "frameFocused"      focusFrameId: request.frameId diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index ee74c3a8..ea0bf776 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -55,7 +55,7 @@ class UIComponent      @showing = true    hide: (focusWindow = true)-> -    @refocusSourceFrame @options?.sourceFrameId if focusWindow and @options?.sourceFrameId? +    @refocusSourceFrame @options?.sourceFrameId if focusWindow      window.removeEventListener "focus", @onFocus if @onFocus      @onFocus = null      @iframeElement.classList.remove "vimiumUIComponentShowing" @@ -63,14 +63,13 @@ class UIComponent      @options = null      @showing = false -  # Refocus the frame from which the UI component was opened. +  # Refocus the frame from which the UI component was opened.  This may be different from the current frame.    # After hiding the UI component, Chrome refocuses the containing frame. To avoid a race condition, we need -  # to wait until that frame receives the focus, before then focusing the frame which should now have the -  # focus. +  # to wait until that frame first receives the focus, before then focusing the frame which should now have +  # the focus.    refocusSourceFrame: (sourceFrameId) -> -    window.addEventListener "focus", handler = (event) -> -      if event.target == window -        window.removeEventListener "focus", handler +    if @showing and sourceFrameId? and sourceFrameId != frameId +      refocusSourceFrame = ->          chrome.runtime.sendMessage            handler: "sendMessageToFrames"            message: @@ -79,5 +78,15 @@ class UIComponent              highlight: false              highlightOnlyIfNotTop: true +      if windowIsFocused() and false +        # We already have the focus. +        refocusSourceFrame() +      else +        # We don't yet have the focus (but we'll be getting it soon). +        window.addEventListener "focus", handler = (event) -> +          if event.target == window +            window.removeEventListener "focus", handler +            refocusSourceFrame() +  root = exports ? window  root.UIComponent = UIComponent diff --git a/content_scripts/vimium_frontend.coffee b/content_scripts/vimium_frontend.coffee index c5bc185f..931b8edf 100644 --- a/content_scripts/vimium_frontend.coffee +++ b/content_scripts/vimium_frontend.coffee @@ -19,6 +19,13 @@ keyQueue = null  currentCompletionKeys = ""  validFirstKeys = "" +# We track whther the current window has the focus or not. +windowIsFocused = do -> +  windowHasFocus = document.hasFocus() +  window.addEventListener "focus", (event) -> windowHasFocus = true if event.target == window; true +  window.addEventListener "blur", (event) -> windowHasFocus = false if event.target == window; true +  -> windowHasFocus +  # The types in <input type="..."> that we consider for focusInput command. Right now this is recalculated in  # each content script. Alternatively we could calculate it once in the background page and use a request to  # fetch it each time. @@ -192,7 +199,7 @@ initializePreDomReady = ->      # We handle the message if we're enabled, or if it's one of these listed message types.      return unless isEnabledForUrl or request.name in [ "getActiveState", "setState", "executePageCommand" ]      # These requests are delivered to the options page, but there are no handlers there. -    return if request.handler in [ "registerFrame", "frameFocused", "unregisterFrame" ] +    return if request.handler in [ "registerFrame", "unregisterFrame" ]      # We don't handle these here.  They're handled elsewhere (e.g. in the vomnibar/UI component).      return if request.name in [ "frameFocused" ]      # Handle the request. @@ -1245,4 +1252,5 @@ root.settings = settings  root.HUD = HUD  root.handlerStack = handlerStack  root.frameId = frameId +root.windowIsFocused = windowIsFocused  root.bgLog = bgLog diff --git a/content_scripts/vomnibar.coffee b/content_scripts/vomnibar.coffee index 3d54e643..2529c077 100644 --- a/content_scripts/vomnibar.coffee +++ b/content_scripts/vomnibar.coffee @@ -40,9 +40,11 @@ Vomnibar =    init: ->      unless @vomnibarUI?        @vomnibarUI = new UIComponent "pages/vomnibar.html", "vomnibarFrame", (event) => -        if event.data == "hide" -          @vomnibarUI.hide() -          @vomnibarUI.postMessage "hidden" +        @vomnibarUI.hide() if event.data == "hide" +      # Whenever the window receives the focus, we tell the Vomnibar UI that it has been hidden (regardless of +      # whether it was previously visible). +      window.addEventListener "focus", (event) => +        @vomnibarUI.postMessage "hidden" if event.target == window; true    # This function opens the vomnibar. It accepts options, a map with the values: diff --git a/pages/vomnibar.coffee b/pages/vomnibar.coffee index dbb37ebf..b133b126 100644 --- a/pages/vomnibar.coffee +++ b/pages/vomnibar.coffee @@ -63,10 +63,11 @@ class VomnibarUI    # The sequence of events when the vomnibar is hidden is as follows:    # 1. Post a "hide" message to the host page. -  # 2. The host page hides the vomnibar and posts back a "hidden" message. -  # 3. Only once "hidden" message is received here is any required action (callback) invoked (in onHidden). -  # This ensures that the vomnibar is actually hidden, and avoids flicker after opening a link in a new tab -  # (see #1485). +  # 2. The host page hides the vomnibar. +  # 3. When that page receives the focus, and it posts back a "hidden" message. +  # 3. Only once the "hidden" message is received here is any required action  invoked (in onHidden). +  # This ensures that the vomnibar is actually hidden before any new tab is created, and avoids flicker after +  # opening a link in a new tab then returning to the original tab (see #1485).    hide: (@postHideCallback = null) ->      UIComponentServer.postMessage "hide"      @reset() | 
