diff options
-rw-r--r-- | chrome/browser/plugin_carbon_interpose_mac.cc | 105 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 21 | ||||
-rw-r--r-- | chrome/chrome.gyp | 52 | ||||
-rw-r--r-- | chrome/common/plugin_carbon_interpose_constants_mac.cc | 13 | ||||
-rw-r--r-- | chrome/common/plugin_carbon_interpose_constants_mac.h | 16 | ||||
-rw-r--r-- | chrome/plugin/plugin_main.cc | 41 | ||||
-rw-r--r-- | webkit/glue/plugins/fake_plugin_window_tracker_mac.cc | 49 | ||||
-rw-r--r-- | webkit/glue/plugins/fake_plugin_window_tracker_mac.h | 42 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl_mac.mm | 98 | ||||
-rw-r--r-- | webkit/webkit.gyp | 2 |
10 files changed, 361 insertions, 78 deletions
diff --git a/chrome/browser/plugin_carbon_interpose_mac.cc b/chrome/browser/plugin_carbon_interpose_mac.cc new file mode 100644 index 0000000..315cdfa --- /dev/null +++ b/chrome/browser/plugin_carbon_interpose_mac.cc @@ -0,0 +1,105 @@ +// 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 "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" + +// 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 }; + +// Bring the plugin process to the front so that the user can see it. +// TODO: Make this an IPC to order the plugin process above the browser +// process but not necessarily the frontmost. +static void SwitchToPluginProcess() { + ProcessSerialNumber this_process, front_process; + if (GetCurrentProcess(&this_process) != noErr) + return; + if (GetFrontProcess(&front_process) != noErr) + return; + Boolean matched = false; + if (SameProcess(&this_process, &front_process, &matched) != noErr) + return; + if (!matched) { + // TODO: We may need to keep a stack, or at least check the total window + // count, since this won't work if a plugin opens more than one window at + // a time. + g_saved_front_process = front_process; + SetFrontProcess(&this_process); + } +} + +// If the plugin process is still the front process, bring the prior +// front process (normally this will be the browser process) back to +// the front. +// TODO: Make this an IPC message so that the browser can properly +// reactivate the window. +static void SwitchToSavedProcess() { + ProcessSerialNumber this_process, front_process; + if (GetCurrentProcess(&this_process) != noErr) + return; + if (GetFrontProcess(&front_process) != noErr) + return; + Boolean matched = false; + if (SameProcess(&this_process, &front_process, &matched) != noErr) + return; + if (matched) { + SetFrontProcess(&g_saved_front_process); + } +} + +#pragma mark - + +static Boolean ChromePluginIsWindowHilited(WindowRef window) { + // TODO(stuartmorgan): Always returning true (instead of the real answer, + // which would be false) means that clicking works, but it's not correct + // either. Ideally we need a way to find out if the delegate corresponds + // to a browser window that is active. + const WebPluginDelegateImpl* delegate = + FakePluginWindowTracker::SharedInstance()->GetDelegateForFakeWindow( + window); + Boolean isHilited = delegate ? true : IsWindowHilited(window); + return isHilited; +} + +static void ChromePluginSelectWindow(WindowRef window) { + SwitchToPluginProcess(); + SelectWindow(window); +} + +static void ChromePluginShowWindow(WindowRef window) { + SwitchToPluginProcess(); + ShowWindow(window); +} + +static void ChromePluginDisposeWindow(WindowRef window) { + SwitchToSavedProcess(); + DisposeWindow(window); +} + +static void ChromePluginHideWindow(WindowRef window) { + SwitchToSavedProcess(); + HideWindow(window); +} + +#pragma mark - + +struct interpose_substitution { + const void* replacement; + const void* original; +}; + +#define INTERPOSE_FUNCTION(function) \ + { reinterpret_cast<const void*>(ChromePlugin##function), \ + reinterpret_cast<const void*>(function) } + +__attribute__((used)) static const interpose_substitution substitutions[] + __attribute__((section("__DATA, __interpose"))) = { + INTERPOSE_FUNCTION(IsWindowHilited), + INTERPOSE_FUNCTION(SelectWindow), + INTERPOSE_FUNCTION(ShowWindow), + INTERPOSE_FUNCTION(DisposeWindow), + INTERPOSE_FUNCTION(HideWindow), +}; diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index d57daae..3c5f169 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -64,6 +64,10 @@ #include "base/gfx/gtk_native_view_id_manager.h" #endif +#if defined(OS_MACOSX) +#include "chrome/common/plugin_carbon_interpose_constants_mac.h" +#endif + static const char kDefaultPluginFinderURL[] = "http://dl.google.com/chrome/plugins/plugins2.xml"; @@ -410,7 +414,22 @@ bool PluginProcessHost::Init(const WebPluginInfo& info, if (ipcfd > -1) fds_to_map.push_back(std::pair<int, int>( ipcfd, kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); - base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process); + base::environment_vector env; +#if defined(OS_MACOSX) + // Add our interposing library for Carbon. This is stripped back out in + // plugin_main.cc, so changes here should be reflected there. + std::string interpose_list(plugin_interpose_strings::kInterposeLibraryPath); + const char* existing_list = + getenv(plugin_interpose_strings::kDYLDInsertLibrariesKey); + if (existing_list) { + interpose_list.insert(0, ":"); + interpose_list.insert(0, existing_list); + } + env.push_back(std::pair<const char*, const char*>( + plugin_interpose_strings::kDYLDInsertLibrariesKey, + interpose_list.c_str())); +#endif + base::LaunchApp(cmd_line.argv(), env, fds_to_map, false, &process); #endif if (!process) diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index c4e12bf..6b59d03 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -453,6 +453,8 @@ 'common/platform_util_linux.cc', 'common/platform_util_mac.mm', 'common/platform_util_win.cc', + 'common/plugin_carbon_interpose_constants_mac.h', + 'common/plugin_carbon_interpose_constants_mac.cc', 'common/plugin_messages.h', 'common/plugin_messages_internal.h', 'common/pref_member.cc', @@ -3015,7 +3017,8 @@ 'destination': '<(PRODUCT_DIR)/<(mac_product_name).app/Contents/MacOS/', 'files': ['../third_party/ffmpeg/binaries/chrome/libavcodec.52.dylib', '../third_party/ffmpeg/binaries/chrome/libavformat.52.dylib', - '../third_party/ffmpeg/binaries/chrome/libavutil.50.dylib'], + '../third_party/ffmpeg/binaries/chrome/libavutil.50.dylib', + '<(PRODUCT_DIR)/plugin_carbon_interpose.dylib'], }, ], }, { # else: 'branding!="Chrome" @@ -3028,7 +3031,8 @@ 'destination': '<(PRODUCT_DIR)/<(mac_product_name).app/Contents/MacOS/', 'files': ['../third_party/ffmpeg/binaries/chromium/libavcodec.52.dylib', '../third_party/ffmpeg/binaries/chromium/libavformat.52.dylib', - '../third_party/ffmpeg/binaries/chromium/libavutil.50.dylib'], + '../third_party/ffmpeg/binaries/chromium/libavutil.50.dylib', + '<(PRODUCT_DIR)/plugin_carbon_interpose.dylib'], }, ], }], @@ -3077,6 +3081,7 @@ # Bring in pdfsqueeze and run it on all pdfs 'dependencies': [ '../build/temp_gyp/pdfsqueeze.gyp:pdfsqueeze', + 'interpose_dependency_shim', ], 'rules': [ { @@ -4496,6 +4501,49 @@ }, ], # 'actions' }, + { + # Dummy target to allow chrome to require plugin_carbon_interpose to + # build without actually linking to the resulting library. + 'target_name': 'interpose_dependency_shim', + 'type': 'executable', + 'dependencies': [ + 'plugin_carbon_interpose', + ], + # In release, we end up with a strip step that is unhappy if there is + # no binary. Rather than check in a new file for this temporary hack, + # just generate a source file on the fly. + 'actions': [ + { + 'action_name': 'generate_stub_main', + 'process_outputs_as_sources': 1, + 'inputs': [], + 'outputs': [ '<(INTERMEDIATE_DIR)/dummy_main.c' ], + 'action': [ + 'bash', '-c', + 'echo "int main() { return 0; }" > <(INTERMEDIATE_DIR)/dummy_main.c' + ], + }, + ], + }, + { + # dylib for interposing Carbon calls in the plugin process. + 'target_name': 'plugin_carbon_interpose', + 'type': 'shared_library', + 'dependencies': [ + 'chrome_dll', + ], + 'sources': [ + 'browser/plugin_carbon_interpose_mac.cc', + ], + 'include_dirs': [ + '..', + ], + 'link_settings': { + 'libraries': [ + '$(SDKROOT)/System/Library/Frameworks/Carbon.framework', + ], + }, + }, ] }, { # else: OS != "mac" 'targets': [ diff --git a/chrome/common/plugin_carbon_interpose_constants_mac.cc b/chrome/common/plugin_carbon_interpose_constants_mac.cc new file mode 100644 index 0000000..26f0edc --- /dev/null +++ b/chrome/common/plugin_carbon_interpose_constants_mac.cc @@ -0,0 +1,13 @@ +// 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 "chrome/common/plugin_carbon_interpose_constants_mac.h" + +namespace plugin_interpose_strings { + +const char kDYLDInsertLibrariesKey[] = "DYLD_INSERT_LIBRARIES"; +const char kInterposeLibraryPath[] = + "@executable_path/plugin_carbon_interpose.dylib"; + +} // namespace plugin_interpose_strings diff --git a/chrome/common/plugin_carbon_interpose_constants_mac.h b/chrome/common/plugin_carbon_interpose_constants_mac.h new file mode 100644 index 0000000..f90085f --- /dev/null +++ b/chrome/common/plugin_carbon_interpose_constants_mac.h @@ -0,0 +1,16 @@ +// 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. + +#ifndef CHROME_COMMON_PLUGIN_CARBON_INTERPOSE_CONSTANTS_MAC_H_ +#define CHROME_COMMON_PLUGIN_CARBON_INTERPOSE_CONSTANTS_MAC_H_ + +// Strings used in setting up Carbon interposing for the plugin process. +namespace plugin_interpose_strings { + +extern const char kDYLDInsertLibrariesKey[]; +extern const char kInterposeLibraryPath[]; + +} // namespace plugin_interpose_strings + +#endif // CHROME_BROWSER_PLUGIN_CARBON_INTERPOSE_CONSTANTS_MAC_H_ diff --git a/chrome/plugin/plugin_main.cc b/chrome/plugin/plugin_main.cc index 63d295d..afc83a5 100644 --- a/chrome/plugin/plugin_main.cc +++ b/chrome/plugin/plugin_main.cc @@ -25,8 +25,45 @@ #elif defined(OS_LINUX) #include "base/global_descriptors_posix.h" #include "ipc/ipc_descriptors.h" +#elif defined(OS_MACOSX) +#include "chrome/common/plugin_carbon_interpose_constants_mac.h" #endif +#if defined(OS_MACOSX) +// Removes our Carbon library interposing from the environment so that it +// doesn't carry into any processes that plugins might start. +static void TrimInterposeEnvironment() { + const char* interpose_list = + getenv(plugin_interpose_strings::kDYLDInsertLibrariesKey); + if (!interpose_list) { + NOTREACHED() << "No interposing libraries set"; + return; + } + + // The list is a :-separated list of paths. Because we append our interpose + // library just before forking in plugin_process_host.cc, the only cases we + // need to handle are: + // 1) The whole string is "<kInterposeLibraryPath>", so just clear it, or + // 2) ":<kInterposeLibraryPath>" is the end of the string, so trim and re-set. + int suffix_offset = strlen(interpose_list) - + strlen(plugin_interpose_strings::kInterposeLibraryPath); + if (suffix_offset == 0 && + strcmp(interpose_list, + plugin_interpose_strings::kInterposeLibraryPath) == 0) { + unsetenv(plugin_interpose_strings::kDYLDInsertLibrariesKey); + } else if (suffix_offset > 0 && interpose_list[suffix_offset - 1] == ':' && + strcmp(interpose_list + suffix_offset, + plugin_interpose_strings::kInterposeLibraryPath) == 0) { + std::string trimmed_list = + std::string(interpose_list).substr(0, suffix_offset - 1); + setenv(plugin_interpose_strings::kDYLDInsertLibrariesKey, + trimmed_list.c_str(), 1); + } else { + NOTREACHED() << "Missing Carbon interposing library"; + } +} +#endif // OS_MACOSX + // main() routine for running as the plugin process. int PluginMain(const MainFunctionParams& parameters) { // The main thread of the plugin services UI. @@ -37,6 +74,10 @@ int PluginMain(const MainFunctionParams& parameters) { // Initialize the SystemMonitor base::SystemMonitor::Start(); +#if defined(OS_MACOSX) + TrimInterposeEnvironment(); +#endif + const CommandLine& parsed_command_line = parameters.command_line_; #if defined(OS_WIN) diff --git a/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc b/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc new file mode 100644 index 0000000..9f809a5 --- /dev/null +++ b/webkit/glue/plugins/fake_plugin_window_tracker_mac.cc @@ -0,0 +1,49 @@ +// 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 "base/logging.h" +#include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" + +FakePluginWindowTracker::FakePluginWindowTracker() + : window_to_delegate_map_(CFDictionaryCreateMutable(kCFAllocatorDefault, + 0, NULL, NULL)) { +} + +FakePluginWindowTracker* FakePluginWindowTracker::SharedInstance() { + static FakePluginWindowTracker* tracker = new FakePluginWindowTracker(); + return tracker; +} + +WindowRef FakePluginWindowTracker::GenerateFakeWindowForDelegate( + WebPluginDelegateImpl* delegate) { + // TODO(stuartmorgan): Eventually we will be interposing enough that we don't + // even need a window, and can just use made-up identifiers, but for now we + // create one so that things that we don't interpose won't crash trying to use + // a bad WindowRef. + + // The real size will be set by the plugin instance, once that size is known. + Rect window_bounds = { 0, 0, 100, 100 }; + WindowRef new_ref = NULL; + if (CreateNewWindow(kDocumentWindowClass, + kWindowStandardDocumentAttributes, + &window_bounds, + &new_ref) == noErr) { + CFDictionaryAddValue(window_to_delegate_map_, new_ref, delegate); + } + return new_ref; +} + +const WebPluginDelegateImpl* FakePluginWindowTracker::GetDelegateForFakeWindow( + WindowRef window) const { + return static_cast<const WebPluginDelegateImpl*>( + CFDictionaryGetValue(window_to_delegate_map_, window)); +} + +void FakePluginWindowTracker::RemoveFakeWindowForDelegate( + WebPluginDelegateImpl* delegate, WindowRef window) { + DCHECK(GetDelegateForFakeWindow(window) == delegate); + CFDictionaryRemoveValue(window_to_delegate_map_, delegate); + if (window) // Check just in case the initial window creation failed. + DisposeWindow(window); +} diff --git a/webkit/glue/plugins/fake_plugin_window_tracker_mac.h b/webkit/glue/plugins/fake_plugin_window_tracker_mac.h new file mode 100644 index 0000000..d2e7bee --- /dev/null +++ b/webkit/glue/plugins/fake_plugin_window_tracker_mac.h @@ -0,0 +1,42 @@ +// 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. + +#ifndef WEBKIT_GLUE_PLUGINS_FAKE_PLUGIN_WINDOW_TRACKER_MAC_H_ +#define WEBKIT_GLUE_PLUGINS_FAKE_PLUGIN_WINDOW_TRACKER_MAC_H_ + +#include <Carbon/Carbon.h> + +#include "base/basictypes.h" +#include "base/scoped_cftyperef.h" + +class WebPluginDelegateImpl; + +// Serves as a bridge between password delegate instances and the Carbon +// interposing library. The Carbon functions we interpose work in terms of +// WindowRefs, and we need to be able to map from those back to the plugin +// delegates that know what we should claim about the state of the world. +class __attribute__((visibility("default"))) FakePluginWindowTracker { + public: + FakePluginWindowTracker(); + + // Returns the shared window tracker instance. + static FakePluginWindowTracker* SharedInstance(); + + // Creates a new fake window ref associated with |delegate|. + WindowRef GenerateFakeWindowForDelegate(WebPluginDelegateImpl* delegate); + + // Returns the WebPluginDelegate associated with the given fake window ref. + const WebPluginDelegateImpl* GetDelegateForFakeWindow(WindowRef window) const; + + // Removes the fake window ref entry for |delegate|. + void RemoveFakeWindowForDelegate(WebPluginDelegateImpl* delegate, + WindowRef window); + + private: + scoped_cftyperef<CFMutableDictionaryRef> window_to_delegate_map_; + + DISALLOW_COPY_AND_ASSIGN(FakePluginWindowTracker); +}; + +#endif // WEBKIT_GLUE_PLUGINS_FAKE_PLUGIN_WINDOW_TRACKER_MAC_H_ diff --git a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm index e5da9eb..4fda86d 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl_mac.mm +++ b/webkit/glue/plugins/webplugin_delegate_impl_mac.mm @@ -18,6 +18,7 @@ #include "webkit/default_plugin/plugin_impl.h" #include "webkit/glue/glue_util.h" #include "webkit/glue/webplugin.h" +#include "webkit/glue/plugins/fake_plugin_window_tracker_mac.h" #include "webkit/glue/plugins/plugin_constants_win.h" #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/plugins/plugin_lib.h" @@ -58,9 +59,6 @@ const int kPluginIdleThrottleDelayMs = 20; // 20ms (50Hz) int g_current_x_offset = 0; int g_current_y_offset = 0; -WindowRef g_last_front_window = NULL; -ProcessSerialNumber g_saved_front_process; - } // namespace WebPluginDelegate* WebPluginDelegate::Create( @@ -101,10 +99,9 @@ WebPluginDelegateImpl::WebPluginDelegateImpl( } WebPluginDelegateImpl::~WebPluginDelegateImpl() { + FakePluginWindowTracker::SharedInstance()->RemoveFakeWindowForDelegate( + this, cg_context_.window); DestroyInstance(); - - if (cg_context_.window) - DisposeWindow(cg_context_.window); } void WebPluginDelegateImpl::PluginDestroyed() { @@ -131,7 +128,11 @@ bool WebPluginDelegateImpl::Initialize(const GURL& url, if (!start_result) return false; - cg_context_.window = NULL; + FakePluginWindowTracker* window_tracker = + FakePluginWindowTracker::SharedInstance(); + cg_context_.window = window_tracker->GenerateFakeWindowForDelegate(this); + Rect window_bounds = { 0, 0, window_rect_.height(), window_rect_.width() }; + SetWindowBounds(cg_context_.window, kWindowContentRgn, &window_bounds); window_.window = &cg_context_; window_.type = NPWindowTypeWindow; @@ -161,7 +162,6 @@ void WebPluginDelegateImpl::DestroyInstance() { void WebPluginDelegateImpl::UpdateGeometry( const gfx::Rect& window_rect, const gfx::Rect& clip_rect) { - DCHECK(windowless_); WindowlessUpdateGeometry(window_rect, clip_rect); } @@ -284,16 +284,22 @@ void WebPluginDelegateImpl::WindowlessPaint(gfx::NativeDrawingContext context, // Moves our dummy window to the given offset relative to the last known // location of the real renderer window's content view. -static void UpdateDummyWindowLocationWithOffset(WindowRef window, - int x_offset, int y_offset) { +// If new_width or new_height is non-zero, the window size (content region) +// will be updated accordingly; if they are zero, the existing size will be +// preserved. +static void UpdateDummyWindowBoundsWithOffset(WindowRef window, + int x_offset, int y_offset, + int new_width, int new_height) { int target_x = g_current_x_offset + x_offset; int target_y = g_current_y_offset + y_offset; Rect window_bounds; GetWindowBounds(window, kWindowContentRgn, &window_bounds); if ((window_bounds.left != target_x) || (window_bounds.top != target_y)) { - int height = window_bounds.bottom - window_bounds.top; - int width = window_bounds.right - window_bounds.left; + int height = new_height ? new_height + : window_bounds.bottom - window_bounds.top; + int width = new_width ? new_width + : window_bounds.right - window_bounds.left; window_bounds.left = target_x; window_bounds.top = target_y; window_bounds.right = window_bounds.left + width; @@ -323,26 +329,9 @@ void WebPluginDelegateImpl::WindowlessSetWindow(bool force_set_window) { // Reset this flag before entering the instance in case of side-effects. windowless_needs_set_window_ = false; - if (!cg_context_.window) { - // For all plugins we create a placeholder offscreen window for the use - // of NPWindow. NPAPI on the Mac requires a Carbon WindowRef for the - // "browser window", even if we're not using the Quickdraw drawing model. - // Not having a valid window reference causes subtle bugs with plugins - // which retreive the NPWindow and validate the same. The NPWindow - // can be retreived via NPN_GetValue of NPNVnetscapeWindow. - Rect window_bounds = { 0, 0, window_rect_.height(), window_rect_.width() }; - WindowRef window_ref; - if (CreateNewWindow(kDocumentWindowClass, - kWindowStandardDocumentAttributes, - &window_bounds, - &window_ref) == noErr) { - cg_context_.window = window_ref; - SelectWindow(window_ref); - g_last_front_window = window_ref; - } - } - UpdateDummyWindowLocationWithOffset(cg_context_.window, window_rect_.x(), - window_rect_.y()); + UpdateDummyWindowBoundsWithOffset(cg_context_.window, window_rect_.x(), + window_rect_.y(), window_rect_.width(), + window_rect_.height()); if (!force_set_window) windowless_needs_set_window_ = false; @@ -484,8 +473,8 @@ static void UpdateWindowLocation(WindowRef window, const WebMouseEvent& event) { g_current_x_offset = event.globalX - event.windowX; g_current_y_offset = event.globalY - event.windowY + 22; - UpdateDummyWindowLocationWithOffset(window, event.windowX - event.x, - event.windowY - event.y); + UpdateDummyWindowBoundsWithOffset(window, event.windowX - event.x, + event.windowY - event.y, 0, 0); } bool WebPluginDelegateImpl::HandleInputEvent(const WebInputEvent& event, @@ -561,47 +550,6 @@ void WebPluginDelegateImpl::OnNullEvent() { np_event.where.v = last_mouse_y_; instance()->NPP_HandleEvent(&np_event); - WindowRef front_window = FrontWindow(); - if (front_window == cg_context_.window) { - if (front_window != g_last_front_window) { - // If our dummy window is now the front window, but was not previously, - // it means that a plugin window has been destroyed. Make sure our fake - // browser window is selected. - // TODO: Use DYLD_INSERT_LIBRARIES to interpose on Carbon window - // APIs within the plugin process. This will allow us to (a) get rid of - // the dummy window, and (b) explicitly track the creation and - // destruction of windows by the plugin. - g_last_front_window = front_window; - SelectWindow(cg_context_.window); - - // If the plugin process is still the front process, bring the prior - // front process (normally this will be the browser process) back to - // the front. - // TODO: make this an IPC message so that the browser can properly - // reactivate the window. - ProcessSerialNumber this_process, front_process; - GetCurrentProcess(&this_process); - GetFrontProcess(&front_process); - Boolean matched = false; - SameProcess(&this_process, &front_process, &matched); - if (matched) - SetFrontProcess(&g_saved_front_process); - g_last_front_window = FrontWindow(); - } - } else if (front_window != g_last_front_window) { - // The plugin has just created a new window and brought it to the front. - // bring the plugin process to the front so that the user can see it (for - // example, an alert or file selection dialog). - // TODO: make this an IPC to order the plugin process above the browser - // process but not necessarily the frontmost. - ProcessSerialNumber this_process; - GetCurrentProcess(&this_process); - GetFrontProcess(&g_saved_front_process); - SetFrontProcess(&this_process); - g_last_front_window = front_window; - SelectWindow(front_window); - } - MessageLoop::current()->PostDelayedTask(FROM_HERE, null_event_factory_.NewRunnableMethod( &WebPluginDelegateImpl::OnNullEvent), diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index 9204703..033acf8 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -1274,6 +1274,8 @@ 'glue/plugins/mozilla_extensions.cc', 'glue/plugins/mozilla_extensions.h', 'glue/plugins/nphostapi.h', + 'glue/plugins/fake_plugin_window_tracker_mac.h', + 'glue/plugins/fake_plugin_window_tracker_mac.cc', 'glue/plugins/gtk_plugin_container.h', 'glue/plugins/gtk_plugin_container.cc', 'glue/plugins/gtk_plugin_container_manager.h', |