Commit e59a1613 authored by mitchelljones's avatar mitchelljones Committed by Commit bot

Hosted apps on OS X now act more like a native app.

- Quitting an app shim will close all associated windows.
- Closing all windows will quit the app shim.
- Can focus between Chrome and app shim windows.
- Can hide/show all windows associated with an app shim.

BUG=440651

Review URL: https://codereview.chromium.org/790043002

Cr-Commit-Position: refs/heads/master@{#308473}
parent 21bca3c7
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
#include "chrome/browser/ui/startup/startup_browser_creator.h" #include "chrome/browser/ui/startup/startup_browser_creator.h"
#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
#include "chrome/browser/ui/user_manager.h" #include "chrome/browser/ui/user_manager.h"
#include "chrome/browser/web_applications/web_app_mac.h"
#include "chrome/common/chrome_paths_internal.h" #include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/cloud_print/cloud_print_class_mac.h" #include "chrome/common/cloud_print/cloud_print_class_mac.h"
...@@ -95,11 +96,14 @@ ...@@ -95,11 +96,14 @@
#include "content/public/browser/plugin_service.h" #include "content/public/browser/plugin_service.h"
#include "content/public/browser/user_metrics.h" #include "content/public/browser/user_metrics.h"
#include "extensions/browser/extension_system.h" #include "extensions/browser/extension_system.h"
#include "extensions/browser/extension_registry.h"
#include "net/base/filename_util.h" #include "net/base/filename_util.h"
#include "ui/base/cocoa/focus_window_set.h" #include "ui/base/cocoa/focus_window_set.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h" #include "ui/base/l10n/l10n_util_mac.h"
using apps::AppShimHandler;
using apps::ExtensionAppShimHandler;
using base::UserMetricsAction; using base::UserMetricsAction;
using content::BrowserContext; using content::BrowserContext;
using content::BrowserThread; using content::BrowserThread;
...@@ -1216,8 +1220,22 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver { ...@@ -1216,8 +1220,22 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
// notifications so we still need to open a new window. // notifications so we still need to open a new window.
if (hasVisibleWindows) { if (hasVisibleWindows) {
std::set<NSWindow*> browserWindows; std::set<NSWindow*> browserWindows;
ExtensionAppShimHandler* appShimHandler =
g_browser_process->platform_part()
->app_shim_host_manager()
->extension_app_shim_handler();
for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) { for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
Browser* browser = *iter; Browser* browser = *iter;
// When focusing Chrome, don't focus any browser windows associated with
// a currently running app shim, so ignore them.
if (browser && browser->is_app()) {
AppShimHandler::Host* host = appShimHandler->FindHost(
browser->profile(),
web_app::GetExtensionIdFromApplicationName(browser->app_name()));
if (host) {
continue;
}
}
browserWindows.insert(browser->window()->GetNativeWindow()); browserWindows.insert(browser->window()->GetNativeWindow());
} }
if (!browserWindows.empty()) { if (!browserWindows.empty()) {
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define CHROME_BROWSER_APPS_APP_SHIM_EXTENSION_APP_SHIM_HANDLER_MAC_H_ #define CHROME_BROWSER_APPS_APP_SHIM_EXTENSION_APP_SHIM_HANDLER_MAC_H_
#include <map> #include <map>
#include <set>
#include <string> #include <string>
#include <vector> #include <vector>
...@@ -13,6 +14,8 @@ ...@@ -13,6 +14,8 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/apps/app_shim/app_shim_handler_mac.h" #include "chrome/browser/apps/app_shim/app_shim_handler_mac.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/app_window_registry.h"
...@@ -38,7 +41,8 @@ namespace apps { ...@@ -38,7 +41,8 @@ namespace apps {
// extension. // extension.
class ExtensionAppShimHandler : public AppShimHandler, class ExtensionAppShimHandler : public AppShimHandler,
public content::NotificationObserver, public content::NotificationObserver,
public AppLifetimeMonitor::Observer { public AppLifetimeMonitor::Observer,
public chrome::BrowserListObserver {
public: public:
class Delegate { class Delegate {
public: public:
...@@ -72,10 +76,25 @@ class ExtensionAppShimHandler : public AppShimHandler, ...@@ -72,10 +76,25 @@ class ExtensionAppShimHandler : public AppShimHandler,
AppShimHandler::Host* FindHost(Profile* profile, const std::string& app_id); AppShimHandler::Host* FindHost(Profile* profile, const std::string& app_id);
void SetHostedAppHidden(Profile* profile,
const std::string& app_id,
bool hidden);
static const extensions::Extension* GetAppExtension(
Profile* profile,
const std::string& extension_id);
static const extensions::Extension* GetAppForBrowser(Browser* browser);
static void QuitAppForWindow(extensions::AppWindow* app_window); static void QuitAppForWindow(extensions::AppWindow* app_window);
static void QuitHostedAppForWindow(Profile* profile,
const std::string& app_id);
static void HideAppForWindow(extensions::AppWindow* app_window); static void HideAppForWindow(extensions::AppWindow* app_window);
static void HideHostedApp(Profile* profile, const std::string& app_id);
static void FocusAppForWindow(extensions::AppWindow* app_window); static void FocusAppForWindow(extensions::AppWindow* app_window);
// Brings the window to the front without showing it and instructs the shim to // Brings the window to the front without showing it and instructs the shim to
...@@ -115,9 +134,15 @@ class ExtensionAppShimHandler : public AppShimHandler, ...@@ -115,9 +134,15 @@ class ExtensionAppShimHandler : public AppShimHandler,
const content::NotificationSource& source, const content::NotificationSource& source,
const content::NotificationDetails& details) override; const content::NotificationDetails& details) override;
// chrome::BrowserListObserver overrides;
void OnBrowserAdded(Browser* browser) override;
void OnBrowserRemoved(Browser* browser) override;
protected: protected:
typedef std::map<std::pair<Profile*, std::string>, AppShimHandler::Host*> typedef std::map<std::pair<Profile*, std::string>, AppShimHandler::Host*>
HostMap; HostMap;
typedef std::set<Browser*> BrowserSet;
typedef std::map<std::string, BrowserSet> AppBrowserMap;
// Exposed for testing. // Exposed for testing.
void set_delegate(Delegate* delegate); void set_delegate(Delegate* delegate);
...@@ -128,6 +153,9 @@ class ExtensionAppShimHandler : public AppShimHandler, ...@@ -128,6 +153,9 @@ class ExtensionAppShimHandler : public AppShimHandler,
// Helper function to get the instance on the browser process. // Helper function to get the instance on the browser process.
static ExtensionAppShimHandler* GetInstance(); static ExtensionAppShimHandler* GetInstance();
// Closes all browsers associated with an app.
void CloseBrowsersForApp(const std::string& app_id);
// This is passed to Delegate::LoadProfileAsync for shim-initiated launches // This is passed to Delegate::LoadProfileAsync for shim-initiated launches
// where the profile was not yet loaded. // where the profile was not yet loaded.
void OnProfileLoaded(Host* host, void OnProfileLoaded(Host* host,
...@@ -145,6 +173,9 @@ class ExtensionAppShimHandler : public AppShimHandler, ...@@ -145,6 +173,9 @@ class ExtensionAppShimHandler : public AppShimHandler,
HostMap hosts_; HostMap hosts_;
// A map of app ids to associated browser windows.
AppBrowserMap app_browser_windows_;
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
base::WeakPtrFactory<ExtensionAppShimHandler> weak_factory_; base::WeakPtrFactory<ExtensionAppShimHandler> weak_factory_;
......
...@@ -10,7 +10,10 @@ ...@@ -10,7 +10,10 @@
#include "chrome/app/chrome_command_ids.h" #include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h" #include "chrome/browser/apps/app_shim/extension_app_shim_handler_mac.h"
#include "chrome/browser/apps/app_window_registry_util.h" #include "chrome/browser/apps/app_window_registry_util.h"
#include "chrome/browser/profiles/profile.h"
#import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h" #import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "extensions/browser/app_window/app_window.h" #include "extensions/browser/app_window/app_window.h"
#include "extensions/common/extension.h" #include "extensions/common/extension.h"
...@@ -295,8 +298,13 @@ void AddDuplicateItem(NSMenuItem* top_level_item, ...@@ -295,8 +298,13 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
window); window);
const extensions::Extension* extension = NULL; const extensions::Extension* extension = NULL;
// If there is no corresponding AppWindow, this could be a hosted app, so
// check for a browser.
if (appWindow) if (appWindow)
extension = appWindow->GetExtension(); extension = appWindow->GetExtension();
else
extension = apps::ExtensionAppShimHandler::GetAppForBrowser(
chrome::FindBrowserWithWindow(window));
if (extension) if (extension)
[self addMenuItems:extension]; [self addMenuItems:extension];
...@@ -374,16 +382,32 @@ void AddDuplicateItem(NSMenuItem* top_level_item, ...@@ -374,16 +382,32 @@ void AddDuplicateItem(NSMenuItem* top_level_item,
extensions::AppWindow* appWindow = extensions::AppWindow* appWindow =
AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile(
[NSApp keyWindow]); [NSApp keyWindow]);
if (appWindow) if (appWindow) {
apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow); apps::ExtensionAppShimHandler::QuitAppForWindow(appWindow);
} else {
Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]);
const extensions::Extension* extension =
apps::ExtensionAppShimHandler::GetAppForBrowser(browser);
if (extension)
apps::ExtensionAppShimHandler::QuitHostedAppForWindow(browser->profile(),
extension->id());
}
} }
- (void)hideCurrentPlatformApp { - (void)hideCurrentPlatformApp {
extensions::AppWindow* appWindow = extensions::AppWindow* appWindow =
AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile( AppWindowRegistryUtil::GetAppWindowForNativeWindowAnyProfile(
[NSApp keyWindow]); [NSApp keyWindow]);
if (appWindow) if (appWindow) {
apps::ExtensionAppShimHandler::HideAppForWindow(appWindow); apps::ExtensionAppShimHandler::HideAppForWindow(appWindow);
} else {
Browser* browser = chrome::FindBrowserWithWindow([NSApp keyWindow]);
const extensions::Extension* extension =
apps::ExtensionAppShimHandler::GetAppForBrowser(browser);
if (extension)
apps::ExtensionAppShimHandler::HideHostedApp(browser->profile(),
extension->id());
}
} }
- (void)focusCurrentPlatformApp { - (void)focusCurrentPlatformApp {
......
...@@ -123,8 +123,8 @@ void BrowserWindowCocoa::Show() { ...@@ -123,8 +123,8 @@ void BrowserWindowCocoa::Show() {
NSWindowAnimationBehavior saved_animation_behavior = NSWindowAnimationBehavior saved_animation_behavior =
NSWindowAnimationBehaviorDefault; NSWindowAnimationBehaviorDefault;
bool did_save_animation_behavior = false; bool did_save_animation_behavior = false;
// Turn off swishing when restoring windows. // Turn off swishing when restoring windows or showing an app.
if (is_session_restore && if ((is_session_restore || browser_->is_app()) &&
[window() respondsToSelector:@selector(animationBehavior)] && [window() respondsToSelector:@selector(animationBehavior)] &&
[window() respondsToSelector:@selector(setAnimationBehavior:)]) { [window() respondsToSelector:@selector(setAnimationBehavior:)]) {
did_save_animation_behavior = true; did_save_animation_behavior = true;
...@@ -163,7 +163,7 @@ void BrowserWindowCocoa::ShowInactive() { ...@@ -163,7 +163,7 @@ void BrowserWindowCocoa::ShowInactive() {
} }
void BrowserWindowCocoa::Hide() { void BrowserWindowCocoa::Hide() {
// Not implemented. [window() orderOut:controller_];
} }
void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) { void BrowserWindowCocoa::SetBounds(const gfx::Rect& bounds) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment