summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/mac_util.h3
-rw-r--r--base/mac_util.mm10
-rw-r--r--chrome/browser/app_controller_mac.mm9
-rw-r--r--chrome/browser/plugin_carbon_interpose_mac.cc20
-rw-r--r--chrome/browser/plugin_process_host.h14
-rw-r--r--chrome/browser/plugin_process_host_mac.cc23
-rw-r--r--chrome/browser/plugin_service.cc26
-rw-r--r--chrome/common/notification_type.h4
-rw-r--r--chrome/common/plugin_messages_internal.h10
-rw-r--r--chrome/plugin/plugin_thread.cc12
-rw-r--r--chrome/plugin/plugin_thread.h3
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_;