1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <Carbon/Carbon.h> 6 7 #include "build/build_config.h" 8 9 #include <vector> 10 11 #include "base/bind.h" 12 #include "base/logging.h" 13 #include "base/mac/mac_util.h" 14 #include "content/browser/browser_child_process_host_impl.h" 15 #include "content/browser/plugin_process_host.h" 16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/child_process_data.h" 18 #include "ui/gfx/rect.h" 19 20 namespace content { 21 22 void PluginProcessHost::OnPluginSelectWindow(uint32 window_id, 23 gfx::Rect window_rect, 24 bool modal) { 25 plugin_visible_windows_set_.insert(window_id); 26 if (modal) 27 plugin_modal_windows_set_.insert(window_id); 28 } 29 30 void PluginProcessHost::OnPluginShowWindow(uint32 window_id, 31 gfx::Rect window_rect, 32 bool modal) { 33 plugin_visible_windows_set_.insert(window_id); 34 if (modal) 35 plugin_modal_windows_set_.insert(window_id); 36 CGRect window_bounds = { 37 { window_rect.x(), window_rect.y() }, 38 { window_rect.width(), window_rect.height() } 39 }; 40 CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID()); 41 if (CGRectEqualToRect(window_bounds, main_display_bounds) && 42 (plugin_fullscreen_windows_set_.find(window_id) == 43 plugin_fullscreen_windows_set_.end())) { 44 plugin_fullscreen_windows_set_.insert(window_id); 45 // If the plugin has just shown a window that's the same dimensions as 46 // the main display, hide the menubar so that it has the whole screen. 47 // (but only if we haven't already seen this fullscreen window, since 48 // otherwise our refcounting can get skewed). 49 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 50 base::Bind(base::mac::RequestFullScreen, 51 base::mac::kFullScreenModeHideAll)); 52 } 53 } 54 55 // Must be called on the UI thread. 56 // If plugin_pid is -1, the browser will be the active process on return, 57 // otherwise that process will be given focus back before this function returns. 58 static void ReleasePluginFullScreen(pid_t plugin_pid) { 59 // Releasing full screen only works if we are the frontmost process; grab 60 // focus, but give it back to the plugin process if requested. 61 base::mac::ActivateProcess(base::GetCurrentProcId()); 62 base::mac::ReleaseFullScreen(base::mac::kFullScreenModeHideAll); 63 if (plugin_pid != -1) { 64 base::mac::ActivateProcess(plugin_pid); 65 } 66 } 67 68 void PluginProcessHost::OnPluginHideWindow(uint32 window_id, 69 gfx::Rect window_rect) { 70 bool had_windows = !plugin_visible_windows_set_.empty(); 71 plugin_visible_windows_set_.erase(window_id); 72 bool browser_needs_activation = had_windows && 73 plugin_visible_windows_set_.empty(); 74 75 plugin_modal_windows_set_.erase(window_id); 76 if (plugin_fullscreen_windows_set_.find(window_id) != 77 plugin_fullscreen_windows_set_.end()) { 78 plugin_fullscreen_windows_set_.erase(window_id); 79 pid_t plugin_pid = 80 browser_needs_activation ? -1 : process_->GetData().handle; 81 browser_needs_activation = false; 82 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 83 base::Bind(ReleasePluginFullScreen, plugin_pid)); 84 } 85 86 if (browser_needs_activation) { 87 BrowserThread::PostTask( 88 BrowserThread::UI, FROM_HERE, 89 base::Bind(base::mac::ActivateProcess, base::GetCurrentProcId())); 90 } 91 } 92 93 void PluginProcessHost::OnAppActivation() { 94 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 95 96 // If our plugin process has any modal windows up, we need to bring it forward 97 // so that they act more like an in-process modal window would. 98 if (!plugin_modal_windows_set_.empty()) { 99 BrowserThread::PostTask( 100 BrowserThread::UI, FROM_HERE, 101 base::Bind(base::mac::ActivateProcess, process_->GetData().handle)); 102 } 103 } 104 105 void PluginProcessHost::OnPluginSetCursorVisibility(bool visible) { 106 if (plugin_cursor_visible_ != visible) { 107 plugin_cursor_visible_ = visible; 108 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 109 base::Bind(base::mac::SetCursorVisibility, 110 visible)); 111 } 112 } 113 114 } // namespace content 115