summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 19:41:56 +0000
committeramanda@chromium.org <amanda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 19:41:56 +0000
commit1d5ac66b45c8e625fb4ec382d4e38e5357fdb257 (patch)
treeb98aaaafe5243bcd63d0db902d6c8bf1e415dec9 /chrome
parent4c98db35cdd001ce1585bc703375c92ec3ebea9b (diff)
downloadchromium_src-1d5ac66b45c8e625fb4ec382d4e38e5357fdb257.zip
chromium_src-1d5ac66b45c8e625fb4ec382d4e38e5357fdb257.tar.gz
chromium_src-1d5ac66b45c8e625fb4ec382d4e38e5357fdb257.tar.bz2
Fix several issues around fullscreen Mac plugins:
* Keystrokes are now properly sent to plugins in fullscreen mode * When a plugin creates a fullscreen window, we hide the menu bar and restore it when the window is closed BUG=19534,21020 TEST=Open a page with plugins that can go full screen (example: flash video players). Enter full screen mode and verify that esc, arrow keys, spacebar, etc. work as expected. Verify that the menu bar is hidden when the plugin goes fullscreen and is restored when it exits fullscreen mode. Review URL: http://codereview.chromium.org/257008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27755 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/plugin_carbon_interpose_mac.cc25
-rw-r--r--chrome/browser/plugin_process_host.cc20
-rw-r--r--chrome/browser/plugin_process_host.h11
-rw-r--r--chrome/browser/plugin_process_host_mac.cc43
-rwxr-xr-xchrome/chrome.gyp1
-rw-r--r--chrome/common/plugin_messages_internal.h28
-rw-r--r--chrome/plugin/plugin_main.cc10
-rw-r--r--chrome/plugin/plugin_thread.cc42
8 files changed, 180 insertions, 0 deletions
diff --git a/chrome/browser/plugin_carbon_interpose_mac.cc b/chrome/browser/plugin_carbon_interpose_mac.cc
index 315cdfa..0443476 100644
--- a/chrome/browser/plugin_carbon_interpose_mac.cc
+++ b/chrome/browser/plugin_carbon_interpose_mac.cc
@@ -4,8 +4,18 @@
#include <Carbon/Carbon.h>
+#include "base/gfx/rect.h"
#include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h"
+namespace webkit_glue {
+
+void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds);
+void NotifyBrowserOfPluginShowWindow(uint32 window_id, CGRect bounds);
+void NotifyBrowserOfPluginHideWindow(uint32 window_id, CGRect bounds);
+void NotifyBrowserOfPluginDisposeWindow(uint32 window_id, CGRect bounds);
+
+}
+
// The process that was frontmost when a plugin created a new window; generally
// we expect this to be the browser UI process.
static ProcessSerialNumber g_saved_front_process = { 0, 0 };
@@ -64,23 +74,38 @@ static Boolean ChromePluginIsWindowHilited(WindowRef window) {
return isHilited;
}
+static CGRect CGRectForWindow(WindowRef window) {
+ CGRect bounds = { { 0, 0 }, { 0, 0 } };
+ HIWindowGetBounds(window, kWindowContentRgn, kHICoordSpace72DPIGlobal,
+ &bounds);
+ return bounds;
+}
+
static void ChromePluginSelectWindow(WindowRef window) {
SwitchToPluginProcess();
SelectWindow(window);
+ webkit_glue::NotifyBrowserOfPluginSelectWindow(HIWindowGetCGWindowID(window),
+ CGRectForWindow(window));
}
static void ChromePluginShowWindow(WindowRef window) {
SwitchToPluginProcess();
ShowWindow(window);
+ webkit_glue::NotifyBrowserOfPluginShowWindow(HIWindowGetCGWindowID(window),
+ CGRectForWindow(window));
}
static void ChromePluginDisposeWindow(WindowRef window) {
SwitchToSavedProcess();
+ webkit_glue::NotifyBrowserOfPluginDisposeWindow(HIWindowGetCGWindowID(window),
+ CGRectForWindow(window));
DisposeWindow(window);
}
static void ChromePluginHideWindow(WindowRef window) {
SwitchToSavedProcess();
+ webkit_glue::NotifyBrowserOfPluginHideWindow(HIWindowGetCGWindowID(window),
+ CGRectForWindow(window));
HideWindow(window);
}
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index 4c1d949..142315d 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -27,7 +27,10 @@
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "base/thread.h"
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/browser_window.h"
#include "chrome/browser/child_process_security_policy.h"
#include "chrome/browser/chrome_plugin_browsing_context.h"
#include "chrome/browser/chrome_thread.h"
@@ -325,6 +328,13 @@ PluginProcessHost::~PluginProcessHost() {
window_index++) {
PostMessage(*window_index, WM_CLOSE, 0, 0);
}
+#elif defined(OS_MACOSX)
+ // If the plugin process crashed but had windows open at the time, make
+ // sure that the menu bar is visible if the browser window is not also in
+ // fullscreen mode.
+ if (!plugin_visible_windows_set_.empty()) {
+ SetSystemUIMode(kUIModeNormal, 0);
+ }
#endif
}
@@ -477,6 +487,16 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(PluginProcessHostMsg_MapNativeViewId,
OnMapNativeViewId)
#endif
+#if defined(OS_MACOSX)
+ IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginSelectWindow,
+ OnPluginSelectWindow)
+ IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginShowWindow,
+ OnPluginShowWindow)
+ IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginHideWindow,
+ OnPluginHideWindow)
+ IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginDisposeWindow,
+ OnPluginDisposeWindow)
+#endif
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
}
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index 36f8d1e..6c5e17f 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -112,6 +112,13 @@ class PluginProcessHost : public ChildProcessHost,
void OnMapNativeViewId(gfx::NativeViewId id, gfx::PluginWindowHandle* output);
#endif
+#if defined(OS_MACOSX)
+ void OnPluginSelectWindow(uint32 window_id, gfx::Rect window_rect);
+ void OnPluginShowWindow(uint32 window_id, gfx::Rect window_rect);
+ void OnPluginHideWindow(uint32 window_id, gfx::Rect window_rect);
+ void OnPluginDisposeWindow(uint32 window_id, gfx::Rect window_rect);
+#endif
+
virtual bool CanShutdown() { return sent_requests_.empty(); }
struct ChannelRequest {
@@ -143,6 +150,10 @@ class PluginProcessHost : public ChildProcessHost,
// Tracks plugin parent windows created on the UI thread.
std::set<HWND> plugin_parent_windows_set_;
#endif
+#if defined(OS_MACOSX)
+ // Tracks plugin windows currently visible
+ std::set<uint32> plugin_visible_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
new file mode 100644
index 0000000..d222880
--- /dev/null
+++ b/chrome/browser/plugin_process_host_mac.cc
@@ -0,0 +1,43 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <Carbon/Carbon.h>
+
+#include "build/build_config.h"
+
+#include <vector>
+
+#include "base/logging.h"
+#include "chrome/browser/plugin_process_host.h"
+
+void PluginProcessHost::OnPluginSelectWindow(uint32 window_id,
+ gfx::Rect window_rect) {
+ plugin_visible_windows_set_.insert(window_id);
+}
+
+void PluginProcessHost::OnPluginShowWindow(uint32 window_id,
+ gfx::Rect window_rect) {
+ plugin_visible_windows_set_.insert(window_id);
+ CGRect window_bounds = {
+ { window_rect.x(), window_rect.y() },
+ { window_rect.width(), window_rect.height() }
+ };
+ CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID());
+ if (CGRectEqualToRect(window_bounds, main_display_bounds)) {
+ // If the plugin has just shown a window that's the same dimensions as
+ // the main display, hide the menubar so that it has the whole screen.
+ SetSystemUIMode(kUIModeAllSuppressed, kUIOptionAutoShowMenuBar);
+ }
+}
+
+void PluginProcessHost::OnPluginHideWindow(uint32 window_id,
+ gfx::Rect window_rect) {
+ plugin_visible_windows_set_.erase(window_id);
+ SetSystemUIMode(kUIModeNormal, 0);
+}
+
+void PluginProcessHost::OnPluginDisposeWindow(uint32 window_id,
+ gfx::Rect window_rect) {
+ plugin_visible_windows_set_.erase(window_id);
+}
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 84fa030..2af7789 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1739,6 +1739,7 @@
'browser/plugin_installer.h',
'browser/plugin_process_host.cc',
'browser/plugin_process_host.h',
+ 'browser/plugin_process_host_mac.cc',
'browser/plugin_service.cc',
'browser/plugin_service.h',
'browser/possible_url_model.cc',
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index f03cf97..6301e68 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -123,6 +123,34 @@ IPC_BEGIN_MESSAGES(PluginProcessHost)
gfx::PluginWindowHandle /* output: X window id */)
#endif
+#if defined(OS_MACOSX)
+ // On Mac OS X, we need the browser to keep track of plugin windows so
+ // that it can add and remove them from stacking groups, hide and show the
+ // menu bar, etc. We pass the window rect for convenience so that the
+ // browser can easily tell if the window is fullscreen.
+
+ // 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,
+ uint32 /* window ID */,
+ gfx::Rect /* window rect */)
+
+ // Notifies the browser that the plugin has shown a window.
+ IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginShowWindow,
+ uint32 /* window ID */,
+ gfx::Rect /* window rect */)
+
+ // Notifies the browser that the plugin has hidden a window.
+ IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginHideWindow,
+ uint32 /* window ID */,
+ gfx::Rect /* window rect */)
+
+ // Notifies the browser that the plugin has disposed of a window.
+ IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginDisposeWindow,
+ uint32 /* window ID */,
+ gfx::Rect /* window rect */)
+#endif
+
IPC_END_MESSAGES(PluginProcessHost)
diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc
index afc83a5..835b6ca 100644
--- a/chrome/plugin/plugin_main.cc
+++ b/chrome/plugin/plugin_main.cc
@@ -67,7 +67,17 @@ static void TrimInterposeEnvironment() {
// main() routine for running as the plugin process.
int PluginMain(const MainFunctionParams& parameters) {
// The main thread of the plugin services UI.
+#if defined(OS_MACOSX)
+ // For Mac NPAPI plugins, we don't want a MessageLoop::TYPE_UI because
+ // that will cause events to be dispatched via the Cocoa responder chain.
+ // If the plugin creates its own windows with Carbon APIs (for example,
+ // full screen mode in Flash), those windows would not receive events.
+ // Instead, WebPluginDelegateImpl::OnNullEvent will dispatch any pending
+ // system events directly to the plugin.
+ MessageLoop main_message_loop(MessageLoop::TYPE_DEFAULT);
+#else
MessageLoop main_message_loop(MessageLoop::TYPE_UI);
+#endif
std::wstring app_name = chrome::kBrowserAppName;
PlatformThread::SetName(WideToASCII(app_name + L"_PluginMain").c_str());
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index c2a21bd..5969089 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -164,6 +164,48 @@ bool GetPluginFinderURL(std::string* plugin_finder_url) {
return true;
}
+#if defined(OS_MACOSX)
+__attribute__((visibility("default")))
+void NotifyBrowserOfPluginSelectWindow(uint32 window_id, CGRect bounds) {
+ PluginThread* plugin_thread = PluginThread::current();
+ if (plugin_thread) {
+ gfx::Rect window_bounds(bounds);
+ plugin_thread->Send(
+ new PluginProcessHostMsg_PluginSelectWindow(window_id, window_bounds));
+ }
+}
+
+__attribute__((visibility("default")))
+void NotifyBrowserOfPluginShowWindow(uint32 window_id, CGRect bounds) {
+ PluginThread* plugin_thread = PluginThread::current();
+ if (plugin_thread) {
+ gfx::Rect window_bounds(bounds);
+ plugin_thread->Send(
+ new PluginProcessHostMsg_PluginShowWindow(window_id, window_bounds));
+ }
+}
+
+__attribute__((visibility("default")))
+void NotifyBrowserOfPluginHideWindow(uint32 window_id, CGRect bounds) {
+ PluginThread* plugin_thread = PluginThread::current();
+ if (plugin_thread) {
+ gfx::Rect window_bounds(bounds);
+ plugin_thread->Send(
+ new PluginProcessHostMsg_PluginHideWindow(window_id, window_bounds));
+ }
+}
+
+__attribute__((visibility("default")))
+void NotifyBrowserOfPluginDisposeWindow(uint32 window_id, CGRect bounds) {
+ PluginThread* plugin_thread = PluginThread::current();
+ if (plugin_thread) {
+ gfx::Rect window_bounds(bounds);
+ plugin_thread->Send(
+ new PluginProcessHostMsg_PluginDisposeWindow(window_id, window_bounds));
+ }
+}
+#endif
+
bool IsDefaultPluginEnabled() {
#if defined(OS_WIN)
return true;