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::OnPluginShowWindow(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 CGRect window_bounds = { 29 { window_rect.x(), window_rect.y() }, 30 { window_rect.width(), window_rect.height() } 31 }; 32 CGRect main_display_bounds = CGDisplayBounds(CGMainDisplayID()); 33 if (CGRectEqualToRect(window_bounds, main_display_bounds) && 34 (plugin_fullscreen_windows_set_.find(window_id) == 35 plugin_fullscreen_windows_set_.end())) { 36 plugin_fullscreen_windows_set_.insert(window_id); 37 // If the plugin has just shown a window that's the same dimensions as 38 // the main display, hide the menubar so that it has the whole screen. 39 // (but only if we haven't already seen this fullscreen window, since 40 // otherwise our refcounting can get skewed). 41 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 42 base::Bind(base::mac::RequestFullScreen, 43 base::mac::kFullScreenModeHideAll)); 44 } 45 } 46 47 // Must be called on the UI thread. 48 // If plugin_pid is -1, the browser will be the active process on return, 49 // otherwise that process will be given focus back before this function returns. 50 static void ReleasePluginFullScreen(pid_t plugin_pid) { 51 // Releasing full screen only works if we are the frontmost process; grab 52 // focus, but give it back to the plugin process if requested. 53 base::mac::ActivateProcess(base::GetCurrentProcId()); 54 base::mac::ReleaseFullScreen(base::mac::kFullScreenModeHideAll); 55 if (plugin_pid != -1) { 56 base::mac::ActivateProcess(plugin_pid); 57 } 58 } 59 60 void PluginProcessHost::OnPluginHideWindow(uint32 window_id, 61 gfx::Rect window_rect) { 62 bool had_windows = !plugin_visible_windows_set_.empty(); 63 plugin_visible_windows_set_.erase(window_id); 64 bool browser_needs_activation = had_windows && 65 plugin_visible_windows_set_.empty(); 66 67 plugin_modal_windows_set_.erase(window_id); 68 if (plugin_fullscreen_windows_set_.find(window_id) != 69 plugin_fullscreen_windows_set_.end()) { 70 plugin_fullscreen_windows_set_.erase(window_id); 71 pid_t plugin_pid = 72 browser_needs_activation ? -1 : process_->GetData().handle; 73 browser_needs_activation = false; 74 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 75 base::Bind(ReleasePluginFullScreen, plugin_pid)); 76 } 77 78 if (browser_needs_activation) { 79 BrowserThread::PostTask( 80 BrowserThread::UI, FROM_HERE, 81 base::Bind(base::mac::ActivateProcess, base::GetCurrentProcId())); 82 } 83 } 84 85 void PluginProcessHost::OnAppActivation() { 86 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 87 88 // If our plugin process has any modal windows up, we need to bring it forward 89 // so that they act more like an in-process modal window would. 90 if (!plugin_modal_windows_set_.empty()) { 91 BrowserThread::PostTask( 92 BrowserThread::UI, FROM_HERE, 93 base::Bind(base::mac::ActivateProcess, process_->GetData().handle)); 94 } 95 } 96 97 void PluginProcessHost::OnPluginSetCursorVisibility(bool visible) { 98 if (plugin_cursor_visible_ != visible) { 99 plugin_cursor_visible_ = visible; 100 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 101 base::Bind(base::mac::SetCursorVisibility, 102 visible)); 103 } 104 } 105 106 } // namespace content 107