diff options
author | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-28 06:37:20 +0000 |
---|---|---|
committer | yusukes@google.com <yusukes@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-28 06:37:20 +0000 |
commit | f5f980ee5418ff27ba44892521b9ef2447d336d4 (patch) | |
tree | 8cbf09f73552a66987b81498dfdae03f5936cf25 | |
parent | 57cb0f76bceab5f05f3d14a23e764795b476f3d3 (diff) | |
download | chromium_src-f5f980ee5418ff27ba44892521b9ef2447d336d4.zip chromium_src-f5f980ee5418ff27ba44892521b9ef2447d336d4.tar.gz chromium_src-f5f980ee5418ff27ba44892521b9ef2447d336d4.tar.bz2 |
Do not hide the popup |frame_| when a mouse is pressed.
In the following scenario, it seems that the popup window does not release mouse/keyboard grab even after it gets hidden.
1. create a popup window by:
views::Widget::CreatePopupWidget(
views::Widget::NotTransparent,
views::Widget::AcceptEvents,
views::Widget::DeleteOnDestroy,
views::Widget::MirrorOriginInRTL)
2. press a mouse button on the window.
3. before releasing the mouse button, Hide() the window.
4. release the button.
We have to submit this change before submitting http://codereview.chromium.org/6259019/ because if we embed IME candidate window into Chrome, the window sometimes gets hidden before mouse button is released for unknown reasons (I'll file a separate bug for the issue.)
BUG=chromium-os:11191
TEST=manually checked that Chrome can receive keyboard/mouse events after clicking IME candidate window. Did the test both on Omnibox and web content area.
Review URL: http://codereview.chromium.org/6270008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72932 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/chromeos/input_method/candidate_window.cc | 74 |
1 files changed, 70 insertions, 4 deletions
diff --git a/chrome/browser/chromeos/input_method/candidate_window.cc b/chrome/browser/chromeos/input_method/candidate_window.cc index cf437f7..fb96d70 100644 --- a/chrome/browser/chromeos/input_method/candidate_window.cc +++ b/chrome/browser/chromeos/input_method/candidate_window.cc @@ -347,6 +347,9 @@ class CandidateWindowView : public views::View { // Commits the candidate currently being selected. void CommitCandidate(); + // Hides the lookup table. + void HideLookupTable(); + // Hides the auxiliary text. void HideAuxiliaryText(); @@ -403,6 +406,13 @@ class CandidateWindowView : public views::View { // Returns 0 if no candidate is present. int GetHorizontalOffset(); + // A function to be called when one of the |candidate_views_| receives a mouse + // press event. + void OnMousePressed(); + // A function to be called when one of the |candidate_views_| receives a mouse + // release event. + void OnMouseReleased(); + void set_cursor_location(const gfx::Rect& cursor_location) { cursor_location_ = cursor_location; } @@ -475,6 +485,9 @@ class CandidateWindowView : public views::View { // The last cursor location. gfx::Rect cursor_location_; + + // true if a mouse button is pressed, and is not yet released. + bool mouse_is_pressed_; }; // CandidateRow renderes a row of a candidate. @@ -704,6 +717,7 @@ gfx::Point CandidateView::GetCandidateLabelPosition() const { } bool CandidateView::OnMousePressed(const views::MouseEvent& event) { + parent_candidate_window_->OnMousePressed(); // Select the candidate. We'll commit the candidate when the mouse // button is released. parent_candidate_window_->SelectCandidateAt(index_in_page_); @@ -727,6 +741,7 @@ void CandidateView::OnMouseReleased(const views::MouseEvent& event, if (!canceled) { parent_candidate_window_->CommitCandidate(); } + parent_candidate_window_->OnMouseReleased(); } CandidateWindowView::CandidateWindowView( @@ -740,8 +755,8 @@ CandidateWindowView::CandidateWindowView( footer_label_(NULL), previous_shortcut_column_width_(0), previous_candidate_column_width_(0), - previous_annotation_column_width_(0) { - + previous_annotation_column_width_(0), + mouse_is_pressed_(false) { SetNotifyWhenVisibleBoundsInRootChanges(true); } @@ -778,6 +793,57 @@ void CandidateWindowView::Init() { layout->AddView(footer_area_); // |footer_area_| is owned by |this|. } +void CandidateWindowView::HideLookupTable() { + if (!mouse_is_pressed_) { + parent_frame_->Hide(); + return; + } + + // We should not hide the |frame_| when a mouse is pressed, so we don't run + // into issues below. + // + // First, in the following scenario, it seems that the Views popup window does + // not release mouse/keyboard grab even after it gets hidden. + // + // 1. create a popup window by views::Widget::CreatePopupWidget() with the + // views::Widget::AcceptEvents flag. + // 2. press a mouse button on the window. + // 3. before releasing the mouse button, Hide() the window. + // 4. release the button. + // + // And if we embed IME candidate window into Chrome, the window sometimes + // receives an extra 'hide-lookup-table' event before mouse button is + // released: + // + // 1. the candidate window is clicked. + // 2. The mouse click handler in this file, OnMousePressed() in CandidateView, + // is called, and the handler consumes the event by returning true. + // 3. HOWEVER, if the candidate window is embedded into Chrome, the event is + // also sent to Chrome! (problem #1) + // 4. im-ibus.so in Chrome sends 'focus-out' event to ibus-daemon. + // 5. ibus-daemon sends 'hide-lookup-table' event to the candidate window. + // 6. the window is hidden, but the window does not release mouse/keyboard + // grab! (problem #2) + // 7. mouse button is released. + // 8. now all mouse/keyboard events are consumed by the hidden popup, and are + // not sent to Chrome. + // + // TODO(yusukes): investigate why the click event is sent to both candidate + // window and Chrome. http://crosbug.com/11423 + // TODO(yusukes): investigate if we could fix Views so it always releases grab + // when a popup window gets hidden. http://crosbug.com/11422 + // + LOG(WARNING) << "Can't hide the table since a mouse button is not released."; +} + +void CandidateWindowView::OnMousePressed() { + mouse_is_pressed_ = true; +} + +void CandidateWindowView::OnMouseReleased() { + mouse_is_pressed_ = false; +} + void CandidateWindowView::HideAuxiliaryText() { views::View* target_area = ( lookup_table_.orientation == InputMethodLookupTable::kHorizontal ? @@ -1267,7 +1333,7 @@ void CandidateWindowController::Impl::OnHideLookupTable( CandidateWindowController::Impl* controller = static_cast<CandidateWindowController::Impl*>(input_method_library); - controller->frame_->Hide(); + controller->candidate_window_->HideLookupTable(); } void CandidateWindowController::Impl::OnSetCursorLocation( @@ -1321,7 +1387,7 @@ void CandidateWindowController::Impl::OnUpdateLookupTable( // If it's not visible, hide the window and return. if (!lookup_table.visible) { - controller->frame_->Hide(); + controller->candidate_window_->HideLookupTable(); return; } |