From 5b6014c2f6d3fa24c04fbb5435fe79896f400001 Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Mon, 16 Feb 2015 11:02:53 +0000 Subject: Add short delay before launching from vomnibar. This is not entirely satisfactory. It would be great if a delay of 0 worked (a la `nextTick`). But it seems we need a little longer because we need to allow the UI component messaging to complete. An alternative would be to thread the action required through the UI component logic. But that's pretty ugly too. Yet another alternative would be to have the UI Component post an "ok, we're done, do it" message once the UI component has been removed. Fixes #1485. --- pages/vomnibar.coffee | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/pages/vomnibar.coffee b/pages/vomnibar.coffee index d0b7a7dd..8243b696 100644 --- a/pages/vomnibar.coffee +++ b/pages/vomnibar.coffee @@ -59,9 +59,13 @@ class VomnibarUI setForceNewTab: (forceNewTab) -> @forceNewTab = forceNewTab - hide: -> + # Hide the vomnibar, then call callback. We add a short delay to allow the vomnibar to close before the + # action is performed. This ensures (hopefully) that the vomnibar isn't visible when the tab is + # subsequently refocused (see #1485). + hide: (callback = ->) -> UIComponentServer.postMessage "hide" @reset() + setTimeout callback, 20 reset: -> @completionList.style.display = "" @@ -123,15 +127,15 @@ class VomnibarUI query = @input.value.trim() # on an empty vomnibar is a no-op. return unless 0 < query.length - @hide() - chrome.runtime.sendMessage({ - handler: if openInNewTab then "openUrlInNewTab" else "openUrlInCurrentTab" - url: query }) + @hide -> + chrome.runtime.sendMessage + handler: if openInNewTab then "openUrlInNewTab" else "openUrlInCurrentTab" + url: query else @update true, => # Shift+Enter will open the result in a new tab instead of the current tab. - @completions[@selection].performAction(openInNewTab) - @hide() + completion = @completions[@selection] + @hide -> completion.performAction openInNewTab # It seems like we have to manually suppress the event here and still return true. event.stopImmediatePropagation() -- cgit v1.2.3 From 3c988a07a64a5bf4cab9ec98fe4d377c2af2208e Mon Sep 17 00:00:00 2001 From: Stephen Blott Date: Fri, 6 Mar 2015 13:45:36 +0000 Subject: Remove need for short delay to prevent vomnibar flicker. This delivers a "hidden" massage to the vomnibar after the vomnibar has been hiddent in the host page. The vomnibar only performs whatever action is required when it receives this "hidden" message. --- content_scripts/ui_component.coffee | 2 +- content_scripts/vomnibar.coffee | 5 ++++- pages/vomnibar.coffee | 20 ++++++++++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/content_scripts/ui_component.coffee b/content_scripts/ui_component.coffee index c6b59464..47ff995e 100644 --- a/content_scripts/ui_component.coffee +++ b/content_scripts/ui_component.coffee @@ -46,7 +46,7 @@ class UIComponent hide: (focusWindow = true)-> @iframeElement.classList.remove "vimiumUIComponentShowing" @iframeElement.classList.add "vimiumUIComponentHidden" - window.removeEventListener @onFocus if @onFocus + window.removeEventListener "focus", @onFocus if @onFocus @onFocus = null window.focus() if focusWindow @showing = false diff --git a/content_scripts/vomnibar.coffee b/content_scripts/vomnibar.coffee index 6381fd7f..c4cfc8b9 100644 --- a/content_scripts/vomnibar.coffee +++ b/content_scripts/vomnibar.coffee @@ -38,7 +38,10 @@ Vomnibar = init: -> unless @vomnibarUI? @vomnibarUI = new UIComponent "pages/vomnibar.html", "vomnibarFrame", (event) => - @vomnibarUI.hide() if event.data == "hide" + if event.data == "hide" + @vomnibarUI.hide() + @vomnibarUI.postMessage "hidden" + # This function opens the vomnibar. It accepts options, a map with the values: # completer - The completer to fetch results from. diff --git a/pages/vomnibar.coffee b/pages/vomnibar.coffee index 8243b696..906aa0f3 100644 --- a/pages/vomnibar.coffee +++ b/pages/vomnibar.coffee @@ -39,10 +39,12 @@ Vomnibar = @vomnibarUI.update() hide: -> @vomnibarUI?.hide() + onHidden: -> @vomnibarUI?.onHidden() class VomnibarUI constructor: -> @refreshInterval = 0 + @postHideCallback = null @initDom() setQuery: (query) -> @input.value = query @@ -59,13 +61,10 @@ class VomnibarUI setForceNewTab: (forceNewTab) -> @forceNewTab = forceNewTab - # Hide the vomnibar, then call callback. We add a short delay to allow the vomnibar to close before the - # action is performed. This ensures (hopefully) that the vomnibar isn't visible when the tab is - # subsequently refocused (see #1485). - hide: (callback = ->) -> + hide: (callback = null) -> UIComponentServer.postMessage "hide" @reset() - setTimeout callback, 20 + @postHideCallback = callback reset: -> @completionList.style.display = "" @@ -74,6 +73,12 @@ class VomnibarUI @completions = [] @selection = @initialSelectionValue + # Called after the vomnibar has been hidden. We wait until after the vomnibar has been hidden to avoid + # vomnibar flicker (see #1485). + onHidden: -> + @postHideCallback?() + @postHideCallback = null + updateSelection: -> # We retain global state here (previousAutoSelect) to tell if a search item (for which autoSelect is set) # has just appeared or disappeared. If that happens, we set @selection to 0 or -1. @@ -238,7 +243,10 @@ extend BackgroundCompleter, switchToTab: (tabId) -> chrome.runtime.sendMessage({ handler: "selectSpecificTab", id: tabId }) UIComponentServer.registerHandler (event) -> - if event.data == "hide" then Vomnibar.hide() else Vomnibar.activate event.data + switch event.data + when "hide" then Vomnibar.hide() + when "hidden" then Vomnibar.onHidden() + else Vomnibar.activate event.data root = exports ? window root.Vomnibar = Vomnibar -- cgit v1.2.3