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

Side by Side Diff: chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc

Issue 155971: Linux: Select omnibox text on button release instead of press. (Closed)
Patch Set: Created 11 years, 5 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
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.h ('k') | no next file » | 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) 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 "app/l10n_util.h" 10 #include "app/l10n_util.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 insecure_scheme_tag_(NULL), 79 insecure_scheme_tag_(NULL),
80 model_(new AutocompleteEditModel(this, controller, profile)), 80 model_(new AutocompleteEditModel(this, controller, profile)),
81 popup_view_(new AutocompletePopupViewGtk(this, model_.get(), profile, 81 popup_view_(new AutocompletePopupViewGtk(this, model_.get(), profile,
82 popup_positioner)), 82 popup_positioner)),
83 controller_(controller), 83 controller_(controller),
84 toolbar_model_(toolbar_model), 84 toolbar_model_(toolbar_model),
85 command_updater_(command_updater), 85 command_updater_(command_updater),
86 popup_window_mode_(false), // TODO(deanm) 86 popup_window_mode_(false), // TODO(deanm)
87 scheme_security_level_(ToolbarModel::NORMAL), 87 scheme_security_level_(ToolbarModel::NORMAL),
88 selection_saved_(false), 88 selection_saved_(false),
89 mark_set_handler_id_(0) { 89 mark_set_handler_id_(0),
90 button_1_pressed_(false),
91 text_selected_during_click_(false),
92 text_view_focused_before_button_press_(false) {
90 model_->set_popup_model(popup_view_->GetModel()); 93 model_->set_popup_model(popup_view_->GetModel());
91 } 94 }
92 95
93 AutocompleteEditViewGtk::~AutocompleteEditViewGtk() { 96 AutocompleteEditViewGtk::~AutocompleteEditViewGtk() {
94 NotificationService::current()->Notify( 97 NotificationService::current()->Notify(
95 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED, 98 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED,
96 Source<AutocompleteEditViewGtk>(this), 99 Source<AutocompleteEditViewGtk>(this),
97 NotificationService::NoDetails()); 100 NotificationService::NoDetails());
98 101
99 // Explicitly teardown members which have a reference to us. Just to be safe 102 // Explicitly teardown members which have a reference to us. Just to be safe
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 G_CALLBACK(&HandleBeginUserActionThunk), this); 159 G_CALLBACK(&HandleBeginUserActionThunk), this);
157 g_signal_connect(text_buffer_, "end-user-action", 160 g_signal_connect(text_buffer_, "end-user-action",
158 G_CALLBACK(&HandleEndUserActionThunk), this); 161 G_CALLBACK(&HandleEndUserActionThunk), this);
159 // We connect to key press and release for special handling of a few keys. 162 // We connect to key press and release for special handling of a few keys.
160 g_signal_connect(text_view_, "key-press-event", 163 g_signal_connect(text_view_, "key-press-event",
161 G_CALLBACK(&HandleKeyPressThunk), this); 164 G_CALLBACK(&HandleKeyPressThunk), this);
162 g_signal_connect(text_view_, "key-release-event", 165 g_signal_connect(text_view_, "key-release-event",
163 G_CALLBACK(&HandleKeyReleaseThunk), this); 166 G_CALLBACK(&HandleKeyReleaseThunk), this);
164 g_signal_connect(text_view_, "button-press-event", 167 g_signal_connect(text_view_, "button-press-event",
165 G_CALLBACK(&HandleViewButtonPressThunk), this); 168 G_CALLBACK(&HandleViewButtonPressThunk), this);
169 g_signal_connect(text_view_, "button-release-event",
170 G_CALLBACK(&HandleViewButtonReleaseThunk), this);
166 g_signal_connect(text_view_, "focus-in-event", 171 g_signal_connect(text_view_, "focus-in-event",
167 G_CALLBACK(&HandleViewFocusInThunk), this); 172 G_CALLBACK(&HandleViewFocusInThunk), this);
168 g_signal_connect(text_view_, "focus-out-event", 173 g_signal_connect(text_view_, "focus-out-event",
169 G_CALLBACK(&HandleViewFocusOutThunk), this); 174 G_CALLBACK(&HandleViewFocusOutThunk), this);
170 // NOTE: The GtkTextView documentation asks you not to connect to this 175 // NOTE: The GtkTextView documentation asks you not to connect to this
171 // signal, but it is very convenient and clean for catching up/down. 176 // signal, but it is very convenient and clean for catching up/down.
172 g_signal_connect(text_view_, "move-cursor", 177 g_signal_connect(text_view_, "move-cursor",
173 G_CALLBACK(&HandleViewMoveCursorThunk), this); 178 G_CALLBACK(&HandleViewMoveCursorThunk), this);
174 // Override the size request. We want to keep the original height request 179 // Override the size request. We want to keep the original height request
175 // from the widget, since that's font dependent. We want to ignore the width 180 // from the widget, since that's font dependent. We want to ignore the width
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 494
490 gboolean AutocompleteEditViewGtk::HandleKeyRelease(GtkWidget* widget, 495 gboolean AutocompleteEditViewGtk::HandleKeyRelease(GtkWidget* widget,
491 GdkEventKey* event) { 496 GdkEventKey* event) {
492 // Even though we handled the press ourselves, let GtkTextView handle the 497 // Even though we handled the press ourselves, let GtkTextView handle the
493 // release. It shouldn't do anything particularly interesting, but it will 498 // release. It shouldn't do anything particularly interesting, but it will
494 // handle the IME work for us. 499 // handle the IME work for us.
495 return FALSE; // Propagate into GtkTextView. 500 return FALSE; // Propagate into GtkTextView.
496 } 501 }
497 502
498 gboolean AutocompleteEditViewGtk::HandleViewButtonPress(GdkEventButton* event) { 503 gboolean AutocompleteEditViewGtk::HandleViewButtonPress(GdkEventButton* event) {
499 // When the GtkTextView is clicked, it will call gtk_widget_grab_focus. 504 if (event->button == 1) {
500 // I believe this causes the focus-in event to be fired before the main 505 // When the first button is pressed, track some stuff that will help us
501 // clicked handling code. If we were to try to set the selection from 506 // determine whether we should select all of the text when the button is
502 // the focus-in event, it's just going to be undone by the click handler. 507 // released.
503 // This is a bit ugly. We shim in to get the click before the GtkTextView, 508 button_1_pressed_ = true;
504 // then if we don't have focus, we (hopefully safely) assume that the click 509 text_view_focused_before_button_press_ = GTK_WIDGET_HAS_FOCUS(text_view_);
505 // will cause us to become focused. We call GtkTextView's default handler 510 text_selected_during_click_ = false;
506 // and then stop propagation. This allows us to run our code after the 511 }
507 // default handler, even if that handler stopped propagation. 512 return FALSE;
508 if (GTK_WIDGET_HAS_FOCUS(text_view_)) 513 }
509 return FALSE; // Continue to propagate into the GtkTextView handler.
510 514
511 // We only want to select everything on left-click; otherwise we'll end up 515 gboolean AutocompleteEditViewGtk::HandleViewButtonRelease(
512 // stealing the PRIMARY selection when the user middle-clicks to paste it 516 GdkEventButton* event) {
513 // here.
514 if (event->button != 1) 517 if (event->button != 1)
515 return FALSE; 518 return FALSE;
516 519
520 button_1_pressed_ = false;
521
517 // Call the GtkTextView default handler, ignoring the fact that it will 522 // Call the GtkTextView default handler, ignoring the fact that it will
518 // likely have told us to stop propagating. We want to handle selection. 523 // likely have told us to stop propagating. We want to handle selection.
519 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_); 524 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_);
520 klass->button_press_event(text_view_, event); 525 klass->button_release_event(text_view_, event);
521 526
522 // Select the full input and update the PRIMARY selection when we get focus. 527 if (!text_view_focused_before_button_press_ && !text_selected_during_click_) {
523 SelectAllInternal(false, true); 528 // If this was a focusing click and the user didn't drag to highlight any
529 // text, select the full input and update the PRIMARY selection.
530 SelectAllInternal(false, true);
524 531
525 // So we told the buffer where the cursor should be, but make sure to tell 532 // So we told the buffer where the cursor should be, but make sure to tell
526 // the view so it can scroll it to be visible if needed. 533 // the view so it can scroll it to be visible if needed.
527 // NOTE: This function doesn't seem to like a count of 0, looking at the 534 // NOTE: This function doesn't seem to like a count of 0, looking at the
528 // code it will skip an important loop. Use -1 to achieve the same. 535 // code it will skip an important loop. Use -1 to achieve the same.
529 GtkTextIter start, end; 536 GtkTextIter start, end;
530 gtk_text_buffer_get_bounds(text_buffer_, &start, &end); 537 gtk_text_buffer_get_bounds(text_buffer_, &start, &end);
531 gtk_text_view_move_visually(GTK_TEXT_VIEW(text_view_), &start, -1); 538 gtk_text_view_move_visually(GTK_TEXT_VIEW(text_view_), &start, -1);
539 }
532 540
533 return TRUE; // Don't continue, we called the default handler already. 541 return TRUE; // Don't continue, we called the default handler already.
534 } 542 }
535 543
536 gboolean AutocompleteEditViewGtk::HandleViewFocusIn() { 544 gboolean AutocompleteEditViewGtk::HandleViewFocusIn() {
537 model_->OnSetFocus(false); 545 model_->OnSetFocus(false);
538 // TODO(deanm): Some keyword hit business, etc here. 546 // TODO(deanm): Some keyword hit business, etc here.
539 547
540 return FALSE; // Continue propagation. 548 return FALSE; // Continue propagation.
541 } 549 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 size_t text_len = strlen(text); 642 size_t text_len = strlen(text);
635 if (!text_len) { 643 if (!text_len) {
636 no_text_selected = true; 644 no_text_selected = true;
637 } else { 645 } else {
638 selected_text_ = std::string(text, text_len); 646 selected_text_ = std::string(text, text_len);
639 selection_saved_ = false; 647 selection_saved_ = false;
640 } 648 }
641 g_free(text); 649 g_free(text);
642 } 650 }
643 651
652 // If the user just selected some text with the mouse (or at least while the
653 // mouse button was down), make sure that we won't blow their selection away
654 // later by selecting all of the text when the button is released.
655 if (button_1_pressed_ && !no_text_selected) {
656 text_selected_during_click_ = true;
657 }
658
644 // If we have some previously-selected text but it's no longer highlighted 659 // If we have some previously-selected text but it's no longer highlighted
645 // and we haven't saved it as the selection yet, we save it now. 660 // and we haven't saved it as the selection yet, we save it now.
646 if (!selected_text_.empty() && no_text_selected && !selection_saved_) { 661 if (!selected_text_.empty() && no_text_selected && !selection_saved_) {
647 SavePrimarySelection(selected_text_); 662 SavePrimarySelection(selected_text_);
648 selection_saved_ = true; 663 selection_saved_ = true;
649 } 664 }
650 } 665 }
651 666
652 void AutocompleteEditViewGtk::SelectAllInternal(bool reversed, 667 void AutocompleteEditViewGtk::SelectAllInternal(bool reversed,
653 bool update_primary_selection) { 668 bool update_primary_selection) {
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
781 const std::string& selected_text) { 796 const std::string& selected_text) {
782 GtkClipboard* clipboard = 797 GtkClipboard* clipboard =
783 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); 798 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY);
784 DCHECK(clipboard); 799 DCHECK(clipboard);
785 if (!clipboard) 800 if (!clipboard)
786 return; 801 return;
787 802
788 gtk_clipboard_set_text( 803 gtk_clipboard_set_text(
789 clipboard, selected_text.data(), selected_text.size()); 804 clipboard, selected_text.data(), selected_text.size());
790 } 805 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698