summaryrefslogtreecommitdiffstats
path: root/chrome/browser/browser.cc
diff options
context:
space:
mode:
authorskerner@chromium.org <skerner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-04 15:08:40 +0000
committerskerner@chromium.org <skerner@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-04 15:08:40 +0000
commit51dac4e7dc4622b0f0c65c35d992ec8e743cac02 (patch)
tree58a9f74d4c53bc7163061ef705bae6763fbde03a /chrome/browser/browser.cc
parent5a9d4ed6f85d345926f6e318f51ab6396124468f (diff)
downloadchromium_src-51dac4e7dc4622b0f0c65c35d992ec8e743cac02.zip
chromium_src-51dac4e7dc4622b0f0c65c35d992ec8e743cac02.tar.gz
chromium_src-51dac4e7dc4622b0f0c65c35d992ec8e743cac02.tar.bz2
Focus an existing app tab when an app is clicked on the new tab page or invoked using --app-id=...
BUG=none TEST=BrowserAppRefocusTest.* Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=46208 Review URL: http://codereview.chromium.org/1693006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46347 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/browser.cc')
-rw-r--r--chrome/browser/browser.cc112
1 files changed, 112 insertions, 0 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index fe0648c..f57dab0 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -153,6 +153,112 @@ static bool CompareURLsIgnoreRef(const GURL& url, const GURL& other) {
return url_no_ref == other_no_ref;
}
+// Helper for FindOpenAppInstance(), defined below. Given a browser, test
+// if it runs under |profile| and hosts app |extension_app|. If
+// |find_panel_or_window| is true, check that |browser| is an app window
+// or panel, otherwise check that it is not. Set |out_tab_idx| to
+// the index of the tab that hosts the app. If the entire browser hosts
+// app, |out_tab_idx| is set to kNoTab.
+bool FindOpenAppInstanceInBrowser(Browser* browser,
+ Profile* profile,
+ Extension* extension_app,
+ bool find_panel_or_window,
+ int* out_tab_idx) {
+ if (browser->profile() != profile)
+ return false;
+
+ // If we are looking for an app panel or app window and |browser| is not
+ // one of those types, or vise-versa, then return.
+ Browser::Type type = browser->type();
+ if (find_panel_or_window != ((type == Browser::TYPE_EXTENSION_APP) ||
+ (type == Browser::TYPE_APP_PANEL)))
+ return false;
+
+ if (browser->extension_app() &&
+ browser->extension_app() == extension_app) {
+ DCHECK(find_panel_or_window) << "Non-app window has an extension app?";
+ *out_tab_idx = TabStripModel::kNoTab; // The whole window contains the app.
+ return true;
+ }
+
+ for (int tab_idx = 0; tab_idx < browser->tab_count(); ++tab_idx) {
+ TabContents* tab_contents = browser->GetTabContentsAt(tab_idx);
+ if (!tab_contents)
+ continue;
+
+ if (tab_contents->app_extension() != extension_app)
+ continue;
+
+ *out_tab_idx = tab_idx;
+ return true;
+ }
+ return false;
+}
+
+// Find a tab in an open browser window which is running an application
+// |extension_app|. The browser must use profile |profile|, and be an
+// app window or panel if and only if |find_panel_or_window| is true.
+// Sets |out_browser| and |out_tab_idx| to the browser and tab index of
+// the matching tab on success. |out_tab_idx| will be kNoTab if the
+// browser is an app window.
+bool FindOpenAppInstance(Profile* profile,
+ Extension* extension_app,
+ bool find_panel_or_window,
+ Browser** out_browser,
+ int* out_tab_idx) {
+ // Test the focused browser first.
+ Browser* browser = BrowserList::GetLastActive();
+ if (browser && FindOpenAppInstanceInBrowser(browser,
+ profile,
+ extension_app,
+ find_panel_or_window,
+ out_tab_idx)) {
+ *out_browser = browser;
+ return true;
+ }
+
+ BrowserList::const_iterator browser_all;
+ for (browser_all = BrowserList::begin();
+ browser_all != BrowserList::end();
+ ++browser_all) {
+ if (FindOpenAppInstanceInBrowser(*browser_all,
+ profile,
+ extension_app,
+ find_panel_or_window,
+ out_tab_idx)) {
+ *out_browser = *browser_all;
+ return true;
+ }
+ }
+ return false;
+}
+
+// Find an existing browser window running under |profile| and hosting
+// the app |extension_app|. Focus it, and return the TabContents of the
+// focused tab.
+TabContents* FocusExistingAppInstance(Profile* profile,
+ Extension* extension_app) {
+ Browser* browser;
+ int tab_idx;
+
+ // Fist, search for app windows or panels. If none are found, search
+ // for app tabs.
+ if (FindOpenAppInstance(profile, extension_app, true, &browser, &tab_idx) ||
+ FindOpenAppInstance(profile, extension_app, false, &browser, &tab_idx)) {
+
+ // If the entire window is owned by the app, then select the first
+ // tab. TODO(skerner): Does it make more sense to not change the
+ // focused tab? Reconsider this after using apps for a week or two.
+ if (tab_idx == TabStripModel::kNoTab)
+ tab_idx = 0;
+
+ browser->SelectTabContentsAt(tab_idx, false);
+ browser->window()->Show();
+ return browser->GetTabContentsAt(tab_idx);
+ }
+ return NULL;
+}
+
} // namespace
///////////////////////////////////////////////////////////////////////////////
@@ -416,6 +522,12 @@ TabContents* Browser::OpenApplication(Profile* profile,
if (!extension)
return NULL;
+ // If the app is loaded in an existing window or tab, Focus it.
+ TabContents* tab = FocusExistingAppInstance(profile, extension);
+ if (tab)
+ return tab;
+
+ // The app is not yet open. Load it.
return OpenApplication(profile, extension, extension->launch_container());
}