diff options
author | oshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-08 23:55:52 +0000 |
---|---|---|
committer | oshima@google.com <oshima@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-08 23:55:52 +0000 |
commit | 9dfb3a1072ea2e304b6d5c4bf825e46a820a3667 (patch) | |
tree | 9afa52a95a58cb7ae63dfa89ee415a6e3d33ef95 /chrome/browser | |
parent | 4978976710e30b759ccd7bf47e2eb2dce7a0a05b (diff) | |
download | chromium_src-9dfb3a1072ea2e304b6d5c4bf825e46a820a3667.zip chromium_src-9dfb3a1072ea2e304b6d5c4bf825e46a820a3667.tar.gz chromium_src-9dfb3a1072ea2e304b6d5c4bf825e46a820a3667.tar.bz2 |
Use destroy signal to safe guard TextWidget method.
Looks like TextView related function stops working properly when TextView gets destroyed even if the object itself is not deleted. This CL address this case by using destroy signal explicitly.
BUG=70192
TEST=FIFrameTest.InEmptyFrame should pass.
Review URL: http://codereview.chromium.org/6413021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74203 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc | 208 | ||||
-rw-r--r-- | chrome/browser/autocomplete/autocomplete_edit_view_gtk.h | 13 | ||||
-rw-r--r-- | chrome/browser/iframe_uitest.cc | 8 |
3 files changed, 126 insertions, 103 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc index fbfd3ff..33eb4ff 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc @@ -150,7 +150,8 @@ AutocompleteEditViewGtk::AutocompleteEditViewGtk( #else GtkWidget* location_bar) #endif - : tag_table_(NULL), + : text_view_(NULL), + tag_table_(NULL), text_buffer_(NULL), faded_text_tag_(NULL), secure_scheme_tag_(NULL), @@ -213,7 +214,6 @@ AutocompleteEditViewGtk::~AutocompleteEditViewGtk() { // We own our widget and TextView related objects. if (alignment_.get()) { // Init() has been called. alignment_.Destroy(); - text_view_.Destroy(); g_object_unref(text_buffer_); g_object_unref(tag_table_); // The tags we created are owned by the tag_table, and should be destroyed @@ -245,26 +245,25 @@ void AutocompleteEditViewGtk::Init() { g_signal_connect(text_buffer_, "mark-set", G_CALLBACK(&HandleMarkSetAlwaysThunk), this); - text_view_.Own(gtk_undo_view_new(text_buffer_)); - GtkWidget* text_view = text_view_.get(); + text_view_ = gtk_undo_view_new(text_buffer_); if (popup_window_mode_) - gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), false); + gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view_), false); // One pixel left margin is necessary to make the cursor visible when UI // language direction is LTR but |text_buffer_|'s content direction is RTL. - gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_view), 1); + gtk_text_view_set_left_margin(GTK_TEXT_VIEW(text_view_), 1); // See SetEntryStyle() comments. - gtk_widget_set_name(text_view, "chrome-location-bar-entry"); + gtk_widget_set_name(text_view_, "chrome-location-bar-entry"); // The text view was floating. It will now be owned by the alignment. - gtk_container_add(GTK_CONTAINER(alignment_.get()), text_view); + gtk_container_add(GTK_CONTAINER(alignment_.get()), text_view_); // Do not allow inserting tab characters when pressing Tab key, so that when // Tab key is pressed, |text_view_| will emit "move-focus" signal, which will // be intercepted by our own handler to trigger Tab to search feature when // necessary. - gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view), FALSE); + gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), FALSE); faded_text_tag_ = gtk_text_buffer_create_tag(text_buffer_, NULL, "foreground", kTextBaseColor, NULL); @@ -284,67 +283,69 @@ void AutocompleteEditViewGtk::Init() { g_signal_connect(text_buffer_, "end-user-action", G_CALLBACK(&HandleEndUserActionThunk), this); // We connect to key press and release for special handling of a few keys. - g_signal_connect(text_view, "key-press-event", + g_signal_connect(text_view_, "key-press-event", G_CALLBACK(&HandleKeyPressThunk), this); - g_signal_connect(text_view, "key-release-event", + g_signal_connect(text_view_, "key-release-event", G_CALLBACK(&HandleKeyReleaseThunk), this); - g_signal_connect(text_view, "button-press-event", + g_signal_connect(text_view_, "button-press-event", G_CALLBACK(&HandleViewButtonPressThunk), this); - g_signal_connect(text_view, "button-release-event", + g_signal_connect(text_view_, "button-release-event", G_CALLBACK(&HandleViewButtonReleaseThunk), this); - g_signal_connect(text_view, "focus-in-event", + g_signal_connect(text_view_, "focus-in-event", G_CALLBACK(&HandleViewFocusInThunk), this); - g_signal_connect(text_view, "focus-out-event", + g_signal_connect(text_view_, "focus-out-event", G_CALLBACK(&HandleViewFocusOutThunk), this); // NOTE: The GtkTextView documentation asks you not to connect to this // signal, but it is very convenient and clean for catching up/down. - g_signal_connect(text_view, "move-cursor", + g_signal_connect(text_view_, "move-cursor", G_CALLBACK(&HandleViewMoveCursorThunk), this); - g_signal_connect(text_view, "move-focus", + g_signal_connect(text_view_, "move-focus", G_CALLBACK(&HandleViewMoveFocusThunk), this); // Override the size request. We want to keep the original height request // from the widget, since that's font dependent. We want to ignore the width // so we don't force a minimum width based on the text length. - g_signal_connect(text_view, "size-request", + g_signal_connect(text_view_, "size-request", G_CALLBACK(&HandleViewSizeRequestThunk), this); - g_signal_connect(text_view, "populate-popup", + g_signal_connect(text_view_, "populate-popup", G_CALLBACK(&HandlePopulatePopupThunk), this); mark_set_handler_id_ = g_signal_connect( text_buffer_, "mark-set", G_CALLBACK(&HandleMarkSetThunk), this); mark_set_handler_id2_ = g_signal_connect_after( text_buffer_, "mark-set", G_CALLBACK(&HandleMarkSetAfterThunk), this); - g_signal_connect(text_view, "drag-data-received", + g_signal_connect(text_view_, "drag-data-received", G_CALLBACK(&HandleDragDataReceivedThunk), this); // Override the text_view_'s default drag-data-get handler by calling our own // version after the normal call has happened. - g_signal_connect_after(text_view, "drag-data-get", + g_signal_connect_after(text_view_, "drag-data-get", G_CALLBACK(&HandleDragDataGetThunk), this); - g_signal_connect(text_view, "backspace", + g_signal_connect(text_view_, "backspace", G_CALLBACK(&HandleBackSpaceThunk), this); - g_signal_connect(text_view, "copy-clipboard", + g_signal_connect(text_view_, "copy-clipboard", G_CALLBACK(&HandleCopyClipboardThunk), this); - g_signal_connect(text_view, "cut-clipboard", + g_signal_connect(text_view_, "cut-clipboard", G_CALLBACK(&HandleCutClipboardThunk), this); - g_signal_connect(text_view, "paste-clipboard", + g_signal_connect(text_view_, "paste-clipboard", G_CALLBACK(&HandlePasteClipboardThunk), this); - g_signal_connect_after(text_view, "expose-event", + g_signal_connect_after(text_view_, "expose-event", G_CALLBACK(&HandleExposeEventThunk), this); - g_signal_connect(text_view, "direction-changed", + g_signal_connect(text_view_, "direction-changed", G_CALLBACK(&HandleWidgetDirectionChangedThunk), this); - g_signal_connect(text_view, "delete-from-cursor", + g_signal_connect(text_view_, "delete-from-cursor", G_CALLBACK(&HandleDeleteFromCursorThunk), this); - g_signal_connect(text_view, "hierarchy-changed", + g_signal_connect(text_view_, "hierarchy-changed", G_CALLBACK(&HandleHierarchyChangedThunk), this); #if GTK_CHECK_VERSION(2, 20, 0) - g_signal_connect(text_view, "preedit-changed", + g_signal_connect(text_view_, "preedit-changed", G_CALLBACK(&HandlePreeditChangedThunk), this); #endif - g_signal_connect(text_view, "undo", G_CALLBACK(&HandleUndoRedoThunk), this); - g_signal_connect(text_view, "redo", G_CALLBACK(&HandleUndoRedoThunk), this); - g_signal_connect_after(text_view, "undo", + g_signal_connect(text_view_, "undo", G_CALLBACK(&HandleUndoRedoThunk), this); + g_signal_connect(text_view_, "redo", G_CALLBACK(&HandleUndoRedoThunk), this); + g_signal_connect_after(text_view_, "undo", G_CALLBACK(&HandleUndoRedoAfterThunk), this); - g_signal_connect_after(text_view, "redo", + g_signal_connect_after(text_view_, "redo", G_CALLBACK(&HandleUndoRedoAfterThunk), this); + g_signal_connect(text_view_, "destroy", + G_CALLBACK(>k_widget_destroyed), &text_view_); // Setup for the Instant suggestion text view. // GtkLabel is used instead of GtkTextView to get transparent background. @@ -363,7 +364,7 @@ void AutocompleteEditViewGtk::Init() { GtkTextChildAnchor* instant_anchor = gtk_text_buffer_create_child_anchor(text_buffer_, &end_iter); - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(text_view), + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(text_view_), instant_view_, instant_anchor); @@ -421,7 +422,8 @@ void AutocompleteEditViewGtk::HandleHierarchyChanged( } void AutocompleteEditViewGtk::SetFocus() { - gtk_widget_grab_focus(text_view_.get()); + DCHECK(text_view_); + gtk_widget_grab_focus(text_view_); } int AutocompleteEditViewGtk::WidthOfTextAfterCursor() { @@ -782,14 +784,20 @@ string16 AutocompleteEditViewGtk::GetInstantSuggestion() const { } int AutocompleteEditViewGtk::TextWidth() const { - GtkWidget* text_view = text_view_.get(); + // TextWidth may be called after gtk widget tree is destroyed but + // before AutocompleteEditViewGtk gets deleted. This is a safe guard + // to avoid accessing |text_view_| that has already been destroyed. + // See crbug.com/70192. + if (!text_view_) + return 0; + int horizontal_border_size = - gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view), + gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), GTK_TEXT_WINDOW_LEFT) + - gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view), + gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), GTK_TEXT_WINDOW_RIGHT) + - gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view)) + - gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view)); + gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) + + gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_)); GtkTextIter start, end; GdkRectangle first_char_bounds, last_char_bounds; @@ -798,9 +806,9 @@ int AutocompleteEditViewGtk::TextWidth() const { // Use the real end iterator here to take the width of instant suggestion // text into account, so that location bar can layout its children correctly. gtk_text_buffer_get_end_iter(text_buffer_, &end); - gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view), + gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), &start, &first_char_bounds); - gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view), + gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), &end, &last_char_bounds); gint first_char_start = first_char_bounds.x; @@ -909,26 +917,26 @@ void AutocompleteEditViewGtk::AnimationCanceled( } void AutocompleteEditViewGtk::SetBaseColor() { + DCHECK(text_view_); + #if defined(TOOLKIT_VIEWS) bool use_gtk = false; #else bool use_gtk = theme_provider_->UseGtkTheme(); #endif - GtkWidget* text_view = text_view_.get(); - if (use_gtk) { - gtk_widget_modify_cursor(text_view, NULL, NULL); - gtk_widget_modify_base(text_view, GTK_STATE_NORMAL, NULL); - gtk_widget_modify_base(text_view, GTK_STATE_SELECTED, NULL); - gtk_widget_modify_text(text_view, GTK_STATE_SELECTED, NULL); - gtk_widget_modify_base(text_view, GTK_STATE_ACTIVE, NULL); - gtk_widget_modify_text(text_view, GTK_STATE_ACTIVE, NULL); - - gtk_util::UndoForceFontSize(text_view); + gtk_widget_modify_cursor(text_view_, NULL, NULL); + gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, NULL); + gtk_widget_modify_base(text_view_, GTK_STATE_SELECTED, NULL); + gtk_widget_modify_text(text_view_, GTK_STATE_SELECTED, NULL); + gtk_widget_modify_base(text_view_, GTK_STATE_ACTIVE, NULL); + gtk_widget_modify_text(text_view_, GTK_STATE_ACTIVE, NULL); + + gtk_util::UndoForceFontSize(text_view_); gtk_util::UndoForceFontSize(instant_view_); // Grab the text colors out of the style and set our tags to use them. - GtkStyle* style = gtk_rc_get_style(text_view); + GtkStyle* style = gtk_rc_get_style(text_view_); // style may be unrealized at this point, so calculate the halfway point // between text[] and base[] manually instead of just using text_aa[]. @@ -949,8 +957,8 @@ void AutocompleteEditViewGtk::SetBaseColor() { background_color_ptr = &LocationBarViewGtk::kBackgroundColor; #endif gtk_widget_modify_cursor( - text_view, >k_util::kGdkBlack, >k_util::kGdkGray); - gtk_widget_modify_base(text_view, GTK_STATE_NORMAL, background_color_ptr); + text_view_, >k_util::kGdkBlack, >k_util::kGdkGray); + gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, background_color_ptr); #if !defined(TOOLKIT_VIEWS) GdkColor c; @@ -958,23 +966,23 @@ void AutocompleteEditViewGtk::SetBaseColor() { // gtk theme into the chrome-theme. c = gfx::SkColorToGdkColor( theme_provider_->get_active_selection_bg_color()); - gtk_widget_modify_base(text_view, GTK_STATE_SELECTED, &c); + gtk_widget_modify_base(text_view_, GTK_STATE_SELECTED, &c); c = gfx::SkColorToGdkColor( theme_provider_->get_active_selection_fg_color()); - gtk_widget_modify_text(text_view, GTK_STATE_SELECTED, &c); + gtk_widget_modify_text(text_view_, GTK_STATE_SELECTED, &c); c = gfx::SkColorToGdkColor( theme_provider_->get_inactive_selection_bg_color()); - gtk_widget_modify_base(text_view, GTK_STATE_ACTIVE, &c); + gtk_widget_modify_base(text_view_, GTK_STATE_ACTIVE, &c); c = gfx::SkColorToGdkColor( theme_provider_->get_inactive_selection_fg_color()); - gtk_widget_modify_text(text_view, GTK_STATE_ACTIVE, &c); + gtk_widget_modify_text(text_view_, GTK_STATE_ACTIVE, &c); #endif // Until we switch to vector graphics, force the font size. - gtk_util::ForceFontSizePixels(text_view, GetFont().GetFontSize()); + gtk_util::ForceFontSizePixels(text_view_, GetFont().GetFontSize()); gtk_util::ForceFontSizePixels(instant_view_, GetFont().GetFontSize()); g_object_set(faded_text_tag_, "foreground", kTextBaseColor, NULL); @@ -1224,14 +1232,15 @@ gboolean AutocompleteEditViewGtk::HandleViewButtonPress(GtkWidget* sender, if (event->type != GDK_BUTTON_PRESS) return FALSE; + DCHECK(text_view_); + if (event->button == 1) { #if defined(OS_CHROMEOS) // When the first button is pressed, track some stuff that will help us // determine whether we should select all of the text when the button is // released. button_1_pressed_ = true; - text_view_focused_before_button_press_ = - GTK_WIDGET_HAS_FOCUS(text_view_.get()); + text_view_focused_before_button_press_ = GTK_WIDGET_HAS_FOCUS(text_view_); text_selected_during_click_ = false; #endif @@ -1252,14 +1261,16 @@ gboolean AutocompleteEditViewGtk::HandleViewButtonRelease( if (event->button != 1) return FALSE; + DCHECK(text_view_); + #if defined(OS_CHROMEOS) button_1_pressed_ = false; #endif // Call the GtkTextView default handler, ignoring the fact that it will // likely have told us to stop propagating. We want to handle selection. - GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_.get()); - klass->button_release_event(text_view_.get(), event); + GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_); + klass->button_release_event(text_view_, event); #if defined(OS_CHROMEOS) if (!text_view_focused_before_button_press_ && !text_selected_during_click_) { @@ -1273,7 +1284,7 @@ gboolean AutocompleteEditViewGtk::HandleViewButtonRelease( // code it will skip an important loop. Use -1 to achieve the same. GtkTextIter start, end; GetTextBufferBounds(&start, &end); - gtk_text_view_move_visually(GTK_TEXT_VIEW(text_view_.get()), &start, -1); + gtk_text_view_move_visually(GTK_TEXT_VIEW(text_view_), &start, -1); } #endif @@ -1285,6 +1296,7 @@ gboolean AutocompleteEditViewGtk::HandleViewButtonRelease( gboolean AutocompleteEditViewGtk::HandleViewFocusIn(GtkWidget* sender, GdkEventFocus* event) { + DCHECK(text_view_); update_popup_without_focus_ = false; GdkModifierType modifiers; @@ -1294,7 +1306,7 @@ gboolean AutocompleteEditViewGtk::HandleViewFocusIn(GtkWidget* sender, // TODO(deanm): Some keyword hit business, etc here. g_signal_connect( - gdk_keymap_get_for_display(gtk_widget_get_display(text_view_.get())), + gdk_keymap_get_for_display(gtk_widget_get_display(text_view_)), "direction-changed", G_CALLBACK(&HandleKeymapDirectionChangedThunk), this); @@ -1305,6 +1317,7 @@ gboolean AutocompleteEditViewGtk::HandleViewFocusIn(GtkWidget* sender, gboolean AutocompleteEditViewGtk::HandleViewFocusOut(GtkWidget* sender, GdkEventFocus* event) { + DCHECK(text_view_); GtkWidget* view_getting_focus = NULL; GtkWindow* toplevel = platform_util::GetTopLevel(sender); if (gtk_window_is_active(toplevel)) @@ -1320,7 +1333,7 @@ gboolean AutocompleteEditViewGtk::HandleViewFocusOut(GtkWidget* sender, controller_->OnKillFocus(); g_signal_handlers_disconnect_by_func( - gdk_keymap_get_for_display(gtk_widget_get_display(text_view_.get())), + gdk_keymap_get_for_display(gtk_widget_get_display(text_view_)), reinterpret_cast<gpointer>(&HandleKeymapDirectionChangedThunk), this); return FALSE; // Pass the event on to the GtkTextView. @@ -1331,6 +1344,7 @@ void AutocompleteEditViewGtk::HandleViewMoveCursor( GtkMovementStep step, gint count, gboolean extend_selection) { + DCHECK(text_view_); GtkTextIter sel_start, sel_end; gboolean has_selection = gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end); @@ -1379,8 +1393,8 @@ void AutocompleteEditViewGtk::HandleViewMoveCursor( OnBeforePossibleChange(); // Propagate into GtkTextView - GtkTextViewClass* klass = GTK_TEXT_VIEW_GET_CLASS(text_view_.get()); - klass->move_cursor(GTK_TEXT_VIEW(text_view_.get()), step, count, + GtkTextViewClass* klass = GTK_TEXT_VIEW_GET_CLASS(text_view_); + klass->move_cursor(GTK_TEXT_VIEW(text_view_), step, count, extend_selection); if (has_selection || extend_selection) @@ -1390,7 +1404,7 @@ void AutocompleteEditViewGtk::HandleViewMoveCursor( // move-cursor doesn't use a signal accumulator on the return value (it // just ignores then), so we have to stop the propagation. static guint signal_id = g_signal_lookup("move-cursor", GTK_TYPE_TEXT_VIEW); - g_signal_stop_emission(text_view_.get(), signal_id, 0); + g_signal_stop_emission(text_view_, signal_id, 0); } void AutocompleteEditViewGtk::HandleViewSizeRequest(GtkWidget* sender, @@ -1517,6 +1531,8 @@ void AutocompleteEditViewGtk::HandleMarkSetAfter(GtkTextBuffer* buffer, void AutocompleteEditViewGtk::HandleDragDataReceived( GtkWidget* sender, GdkDragContext* context, gint x, gint y, GtkSelectionData* selection_data, guint target_type, guint time) { + DCHECK(text_view_); + // Reset |paste_clipboard_requested_| to make sure we won't misinterpret this // drop action as a paste action. paste_clipboard_requested_ = false; @@ -1538,7 +1554,7 @@ void AutocompleteEditViewGtk::HandleDragDataReceived( static guint signal_id = g_signal_lookup("drag-data-received", GTK_TYPE_WIDGET); - g_signal_stop_emission(text_view_.get(), signal_id, 0); + g_signal_stop_emission(text_view_, signal_id, 0); } } @@ -1548,6 +1564,7 @@ void AutocompleteEditViewGtk::HandleDragDataGet( GtkSelectionData* selection_data, guint target_type, guint time) { + DCHECK(text_view_); // If GTK put the normal textual version of the selection in our drag data, // put our doctored selection that might have the 'http://' prefix. Also, GTK // is confused about signedness of its datatypes, leading to the weird switch @@ -1611,6 +1628,8 @@ void AutocompleteEditViewGtk::HandleBackSpace(GtkWidget* sender) { if (model_->is_keyword_hint() || model_->keyword().empty()) return; // Propgate into GtkTextView. + DCHECK(text_view_); + GtkTextIter sel_start, sel_end; // Checks if there is some text selected. if (gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end)) @@ -1628,7 +1647,7 @@ void AutocompleteEditViewGtk::HandleBackSpace(GtkWidget* sender) { // Stop propagating the signal emission into GtkTextView. static guint signal_id = g_signal_lookup("backspace", GTK_TYPE_TEXT_VIEW); - g_signal_stop_emission(text_view_.get(), signal_id, 0); + g_signal_stop_emission(text_view_, signal_id, 0); } void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget, @@ -1679,6 +1698,8 @@ void AutocompleteEditViewGtk::HandleCutClipboard(GtkWidget* sender) { } void AutocompleteEditViewGtk::HandleCopyOrCutClipboard(bool copy) { + DCHECK(text_view_); + // On copy or cut, we manually update the PRIMARY selection to contain the // highlighted text. This matches Firefox -- we highlight the URL but don't // update PRIMARY on Ctrl-L, so Ctrl-L, Ctrl-C and then middle-click is a @@ -1708,7 +1729,7 @@ void AutocompleteEditViewGtk::HandleCopyOrCutClipboard(bool copy) { g_signal_lookup("copy-clipboard", GTK_TYPE_TEXT_VIEW); static guint cut_signal_id = g_signal_lookup("cut-clipboard", GTK_TYPE_TEXT_VIEW); - g_signal_stop_emission(text_view_.get(), + g_signal_stop_emission(text_view_, copy ? copy_signal_id : cut_signal_id, 0); @@ -1721,20 +1742,20 @@ void AutocompleteEditViewGtk::HandleCopyOrCutClipboard(bool copy) { gfx::Font AutocompleteEditViewGtk::GetFont() { #if defined(TOOLKIT_VIEWS) - bool use_gtk_theme = false; + bool use_gtk = false; #else - bool use_gtk_theme = theme_provider_->UseGtkTheme(); + bool use_gtk = theme_provider_->UseGtkTheme(); #endif - if (use_gtk_theme) { + + if (use_gtk) { // If we haven't initialized the text view yet, just create a temporary one // whose style we can grab. - GtkWidget* widget = - text_view_.get() ? text_view_.get() : gtk_text_view_new(); + GtkWidget* widget = text_view_ ? text_view_ : gtk_text_view_new(); GtkRcStyle* rc_style = gtk_widget_get_modifier_style(widget); gfx::Font font((rc_style && rc_style->font_desc) ? rc_style->font_desc : widget->style->font_desc); - if (!text_view_.get()) + if (!text_view_) g_object_unref(g_object_ref_sink(widget)); // Scaling the font down for popup windows doesn't help here, since we just @@ -1779,7 +1800,7 @@ void AutocompleteEditViewGtk::HandlePasteClipboard(GtkWidget* sender) { gfx::Rect AutocompleteEditViewGtk::WindowBoundsFromIters( GtkTextIter* iter1, GtkTextIter* iter2) { GdkRectangle start_location, end_location; - GtkTextView* text_view = GTK_TEXT_VIEW(text_view_.get()); + GtkTextView* text_view = GTK_TEXT_VIEW(text_view_); gtk_text_view_get_iter_location(text_view, iter1, &start_location); gtk_text_view_get_iter_location(text_view, iter2, &end_location); @@ -1799,6 +1820,7 @@ gboolean AutocompleteEditViewGtk::HandleExposeEvent(GtkWidget* sender, GdkEventExpose* expose) { if (strikethrough_.cp_min >= strikethrough_.cp_max) return FALSE; + DCHECK(text_view_); gfx::Rect expose_rect(expose->area); @@ -1847,9 +1869,9 @@ void AutocompleteEditViewGtk::SelectAllInternal(bool reversed, } void AutocompleteEditViewGtk::StartUpdatingHighlightedText() { - if (GTK_WIDGET_REALIZED(text_view_.get())) { + if (GTK_WIDGET_REALIZED(text_view_)) { GtkClipboard* clipboard = - gtk_widget_get_clipboard(text_view_.get(), GDK_SELECTION_PRIMARY); + gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); DCHECK(clipboard); if (clipboard) gtk_text_buffer_remove_selection_clipboard(text_buffer_, clipboard); @@ -1859,9 +1881,9 @@ void AutocompleteEditViewGtk::StartUpdatingHighlightedText() { } void AutocompleteEditViewGtk::FinishUpdatingHighlightedText() { - if (GTK_WIDGET_REALIZED(text_view_.get())) { + if (GTK_WIDGET_REALIZED(text_view_)) { GtkClipboard* clipboard = - gtk_widget_get_clipboard(text_view_.get(), GDK_SELECTION_PRIMARY); + gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); DCHECK(clipboard); if (clipboard) gtk_text_buffer_add_selection_clipboard(text_buffer_, clipboard); @@ -2014,8 +2036,10 @@ void AutocompleteEditViewGtk::TextChanged() { void AutocompleteEditViewGtk::SavePrimarySelection( const std::string& selected_text) { + DCHECK(text_view_); + GtkClipboard* clipboard = - gtk_widget_get_clipboard(text_view_.get(), GDK_SELECTION_PRIMARY); + gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); DCHECK(clipboard); if (!clipboard) return; @@ -2046,23 +2070,25 @@ void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) { } void AutocompleteEditViewGtk::AdjustTextJustification() { + DCHECK(text_view_); + PangoDirection content_dir = GetContentDirection(); - GtkWidget* text_view = text_view_.get(); + // Use keymap direction if content does not have strong direction. // It matches the behavior of GtkTextView. if (content_dir == PANGO_DIRECTION_NEUTRAL) { content_dir = gdk_keymap_get_direction( - gdk_keymap_get_for_display(gtk_widget_get_display(text_view))); + gdk_keymap_get_for_display(gtk_widget_get_display(text_view_))); } - GtkTextDirection widget_dir = gtk_widget_get_direction(text_view); + GtkTextDirection widget_dir = gtk_widget_get_direction(text_view_); if ((widget_dir == GTK_TEXT_DIR_RTL && content_dir == PANGO_DIRECTION_LTR) || (widget_dir == GTK_TEXT_DIR_LTR && content_dir == PANGO_DIRECTION_RTL)) { - gtk_text_view_set_justification(GTK_TEXT_VIEW(text_view), + gtk_text_view_set_justification(GTK_TEXT_VIEW(text_view_), GTK_JUSTIFY_RIGHT); } else { - gtk_text_view_set_justification(GTK_TEXT_VIEW(text_view), + gtk_text_view_set_justification(GTK_TEXT_VIEW(text_view_), GTK_JUSTIFY_LEFT); } } diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h index 846bc02..615b137 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h @@ -179,8 +179,10 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, // the animation state. void UpdateInstantViewColors(); + // Returns the text view gtk widget. May return NULL if the widget + // has already been destroyed. GtkWidget* text_view() { - return text_view_.get(); + return text_view_; } private: @@ -370,10 +372,11 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, // since the height will change based on the font / font size, etc. OwnedWidgetGtk alignment_; - // The actual text entry which will be owned by the alignment_. - // This widget has to be owned too beause GTK destroys children - // when parent is destroyed even if the parent's refcount is > 0. - OwnedWidgetGtk text_view_; + // The actual text entry which will be owned by the alignment_. The + // reference will be set to NULL upon destruction to tell if the gtk + // widget tree has been destroyed. This is because gtk destroies child + // widgets if the parent (alignemtn_)'s refcount does not go down to 0. + GtkWidget* text_view_; GtkTextTagTable* tag_table_; GtkTextBuffer* text_buffer_; diff --git a/chrome/browser/iframe_uitest.cc b/chrome/browser/iframe_uitest.cc index fca703b..bc69358 100644 --- a/chrome/browser/iframe_uitest.cc +++ b/chrome/browser/iframe_uitest.cc @@ -23,12 +23,6 @@ TEST_F(IFrameTest, Crash) { NavigateAndVerifyTitle("iframe.html", L"iframe test"); } -#if defined(OS_LINUX) -// Flakily crashes on linux: http://crbug.com/70192 -#define MAYBE_InEmptyFrame DISABLED_InEmptyFrame -#else -#define MAYBE_InEmptyFrame InEmptyFrame -#endif -TEST_F(IFrameTest, MAYBE_InEmptyFrame) { +TEST_F(IFrameTest, InEmptyFrame) { NavigateAndVerifyTitle("iframe_in_empty_frame.html", L"iframe test"); } |