Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1728)

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac.mm

Issue 2756893002: Add Keyboard Latency UMA Metrics. (Closed)
Patch Set: mfomitchev responses, rebase Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
6 6
7 #import <Carbon/Carbon.h> 7 #import <Carbon/Carbon.h>
8 #import <objc/runtime.h> 8 #import <objc/runtime.h>
9 #include <OpenGL/gl.h> 9 #include <OpenGL/gl.h>
10 #include <QuartzCore/QuartzCore.h> 10 #include <QuartzCore/QuartzCore.h>
(...skipping 2089 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 return; 2100 return;
2101 } 2101 }
2102 2102
2103 // Don't cancel child popups; the key events are probably what's triggering 2103 // Don't cancel child popups; the key events are probably what's triggering
2104 // the popup in the first place. 2104 // the popup in the first place.
2105 2105
2106 RenderWidgetHostImpl* widgetHost = renderWidgetHostView_->render_widget_host_; 2106 RenderWidgetHostImpl* widgetHost = renderWidgetHostView_->render_widget_host_;
2107 DCHECK(widgetHost); 2107 DCHECK(widgetHost);
2108 2108
2109 NativeWebKeyboardEvent event(theEvent); 2109 NativeWebKeyboardEvent event(theEvent);
2110 ui::LatencyInfo latency_info(ui::SourceEventType::KEY);
2111 latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, 0);
2110 2112
2111 // Force fullscreen windows to close on Escape so they won't keep the keyboard 2113 // Force fullscreen windows to close on Escape so they won't keep the keyboard
2112 // grabbed or be stuck onscreen if the renderer is hanging. 2114 // grabbed or be stuck onscreen if the renderer is hanging.
2113 if (event.GetType() == NativeWebKeyboardEvent::kRawKeyDown && 2115 if (event.GetType() == NativeWebKeyboardEvent::kRawKeyDown &&
2114 event.windows_key_code == ui::VKEY_ESCAPE && 2116 event.windows_key_code == ui::VKEY_ESCAPE &&
2115 renderWidgetHostView_->pepper_fullscreen_window()) { 2117 renderWidgetHostView_->pepper_fullscreen_window()) {
2116 RenderWidgetHostViewMac* parent = 2118 RenderWidgetHostViewMac* parent =
2117 renderWidgetHostView_->fullscreen_parent_host_view(); 2119 renderWidgetHostView_->fullscreen_parent_host_view();
2118 if (parent) 2120 if (parent)
2119 parent->cocoa_view()->suppressNextEscapeKeyUp_ = YES; 2121 parent->cocoa_view()->suppressNextEscapeKeyUp_ = YES;
(...skipping 19 matching lines...) Expand all
2139 // otherwise we might get an event from releasing the return key in the 2141 // otherwise we might get an event from releasing the return key in the
2140 // omnibox (http://crbug.com/338736). 2142 // omnibox (http://crbug.com/338736).
2141 if ([theEvent type] == NSKeyUp) { 2143 if ([theEvent type] == NSKeyUp) {
2142 auto numErased = keyDownCodes_.erase([theEvent keyCode]); 2144 auto numErased = keyDownCodes_.erase([theEvent keyCode]);
2143 if (numErased < 1) 2145 if (numErased < 1)
2144 return; 2146 return;
2145 } 2147 }
2146 2148
2147 // We only handle key down events and just simply forward other events. 2149 // We only handle key down events and just simply forward other events.
2148 if ([theEvent type] != NSKeyDown) { 2150 if ([theEvent type] != NSKeyDown) {
2149 widgetHost->ForwardKeyboardEvent(event); 2151 widgetHost->ForwardKeyboardEventWithLatencyInfo(event, latency_info);
2150 2152
2151 // Possibly autohide the cursor. 2153 // Possibly autohide the cursor.
2152 if ([self shouldAutohideCursorForEvent:theEvent]) 2154 if ([self shouldAutohideCursorForEvent:theEvent])
2153 [NSCursor setHiddenUntilMouseMoves:YES]; 2155 [NSCursor setHiddenUntilMouseMoves:YES];
2154 2156
2155 return; 2157 return;
2156 } 2158 }
2157 2159
2158 keyDownCodes_.insert([theEvent keyCode]); 2160 keyDownCodes_.insert([theEvent keyCode]);
2159 2161
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2194 // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY 2196 // To emulate Windows, over-write |event.windowsKeyCode| to VK_PROCESSKEY
2195 // while an input method is composing or inserting a text. 2197 // while an input method is composing or inserting a text.
2196 // Gmail checks this code in its onkeydown handler to stop auto-completing 2198 // Gmail checks this code in its onkeydown handler to stop auto-completing
2197 // e-mail addresses while composing a CJK text. 2199 // e-mail addresses while composing a CJK text.
2198 // If the text to be inserted has only one character, then we don't need this 2200 // If the text to be inserted has only one character, then we don't need this
2199 // trick, because we'll send the text as a key press event instead. 2201 // trick, because we'll send the text as a key press event instead.
2200 if (hasMarkedText_ || oldHasMarkedText || textToBeInserted_.length() > 1) { 2202 if (hasMarkedText_ || oldHasMarkedText || textToBeInserted_.length() > 1) {
2201 NativeWebKeyboardEvent fakeEvent = event; 2203 NativeWebKeyboardEvent fakeEvent = event;
2202 fakeEvent.windows_key_code = 0xE5; // VKEY_PROCESSKEY 2204 fakeEvent.windows_key_code = 0xE5; // VKEY_PROCESSKEY
2203 fakeEvent.skip_in_browser = true; 2205 fakeEvent.skip_in_browser = true;
2204 widgetHost->ForwardKeyboardEvent(fakeEvent); 2206 widgetHost->ForwardKeyboardEventWithLatencyInfo(fakeEvent, latency_info);
2205 // If this key event was handled by the input method, but 2207 // If this key event was handled by the input method, but
2206 // -doCommandBySelector: (invoked by the call to -interpretKeyEvents: above) 2208 // -doCommandBySelector: (invoked by the call to -interpretKeyEvents: above)
2207 // enqueued edit commands, then in order to let webkit handle them 2209 // enqueued edit commands, then in order to let webkit handle them
2208 // correctly, we need to send the real key event and corresponding edit 2210 // correctly, we need to send the real key event and corresponding edit
2209 // commands after processing the input method result. 2211 // commands after processing the input method result.
2210 // We shouldn't do this if a new marked text was set by the input method, 2212 // We shouldn't do this if a new marked text was set by the input method,
2211 // otherwise the new marked text might be cancelled by webkit. 2213 // otherwise the new marked text might be cancelled by webkit.
2212 if (hasEditCommands_ && !hasMarkedText_) 2214 if (hasEditCommands_ && !hasMarkedText_)
2213 delayEventUntilAfterImeCompostion = YES; 2215 delayEventUntilAfterImeCompostion = YES;
2214 } else { 2216 } else {
2215 widgetHost->ForwardKeyboardEventWithCommands(event, &editCommands_); 2217 widgetHost->ForwardKeyboardEventWithCommands(event, latency_info,
2218 &editCommands_);
2216 } 2219 }
2217 2220
2218 // Calling ForwardKeyboardEvent() could have destroyed the widget. When the 2221 // Calling ForwardKeyboardEventWithCommands() could have destroyed the
2219 // widget was destroyed, |renderWidgetHostView_->render_widget_host_| will 2222 // widget. When the widget was destroyed,
2220 // be set to NULL. So we check it here and return immediately if it's NULL. 2223 // |renderWidgetHostView_->render_widget_host_| will be set to NULL. So we
2224 // check it here and return immediately if it's NULL.
2221 if (!renderWidgetHostView_->render_widget_host_) 2225 if (!renderWidgetHostView_->render_widget_host_)
2222 return; 2226 return;
2223 2227
2224 // Then send keypress and/or composition related events. 2228 // Then send keypress and/or composition related events.
2225 // If there was a marked text or the text to be inserted is longer than 1 2229 // If there was a marked text or the text to be inserted is longer than 1
2226 // character, then we send the text by calling FinishComposingText(). 2230 // character, then we send the text by calling FinishComposingText().
2227 // Otherwise, if the text to be inserted only contains 1 character, then we 2231 // Otherwise, if the text to be inserted only contains 1 character, then we
2228 // can just send a keypress event which is fabricated by changing the type of 2232 // can just send a keypress event which is fabricated by changing the type of
2229 // the keydown event, so that we can retain all necessary informations, such 2233 // the keydown event, so that we can retain all necessary informations, such
2230 // as unmodifiedText, etc. And we need to set event.skip_in_browser to true to 2234 // as unmodifiedText, etc. And we need to set event.skip_in_browser to true to
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2269 // finish current composition session but still wants the application to 2273 // finish current composition session but still wants the application to
2270 // handle the key event. See http://crbug.com/48161 for reference. 2274 // handle the key event. See http://crbug.com/48161 for reference.
2271 if (delayEventUntilAfterImeCompostion) { 2275 if (delayEventUntilAfterImeCompostion) {
2272 // If |delayEventUntilAfterImeCompostion| is YES, then a fake key down event 2276 // If |delayEventUntilAfterImeCompostion| is YES, then a fake key down event
2273 // with windowsKeyCode == 0xE5 has already been sent to webkit. 2277 // with windowsKeyCode == 0xE5 has already been sent to webkit.
2274 // So before sending the real key down event, we need to send a fake key up 2278 // So before sending the real key down event, we need to send a fake key up
2275 // event to balance it. 2279 // event to balance it.
2276 NativeWebKeyboardEvent fakeEvent = event; 2280 NativeWebKeyboardEvent fakeEvent = event;
2277 fakeEvent.SetType(blink::WebInputEvent::kKeyUp); 2281 fakeEvent.SetType(blink::WebInputEvent::kKeyUp);
2278 fakeEvent.skip_in_browser = true; 2282 fakeEvent.skip_in_browser = true;
2279 widgetHost->ForwardKeyboardEvent(fakeEvent); 2283 widgetHost->ForwardKeyboardEventWithLatencyInfo(fakeEvent, latency_info);
2280 // Not checking |renderWidgetHostView_->render_widget_host_| here because 2284 // Not checking |renderWidgetHostView_->render_widget_host_| here because
2281 // a key event with |skip_in_browser| == true won't be handled by browser, 2285 // a key event with |skip_in_browser| == true won't be handled by browser,
2282 // thus it won't destroy the widget. 2286 // thus it won't destroy the widget.
2283 2287
2284 widgetHost->ForwardKeyboardEventWithCommands(event, &editCommands_); 2288 widgetHost->ForwardKeyboardEventWithCommands(event, latency_info,
2289 &editCommands_);
2285 2290
2286 // Calling ForwardKeyboardEvent() could have destroyed the widget. When the 2291 // Calling ForwardKeyboardEventWithCommands() could have destroyed the
2287 // widget was destroyed, |renderWidgetHostView_->render_widget_host_| will 2292 // widget. When the widget was destroyed,
2288 // be set to NULL. So we check it here and return immediately if it's NULL. 2293 // |renderWidgetHostView_->render_widget_host_| will be set to NULL. So we
2294 // check it here and return immediately if it's NULL.
2289 if (!renderWidgetHostView_->render_widget_host_) 2295 if (!renderWidgetHostView_->render_widget_host_)
2290 return; 2296 return;
2291 } 2297 }
2292 2298
2293 const NSUInteger kCtrlCmdKeyMask = NSControlKeyMask | NSCommandKeyMask; 2299 const NSUInteger kCtrlCmdKeyMask = NSControlKeyMask | NSCommandKeyMask;
2294 // Only send a corresponding key press event if there is no marked text. 2300 // Only send a corresponding key press event if there is no marked text.
2295 if (!hasMarkedText_) { 2301 if (!hasMarkedText_) {
2296 if (!textInserted && textToBeInserted_.length() == 1) { 2302 if (!textInserted && textToBeInserted_.length() == 1) {
2297 // If a single character was inserted, then we just send it as a keypress 2303 // If a single character was inserted, then we just send it as a keypress
2298 // event. 2304 // event.
2299 event.SetType(blink::WebInputEvent::kChar); 2305 event.SetType(blink::WebInputEvent::kChar);
2300 event.text[0] = textToBeInserted_[0]; 2306 event.text[0] = textToBeInserted_[0];
2301 event.text[1] = 0; 2307 event.text[1] = 0;
2302 event.skip_in_browser = true; 2308 event.skip_in_browser = true;
2303 widgetHost->ForwardKeyboardEvent(event); 2309 widgetHost->ForwardKeyboardEventWithLatencyInfo(event, latency_info);
2304 } else if ((!textInserted || delayEventUntilAfterImeCompostion) && 2310 } else if ((!textInserted || delayEventUntilAfterImeCompostion) &&
2305 event.text[0] != '\0' && 2311 event.text[0] != '\0' &&
2306 (([theEvent modifierFlags] & kCtrlCmdKeyMask) || 2312 (([theEvent modifierFlags] & kCtrlCmdKeyMask) ||
2307 (hasEditCommands_ && editCommands_.empty()))) { 2313 (hasEditCommands_ && editCommands_.empty()))) {
2308 // We don't get insertText: calls if ctrl or cmd is down, or the key event 2314 // We don't get insertText: calls if ctrl or cmd is down, or the key event
2309 // generates an insert command. So synthesize a keypress event for these 2315 // generates an insert command. So synthesize a keypress event for these
2310 // cases, unless the key event generated any other command. 2316 // cases, unless the key event generated any other command.
2311 event.SetType(blink::WebInputEvent::kChar); 2317 event.SetType(blink::WebInputEvent::kChar);
2312 event.skip_in_browser = true; 2318 event.skip_in_browser = true;
2313 widgetHost->ForwardKeyboardEvent(event); 2319 widgetHost->ForwardKeyboardEventWithLatencyInfo(event, latency_info);
2314 } 2320 }
2315 } 2321 }
2316 2322
2317 // Possibly autohide the cursor. 2323 // Possibly autohide the cursor.
2318 if ([self shouldAutohideCursorForEvent:theEvent]) 2324 if ([self shouldAutohideCursorForEvent:theEvent])
2319 [NSCursor setHiddenUntilMouseMoves:YES]; 2325 [NSCursor setHiddenUntilMouseMoves:YES];
2320 } 2326 }
2321 2327
2322 - (void)forceTouchEvent:(NSEvent*)theEvent { 2328 - (void)forceTouchEvent:(NSEvent*)theEvent {
2323 if (ui::ForceClickInvokesQuickLook()) 2329 if (ui::ForceClickInvokesQuickLook())
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after
3503 3509
3504 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding 3510 // "-webkit-app-region: drag | no-drag" is implemented on Mac by excluding
3505 // regions that are not draggable. (See ControlRegionView in 3511 // regions that are not draggable. (See ControlRegionView in
3506 // native_app_window_cocoa.mm). This requires the render host view to be 3512 // native_app_window_cocoa.mm). This requires the render host view to be
3507 // draggable by default. 3513 // draggable by default.
3508 - (BOOL)mouseDownCanMoveWindow { 3514 - (BOOL)mouseDownCanMoveWindow {
3509 return YES; 3515 return YES;
3510 } 3516 }
3511 3517
3512 @end 3518 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698