summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-07 01:57:28 +0000
committerestade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-07 01:57:28 +0000
commitc9bd64d670e6fb58d24d8251d8680a0ed1cc7cc7 (patch)
tree2435bd2b1e45990d74c9d3ee05391e5078ccf7aa
parentd8c21a50746fefcf8fcffc8bdbd2556327f9fed7 (diff)
downloadchromium_src-c9bd64d670e6fb58d24d8251d8680a0ed1cc7cc7.zip
chromium_src-c9bd64d670e6fb58d24d8251d8680a0ed1cc7cc7.tar.gz
chromium_src-c9bd64d670e6fb58d24d8251d8680a0ed1cc7cc7.tar.bz2
GTK: make sure to delete any remaining dialogs when the SelectFileDialogImpl object goes out of scope.
The control flow was as follows: 1. user initiates a save page command 2. user initiates a second save page command 3. tab contents creates a SavePackage, shows dialog 4. tab contents gets second OnSavePage, deletes old SavePackage, which deletes its SelectFileDialogImpl 5. At this point two dialogs are visible. 6. User dismisses second dialog. 7. User dismisses first dialog, and calls us back with pointer to freed SelectFileDialogImpl. 8. Bad stuff. BUG=23817 TEST=I put a sleep in Browser::SavePage, then hit ctrl+s twice quickly. Only one dialog appeared. Review URL: http://codereview.chromium.org/243117 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28213 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/gtk/dialogs_gtk.cc11
1 files changed, 11 insertions, 0 deletions
diff --git a/chrome/browser/gtk/dialogs_gtk.cc b/chrome/browser/gtk/dialogs_gtk.cc
index 7681ad1..08b484f 100644
--- a/chrome/browser/gtk/dialogs_gtk.cc
+++ b/chrome/browser/gtk/dialogs_gtk.cc
@@ -127,6 +127,9 @@ class SelectFileDialogImpl : public SelectFileDialog {
// The GtkImage widget for showing previews of selected images.
GtkWidget* preview_;
+ // All our dialogs.
+ std::set<GtkWidget*> dialogs_;
+
DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl);
};
@@ -151,6 +154,10 @@ SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener)
}
SelectFileDialogImpl::~SelectFileDialogImpl() {
+ for (std::set<GtkWidget*>::iterator iter = dialogs_.begin();
+ iter != dialogs_.end(); ++iter) {
+ gtk_widget_destroy(*iter);
+ }
}
bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const {
@@ -205,6 +212,7 @@ void SelectFileDialogImpl::SelectFile(
NOTREACHED();
return;
}
+ dialogs_.insert(dialog);
preview_ = gtk_image_new();
g_signal_connect(dialog, "update-preview", G_CALLBACK(OnUpdatePreview), this);
@@ -287,6 +295,7 @@ void SelectFileDialogImpl::FileSelected(GtkWidget* dialog,
}
RemoveParentForDialog(dialog);
gtk_widget_destroy(dialog);
+ dialogs_.erase(dialog);
}
void SelectFileDialogImpl::MultiFilesSelected(GtkWidget* dialog,
@@ -297,6 +306,7 @@ void SelectFileDialogImpl::MultiFilesSelected(GtkWidget* dialog,
listener_->MultiFilesSelected(files, PopParamsForDialog(dialog));
RemoveParentForDialog(dialog);
gtk_widget_destroy(dialog);
+ dialogs_.erase(dialog);
}
void SelectFileDialogImpl::FileNotSelected(GtkWidget* dialog) {
@@ -305,6 +315,7 @@ void SelectFileDialogImpl::FileNotSelected(GtkWidget* dialog) {
listener_->FileSelectionCanceled(params);
RemoveParentForDialog(dialog);
gtk_widget_destroy(dialog);
+ dialogs_.erase(dialog);
}
GtkWidget* SelectFileDialogImpl::CreateSelectFolderDialog(