OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, | 96 popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, |
97 model_.get(), | 97 model_.get(), |
98 profile, | 98 profile, |
99 bubble_positioner)), | 99 bubble_positioner)), |
100 controller_(controller), | 100 controller_(controller), |
101 toolbar_model_(toolbar_model), | 101 toolbar_model_(toolbar_model), |
102 command_updater_(command_updater), | 102 command_updater_(command_updater), |
103 popup_window_mode_(popup_window_mode), | 103 popup_window_mode_(popup_window_mode), |
104 scheme_security_level_(ToolbarModel::NORMAL), | 104 scheme_security_level_(ToolbarModel::NORMAL), |
105 mark_set_handler_id_(0), | 105 mark_set_handler_id_(0), |
| 106 #if defined(OS_CHROMEOS) |
| 107 button_1_pressed_(false), |
| 108 text_selected_during_click_(false), |
| 109 text_view_focused_before_button_press_(false), |
| 110 #endif |
106 #if !defined(TOOLKIT_VIEWS) | 111 #if !defined(TOOLKIT_VIEWS) |
107 theme_provider_(GtkThemeProvider::GetFrom(profile)), | 112 theme_provider_(GtkThemeProvider::GetFrom(profile)), |
108 #endif | 113 #endif |
109 enter_was_pressed_(false), | 114 enter_was_pressed_(false), |
110 tab_was_pressed_(false), | 115 tab_was_pressed_(false), |
111 paste_clipboard_requested_(false), | 116 paste_clipboard_requested_(false), |
112 enter_was_inserted_(false) { | 117 enter_was_inserted_(false) { |
113 model_->SetPopupModel(popup_view_->GetModel()); | 118 model_->SetPopupModel(popup_view_->GetModel()); |
114 } | 119 } |
115 | 120 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 G_CALLBACK(&HandleBeginUserActionThunk), this); | 187 G_CALLBACK(&HandleBeginUserActionThunk), this); |
183 g_signal_connect(text_buffer_, "end-user-action", | 188 g_signal_connect(text_buffer_, "end-user-action", |
184 G_CALLBACK(&HandleEndUserActionThunk), this); | 189 G_CALLBACK(&HandleEndUserActionThunk), this); |
185 g_signal_connect(text_buffer_, "insert-text", | 190 g_signal_connect(text_buffer_, "insert-text", |
186 G_CALLBACK(&HandleInsertTextThunk), this); | 191 G_CALLBACK(&HandleInsertTextThunk), this); |
187 // We connect to key press and release for special handling of a few keys. | 192 // We connect to key press and release for special handling of a few keys. |
188 g_signal_connect(text_view_, "key-press-event", | 193 g_signal_connect(text_view_, "key-press-event", |
189 G_CALLBACK(&HandleKeyPressThunk), this); | 194 G_CALLBACK(&HandleKeyPressThunk), this); |
190 g_signal_connect(text_view_, "key-release-event", | 195 g_signal_connect(text_view_, "key-release-event", |
191 G_CALLBACK(&HandleKeyReleaseThunk), this); | 196 G_CALLBACK(&HandleKeyReleaseThunk), this); |
| 197 #if defined(OS_CHROMEOS) |
| 198 g_signal_connect(text_view_, "button-press-event", |
| 199 G_CALLBACK(&HandleViewButtonPressThunk), this); |
| 200 g_signal_connect(text_view_, "button-release-event", |
| 201 G_CALLBACK(&HandleViewButtonReleaseThunk), this); |
| 202 #endif |
192 g_signal_connect(text_view_, "focus-in-event", | 203 g_signal_connect(text_view_, "focus-in-event", |
193 G_CALLBACK(&HandleViewFocusInThunk), this); | 204 G_CALLBACK(&HandleViewFocusInThunk), this); |
194 g_signal_connect(text_view_, "focus-out-event", | 205 g_signal_connect(text_view_, "focus-out-event", |
195 G_CALLBACK(&HandleViewFocusOutThunk), this); | 206 G_CALLBACK(&HandleViewFocusOutThunk), this); |
196 // NOTE: The GtkTextView documentation asks you not to connect to this | 207 // NOTE: The GtkTextView documentation asks you not to connect to this |
197 // signal, but it is very convenient and clean for catching up/down. | 208 // signal, but it is very convenient and clean for catching up/down. |
198 g_signal_connect(text_view_, "move-cursor", | 209 g_signal_connect(text_view_, "move-cursor", |
199 G_CALLBACK(&HandleViewMoveCursorThunk), this); | 210 G_CALLBACK(&HandleViewMoveCursorThunk), this); |
200 g_signal_connect(text_view_, "move-focus", | 211 g_signal_connect(text_view_, "move-focus", |
201 G_CALLBACK(&HandleViewMoveFocusThunk), this); | 212 G_CALLBACK(&HandleViewMoveFocusThunk), this); |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 if (!(mod & GDK_CONTROL_MASK)) | 719 if (!(mod & GDK_CONTROL_MASK)) |
709 model_->OnControlKeyChanged(false); | 720 model_->OnControlKeyChanged(false); |
710 } | 721 } |
711 | 722 |
712 // Even though we handled the press ourselves, let GtkTextView handle the | 723 // Even though we handled the press ourselves, let GtkTextView handle the |
713 // release. It shouldn't do anything particularly interesting, but it will | 724 // release. It shouldn't do anything particularly interesting, but it will |
714 // handle the IME work for us. | 725 // handle the IME work for us. |
715 return FALSE; // Propagate into GtkTextView. | 726 return FALSE; // Propagate into GtkTextView. |
716 } | 727 } |
717 | 728 |
| 729 #if defined(OS_CHROMEOS) |
| 730 gboolean AutocompleteEditViewGtk::HandleViewButtonPress(GdkEventButton* event) { |
| 731 // We don't need to care about double and triple clicks. |
| 732 if (event->type != GDK_BUTTON_PRESS) |
| 733 return FALSE; |
| 734 |
| 735 if (event->button == 1) { |
| 736 // When the first button is pressed, track some stuff that will help us |
| 737 // determine whether we should select all of the text when the button is |
| 738 // released. |
| 739 button_1_pressed_ = true; |
| 740 text_view_focused_before_button_press_ = GTK_WIDGET_HAS_FOCUS(text_view_); |
| 741 text_selected_during_click_ = false; |
| 742 |
| 743 // Button press event may change the selection, we need to record the change |
| 744 // and report it to |model_| later when button is released. |
| 745 OnBeforePossibleChange(); |
| 746 } else if (event->button == 2) { |
| 747 // GtkTextView pastes PRIMARY selection with middle click. |
| 748 // We can't call model_->on_paste_replacing_all() here, because the actual |
| 749 // paste clipboard action may not be performed if the clipboard is empty. |
| 750 paste_clipboard_requested_ = true; |
| 751 } |
| 752 return FALSE; |
| 753 } |
| 754 |
| 755 gboolean AutocompleteEditViewGtk::HandleViewButtonRelease( |
| 756 GdkEventButton* event) { |
| 757 if (event->button != 1) |
| 758 return FALSE; |
| 759 |
| 760 button_1_pressed_ = false; |
| 761 |
| 762 // Call the GtkTextView default handler, ignoring the fact that it will |
| 763 // likely have told us to stop propagating. We want to handle selection. |
| 764 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_); |
| 765 klass->button_release_event(text_view_, event); |
| 766 |
| 767 if (!text_view_focused_before_button_press_ && !text_selected_during_click_) { |
| 768 // If this was a focusing click and the user didn't drag to highlight any |
| 769 // text, select the full input and update the PRIMARY selection. |
| 770 SelectAllInternal(false, true); |
| 771 |
| 772 // So we told the buffer where the cursor should be, but make sure to tell |
| 773 // the view so it can scroll it to be visible if needed. |
| 774 // NOTE: This function doesn't seem to like a count of 0, looking at the |
| 775 // code it will skip an important loop. Use -1 to achieve the same. |
| 776 GtkTextIter start, end; |
| 777 gtk_text_buffer_get_bounds(text_buffer_, &start, &end); |
| 778 gtk_text_view_move_visually(GTK_TEXT_VIEW(text_view_), &start, -1); |
| 779 } |
| 780 |
| 781 // Inform |model_| about possible text selection change. |
| 782 OnAfterPossibleChange(); |
| 783 |
| 784 return TRUE; // Don't continue, we called the default handler already. |
| 785 } |
| 786 #endif |
| 787 |
718 gboolean AutocompleteEditViewGtk::HandleViewFocusIn() { | 788 gboolean AutocompleteEditViewGtk::HandleViewFocusIn() { |
719 GdkModifierType modifiers; | 789 GdkModifierType modifiers; |
720 gdk_window_get_pointer(text_view_->window, NULL, NULL, &modifiers); | 790 gdk_window_get_pointer(text_view_->window, NULL, NULL, &modifiers); |
721 model_->OnSetFocus((modifiers & GDK_CONTROL_MASK) != 0); | 791 model_->OnSetFocus((modifiers & GDK_CONTROL_MASK) != 0); |
722 controller_->OnSetFocus(); | 792 controller_->OnSetFocus(); |
723 // TODO(deanm): Some keyword hit business, etc here. | 793 // TODO(deanm): Some keyword hit business, etc here. |
724 | 794 |
725 return FALSE; // Continue propagation. | 795 return FALSE; // Continue propagation. |
726 } | 796 } |
727 | 797 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
845 std::string new_selected_text; | 915 std::string new_selected_text; |
846 GtkTextIter start, end; | 916 GtkTextIter start, end; |
847 if (gtk_text_buffer_get_selection_bounds(text_buffer_, &start, &end)) { | 917 if (gtk_text_buffer_get_selection_bounds(text_buffer_, &start, &end)) { |
848 gchar* text = gtk_text_iter_get_text(&start, &end); | 918 gchar* text = gtk_text_iter_get_text(&start, &end); |
849 size_t text_len = strlen(text); | 919 size_t text_len = strlen(text); |
850 if (text_len) | 920 if (text_len) |
851 new_selected_text = std::string(text, text_len); | 921 new_selected_text = std::string(text, text_len); |
852 g_free(text); | 922 g_free(text); |
853 } | 923 } |
854 | 924 |
| 925 #if defined(OS_CHROMEOS) |
| 926 // If the user just selected some text with the mouse (or at least while the |
| 927 // mouse button was down), make sure that we won't blow their selection away |
| 928 // later by selecting all of the text when the button is released. |
| 929 if (button_1_pressed_ && !new_selected_text.empty()) |
| 930 text_selected_during_click_ = true; |
| 931 #endif |
| 932 |
855 // If we had some text selected earlier but it's no longer highlighted, we | 933 // If we had some text selected earlier but it's no longer highlighted, we |
856 // might need to save it now... | 934 // might need to save it now... |
857 if (!selected_text_.empty() && new_selected_text.empty()) { | 935 if (!selected_text_.empty() && new_selected_text.empty()) { |
858 // ... but only if we currently own the selection. We want to manually | 936 // ... but only if we currently own the selection. We want to manually |
859 // update the selection when the text is unhighlighted because the user | 937 // update the selection when the text is unhighlighted because the user |
860 // clicked in a blank area of the text view, but not when it's unhighlighted | 938 // clicked in a blank area of the text view, but not when it's unhighlighted |
861 // because another client or widget took the selection. (This handler gets | 939 // because another client or widget took the selection. (This handler gets |
862 // called before the default handler, so as long as nobody else took the | 940 // called before the default handler, so as long as nobody else took the |
863 // selection, the text buffer still owns it even if GTK is about to take it | 941 // selection, the text buffer still owns it even if GTK is about to take it |
864 // away in the default handler.) | 942 // away in the default handler.) |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1207 std::string utf8 = WideToUTF8(text); | 1285 std::string utf8 = WideToUTF8(text); |
1208 gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length()); | 1286 gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length()); |
1209 SetSelectedRange(range); | 1287 SetSelectedRange(range); |
1210 } | 1288 } |
1211 | 1289 |
1212 void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) { | 1290 void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) { |
1213 GtkTextIter insert, bound; | 1291 GtkTextIter insert, bound; |
1214 ItersFromCharRange(range, &bound, &insert); | 1292 ItersFromCharRange(range, &bound, &insert); |
1215 gtk_text_buffer_select_range(text_buffer_, &insert, &bound); | 1293 gtk_text_buffer_select_range(text_buffer_, &insert, &bound); |
1216 } | 1294 } |
OLD | NEW |