From b3924f2a5509596645492d232c9b3dcf1ad35965 Mon Sep 17 00:00:00 2001 From: Christian Persch Date: Mon, 18 Feb 2008 13:40:59 +0000 Subject: Fix prompt service for xr 1.9 wrt. DOM notifications. Bug #504445. svn path=/trunk/; revision=7967 --- embed/mozilla/AutoModalDialog.cpp | 182 +++++++++++++++++++++++++ embed/mozilla/AutoModalDialog.h | 70 ++++++++++ embed/mozilla/ContentHandler.cpp | 20 ++- embed/mozilla/EphyPromptService.cpp | 14 +- embed/mozilla/FilePicker.cpp | 17 ++- embed/mozilla/GeckoCookiePromptService.cpp | 23 ++-- embed/mozilla/GeckoFormSigningDialog.cpp | 16 +-- embed/mozilla/GeckoPrintService.cpp | 19 +-- embed/mozilla/GtkNSSClientAuthDialogs.cpp | 22 +-- embed/mozilla/GtkNSSDialogs.cpp | 155 +++++++++++---------- embed/mozilla/GtkNSSKeyPairDialogs.cpp | 19 +-- embed/mozilla/GtkNSSSecurityWarningDialogs.cpp | 28 ++-- embed/mozilla/Makefile.am | 2 + 13 files changed, 415 insertions(+), 172 deletions(-) create mode 100644 embed/mozilla/AutoModalDialog.cpp create mode 100644 embed/mozilla/AutoModalDialog.h (limited to 'embed') diff --git a/embed/mozilla/AutoModalDialog.cpp b/embed/mozilla/AutoModalDialog.cpp new file mode 100644 index 000000000..994cfe4fa --- /dev/null +++ b/embed/mozilla/AutoModalDialog.cpp @@ -0,0 +1,182 @@ +/* + * Copyright © 2006, 2008 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Some code taken from mozilla/embedding/components/windowwatcher/src/nsPromptService.cpp + * which was under MPL/LGPL/GPL tri-licence and is here being used under the licence above. + * Original notice: + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + */ + +#include +#include + +#ifdef HAVE_GECKO_1_9 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* HAVE_GECKO_1_9 */ + +#include + +#include "EphyUtils.h" + +#include "AutoModalDialog.h" + +AutoModalDialog::AutoModalDialog (nsIDOMWindow *aWindow, + PRBool aNotifyDOM) + : mWindow (aWindow), + mStack (), + mModalState (aWindow), +#ifdef HAVE_GECKO_1_9 + mDefaultEnabled (DispatchEvent ("DOMWillOpenModalDialog", aNotifyDOM)), +#endif + mContextPushed (NS_SUCCEEDED (mStack.Init ())) +{ +} + +AutoModalDialog::~AutoModalDialog () +{ +#ifdef HAVE_GECKO_1_9 + if (mDefaultEnabled) { + DispatchEvent ("DOMModalDialogClosed", PR_TRUE); + } +#endif /* HAVE_GECKO_1_9 */ +} + +GtkWindow * +AutoModalDialog::GetParent () +{ + return GTK_WINDOW (EphyUtils::FindGtkParent (mWindow)); +} + +int +AutoModalDialog::Run (GtkDialog *aDialog) +{ + NS_ASSERTION (ShouldShow(), "Calling ::Run on a prevented dialogue!"); + + nsCOMPtr pWindow (do_QueryInterface (mWindow)); + + // Reset popup state while opening a modal dialog, and firing + // events about the dialog, to prevent the current state from + // being active the whole time a modal dialog is open. + nsAutoPopupStatePusher popupStatePusher (pWindow, openAbused); + +#if 1 + return gtk_dialog_run (aDialog); +#else + /* Do NOT use gtk_dialog_run here, since it blocks the network thread! + * See https://bugzilla.mozilla.org/show_bug.cgi?id=338225 + */ + + g_object_ref_sink (aDialog); + mResponse = GTK_RESPONSE_DELETE_EVENT; + + gulong responseHandler = g_signal_connect (aDialog, "response", + G_CALLBACK (ResponseCallback), + reinterpret_cast(this)); + gulong deleteHandler = g_signal_connect (aDialog, "delete-event", + G_CALLBACK (DeleteCallback), NULL); + + gtk_window_present (GTK_WINDOW (aDialog)); + + nsCOMPtr thread (do_GetCurrentThread ()); + NS_ASSERTION (thread, "No UI thread?"); + + mContinueModalLoop = PR_TRUE; + while (mContinueModalLoop) { + if (!NS_ProcessNextEvent (thread)) + break; + } + + g_signal_handler_disconnect (aDialog, responseHandler); + g_signal_handler_disconnect (aDialog, deleteHandler); + g_object_unref (aDialog); + + return mResponse; +#endif +} + +#ifdef HAVE_GECKO_1_9 + +PRBool +AutoModalDialog::DispatchEvent (const char *aEventName, + PRBool aDoNotify) +{ + if (!mWindow || !aDoNotify) { + return PR_TRUE; + } + + nsCOMPtr domdoc; + mWindow->GetDocument (getter_AddRefs (domdoc)); + + nsCOMPtr docevent (do_QueryInterface (domdoc)); + nsCOMPtr event; + + PRBool defaultActionEnabled = PR_TRUE; + + if (docevent) { + docevent->CreateEvent (NS_LITERAL_STRING ("Events"), getter_AddRefs (event)); + + nsCOMPtr privateEvent (do_QueryInterface (event)); + if (privateEvent) { + event->InitEvent (NS_ConvertASCIItoUTF16 (aEventName), PR_TRUE, PR_TRUE); + + privateEvent->SetTrusted(PR_TRUE); + + nsCOMPtr target (do_QueryInterface (mWindow)); + + target->DispatchEvent (event, &defaultActionEnabled); + } + } + + return defaultActionEnabled; +} + +/* static */ void PR_CALLBACK +AutoModalDialog::ResponseCallback (GtkWidget *aDialog, + int aResponse, + void *aData) +{ + AutoModalDialog *obj = reinterpret_cast(aData); + + gtk_widget_hide (aDialog); + obj->mResponse = aResponse; + obj->mContinueModalLoop = PR_FALSE; +} + +/* static */ gboolean PR_CALLBACK +AutoModalDialog::DeleteCallback (GtkWidget *aDialog, + void *aEvent, + void *aData) +{ + gtk_dialog_response (GTK_DIALOG (aDialog), GTK_RESPONSE_DELETE_EVENT); + return TRUE; +} + +#endif /* HAVE_GECKO_1_9 */ diff --git a/embed/mozilla/AutoModalDialog.h b/embed/mozilla/AutoModalDialog.h new file mode 100644 index 000000000..91bb71007 --- /dev/null +++ b/embed/mozilla/AutoModalDialog.h @@ -0,0 +1,70 @@ +/* + * Copyright © 2006, 2008 Christian Persch + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef AUTOMODALDIALOG_H +#define AUTOMODALDIALOG_H + +#include + +#include + +#include "AutoJSContextStack.h" +#include "AutoWindowModalState.h" + +/** + * AutoModalDialog: + * A stack-based helper class for modal GTK+ dialogues. + * + * You MUST check ::ShouldShow() before showing the dialogue! + */ +class AutoModalDialog +{ + public: + AutoModalDialog (nsIDOMWindow *, PRBool); + ~AutoModalDialog (); + + GtkWindow *GetParent (); + + PRBool ShouldShow () { return mDefaultEnabled && mContextPushed; } + + int Run (GtkDialog *aDialog); + + private: + // stack only please + void *operator new (size_t) CPP_THROW_NEW; + + nsCOMPtr mWindow; + + AutoJSContextStack mStack; + AutoWindowModalState mModalState; + +#ifdef HAVE_GECKO_1_9 + static void PR_CALLBACK ResponseCallback (GtkWidget*, int, void*); + static gboolean PR_CALLBACK DeleteCallback (GtkWidget*, void*, void*); + + PRBool DispatchEvent (const char*, PRBool); + + int mResponse; + PRPackedBool mContinueModalLoop; +#endif + + PRPackedBool mDefaultEnabled; + PRPackedBool mContextPushed; +}; + +#endif diff --git a/embed/mozilla/ContentHandler.cpp b/embed/mozilla/ContentHandler.cpp index 5b7a5ac0e..c70f460c2 100644 --- a/embed/mozilla/ContentHandler.cpp +++ b/embed/mozilla/ContentHandler.cpp @@ -56,8 +56,7 @@ #include "ephy-prefs.h" #include "ephy-stock-icons.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "MozDownload.h" @@ -144,18 +143,15 @@ NS_IMETHODIMP GContentHandler::PromptForSaveToFile( { return BuildDownloadPath (defaultFile.get(), _retval); } - - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parentDOMWindow (do_GetInterface (aWindowContext)); - GtkWidget *parentWindow = GTK_WIDGET (EphyUtils::FindGtkParent (parentDOMWindow)); - AutoWindowModalState modalState (parentDOMWindow); + AutoModalDialog modalDialog (parentDOMWindow, PR_FALSE); + if (!modalDialog.ShouldShow ()) + return NS_ERROR_FAILURE; + + GtkWindow *parentWindow = modalDialog.GetParent (); - dialog = ephy_file_chooser_new (_("Save"), parentWindow, + dialog = ephy_file_chooser_new (_("Save"), GTK_WIDGET (parentWindow), GTK_FILE_CHOOSER_ACTION_SAVE, CONF_STATE_SAVE_DIR, EPHY_FILE_FILTER_ALL); @@ -175,7 +171,7 @@ NS_IMETHODIMP GContentHandler::PromptForSaveToFile( do { g_free (filename); - response = gtk_dialog_run (GTK_DIALOG (dialog)); + response = modalDialog.Run (GTK_DIALOG (dialog)); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); } while (response == GTK_RESPONSE_ACCEPT && !ephy_gui_check_location_writable (GTK_WIDGET (dialog), filename)); diff --git a/embed/mozilla/EphyPromptService.cpp b/embed/mozilla/EphyPromptService.cpp index 29813f300..915649aea 100644 --- a/embed/mozilla/EphyPromptService.cpp +++ b/embed/mozilla/EphyPromptService.cpp @@ -36,8 +36,7 @@ #include "ephy-gui.h" #include "ephy-debug.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "EphyPromptService.h" @@ -470,12 +469,9 @@ Prompter::Run (PRBool *aSuccess) } #endif - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - - AutoWindowModalState modalState (mWindow); + AutoModalDialog modalDialog (mWindow, PR_TRUE); + if (!modalDialog.ShouldShow ()) + return GTK_RESPONSE_CANCEL; if (mDelay) { @@ -491,7 +487,7 @@ Prompter::Run (PRBool *aSuccess) GtkWidget *widget = GTK_WIDGET (mDialog); gtk_widget_show (widget); - mResponse = gtk_dialog_run (mDialog); + mResponse = modalDialog.Run (mDialog); gtk_widget_hide (widget); g_object_set_data (G_OBJECT (mDialog), TIMEOUT_DATA_KEY, NULL); diff --git a/embed/mozilla/FilePicker.cpp b/embed/mozilla/FilePicker.cpp index 90b041ef4..6850b8e34 100644 --- a/embed/mozilla/FilePicker.cpp +++ b/embed/mozilla/FilePicker.cpp @@ -46,8 +46,7 @@ #include "ephy-gui.h" #include "ephy-prefs.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "FilePicker.h" @@ -390,12 +389,12 @@ NS_IMETHODIMP GFilePicker::GetFiles(nsISimpleEnumerator * *aFiles) /* short show (); */ NS_IMETHODIMP GFilePicker::Show(PRInt16 *_retval) { - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - - AutoWindowModalState modelState (mParent); + AutoModalDialog modalDialog (mParent, PR_FALSE); + if (!modalDialog.ShouldShow ()) { + *_retval = nsIFilePicker::returnCancel; + return NS_OK; + } + mParent = nsnull; LOG ("GFilePicker::Show"); @@ -425,7 +424,7 @@ NS_IMETHODIMP GFilePicker::Show(PRInt16 *_retval) do { - response = gtk_dialog_run (GTK_DIALOG (mDialog)); + response = modalDialog.Run (GTK_DIALOG (mDialog)); g_free (filename); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (mDialog)); diff --git a/embed/mozilla/GeckoCookiePromptService.cpp b/embed/mozilla/GeckoCookiePromptService.cpp index 1b32265f5..b228e7c93 100644 --- a/embed/mozilla/GeckoCookiePromptService.cpp +++ b/embed/mozilla/GeckoCookiePromptService.cpp @@ -36,8 +36,7 @@ #include "ephy-gui.h" #include "ephy-stock-icons.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "GeckoCookiePromptService.h" @@ -72,22 +71,20 @@ GeckoCookiePromptService::CookieDialog (nsIDOMWindow *aParent, // TODO short-circuit and accept session cookies as per preference // TODO until mozilla starts supporting it natively? - GtkWidget *parent = EphyUtils::FindGtkParent (aParent); - NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); - - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) { - return rv; + AutoModalDialog modalDialog (aParent, PR_FALSE); + if (!modalDialog.ShouldShow ()) { + *_retval = PR_FALSE; + *_checkValue = PR_FALSE; + return NS_OK; } - AutoWindowModalState modalState (aParent); + GtkWindow *parent = modalDialog.GetParent (); + NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); nsCString host(aHostname); GtkWidget *dialog = gtk_message_dialog_new - (GTK_WINDOW (parent), + (parent, GTK_DIALOG_MODAL /* FIXME mozilla sucks! */, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, @@ -141,7 +138,7 @@ GeckoCookiePromptService::CookieDialog (nsIDOMWindow *aParent, _("_Accept"), GTK_RESPONSE_ACCEPT); gtk_dialog_set_default_response (gdialog, GTK_RESPONSE_ACCEPT); - int response = gtk_dialog_run (gdialog); + int response = modalDialog.Run (gdialog); if (response == GTK_RESPONSE_ACCEPT || response == GTK_RESPONSE_REJECT) { *_retval = (response == GTK_RESPONSE_ACCEPT); diff --git a/embed/mozilla/GeckoFormSigningDialog.cpp b/embed/mozilla/GeckoFormSigningDialog.cpp index 309b3c11e..cf538c145 100644 --- a/embed/mozilla/GeckoFormSigningDialog.cpp +++ b/embed/mozilla/GeckoFormSigningDialog.cpp @@ -39,8 +39,7 @@ #include "ephy-file-helpers.h" #include "ephy-prefs.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "GeckoFormSigningDialog.h" @@ -83,11 +82,6 @@ GeckoFormSigningDialog::ConfirmSignText (nsIInterfaceRequestor *ctx, { /* FIXME: limit |signText| to a sensitlbe length (maybe 100k)? */ - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parent (do_GetInterface (ctx)); if (!parent) { parent = EphyJSUtils::GetDOMWindowFromCallContext (); @@ -95,7 +89,11 @@ GeckoFormSigningDialog::ConfirmSignText (nsIInterfaceRequestor *ctx, } GtkWidget *gparent = EphyUtils::FindGtkParent (parent); - AutoWindowModalState modalState (parent); + AutoModalDialog modalDialog (parent, PR_TRUE); + if (!modalDialog.ShouldShow ()) { + *_cancelled = PR_TRUE; + return NS_OK; + } GladeXML *gxml = glade_xml_new (ephy_file ("form-signing-dialog.glade"), "form_signing_dialog", NULL); @@ -143,7 +141,7 @@ GeckoFormSigningDialog::ConfirmSignText (nsIInterfaceRequestor *ctx, g_object_unref (gxml); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); *_cancelled = response != GTK_RESPONSE_ACCEPT; diff --git a/embed/mozilla/GeckoPrintService.cpp b/embed/mozilla/GeckoPrintService.cpp index 4d3de3fb8..de2020397 100644 --- a/embed/mozilla/GeckoPrintService.cpp +++ b/embed/mozilla/GeckoPrintService.cpp @@ -46,8 +46,7 @@ #include "ephy-prefs.h" #include "ephy-stock-icons.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "GeckoPrintSession.h" @@ -121,16 +120,12 @@ GeckoPrintService::ShowPrintDialog (nsIDOMWindow *aParent, rv = aSettings->GetHowToEnableFrameUI (&frameUI); NS_ENSURE_SUCCESS (rv, rv); - GtkWidget *parent = EphyUtils::FindGtkParent (aParent); - NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); - - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) { - return rv; - } + AutoModalDialog modalDialog (aParent, PR_TRUE); + if (!modalDialog.ShouldShow ()) + return NS_ERROR_ABORT; - AutoWindowModalState modalState (aParent); + GtkWindow *parent = modalDialog.GetParent (); + NS_ENSURE_TRUE(parent, NS_ERROR_INVALID_POINTER); EphyEmbedShell *shell = ephy_embed_shell_get_default (); @@ -200,7 +195,7 @@ GeckoPrintService::ShowPrintDialog (nsIDOMWindow *aParent, gtk_window_set_icon_name (GTK_WINDOW (dialog), EPHY_STOCK_EPHY); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); gtk_widget_hide (dialog); GtkPrinter *printer = gtk_print_unix_dialog_get_selected_printer (print_dialog); diff --git a/embed/mozilla/GtkNSSClientAuthDialogs.cpp b/embed/mozilla/GtkNSSClientAuthDialogs.cpp index 410827166..ee699a23d 100644 --- a/embed/mozilla/GtkNSSClientAuthDialogs.cpp +++ b/embed/mozilla/GtkNSSClientAuthDialogs.cpp @@ -57,8 +57,7 @@ #include "ephy-state.h" #include "ephy-stock-icons.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" #include "EphyUtils.h" #include "GtkNSSClientAuthDialogs.h" @@ -146,18 +145,19 @@ GtkNSSClientAuthDialogs::ChooseCertificate (nsIInterfaceRequestor *ctx, char *msg, *markup_text; PRUint32 i; - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parent (do_GetInterface (ctx)); - GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent)); - AutoWindowModalState modalState (parent); + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *canceled = PR_TRUE; + return NS_OK; + } + + GtkWindow *gparent = modalDialog.GetParent (); dialog = gtk_dialog_new_with_buttons ("", - GTK_WINDOW (gparent), + gparent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, @@ -268,7 +268,7 @@ GtkNSSClientAuthDialogs::ChooseCertificate (nsIInterfaceRequestor *ctx, gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); /* run the dialog */ - int res = gtk_dialog_run (GTK_DIALOG (dialog)); + int res = modalDialog.Run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_OK) { *canceled = PR_FALSE; diff --git a/embed/mozilla/GtkNSSDialogs.cpp b/embed/mozilla/GtkNSSDialogs.cpp index 3af7aec22..c21460b8c 100644 --- a/embed/mozilla/GtkNSSDialogs.cpp +++ b/embed/mozilla/GtkNSSDialogs.cpp @@ -88,8 +88,8 @@ #include "ephy-password-dialog.h" #include "ephy-stock-icons.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" +#include "AutoModalDialog.h" + #include "EphyUtils.h" #include "GtkNSSDialogs.h" @@ -239,18 +239,16 @@ display_cert_warning_box (nsIInterfaceRequestor *ctx, g_return_val_if_fail (markup_text, GTK_RESPONSE_CANCEL); g_return_val_if_fail (!checkbox_text || checkbox_value, GTK_RESPONSE_CANCEL); - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - /* NOTE: Due to a mozilla bug [https://bugzilla.mozilla.org/show_bug.cgi?id=306288], * we will always end up without a parent! */ nsCOMPtr parent (do_GetInterface (ctx)); - GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent)); + + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + return GTK_RESPONSE_CANCEL; - AutoWindowModalState modalState (parent); + GtkWindow *gparent = modalDialog.GetParent (); dialog = gtk_dialog_new_with_buttons ("", gparent, GTK_DIALOG_DESTROY_WITH_PARENT, @@ -305,7 +303,7 @@ display_cert_warning_box (nsIInterfaceRequestor *ctx, while (1) { - res = gtk_dialog_run (GTK_DIALOG (dialog)); + res = modalDialog.Run (GTK_DIALOG (dialog)); if (res == NSSDIALOG_RESPONSE_VIEW_CERT) { view_certificate (ctx, cert); @@ -619,15 +617,16 @@ GtkNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx, GtkWidget *dialog, *label; char *msg, *primary; - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parent (do_GetInterface (ctx)); - GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent)); + + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *_retval = PR_FALSE; + return NS_OK; + } - AutoWindowModalState modalState (parent); + GtkWindow *gparent = modalDialog.GetParent (); dialog = gtk_dialog_new_with_buttons (_("Trust new Certificate Authority?"), gparent, GTK_DIALOG_DESTROY_WITH_PARENT, @@ -670,7 +669,7 @@ GtkNSSDialogs::ConfirmDownloadCACert(nsIInterfaceRequestor *ctx, while (1) { - ret = gtk_dialog_run (GTK_DIALOG (dialog)); + ret = modalDialog.Run (GTK_DIALOG (dialog)); if (ret == NSSDIALOG_RESPONSE_VIEW_CERT) { view_certificate (ctx, cert); @@ -751,17 +750,18 @@ GtkNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor *ctx, GtkWidget *dialog; char *msg; - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parent (do_GetInterface (ctx)); - GtkWidget *gparent = EphyUtils::FindGtkParent (parent); + + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *_retval = PR_FALSE; + return NS_OK; + } - AutoWindowModalState modalState (parent); + GtkWindow *gparent = modalDialog.GetParent (); - dialog = ephy_password_dialog_new (gparent, + dialog = ephy_password_dialog_new (GTK_WIDGET (gparent), _("Select Password"), EphyPasswordDialogFlags(EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD | EPHY_PASSWORD_DIALOG_FLAGS_SHOW_QUALITY_METER)); @@ -776,7 +776,7 @@ GtkNSSDialogs::SetPKCS12FilePassword(nsIInterfaceRequestor *ctx, gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), msg); g_free (msg); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); gtk_widget_hide (dialog); if (response == GTK_RESPONSE_ACCEPT) @@ -801,18 +801,19 @@ GtkNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor *ctx, { g_print ("GtkNSSDialogs::GetPKCS12FilePassword\n"); - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parent (do_GetInterface (ctx)); - GtkWidget *gparent = EphyUtils::FindGtkParent (parent); + + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *_retval = PR_FALSE; + return NS_OK; + } - AutoWindowModalState modalState (parent); + GtkWindow *gparent = modalDialog.GetParent (); GtkWidget *dialog = ephy_password_dialog_new - (gparent, + (GTK_WIDGET (gparent), "", EphyPasswordDialogFlags (EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD)); EphyPasswordDialog *password_dialog = EPHY_PASSWORD_DIALOG (dialog); @@ -825,7 +826,7 @@ GtkNSSDialogs::GetPKCS12FilePassword(nsIInterfaceRequestor *ctx, gtk_message_dialog_set_markup (GTK_MESSAGE_DIALOG (dialog), msg); g_free (msg); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_ACCEPT) { @@ -1213,10 +1214,13 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx, PRUnichar ** usage; GtkSizeGroup * sizegroup; - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; + nsCOMPtr parent (do_GetInterface (ctx)); + + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + return NS_OK; + + GtkWindow *gparent = modalDialog.GetParent (); gxml = glade_xml_new (ephy_file ("certificate-dialogs.glade"), "viewcert_dialog", NULL); @@ -1225,11 +1229,6 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx, dialog = glade_xml_get_widget (gxml, "viewcert_dialog"); g_return_val_if_fail (dialog != NULL, NS_ERROR_FAILURE); - nsCOMPtr parent (do_GetInterface (ctx)); - GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent)); - - AutoWindowModalState modalState (parent); - if (gparent) { gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(gparent)); @@ -1255,6 +1254,7 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx, gtk_size_group_add_widget (sizegroup, widget); g_object_unref (sizegroup); + nsresult rv; rv = cert->GetUsagesArray (FALSE, &verifystate, &count, &usage); if (NS_FAILED(rv)) return rv; @@ -1371,7 +1371,7 @@ GtkNSSDialogs::ViewCert(nsIInterfaceRequestor *ctx, int res; while (1) { - res = gtk_dialog_run (GTK_DIALOG (dialog)); + res = modalDialog.Run (GTK_DIALOG (dialog)); if (res == GTK_RESPONSE_HELP) { ephy_gui_help (GTK_WINDOW (dialog), "epiphany", "using-certificate-viewer"); @@ -1412,9 +1412,15 @@ GtkNSSDialogs::SetPassword(nsIInterfaceRequestor *aCtx, slot->GetStatus (&status); nsCOMPtr parent (do_GetInterface (aCtx)); - GtkWidget *gparent = EphyUtils::FindGtkParent (parent); - AutoWindowModalState modalState (parent); + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *aCancelled = PR_TRUE; + return NS_OK; + } + + GtkWindow *gparent = modalDialog.GetParent (); EphyPasswordDialogFlags flags = EphyPasswordDialogFlags (EPHY_PASSWORD_DIALOG_FLAGS_SHOW_NEW_PASSWORD | @@ -1423,7 +1429,7 @@ GtkNSSDialogs::SetPassword(nsIInterfaceRequestor *aCtx, flags = EphyPasswordDialogFlags (flags | EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD); GtkWidget *dialog = ephy_password_dialog_new - (gparent, + (GTK_WIDGET (gparent), _("Change Token Password"), flags); EphyPasswordDialog *password_dialog = EPHY_PASSWORD_DIALOG (dialog); @@ -1445,7 +1451,7 @@ GtkNSSDialogs::SetPassword(nsIInterfaceRequestor *aCtx, nsString oldPassword; PRBool pwdOk, needsLogin; do { - response = gtk_dialog_run (GTK_DIALOG (dialog)); + response = modalDialog.Run (GTK_DIALOG (dialog)); if (status != nsIPKCS11Slot::SLOT_UNINITIALIZED) { @@ -1503,20 +1509,22 @@ GtkNSSDialogs::GetPassword(nsIInterfaceRequestor *aCtx, NS_ENSURE_SUCCESS (rv, rv); NS_ENSURE_TRUE (token && slot, NS_ERROR_FAILURE); - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - nsCOMPtr parent (do_GetInterface (aCtx)); - GtkWidget *gparent = EphyUtils::FindGtkParent (parent); - AutoWindowModalState modalState (parent); + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *aCancelled = PR_TRUE; + return NS_OK; + } + + GtkWindow *gparent = modalDialog.GetParent (); EphyPasswordDialogFlags flags = EphyPasswordDialogFlags (EPHY_PASSWORD_DIALOG_FLAGS_SHOW_PASSWORD); GtkWidget *dialog = ephy_password_dialog_new - (gparent, + (GTK_WIDGET (gparent), _("Get Token Password"), /* FIXME */ flags); EphyPasswordDialog *password_dialog = EPHY_PASSWORD_DIALOG (dialog); @@ -1531,7 +1539,7 @@ GtkNSSDialogs::GetPassword(nsIInterfaceRequestor *aCtx, message); g_free (message); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); if (response == GTK_RESPONSE_ACCEPT) { @@ -1571,23 +1579,23 @@ GtkNSSDialogs::ChooseToken (nsIInterfaceRequestor *aContext, NS_ENSURE_ARG (tokenNameList); NS_ENSURE_ARG (count); - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; - /* Didn't you know it? MOZILLA SUCKS! ChooseToken is always called with |aContext| == NULL! See * http://bonsai.mozilla.org/cvsblame.cgi?file=mozilla/security/manager/ssl/src/nsKeygenHandler.cpp&rev=1.39&mark=346#346 * Need to investigate if we it's always called directly from code called from JS, in which case we * can use EphyJSUtils::GetDOMWindowFromCallContext. */ nsCOMPtr parent (do_GetInterface (aContext)); - GtkWidget *gparent = EphyUtils::FindGtkParent (parent); - AutoWindowModalState modalState (parent); + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) { + *_cancelled = PR_TRUE; + return NS_OK; + } + + GtkWindow *gparent = modalDialog.GetParent (); GtkWidget *dialog = gtk_message_dialog_new - (GTK_WINDOW (gparent), + (gparent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER, GTK_BUTTONS_CANCEL, @@ -1615,7 +1623,7 @@ GtkNSSDialogs::ChooseToken (nsIInterfaceRequestor *aContext, gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); int selected = gtk_combo_box_get_active (GTK_COMBO_BOX (combo)); gtk_widget_destroy (dialog); @@ -1660,16 +1668,21 @@ GtkNSSDialogs::ConfirmKeyEscrow (nsIX509Cert *aEscrowAuthority, nsCOMPtr parent (do_GetInterface (aCtx)); #endif nsCOMPtr parent (EphyJSUtils::GetDOMWindowFromCallContext ()); - GtkWidget *gparent = EphyUtils::FindGtkParent (parent); - AutoWindowModalState modalState (parent); + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) { + *_retval = PR_FALSE; + return NS_OK; + } + + GtkWindow *gparent = modalDialog.GetParent (); /* FIXME: is that guaranteed to be non-empty? */ nsString commonName; aEscrowAuthority->GetCommonName (commonName); GtkWidget *dialog = gtk_message_dialog_new - (GTK_WINDOW (gparent), + (gparent, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING /* QUESTION really but it's also a strong warnings... */, GTK_BUTTONS_NONE, @@ -1703,7 +1716,7 @@ GtkNSSDialogs::ConfirmKeyEscrow (nsIX509Cert *aEscrowAuthority, gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_REJECT); gtk_widget_grab_focus (button); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); *_retval = response == GTK_RESPONSE_ACCEPT; diff --git a/embed/mozilla/GtkNSSKeyPairDialogs.cpp b/embed/mozilla/GtkNSSKeyPairDialogs.cpp index 3b9e405cc..916cf5b7c 100644 --- a/embed/mozilla/GtkNSSKeyPairDialogs.cpp +++ b/embed/mozilla/GtkNSSKeyPairDialogs.cpp @@ -49,9 +49,7 @@ #include "ephy-gui.h" #include "ephy-stock-icons.h" -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" -#include "EphyUtils.h" +#include "AutoModalDialog.h" #include "GtkNSSKeyPairDialogs.h" @@ -142,15 +140,12 @@ GtkNSSKeyPairDialogs::DisplayGeneratingKeypairInfo (nsIInterfaceRequestor *ctx, GtkWidget *dialog, *progress, *label, *vbox; gint timeout_id; - nsresult rv; - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return rv; + nsCOMPtr parent (do_GetInterface (ctx)); + AutoModalDialog modalDialog (parent, PR_FALSE); + if (!modalDialog.ShouldShow ()) + return NS_ERROR_ABORT; - nsCOMPtr parent = do_GetInterface (ctx); - GtkWindow *gparent = GTK_WINDOW (EphyUtils::FindGtkParent (parent)); - - AutoWindowModalState modalState (parent); + GtkWindow *gparent = modalDialog.GetParent (); dialog = gtk_dialog_new_with_buttons ("", gparent, GTK_DIALOG_DESTROY_WITH_PARENT, (char *) NULL); @@ -199,7 +194,7 @@ GtkNSSKeyPairDialogs::DisplayGeneratingKeypairInfo (nsIInterfaceRequestor *ctx, begin_busy (dialog); runnable->StartKeyGeneration (helper); - int res = gtk_dialog_run (GTK_DIALOG (dialog)); + int res = modalDialog.Run (GTK_DIALOG (dialog)); if (res != GTK_RESPONSE_OK && helper->close_called == FALSE) { /* Ignore the already_closed flag, our nsIDOMWindowInterna::Close diff --git a/embed/mozilla/GtkNSSSecurityWarningDialogs.cpp b/embed/mozilla/GtkNSSSecurityWarningDialogs.cpp index b50b3762a..4e8d80c6d 100644 --- a/embed/mozilla/GtkNSSSecurityWarningDialogs.cpp +++ b/embed/mozilla/GtkNSSSecurityWarningDialogs.cpp @@ -62,9 +62,7 @@ #include #include -#include "AutoJSContextStack.h" -#include "AutoWindowModalState.h" -#include "EphyUtils.h" +#include "AutoModalDialog.h" #include "GtkNSSSecurityWarningDialogs.h" @@ -236,28 +234,30 @@ GtkNSSSecurityWarningDialogs::DoDialog (nsIInterfaceRequestor *aContext, * https://bugzilla.mozilla.org/show_bug.cgi?id=277587 */ nsCOMPtr domWin (do_GetInterface (aContext)); - GtkWidget *parent = EphyUtils::FindGtkParent (domWin); - AutoJSContextStack stack; - rv = stack.Init (); - if (NS_FAILED (rv)) return; + AutoModalDialog modalDialog (domWin, PR_FALSE); + if (!modalDialog.ShouldShow ()) + { + *_retval = PR_FALSE; + return; + } - AutoWindowModalState modalState (domWin); + GtkWindow *parent = modalDialog.GetParent (); - GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (parent), + GtkWidget *dialog = gtk_message_dialog_new (parent, GTK_DIALOG_MODAL, aType, - aButtons, aPrimary); + aButtons, "%s", aPrimary); - if (parent && GTK_WINDOW (parent)->group) + if (parent && parent->group) { - gtk_window_group_add_window (GTK_WINDOW (parent)->group, + gtk_window_group_add_window (parent->group, GTK_WINDOW (dialog)); } if (aSecondary) { gtk_message_dialog_format_secondary_text - (GTK_MESSAGE_DIALOG (dialog), aSecondary); + (GTK_MESSAGE_DIALOG (dialog), "%s", aSecondary); } if (aButtonText) @@ -271,7 +271,7 @@ GtkNSSSecurityWarningDialogs::DoDialog (nsIInterfaceRequestor *aContext, gtk_window_set_title (GTK_WINDOW (dialog), aTitle); gtk_window_set_icon_name (GTK_WINDOW (dialog), EPHY_STOCK_EPHY); - int response = gtk_dialog_run (GTK_DIALOG (dialog)); + int response = modalDialog.Run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); *_retval = (response == GTK_RESPONSE_ACCEPT || response == GTK_RESPONSE_OK); diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am index cf2259316..ef3efed61 100644 --- a/embed/mozilla/Makefile.am +++ b/embed/mozilla/Makefile.am @@ -3,6 +3,8 @@ noinst_LTLIBRARIES = libephymozillaembed.la libephymozillaembed_la_SOURCES = \ AutoJSContextStack.cpp \ AutoJSContextStack.h \ + AutoModalDialog.cpp \ + AutoModalDialog.h \ AutoWindowModalState.cpp \ AutoWindowModalState.h \ ContentHandler.cpp \ -- cgit v1.2.3