diff options
author | stuartmorgan@google.com <stuartmorgan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-07 22:03:17 +0000 |
---|---|---|
committer | stuartmorgan@google.com <stuartmorgan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-07 22:03:17 +0000 |
commit | f3ef7b1c17b3f9a1db703a7b099e697e401d21a9 (patch) | |
tree | c6252141eeb6637bb2a4630d1735bbf965933a56 /chrome/browser | |
parent | 1ef7ccfa171759ab86cdf6b98cf5145b9db688b0 (diff) | |
download | chromium_src-f3ef7b1c17b3f9a1db703a7b099e697e401d21a9.zip chromium_src-f3ef7b1c17b3f9a1db703a7b099e697e401d21a9.tar.gz chromium_src-f3ef7b1c17b3f9a1db703a7b099e697e401d21a9.tar.bz2 |
Set up a interposing library for Carbon calls made by plugins.
This gives us a library that's inserted into plugin process via DYLD_INSERT_LIBRARIES to intercept Carbon calls, and moves the window/process activation handling into that library (based on Carbon window activation/deactivation calls, rather than polling the front window). Over time we'll interpose more, but this gives us the foundation.
This fixes both the "window loses focus when loading a page with plugins" and "can't click on YouTube controls" bugs.
BUG=18203,18553
TEST=Clicking on Flash plugins should work much more reliably, opening a page with a plugin shouldn't cause the window to lose focus.
Review URL: http://codereview.chromium.org/164100
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@22799 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/plugin_carbon_interpose_mac.cc | 105 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 21 |
2 files changed, 125 insertions, 1 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) |