diff options
-rw-r--r-- | base/mac_util.h | 3 | ||||
-rw-r--r-- | base/mac_util.mm | 10 | ||||
-rw-r--r-- | chrome/browser/app_controller_mac.mm | 9 | ||||
-rw-r--r-- | chrome/browser/plugin_carbon_interpose_mac.cc | 20 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 14 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host_mac.cc | 23 | ||||
-rw-r--r-- | chrome/browser/plugin_service.cc | 26 | ||||
-rw-r--r-- | chrome/common/notification_type.h | 4 | ||||
-rw-r--r-- | chrome/common/plugin_messages_internal.h | 10 | ||||
-rw-r--r-- | chrome/plugin/plugin_thread.cc | 12 | ||||
-rw-r--r-- | chrome/plugin/plugin_thread.h | 3 |
11 files changed, 118 insertions, 16 deletions
diff --git a/base/mac_util.h b/base/mac_util.h index 3c99b2a..093ae63 100644 --- a/base/mac_util.h +++ b/base/mac_util.h @@ -75,6 +75,9 @@ void RequestFullScreen(); // this will show the menu bar. Must be called on main thread. void ReleaseFullScreen(); +// Activates the process with the given PID. +void ActivateProcess(pid_t); + // Pulls a snapshot of the entire browser into png_representation. void GrabWindowSnapshot(NSWindow* window, std::vector<unsigned char>* png_representation); diff --git a/base/mac_util.mm b/base/mac_util.mm index 3ffab82..de07c88 100644 --- a/base/mac_util.mm +++ b/base/mac_util.mm @@ -178,4 +178,14 @@ void GrabWindowSnapshot(NSWindow* window, } } +void ActivateProcess(pid_t pid) { + ProcessSerialNumber process; + OSStatus status = GetProcessForPID(pid, &process); + if (status == noErr) { + SetFrontProcess(&process); + } else { + LOG(WARNING) << "Unable to get process for pid " << pid; + } +} + } // namespace mac_util diff --git a/chrome/browser/app_controller_mac.mm b/chrome/browser/app_controller_mac.mm index c173740..50973f6 100644 --- a/chrome/browser/app_controller_mac.mm +++ b/chrome/browser/app_controller_mac.mm @@ -34,6 +34,7 @@ #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/notification_service.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "chrome/browser/profile_manager.h" @@ -333,6 +334,14 @@ static bool g_is_opening_new_window = false; [self openPendingURLs]; } +// This is called after profiles have been loaded and preferences registered. +// It is safe to access the default profile here. +- (void)applicationDidBecomeActive:(NSNotification*)notify { + NotificationService::current()->Notify(NotificationType::APP_ACTIVATED, + NotificationService::AllSources(), + NotificationService::NoDetails()); +} + // Helper function for populating and displaying the in progress downloads at // exit alert panel. - (BOOL)userWillWaitForInProgressDownloads:(int)downloadCount { diff --git a/chrome/browser/plugin_carbon_interpose_mac.cc b/chrome/browser/plugin_carbon_interpose_mac.cc index e9a4997..1957f47 100644 --- a/chrome/browser/plugin_carbon_interpose_mac.cc +++ b/chrome/browser/plugin_carbon_interpose_mac.cc @@ -9,8 +9,10 @@ namespace webkit_glue { -void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds); -void NotifyBrowserOfPluginShowWindow(uint32 window_id, CGRect bounds); +void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds, + bool modal); +void NotifyBrowserOfPluginShowWindow(uint32 window_id, CGRect bounds, + bool modal); void NotifyBrowserOfPluginHideWindow(uint32 window_id, CGRect bounds); void NotifyBrowserOfPluginDisposeWindow(uint32 window_id, CGRect bounds); @@ -75,6 +77,14 @@ static void MaybeReactivateSavedProcess() { SwitchToSavedProcess(); } +// Returns true if the given window is modal. +static bool IsModalWindow(WindowRef window) { + WindowModality modality = kWindowModalityNone; + WindowRef modal_target = NULL; + OSStatus status = GetWindowModality(window, &modality, &modal_target); + return (status == noErr) && (modality != kWindowModalityNone); +} + #pragma mark - static Boolean ChromePluginIsWindowHilited(WindowRef window) { @@ -100,14 +110,16 @@ static void ChromePluginSelectWindow(WindowRef window) { SwitchToPluginProcess(); SelectWindow(window); webkit_glue::NotifyBrowserOfPluginSelectWindow(HIWindowGetCGWindowID(window), - CGRectForWindow(window)); + CGRectForWindow(window), + IsModalWindow(window)); } static void ChromePluginShowWindow(WindowRef window) { SwitchToPluginProcess(); ShowWindow(window); webkit_glue::NotifyBrowserOfPluginShowWindow(HIWindowGetCGWindowID(window), - CGRectForWindow(window)); + CGRectForWindow(window), + IsModalWindow(window)); } static void ChromePluginDisposeWindow(WindowRef window) { diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index 3ce66b2..2717e0c 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -72,6 +72,12 @@ class PluginProcessHost : public ChildProcessHost, void OnModalDialogResponse(const std::string& json_retval, IPC::Message* sync_result); +#if defined(OS_MACOSX) + // This function is called on the IO thread when the browser becomes the + // active application. + void OnAppActivation(); +#endif + const WebPluginInfo& info() const { return info_; } #if defined(OS_WIN) @@ -113,8 +119,10 @@ class PluginProcessHost : public ChildProcessHost, #endif #if defined(OS_MACOSX) - void OnPluginSelectWindow(uint32 window_id, gfx::Rect window_rect); - void OnPluginShowWindow(uint32 window_id, gfx::Rect window_rect); + void OnPluginSelectWindow(uint32 window_id, gfx::Rect window_rect, + bool modal); + void OnPluginShowWindow(uint32 window_id, gfx::Rect window_rect, + bool modal); void OnPluginHideWindow(uint32 window_id, gfx::Rect window_rect); void OnPluginDisposeWindow(uint32 window_id, gfx::Rect window_rect); #endif @@ -155,6 +163,8 @@ class PluginProcessHost : public ChildProcessHost, std::set<uint32> plugin_visible_windows_set_; // Tracks full screen windows currently visible std::set<uint32> plugin_fullscreen_windows_set_; + // Tracks modal windows currently visible + std::set<uint32> plugin_modal_windows_set_; #endif DISALLOW_COPY_AND_ASSIGN(PluginProcessHost); diff --git a/chrome/browser/plugin_process_host_mac.cc b/chrome/browser/plugin_process_host_mac.cc index 6e6bb18..f003a4c 100644 --- a/chrome/browser/plugin_process_host_mac.cc +++ b/chrome/browser/plugin_process_host_mac.cc @@ -14,13 +14,19 @@ #include "chrome/browser/plugin_process_host.h" void PluginProcessHost::OnPluginSelectWindow(uint32 window_id, - gfx::Rect window_rect) { + gfx::Rect window_rect, + bool modal) { plugin_visible_windows_set_.insert(window_id); + if (modal) + plugin_modal_windows_set_.insert(window_id); } void PluginProcessHost::OnPluginShowWindow(uint32 window_id, - gfx::Rect window_rect) { + gfx::Rect window_rect, + bool modal) { plugin_visible_windows_set_.insert(window_id); + if (modal) + plugin_modal_windows_set_.insert(window_id); CGRect window_bounds = { { window_rect.x(), window_rect.y() }, { window_rect.width(), window_rect.height() } @@ -39,6 +45,7 @@ void PluginProcessHost::OnPluginShowWindow(uint32 window_id, void PluginProcessHost::OnPluginHideWindow(uint32 window_id, gfx::Rect window_rect) { plugin_visible_windows_set_.erase(window_id); + plugin_modal_windows_set_.erase(window_id); if (plugin_fullscreen_windows_set_.find(window_id) != plugin_fullscreen_windows_set_.end()) { plugin_fullscreen_windows_set_.erase(window_id); @@ -52,3 +59,15 @@ void PluginProcessHost::OnPluginDisposeWindow(uint32 window_id, gfx::Rect window_rect) { OnPluginHideWindow(window_id, window_rect); } + +void PluginProcessHost::OnAppActivation() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + + // If our plugin process has any modal windows up, we need to bring it forward + // so that they act more like an in-process modal window would. + if (!plugin_modal_windows_set_.empty()) { + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableFunction(mac_util::ActivateProcess, handle())); + } +} diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc index 54577a7..f9153c6 100644 --- a/chrome/browser/plugin_service.cc +++ b/chrome/browser/plugin_service.cc @@ -29,6 +29,18 @@ #include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_list.h" +#if defined(OS_MACOSX) +static void NotifyPluginsOfActivation() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + + for (ChildProcessHost::Iterator iter(ChildProcessInfo::PLUGIN_PROCESS); + !iter.Done(); ++iter) { + PluginProcessHost* plugin = static_cast<PluginProcessHost*>(*iter); + plugin->OnAppActivation(); + } +} +#endif + // static PluginService* PluginService::GetInstance() { return Singleton<PluginService>::get(); @@ -72,6 +84,12 @@ PluginService::PluginService() NotificationService::AllSources()); registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, NotificationService::AllSources()); +#if defined(OS_MACOSX) + // We need to know when the browser comes forward so we can bring modal plugin + // windows forward too. + registrar_.Add(this, NotificationType::APP_ACTIVATED, + NotificationService::AllSources()); +#endif } PluginService::~PluginService() { @@ -243,6 +261,14 @@ void PluginService::Observe(NotificationType type, break; } +#if defined(OS_MACOSX) + case NotificationType::APP_ACTIVATED: { + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, + NewRunnableFunction(&NotifyPluginsOfActivation)); + break; + } +#endif + default: DCHECK(false); } diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index 1ea5923..db22312 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -205,6 +205,10 @@ class NotificationType { // details are passed. ALL_APPWINDOWS_CLOSED, + // This message is sent when the application is made active (Mac OS X only + // at present). No source or details are passed. + APP_ACTIVATED, + // Indicates that a top window has been closed. The source is the HWND // that was closed, no details are expected. WINDOW_CLOSED, diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h index cd44d21..f9a5bbf 100644 --- a/chrome/common/plugin_messages_internal.h +++ b/chrome/common/plugin_messages_internal.h @@ -131,14 +131,16 @@ IPC_BEGIN_MESSAGES(PluginProcessHost) // Notifies the browser that the plugin has selected a window (i.e., brought // it to the front and wants it to have keyboard focus). - IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginSelectWindow, + IPC_MESSAGE_CONTROL3(PluginProcessHostMsg_PluginSelectWindow, uint32 /* window ID */, - gfx::Rect /* window rect */) + gfx::Rect /* window rect */, + bool /* modal */) // Notifies the browser that the plugin has shown a window. - IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginShowWindow, + IPC_MESSAGE_CONTROL3(PluginProcessHostMsg_PluginShowWindow, uint32 /* window ID */, - gfx::Rect /* window rect */) + gfx::Rect /* window rect */, + bool /* modal */) // Notifies the browser that the plugin has hidden a window. IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginHideWindow, diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc index 5969089..85caf16 100644 --- a/chrome/plugin/plugin_thread.cc +++ b/chrome/plugin/plugin_thread.cc @@ -166,22 +166,26 @@ bool GetPluginFinderURL(std::string* plugin_finder_url) { #if defined(OS_MACOSX) __attribute__((visibility("default"))) -void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds) { +void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds, + bool modal) { PluginThread* plugin_thread = PluginThread::current(); if (plugin_thread) { gfx::Rect window_bounds(bounds); plugin_thread->Send( - new PluginProcessHostMsg_PluginSelectWindow(window_id, window_bounds)); + new PluginProcessHostMsg_PluginSelectWindow(window_id, window_bounds, + modal)); } } __attribute__((visibility("default"))) -void NotifyBrowserOfPluginShowWindow(uint32 window_id, CGRect bounds) { +void NotifyBrowserOfPluginShowWindow(uint32 window_id, CGRect bounds, + bool modal) { PluginThread* plugin_thread = PluginThread::current(); if (plugin_thread) { gfx::Rect window_bounds(bounds); plugin_thread->Send( - new PluginProcessHostMsg_PluginShowWindow(window_id, window_bounds)); + new PluginProcessHostMsg_PluginShowWindow(window_id, window_bounds, + modal)); } } diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h index c6f05ba..435d8c3 100644 --- a/chrome/plugin/plugin_thread.h +++ b/chrome/plugin/plugin_thread.h @@ -35,6 +35,9 @@ class PluginThread : public ChildThread { // Callback for when a channel has been created. void OnCreateChannel(int renderer_id, bool off_the_record); void OnPluginMessage(const std::vector<uint8> &data); +#if defined(OS_MACOSX) + void OnAppActivated(); +#endif // The plugin module which is preloaded in Init base::NativeLibrary preloaded_plugin_module_; |