Index: content/browser/renderer_host/render_widget_host.cc |
diff --git a/content/browser/renderer_host/render_widget_host.cc b/content/browser/renderer_host/render_widget_host.cc |
index f006033c70433f0ed6365ca63cb2c188f76b2456..bfc5ce81292d632f1fcecfaf079570056cde7cfd 100644 |
--- a/content/browser/renderer_host/render_widget_host.cc |
+++ b/content/browser/renderer_host/render_widget_host.cc |
@@ -102,8 +102,7 @@ RenderWidgetHost::RenderWidgetHost(content::RenderProcessHost* process, |
text_direction_updated_(false), |
text_direction_(WebKit::WebTextDirectionLeftToRight), |
text_direction_canceled_(false), |
- suppress_incoming_char_events_(false), |
- suppress_outgoing_char_events_(false), |
+ suppress_next_char_events_(false), |
pending_mouse_lock_request_(false), |
ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
if (routing_id_ == MSG_ROUTING_NONE) |
@@ -576,7 +575,7 @@ void RenderWidgetHost::ForwardMouseEvent(const WebMouseEvent& mouse_event) { |
OnUserGesture(); |
} |
- ForwardInputEvent(mouse_event, sizeof(WebMouseEvent)); |
+ ForwardInputEvent(mouse_event, sizeof(WebMouseEvent), false); |
} |
void RenderWidgetHost::OnMouseActivate() { |
@@ -614,7 +613,7 @@ void RenderWidgetHost::ForwardWheelEvent( |
HISTOGRAM_COUNTS_100("MPArch.RWH_WheelQueueSize", |
coalesced_mouse_wheel_events_.size()); |
- ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent)); |
+ ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent), false); |
} |
void RenderWidgetHost::ForwardGestureEvent( |
@@ -623,7 +622,7 @@ void RenderWidgetHost::ForwardGestureEvent( |
if (ignore_input_events_ || process_->IgnoreInputEvents()) |
return; |
- ForwardInputEvent(gesture_event, sizeof(WebGestureEvent)); |
+ ForwardInputEvent(gesture_event, sizeof(WebGestureEvent), false); |
} |
void RenderWidgetHost::ForwardKeyboardEvent( |
@@ -632,84 +631,64 @@ void RenderWidgetHost::ForwardKeyboardEvent( |
if (ignore_input_events_ || process_->IgnoreInputEvents()) |
return; |
- // Double check the type to make sure caller hasn't sent us nonsense that |
- // will mess up our key queue. |
- if (!WebInputEvent::isKeyboardEventType(key_event.type)) |
- return; |
- |
if (key_event.type == WebKeyboardEvent::Char && |
(key_event.windowsKeyCode == ui::VKEY_RETURN || |
key_event.windowsKeyCode == ui::VKEY_SPACE)) { |
OnUserGesture(); |
} |
- if (suppress_incoming_char_events_) { |
- // If the preceding RawKeyDown event was handled by the browser, then we |
- // need to suppress all Char events generated by it. Please note that, one |
- // RawKeyDown event may generate multiple Char events, so we can't reset |
- // |suppress_incoming_char_events_| until we get a KeyUp or a RawKeyDown. |
- if (key_event.type == WebKeyboardEvent::Char) |
- return; |
- // We get a KeyUp or a RawKeyDown event. |
- suppress_incoming_char_events_ = false; |
- } |
- |
- bool is_keyboard_shortcut = false; |
- // Only pre-handle the key event if it's not handled by the input method. |
- if (!key_event.skip_in_browser) { |
- // We need to set |suppress_incoming_char_events_| to true if |
- // PreHandleKeyboardEvent() returns true, but |this| may already be |
- // destroyed at that time. So set |suppress_incoming_char_events_| true |
- // here, then revert it afterwards when necessary. |
- if (key_event.type == WebKeyboardEvent::RawKeyDown) |
- suppress_incoming_char_events_ = true; |
- |
- // Tab switching/closing accelerators aren't sent to the renderer to avoid |
- // a hung/malicious renderer from interfering. |
- if (PreHandleKeyboardEvent(key_event, &is_keyboard_shortcut)) |
- return; |
- |
- if (key_event.type == WebKeyboardEvent::RawKeyDown) |
- suppress_incoming_char_events_ = false; |
- } |
- |
- // Don't add this key to the queue if we have no way to send the message... |
- if (!process_->HasConnection()) |
- return; |
- |
- bool has_pending_key = !key_queue_.empty(); |
- |
- // We keep track of all pending keyboard events so that if any are not |
- // processed by the renderer, we have the ability to process them in the |
- // browser (via UnhandledKeyboardEvent). We also delay sending the next |
- // keyboard event until the previous has been ACK'd by the renderer. |
- key_queue_.push_back(Key(key_event, is_keyboard_shortcut)); |
- HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); |
+ // Double check the type to make sure caller hasn't sent us nonsense that |
+ // will mess up our key queue. |
+ if (WebInputEvent::isKeyboardEventType(key_event.type)) { |
+ if (suppress_next_char_events_) { |
+ // If preceding RawKeyDown event was handled by the browser, then we need |
+ // suppress all Char events generated by it. Please note that, one |
+ // RawKeyDown event may generate multiple Char events, so we can't reset |
+ // |suppress_next_char_events_| until we get a KeyUp or a RawKeyDown. |
+ if (key_event.type == WebKeyboardEvent::Char) |
+ return; |
+ // We get a KeyUp or a RawKeyDown event. |
+ suppress_next_char_events_ = false; |
+ } |
- if (!has_pending_key) |
- ForwardNextKeyboardEvent(); |
-} |
+ bool is_keyboard_shortcut = false; |
+ // Only pre-handle the key event if it's not handled by the input method. |
+ if (!key_event.skip_in_browser) { |
+ // We need to set |suppress_next_char_events_| to true if |
+ // PreHandleKeyboardEvent() returns true, but |this| may already be |
+ // destroyed at that time. So set |suppress_next_char_events_| true here, |
+ // then revert it afterwards when necessary. |
+ if (key_event.type == WebKeyboardEvent::RawKeyDown) |
+ suppress_next_char_events_ = true; |
+ |
+ // Tab switching/closing accelerators aren't sent to the renderer to avoid |
+ // a hung/malicious renderer from interfering. |
+ if (PreHandleKeyboardEvent(key_event, &is_keyboard_shortcut)) |
+ return; |
+ |
+ if (key_event.type == WebKeyboardEvent::RawKeyDown) |
+ suppress_next_char_events_ = false; |
+ } |
-void RenderWidgetHost::ForwardNextKeyboardEvent() { |
- while (!key_queue_.empty()) { |
- const Key& front_item = key_queue_.front(); |
+ // Don't add this key to the queue if we have no way to send the message... |
+ if (!process_->HasConnection()) |
+ return; |
- if (suppress_outgoing_char_events_) { |
- if (front_item.event.type == WebInputEvent::Char) { |
- key_queue_.pop_front(); |
- continue; |
- } |
- suppress_outgoing_char_events_ = false; |
- } |
+ // Put all WebKeyboardEvent objects in a queue since we can't trust the |
+ // renderer and we need to give something to the UnhandledInputEvent |
+ // handler. |
+ key_queue_.push_back(key_event); |
+ HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size()); |
- // The renderer only cares about the platform-independent event data. |
- ForwardInputEvent(front_item.event, sizeof(WebKeyboardEvent)); |
- break; |
+ // Only forward the non-native portions of our event. |
+ ForwardInputEvent(key_event, sizeof(WebKeyboardEvent), |
+ is_keyboard_shortcut); |
} |
} |
void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, |
- int event_size) { |
+ int event_size, |
+ bool is_keyboard_shortcut) { |
TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardInputEvent"); |
if (!process_->HasConnection()) |
@@ -720,6 +699,9 @@ void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, |
IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); |
message->WriteData( |
reinterpret_cast<const char*>(&input_event), event_size); |
+ // |is_keyboard_shortcut| only makes sense for RawKeyDown events. |
+ if (input_event.type == WebInputEvent::RawKeyDown) |
+ message->WriteBool(is_keyboard_shortcut); |
input_event_start_time_ = TimeTicks::Now(); |
Send(message); |
@@ -752,7 +734,7 @@ void RenderWidgetHost::ForwardTouchEvent( |
touch_move_pending_ = true; |
else |
touch_move_pending_ = false; |
- ForwardInputEvent(touch_event, sizeof(WebKit::WebTouchEvent)); |
+ ForwardInputEvent(touch_event, sizeof(WebKit::WebTouchEvent), false); |
} |
void RenderWidgetHost::RendererExited(base::TerminationStatus status, |
@@ -772,8 +754,7 @@ void RenderWidgetHost::RendererExited(base::TerminationStatus status, |
// Must reset these to ensure that keyboard events work with a new renderer. |
key_queue_.clear(); |
- suppress_incoming_char_events_ = false; |
- suppress_outgoing_char_events_ = false; |
+ suppress_next_char_events_ = false; |
// Reset some fields in preparation for recovering from a crash. |
resize_ack_pending_ = false; |
@@ -1363,40 +1344,29 @@ void RenderWidgetHost::ProcessKeyboardEventAck(int type, bool processed) { |
if (key_queue_.empty()) { |
LOG(ERROR) << "Got a KeyEvent back from the renderer but we " |
<< "don't seem to have sent it to the renderer!"; |
- } else if (key_queue_.front().event.type != type) { |
+ } else if (key_queue_.front().type != type) { |
LOG(ERROR) << "We seem to have a different key type sent from " |
- << "the renderer. (" << key_queue_.front().event.type << " vs. " |
+ << "the renderer. (" << key_queue_.front().type << " vs. " |
<< type << "). Ignoring event."; |
// Something must be wrong. Clear the |key_queue_| and |
- // |suppress_incoming_char_events_| so that we can resume from the error. |
+ // |suppress_next_char_events_| so that we can resume from the error. |
key_queue_.clear(); |
- suppress_incoming_char_events_ = false; |
- suppress_outgoing_char_events_ = false; |
+ suppress_next_char_events_ = false; |
} else { |
- Key front_item = key_queue_.front(); |
+ NativeWebKeyboardEvent front_item = key_queue_.front(); |
key_queue_.pop_front(); |
#if defined(OS_MACOSX) |
- if (!is_hidden_ && view_->PostProcessEventForPluginIme(front_item.event)) |
+ if (!is_hidden_ && view_->PostProcessEventForPluginIme(front_item)) |
return; |
#endif |
- // If this RawKeyDown event corresponds to a browser keyboard shortcut and |
- // it's not processed by the renderer, then we need to suppress the |
- // upcoming Char event. |
- if (!processed && front_item.is_shortcut) { |
- DCHECK(front_item.event.type == WebInputEvent::RawKeyDown); |
- suppress_outgoing_char_events_ = true; |
- } |
- |
- ForwardNextKeyboardEvent(); |
- |
// We only send unprocessed key event upwards if we are not hidden, |
// because the user has moved away from us and no longer expect any effect |
// of this key event. |
- if (!processed && !is_hidden_ && !front_item.event.skip_in_browser) { |
- UnhandledKeyboardEvent(front_item.event); |
+ if (!processed && !is_hidden_ && !front_item.skip_in_browser) { |
+ UnhandledKeyboardEvent(front_item); |
// WARNING: This RenderWidgetHost can be deallocated at this point |
// (i.e. in the case of Ctrl+W, where the call to |