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

Side by Side Diff: content/browser/renderer_host/render_widget_host.cc

Issue 8885009: Revert r112160 ("Send one WebKeyboardEvent to the RenderWidget at a time.") (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years 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 | Annotate | Revision Log
« no previous file with comments | « content/browser/renderer_host/render_widget_host.h ('k') | content/common/view_messages.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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.h" 5 #include "content/browser/renderer_host/render_widget_host.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 touch_move_pending_(false), 95 touch_move_pending_(false),
96 touch_event_is_queued_(false), 96 touch_event_is_queued_(false),
97 needs_repainting_on_restore_(false), 97 needs_repainting_on_restore_(false),
98 is_unresponsive_(false), 98 is_unresponsive_(false),
99 in_get_backing_store_(false), 99 in_get_backing_store_(false),
100 view_being_painted_(false), 100 view_being_painted_(false),
101 ignore_input_events_(false), 101 ignore_input_events_(false),
102 text_direction_updated_(false), 102 text_direction_updated_(false),
103 text_direction_(WebKit::WebTextDirectionLeftToRight), 103 text_direction_(WebKit::WebTextDirectionLeftToRight),
104 text_direction_canceled_(false), 104 text_direction_canceled_(false),
105 suppress_incoming_char_events_(false), 105 suppress_next_char_events_(false),
106 suppress_outgoing_char_events_(false),
107 pending_mouse_lock_request_(false), 106 pending_mouse_lock_request_(false),
108 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 107 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
109 if (routing_id_ == MSG_ROUTING_NONE) 108 if (routing_id_ == MSG_ROUTING_NONE)
110 routing_id_ = process_->GetNextRoutingID(); 109 routing_id_ = process_->GetNextRoutingID();
111 110
112 process_->Attach(this, routing_id_); 111 process_->Attach(this, routing_id_);
113 // Because the widget initializes as is_hidden_ == false, 112 // Because the widget initializes as is_hidden_ == false,
114 // tell the process host that we're alive. 113 // tell the process host that we're alive.
115 process_->WidgetRestored(); 114 process_->WidgetRestored();
116 115
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 next_mouse_move_->movementX += x; 568 next_mouse_move_->movementX += x;
570 next_mouse_move_->movementY += y; 569 next_mouse_move_->movementY += y;
571 } 570 }
572 return; 571 return;
573 } 572 }
574 mouse_move_pending_ = true; 573 mouse_move_pending_ = true;
575 } else if (mouse_event.type == WebInputEvent::MouseDown) { 574 } else if (mouse_event.type == WebInputEvent::MouseDown) {
576 OnUserGesture(); 575 OnUserGesture();
577 } 576 }
578 577
579 ForwardInputEvent(mouse_event, sizeof(WebMouseEvent)); 578 ForwardInputEvent(mouse_event, sizeof(WebMouseEvent), false);
580 } 579 }
581 580
582 void RenderWidgetHost::OnMouseActivate() { 581 void RenderWidgetHost::OnMouseActivate() {
583 } 582 }
584 583
585 void RenderWidgetHost::ForwardWheelEvent( 584 void RenderWidgetHost::ForwardWheelEvent(
586 const WebMouseWheelEvent& wheel_event) { 585 const WebMouseWheelEvent& wheel_event) {
587 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardWheelEvent"); 586 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardWheelEvent");
588 if (ignore_input_events_ || process_->IgnoreInputEvents()) 587 if (ignore_input_events_ || process_->IgnoreInputEvents())
589 return; 588 return;
(...skipping 17 matching lines...) Expand all
607 last_wheel_event->timeStampSeconds = wheel_event.timeStampSeconds; 606 last_wheel_event->timeStampSeconds = wheel_event.timeStampSeconds;
608 } 607 }
609 return; 608 return;
610 } 609 }
611 mouse_wheel_pending_ = true; 610 mouse_wheel_pending_ = true;
612 current_wheel_event_ = wheel_event; 611 current_wheel_event_ = wheel_event;
613 612
614 HISTOGRAM_COUNTS_100("MPArch.RWH_WheelQueueSize", 613 HISTOGRAM_COUNTS_100("MPArch.RWH_WheelQueueSize",
615 coalesced_mouse_wheel_events_.size()); 614 coalesced_mouse_wheel_events_.size());
616 615
617 ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent)); 616 ForwardInputEvent(wheel_event, sizeof(WebMouseWheelEvent), false);
618 } 617 }
619 618
620 void RenderWidgetHost::ForwardGestureEvent( 619 void RenderWidgetHost::ForwardGestureEvent(
621 const WebKit::WebGestureEvent& gesture_event) { 620 const WebKit::WebGestureEvent& gesture_event) {
622 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardWheelEvent"); 621 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardWheelEvent");
623 if (ignore_input_events_ || process_->IgnoreInputEvents()) 622 if (ignore_input_events_ || process_->IgnoreInputEvents())
624 return; 623 return;
625 624
626 ForwardInputEvent(gesture_event, sizeof(WebGestureEvent)); 625 ForwardInputEvent(gesture_event, sizeof(WebGestureEvent), false);
627 } 626 }
628 627
629 void RenderWidgetHost::ForwardKeyboardEvent( 628 void RenderWidgetHost::ForwardKeyboardEvent(
630 const NativeWebKeyboardEvent& key_event) { 629 const NativeWebKeyboardEvent& key_event) {
631 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardKeyboardEvent"); 630 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardKeyboardEvent");
632 if (ignore_input_events_ || process_->IgnoreInputEvents()) 631 if (ignore_input_events_ || process_->IgnoreInputEvents())
633 return; 632 return;
634 633
635 // Double check the type to make sure caller hasn't sent us nonsense that
636 // will mess up our key queue.
637 if (!WebInputEvent::isKeyboardEventType(key_event.type))
638 return;
639
640 if (key_event.type == WebKeyboardEvent::Char && 634 if (key_event.type == WebKeyboardEvent::Char &&
641 (key_event.windowsKeyCode == ui::VKEY_RETURN || 635 (key_event.windowsKeyCode == ui::VKEY_RETURN ||
642 key_event.windowsKeyCode == ui::VKEY_SPACE)) { 636 key_event.windowsKeyCode == ui::VKEY_SPACE)) {
643 OnUserGesture(); 637 OnUserGesture();
644 } 638 }
645 639
646 if (suppress_incoming_char_events_) { 640 // Double check the type to make sure caller hasn't sent us nonsense that
647 // If the preceding RawKeyDown event was handled by the browser, then we 641 // will mess up our key queue.
648 // need to suppress all Char events generated by it. Please note that, one 642 if (WebInputEvent::isKeyboardEventType(key_event.type)) {
649 // RawKeyDown event may generate multiple Char events, so we can't reset 643 if (suppress_next_char_events_) {
650 // |suppress_incoming_char_events_| until we get a KeyUp or a RawKeyDown. 644 // If preceding RawKeyDown event was handled by the browser, then we need
651 if (key_event.type == WebKeyboardEvent::Char) 645 // suppress all Char events generated by it. Please note that, one
652 return; 646 // RawKeyDown event may generate multiple Char events, so we can't reset
653 // We get a KeyUp or a RawKeyDown event. 647 // |suppress_next_char_events_| until we get a KeyUp or a RawKeyDown.
654 suppress_incoming_char_events_ = false; 648 if (key_event.type == WebKeyboardEvent::Char)
655 } 649 return;
650 // We get a KeyUp or a RawKeyDown event.
651 suppress_next_char_events_ = false;
652 }
656 653
657 bool is_keyboard_shortcut = false; 654 bool is_keyboard_shortcut = false;
658 // Only pre-handle the key event if it's not handled by the input method. 655 // Only pre-handle the key event if it's not handled by the input method.
659 if (!key_event.skip_in_browser) { 656 if (!key_event.skip_in_browser) {
660 // We need to set |suppress_incoming_char_events_| to true if 657 // We need to set |suppress_next_char_events_| to true if
661 // PreHandleKeyboardEvent() returns true, but |this| may already be 658 // PreHandleKeyboardEvent() returns true, but |this| may already be
662 // destroyed at that time. So set |suppress_incoming_char_events_| true 659 // destroyed at that time. So set |suppress_next_char_events_| true here,
663 // here, then revert it afterwards when necessary. 660 // then revert it afterwards when necessary.
664 if (key_event.type == WebKeyboardEvent::RawKeyDown) 661 if (key_event.type == WebKeyboardEvent::RawKeyDown)
665 suppress_incoming_char_events_ = true; 662 suppress_next_char_events_ = true;
666 663
667 // Tab switching/closing accelerators aren't sent to the renderer to avoid 664 // Tab switching/closing accelerators aren't sent to the renderer to avoid
668 // a hung/malicious renderer from interfering. 665 // a hung/malicious renderer from interfering.
669 if (PreHandleKeyboardEvent(key_event, &is_keyboard_shortcut)) 666 if (PreHandleKeyboardEvent(key_event, &is_keyboard_shortcut))
667 return;
668
669 if (key_event.type == WebKeyboardEvent::RawKeyDown)
670 suppress_next_char_events_ = false;
671 }
672
673 // Don't add this key to the queue if we have no way to send the message...
674 if (!process_->HasConnection())
670 return; 675 return;
671 676
672 if (key_event.type == WebKeyboardEvent::RawKeyDown) 677 // Put all WebKeyboardEvent objects in a queue since we can't trust the
673 suppress_incoming_char_events_ = false; 678 // renderer and we need to give something to the UnhandledInputEvent
674 } 679 // handler.
680 key_queue_.push_back(key_event);
681 HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size());
675 682
676 // Don't add this key to the queue if we have no way to send the message... 683 // Only forward the non-native portions of our event.
677 if (!process_->HasConnection()) 684 ForwardInputEvent(key_event, sizeof(WebKeyboardEvent),
678 return; 685 is_keyboard_shortcut);
679
680 bool has_pending_key = !key_queue_.empty();
681
682 // We keep track of all pending keyboard events so that if any are not
683 // processed by the renderer, we have the ability to process them in the
684 // browser (via UnhandledKeyboardEvent). We also delay sending the next
685 // keyboard event until the previous has been ACK'd by the renderer.
686 key_queue_.push_back(Key(key_event, is_keyboard_shortcut));
687 HISTOGRAM_COUNTS_100("Renderer.KeyboardQueueSize", key_queue_.size());
688
689 if (!has_pending_key)
690 ForwardNextKeyboardEvent();
691 }
692
693 void RenderWidgetHost::ForwardNextKeyboardEvent() {
694 while (!key_queue_.empty()) {
695 const Key& front_item = key_queue_.front();
696
697 if (suppress_outgoing_char_events_) {
698 if (front_item.event.type == WebInputEvent::Char) {
699 key_queue_.pop_front();
700 continue;
701 }
702 suppress_outgoing_char_events_ = false;
703 }
704
705 // The renderer only cares about the platform-independent event data.
706 ForwardInputEvent(front_item.event, sizeof(WebKeyboardEvent));
707 break;
708 } 686 }
709 } 687 }
710 688
711 void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, 689 void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event,
712 int event_size) { 690 int event_size,
691 bool is_keyboard_shortcut) {
713 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardInputEvent"); 692 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardInputEvent");
714 693
715 if (!process_->HasConnection()) 694 if (!process_->HasConnection())
716 return; 695 return;
717 696
718 DCHECK(!process_->IgnoreInputEvents()); 697 DCHECK(!process_->IgnoreInputEvents());
719 698
720 IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_); 699 IPC::Message* message = new ViewMsg_HandleInputEvent(routing_id_);
721 message->WriteData( 700 message->WriteData(
722 reinterpret_cast<const char*>(&input_event), event_size); 701 reinterpret_cast<const char*>(&input_event), event_size);
702 // |is_keyboard_shortcut| only makes sense for RawKeyDown events.
703 if (input_event.type == WebInputEvent::RawKeyDown)
704 message->WriteBool(is_keyboard_shortcut);
723 input_event_start_time_ = TimeTicks::Now(); 705 input_event_start_time_ = TimeTicks::Now();
724 Send(message); 706 Send(message);
725 707
726 // Any non-wheel input event cancels pending wheel events. 708 // Any non-wheel input event cancels pending wheel events.
727 if (input_event.type != WebInputEvent::MouseWheel) 709 if (input_event.type != WebInputEvent::MouseWheel)
728 coalesced_mouse_wheel_events_.clear(); 710 coalesced_mouse_wheel_events_.clear();
729 711
730 // Any input event cancels a pending mouse move event. Note that 712 // Any input event cancels a pending mouse move event. Note that
731 // |next_mouse_move_| possibly owns |input_event|, so don't use |input_event| 713 // |next_mouse_move_| possibly owns |input_event|, so don't use |input_event|
732 // after this line. 714 // after this line.
(...skipping 12 matching lines...) Expand all
745 touch_move_pending_) { 727 touch_move_pending_) {
746 touch_event_is_queued_ = true; 728 touch_event_is_queued_ = true;
747 queued_touch_event_ = touch_event; 729 queued_touch_event_ = touch_event;
748 return; 730 return;
749 } 731 }
750 732
751 if (touch_event.type == WebInputEvent::TouchMove) 733 if (touch_event.type == WebInputEvent::TouchMove)
752 touch_move_pending_ = true; 734 touch_move_pending_ = true;
753 else 735 else
754 touch_move_pending_ = false; 736 touch_move_pending_ = false;
755 ForwardInputEvent(touch_event, sizeof(WebKit::WebTouchEvent)); 737 ForwardInputEvent(touch_event, sizeof(WebKit::WebTouchEvent), false);
756 } 738 }
757 739
758 void RenderWidgetHost::RendererExited(base::TerminationStatus status, 740 void RenderWidgetHost::RendererExited(base::TerminationStatus status,
759 int exit_code) { 741 int exit_code) {
760 // Clearing this flag causes us to re-create the renderer when recovering 742 // Clearing this flag causes us to re-create the renderer when recovering
761 // from a crashed renderer. 743 // from a crashed renderer.
762 renderer_initialized_ = false; 744 renderer_initialized_ = false;
763 745
764 // Must reset these to ensure that mouse move/wheel events work with a new 746 // Must reset these to ensure that mouse move/wheel events work with a new
765 // renderer. 747 // renderer.
766 mouse_move_pending_ = false; 748 mouse_move_pending_ = false;
767 next_mouse_move_.reset(); 749 next_mouse_move_.reset();
768 mouse_wheel_pending_ = false; 750 mouse_wheel_pending_ = false;
769 coalesced_mouse_wheel_events_.clear(); 751 coalesced_mouse_wheel_events_.clear();
770 touch_move_pending_ = false; 752 touch_move_pending_ = false;
771 touch_event_is_queued_ = false; 753 touch_event_is_queued_ = false;
772 754
773 // Must reset these to ensure that keyboard events work with a new renderer. 755 // Must reset these to ensure that keyboard events work with a new renderer.
774 key_queue_.clear(); 756 key_queue_.clear();
775 suppress_incoming_char_events_ = false; 757 suppress_next_char_events_ = false;
776 suppress_outgoing_char_events_ = false;
777 758
778 // Reset some fields in preparation for recovering from a crash. 759 // Reset some fields in preparation for recovering from a crash.
779 resize_ack_pending_ = false; 760 resize_ack_pending_ = false;
780 repaint_ack_pending_ = false; 761 repaint_ack_pending_ = false;
781 762
782 in_flight_size_.SetSize(0, 0); 763 in_flight_size_.SetSize(0, 0);
783 in_flight_reserved_rect_.SetRect(0, 0, 0, 0); 764 in_flight_reserved_rect_.SetRect(0, 0, 0, 0);
784 current_size_.SetSize(0, 0); 765 current_size_.SetSize(0, 0);
785 current_reserved_rect_.SetRect(0, 0, 0, 0); 766 current_reserved_rect_.SetRect(0, 0, 0, 0);
786 is_hidden_ = false; 767 is_hidden_ = false;
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1356 if (process_->HasConnection()) { 1337 if (process_->HasConnection()) {
1357 // Renderer accessibility wasn't enabled on process launch. Enable it now. 1338 // Renderer accessibility wasn't enabled on process launch. Enable it now.
1358 Send(new ViewMsg_EnableAccessibility(routing_id())); 1339 Send(new ViewMsg_EnableAccessibility(routing_id()));
1359 } 1340 }
1360 } 1341 }
1361 1342
1362 void RenderWidgetHost::ProcessKeyboardEventAck(int type, bool processed) { 1343 void RenderWidgetHost::ProcessKeyboardEventAck(int type, bool processed) {
1363 if (key_queue_.empty()) { 1344 if (key_queue_.empty()) {
1364 LOG(ERROR) << "Got a KeyEvent back from the renderer but we " 1345 LOG(ERROR) << "Got a KeyEvent back from the renderer but we "
1365 << "don't seem to have sent it to the renderer!"; 1346 << "don't seem to have sent it to the renderer!";
1366 } else if (key_queue_.front().event.type != type) { 1347 } else if (key_queue_.front().type != type) {
1367 LOG(ERROR) << "We seem to have a different key type sent from " 1348 LOG(ERROR) << "We seem to have a different key type sent from "
1368 << "the renderer. (" << key_queue_.front().event.type << " vs. " 1349 << "the renderer. (" << key_queue_.front().type << " vs. "
1369 << type << "). Ignoring event."; 1350 << type << "). Ignoring event.";
1370 1351
1371 // Something must be wrong. Clear the |key_queue_| and 1352 // Something must be wrong. Clear the |key_queue_| and
1372 // |suppress_incoming_char_events_| so that we can resume from the error. 1353 // |suppress_next_char_events_| so that we can resume from the error.
1373 key_queue_.clear(); 1354 key_queue_.clear();
1374 suppress_incoming_char_events_ = false; 1355 suppress_next_char_events_ = false;
1375 suppress_outgoing_char_events_ = false;
1376 } else { 1356 } else {
1377 Key front_item = key_queue_.front(); 1357 NativeWebKeyboardEvent front_item = key_queue_.front();
1378 key_queue_.pop_front(); 1358 key_queue_.pop_front();
1379 1359
1380 #if defined(OS_MACOSX) 1360 #if defined(OS_MACOSX)
1381 if (!is_hidden_ && view_->PostProcessEventForPluginIme(front_item.event)) 1361 if (!is_hidden_ && view_->PostProcessEventForPluginIme(front_item))
1382 return; 1362 return;
1383 #endif 1363 #endif
1384 1364
1385 // If this RawKeyDown event corresponds to a browser keyboard shortcut and
1386 // it's not processed by the renderer, then we need to suppress the
1387 // upcoming Char event.
1388 if (!processed && front_item.is_shortcut) {
1389 DCHECK(front_item.event.type == WebInputEvent::RawKeyDown);
1390 suppress_outgoing_char_events_ = true;
1391 }
1392
1393 ForwardNextKeyboardEvent();
1394
1395 // We only send unprocessed key event upwards if we are not hidden, 1365 // We only send unprocessed key event upwards if we are not hidden,
1396 // because the user has moved away from us and no longer expect any effect 1366 // because the user has moved away from us and no longer expect any effect
1397 // of this key event. 1367 // of this key event.
1398 if (!processed && !is_hidden_ && !front_item.event.skip_in_browser) { 1368 if (!processed && !is_hidden_ && !front_item.skip_in_browser) {
1399 UnhandledKeyboardEvent(front_item.event); 1369 UnhandledKeyboardEvent(front_item);
1400 1370
1401 // WARNING: This RenderWidgetHost can be deallocated at this point 1371 // WARNING: This RenderWidgetHost can be deallocated at this point
1402 // (i.e. in the case of Ctrl+W, where the call to 1372 // (i.e. in the case of Ctrl+W, where the call to
1403 // UnhandledKeyboardEvent destroys this RenderWidgetHost). 1373 // UnhandledKeyboardEvent destroys this RenderWidgetHost).
1404 } 1374 }
1405 } 1375 }
1406 } 1376 }
1407 1377
1408 void RenderWidgetHost::ActivateDeferredPluginHandles() { 1378 void RenderWidgetHost::ActivateDeferredPluginHandles() {
1409 #if !defined(USE_AURA) 1379 #if !defined(USE_AURA)
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 } 1520 }
1551 1521
1552 // static 1522 // static
1553 void RenderWidgetHost::AcknowledgePostSubBuffer(int32 route_id, 1523 void RenderWidgetHost::AcknowledgePostSubBuffer(int32 route_id,
1554 int gpu_host_id) { 1524 int gpu_host_id) {
1555 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id); 1525 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(gpu_host_id);
1556 if (ui_shim) 1526 if (ui_shim)
1557 ui_shim->Send(new AcceleratedSurfaceMsg_PostSubBufferACK(route_id)); 1527 ui_shim->Send(new AcceleratedSurfaceMsg_PostSubBufferACK(route_id));
1558 } 1528 }
1559 #endif 1529 #endif
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host.h ('k') | content/common/view_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698