diff options
-rw-r--r-- | base/mac_util.h | 3 | ||||
-rw-r--r-- | base/mac_util.mm | 7 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 13 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 9 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host_mac.cc | 10 | ||||
-rw-r--r-- | chrome/common/plugin_messages_internal.h | 7 | ||||
-rw-r--r-- | chrome/plugin/plugin_interpose_util_mac.mm | 51 |
7 files changed, 87 insertions, 13 deletions
diff --git a/base/mac_util.h b/base/mac_util.h index 8628e6c..1a0a043 100644 --- a/base/mac_util.h +++ b/base/mac_util.h @@ -87,6 +87,9 @@ void RequestFullScreen(); // this will show the menu bar. Must be called on main thread. void ReleaseFullScreen(); +// Set the visibility of the cursor. +void SetCursorVisibility(bool visible); + // Activates the process with the given PID. void ActivateProcess(pid_t); diff --git a/base/mac_util.mm b/base/mac_util.mm index 1c4ef73b..2975b4e 100644 --- a/base/mac_util.mm +++ b/base/mac_util.mm @@ -167,6 +167,13 @@ void ReleaseFullScreen() { SetSystemUIMode(kUIModeNormal, 0); } +void SetCursorVisibility(bool visible) { + if (visible) + [NSCursor unhide]; + else + [NSCursor hide]; +} + void GrabWindowSnapshot(NSWindow* window, std::vector<unsigned char>* png_representation) { // Make sure to grab the "window frame" view so we get current tab + diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index ea47444..5e1afe9 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -325,6 +325,17 @@ PluginProcessHost::~PluginProcessHost() { NewRunnableFunction(mac_util::ReleaseFullScreen)); } } + // If the plugin hid the cursor, reset that. + if (!plugin_cursor_visible_) { + if (ChromeThread::CurrentlyOn(ChromeThread::UI)) { + mac_util::SetCursorVisibility(true); + } else { + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableFunction(mac_util::SetCursorVisibility, + true)); + } + } #endif } @@ -482,6 +493,8 @@ void PluginProcessHost::OnMessageReceived(const IPC::Message& msg) { OnPluginHideWindow) IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginReceivedFocus, OnPluginReceivedFocus) + IPC_MESSAGE_HANDLER(PluginProcessHostMsg_PluginSetCursorVisibility, + OnPluginSetCursorVisibility) #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 aee437a..8218c65 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -129,6 +129,7 @@ class PluginProcessHost : public ChildProcessHost, bool modal); void OnPluginHideWindow(uint32 window_id, gfx::Rect window_rect); void OnPluginReceivedFocus(int process_id, int instance_id); + void OnPluginSetCursorVisibility(bool visible); #endif virtual bool CanShutdown() { return sent_requests_.empty(); } @@ -163,12 +164,14 @@ class PluginProcessHost : public ChildProcessHost, std::set<HWND> plugin_parent_windows_set_; #endif #if defined(OS_MACOSX) - // Tracks plugin windows currently visible + // Tracks plugin windows currently visible. std::set<uint32> plugin_visible_windows_set_; - // Tracks full screen windows currently visible + // Tracks full screen windows currently visible. std::set<uint32> plugin_fullscreen_windows_set_; - // Tracks modal windows currently visible + // Tracks modal windows currently visible. std::set<uint32> plugin_modal_windows_set_; + // Tracks the current visibility of the cursor. + bool plugin_cursor_visible_; #endif DISALLOW_COPY_AND_ASSIGN(PluginProcessHost); diff --git a/chrome/browser/plugin_process_host_mac.cc b/chrome/browser/plugin_process_host_mac.cc index 2df0eae..77596a0 100644 --- a/chrome/browser/plugin_process_host_mac.cc +++ b/chrome/browser/plugin_process_host_mac.cc @@ -111,3 +111,13 @@ void PluginProcessHost::OnPluginReceivedFocus(int process_id, int instance_id) { plugin->Send(new PluginProcessMsg_PluginFocusNotify(instance)); } } + +void PluginProcessHost::OnPluginSetCursorVisibility(bool visible) { + if (plugin_cursor_visible_ != visible) { + plugin_cursor_visible_ = visible; + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableFunction(mac_util::SetCursorVisibility, + visible)); + } +} diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h index b1af5b0..aecccac 100644 --- a/chrome/common/plugin_messages_internal.h +++ b/chrome/common/plugin_messages_internal.h @@ -155,10 +155,15 @@ IPC_BEGIN_MESSAGES(PluginProcessHost) uint32 /* window ID */, gfx::Rect /* window rect */) - // Notifies the browser that a plugin instance has received keyboard focus + // Notifies the browser that a plugin instance has received keyboard focus. IPC_MESSAGE_CONTROL2(PluginProcessHostMsg_PluginReceivedFocus, uint32 /* process ID */, uint32 /* instance ID */) + + // Notifies the browser that a plugin instance has requested a cursor + // visibility change. + IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_PluginSetCursorVisibility, + bool /* cursor visibility */) #endif IPC_END_MESSAGES(PluginProcessHost) diff --git a/chrome/plugin/plugin_interpose_util_mac.mm b/chrome/plugin/plugin_interpose_util_mac.mm index 7dd20ad..d3c1d74 100644 --- a/chrome/plugin/plugin_interpose_util_mac.mm +++ b/chrome/plugin/plugin_interpose_util_mac.mm @@ -81,6 +81,14 @@ void NotifyPluginOfSetCursor(WebPluginDelegateImpl* delegate, delegate->SetCursor(cursor); } +void NotifyPluginOfSetCursorVisibility(bool visibility) { + PluginThread* plugin_thread = PluginThread::current(); + if (plugin_thread) { + plugin_thread->Send( + new PluginProcessHostMsg_PluginSetCursorVisibility(visibility)); + } +} + __attribute__((visibility("default"))) bool GetPluginWindowHasFocus(const WebPluginDelegateImpl* delegate) { return delegate->GetWindowHasFocus(); @@ -181,6 +189,8 @@ static void OnPluginWindowShown(const WindowInfo& window_info, BOOL is_modal) { @interface NSCursor (ChromePluginInterposing) - (void)chromePlugin_set; ++ (void)chromePlugin_hide; ++ (void)chromePlugin_unhide; @end @implementation NSCursor (ChromePluginInterposing) @@ -194,13 +204,31 @@ static void OnPluginWindowShown(const WindowInfo& window_info, BOOL is_modal) { [self chromePlugin_set]; } ++ (void)chromePlugin_hide { + mac_plugin_interposing::NotifyPluginOfSetCursorVisibility(false); +} + ++ (void)chromePlugin_unhide { + mac_plugin_interposing::NotifyPluginOfSetCursorVisibility(true); +} + @end #pragma mark - -static void ExchangeMethods(Class target_class, SEL original, SEL replacement) { - Method m1 = class_getInstanceMethod(target_class, original); - Method m2 = class_getInstanceMethod(target_class, replacement); +static void ExchangeMethods(Class target_class, + BOOL class_method, + SEL original, + SEL replacement) { + Method m1; + Method m2; + if (class_method) { + m1 = class_getClassMethod(target_class, original); + m2 = class_getClassMethod(target_class, replacement); + } else { + m1 = class_getInstanceMethod(target_class, original); + m2 = class_getInstanceMethod(target_class, replacement); + } if (m1 && m2) method_exchangeImplementations(m1, m2); else @@ -211,20 +239,25 @@ namespace mac_plugin_interposing { void SetUpCocoaInterposing() { Class nswindow_class = [NSWindow class]; - ExchangeMethods(nswindow_class, @selector(orderOut:), + ExchangeMethods(nswindow_class, NO, @selector(orderOut:), @selector(chromePlugin_orderOut:)); - ExchangeMethods(nswindow_class, @selector(orderFront:), + ExchangeMethods(nswindow_class, NO, @selector(orderFront:), @selector(chromePlugin_orderFront:)); - ExchangeMethods(nswindow_class, @selector(makeKeyAndOrderFront:), + ExchangeMethods(nswindow_class, NO, @selector(makeKeyAndOrderFront:), @selector(chromePlugin_makeKeyAndOrderFront:)); - ExchangeMethods(nswindow_class, @selector(_setWindowNumber:), + ExchangeMethods(nswindow_class, NO, @selector(_setWindowNumber:), @selector(chromePlugin_setWindowNumber:)); - ExchangeMethods([NSApplication class], @selector(runModalForWindow:), + ExchangeMethods([NSApplication class], NO, @selector(runModalForWindow:), @selector(chromePlugin_runModalForWindow:)); - ExchangeMethods([NSCursor class], @selector(set), + Class nscursor_class = [NSCursor class]; + ExchangeMethods(nscursor_class, NO, @selector(set), @selector(chromePlugin_set)); + ExchangeMethods(nscursor_class, YES, @selector(hide), + @selector(chromePlugin_hide)); + ExchangeMethods(nscursor_class, YES, @selector(unhide), + @selector(chromePlugin_unhide)); } } // namespace mac_plugin_interposing |