aboutsummaryrefslogtreecommitdiffstats
path: root/embed
diff options
context:
space:
mode:
authorChristian Persch <chpe@cvs.gnome.org>2005-10-03 02:50:51 +0800
committerChristian Persch <chpe@src.gnome.org>2005-10-03 02:50:51 +0800
commitabe1a40d562514cfe6b3c8dae1397d511062ddab (patch)
tree08fb5018af362336c9b92f0e1d83d25c2bd3b2b8 /embed
parent8a92076ee578e5c6aa8bb0a39fcdbe8741ce2e52 (diff)
downloadgsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.tar
gsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.tar.gz
gsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.tar.bz2
gsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.tar.lz
gsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.tar.xz
gsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.tar.zst
gsoc2013-epiphany-abe1a40d562514cfe6b3c8dae1397d511062ddab.zip
Use nsIDOMWindowInternal::Close to close tabs. Delay tabs destruction to
2005-10-02 Christian Persch <chpe@cvs.gnome.org> * configure.ac: * embed/ephy-embed-shell.c: (ephy_embed_shell_dispose), (ephy_embed_shell_finalize), (ephy_embed_shell_class_init): * embed/ephy-embed.c: (ephy_embed_base_init), (ephy_embed_show_page_certificate), (ephy_embed_close): * embed/ephy-embed.h: * embed/mozilla/EphyBrowser.cpp: * embed/mozilla/EphyBrowser.h: * embed/mozilla/mozilla-embed.cpp: * src/ephy-notebook.c: (ephy_notebook_class_init), (close_button_clicked_cb): * src/ephy-notebook.h: * src/ephy-python.c: (ephy_python_init), (ephy_python_shutdown), (ephy_python_schedule_gc): * src/ephy-shell.c: (ephy_shell_class_init), (gnome_session_init), (ephy_shell_dispose), (ephy_shell_finalize): * src/ephy-tab.c: (ephy_tab_init): * src/ephy-window.c: (construct_confirm_close_dialog), (confirm_close_with_modified_forms), (embed_modal_alert_cb), (idle_tab_remove_cb), (schedule_tab_close), (embed_close_request_cb), (embed_destroy_browser_cb), (tab_added_cb), (tab_removed_cb), (tab_close_request_cb), (setup_notebook), (remove_true), (ephy_window_dispose), (cancel_handler), (ephy_window_init), (ephy_window_finalize): * src/window-commands.c: (event_with_shift), (window_cmd_view_reload), (window_cmd_file_close_window): Use nsIDOMWindowInternal::Close to close tabs. Delay tabs destruction to an idle handler, to avoid crashes when tabs are closed from signal handlers (blur, mousedown, keydown etc). Fixes bug #172878, bug #172879, bug #172882, bug #303254, bug #313425.
Diffstat (limited to 'embed')
-rw-r--r--embed/ephy-embed-shell.c32
-rw-r--r--embed/ephy-embed.c30
-rw-r--r--embed/ephy-embed.h4
-rw-r--r--embed/mozilla/EphyBrowser.cpp61
-rw-r--r--embed/mozilla/EphyBrowser.h10
-rw-r--r--embed/mozilla/mozilla-embed.cpp9
6 files changed, 122 insertions, 24 deletions
diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c
index 43e7fb692..fb7a7d216 100644
--- a/embed/ephy-embed-shell.c
+++ b/embed/ephy-embed-shell.c
@@ -87,40 +87,49 @@ ephy_embed_shell_get_type (void)
}
static void
-ephy_embed_shell_finalize (GObject *object)
+ephy_embed_shell_dispose (GObject *object)
{
EphyEmbedShell *shell = EPHY_EMBED_SHELL (object);
- LOG ("Unref history");
- if (shell->priv->global_history)
- {
- g_object_unref (shell->priv->global_history);
- }
-
- LOG ("Unref downloader");
if (shell->priv->downloader_view)
{
+ LOG ("Unref downloader");
g_object_remove_weak_pointer
(G_OBJECT(shell->priv->downloader_view),
(gpointer *) &shell->priv->downloader_view);
g_object_unref (shell->priv->downloader_view);
}
- LOG ("Unref favicon cache");
if (shell->priv->favicon_cache)
{
+ LOG ("Unref favicon cache");
g_object_unref (G_OBJECT (shell->priv->favicon_cache));
}
- LOG ("Unref encodings");
if (shell->priv->encodings)
+ LOG ("Unref encodings");
{
+ LOG ("Unref encodings");
g_object_unref (G_OBJECT (shell->priv->encodings));
}
- LOG ("Unref embed single");
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+static void
+ephy_embed_shell_finalize (GObject *object)
+{
+ EphyEmbedShell *shell = EPHY_EMBED_SHELL (object);
+
+ if (shell->priv->global_history)
+ {
+ LOG ("Unref history");
+ g_object_unref (shell->priv->global_history);
+ }
+
if (shell->priv->embed_single)
{
+ LOG ("Unref embed single");
g_object_unref (G_OBJECT (shell->priv->embed_single));
}
@@ -235,6 +244,7 @@ ephy_embed_shell_class_init (EphyEmbedShellClass *klass)
parent_class = (GObjectClass *) g_type_class_peek_parent (klass);
+ object_class->dispose = ephy_embed_shell_dispose;
object_class->finalize = ephy_embed_shell_finalize;
klass->get_embed_single = impl_get_embed_single;
diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c
index 60e82be0a..b1128a835 100644
--- a/embed/ephy-embed.c
+++ b/embed/ephy-embed.c
@@ -368,6 +368,23 @@ ephy_embed_base_init (gpointer g_class)
1,
GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+/**
+ * EphyEmbed::close-request
+ * @embed:
+ *
+ * The ::close signal is emitted when the embed request closing.
+ * Return %TRUE to prevent closing. You HAVE to process removal of the embed
+ * as soon as possible after that.
+ **/
+ g_signal_new ("close-request",
+ EPHY_TYPE_EMBED,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EphyEmbedIface, close_request),
+ g_signal_accumulator_true_handled, NULL,
+ ephy_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN,
+ 0);
+
initialized = TRUE;
}
}
@@ -732,6 +749,19 @@ ephy_embed_show_page_certificate (EphyEmbed *embed)
}
/**
+ * ephy_embed_close:
+ * @embed: an #EphyEmbed
+ *
+ * Closes the @embed
+ **/
+void
+ephy_embed_close (EphyEmbed *embed)
+{
+ EphyEmbedIface *iface = EPHY_EMBED_GET_IFACE (embed);
+ iface->close (embed);
+}
+
+/**
* ephy_embed_set_encoding:
* @embed: an #EphyEmbed
* @encoding: the desired encoding
diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h
index eaac67801..96e4ee77f 100644
--- a/embed/ephy-embed.h
+++ b/embed/ephy-embed.h
@@ -149,6 +149,7 @@ struct _EphyEmbedIface
EphyEmbed *new_embed);
gboolean (* search_key_press) (EphyEmbed *embed,
GdkEventKey *event);
+ gboolean (* close_request) (EphyEmbed *embed);
/* Methods */
void (* load_url) (EphyEmbed *embed,
@@ -197,6 +198,7 @@ struct _EphyEmbedIface
EphyEmbedPrintPreviewNavType type,
int page);
gboolean (* has_modified_forms) (EphyEmbed *embed);
+ void (* close) (EphyEmbed *embed);
};
GType ephy_embed_net_state_get_type (void);
@@ -290,6 +292,8 @@ void ephy_embed_print_preview_navigate (EphyEmbed *embed,
int page);
/* Misc. utility */
+void ephy_embed_close (EphyEmbed *embed);
+
gboolean ephy_embed_has_modified_forms (EphyEmbed *embed);
G_END_DECLS
diff --git a/embed/mozilla/EphyBrowser.cpp b/embed/mozilla/EphyBrowser.cpp
index 3812b87d1..77b7e2c5c 100644
--- a/embed/mozilla/EphyBrowser.cpp
+++ b/embed/mozilla/EphyBrowser.cpp
@@ -90,6 +90,7 @@
/* will never be frozen */
#include "nsIDocShell.h"
#include "nsIMarkupDocumentViewer.h"
+#include <nsIDOMWindowInternal.h>
#ifdef HAVE_MOZILLA_PSM
/* not sure about this one: */
#include <nsITransportSecurityInfo.h>
@@ -108,6 +109,7 @@ const static PRUnichar kDOMMouseScroll[] = { 'D', 'O', 'M', 'M', 'o', 'u', 's',
const static PRUnichar kDOMPopupBlocked[] = { 'D', 'O', 'M', 'P', 'o', 'p', 'u', 'p', 'B', 'l', 'o', 'c', 'k', 'e', 'd', '\0' };
const static PRUnichar kDOMWillOpenModalDialog[] = { 'D', 'O', 'M', 'W', 'i', 'l', 'l', 'O', 'p', 'e', 'n', 'M', 'o', 'd', 'a', 'l', 'D', 'i', 'a', 'l', 'o', 'g', '\0' };
const static PRUnichar kDOMModalDialogClosed[] = { 'D', 'O', 'M', 'M', 'o', 'd', 'a', 'l', 'D', 'i', 'a', 'l', 'o', 'g', 'C', 'l', 'o', 's', 'e', 'd', '\0' };
+const static PRUnichar kDOMWindowClose[] = { 'D', 'O', 'M', 'W', 'i', 'n', 'd', 'o', 'w', 'C', 'l', 'o', 's', 'e', '\0' };
const static PRUnichar kHrefAttr[] = { 'h', 'r', 'e', 'f', '\0' };
const static PRUnichar kTypeAttr[] = { 't', 'y', 'p', 'e', '\0' };
const static PRUnichar kTitleAttr[] = { 't', 'i', 't', 'l', 'e', '\0' };
@@ -273,11 +275,39 @@ EphyDOMLinkEventListener::HandleEvent (nsIDOMEvent* aDOMEvent)
}
NS_IMETHODIMP
-EphyDOMContentLoadedEventListener::HandleEvent (nsIDOMEvent* aDOMEvent)
+EphyMiscDOMEventsListener::HandleEvent (nsIDOMEvent* aDOMEvent)
{
- LOG ("DOMContentLoaded event fired up");
+ /* make sure the event is trusted */
+ nsCOMPtr<nsIDOMNSEvent> nsEvent (do_QueryInterface (aDOMEvent));
+ NS_ENSURE_TRUE (nsEvent, NS_ERROR_FAILURE);
+ PRBool isTrusted = PR_FALSE;
+ nsEvent->GetIsTrusted (&isTrusted);
+ if (!isTrusted) return NS_OK;
- g_signal_emit_by_name (mOwner->mEmbed, "dom_content_loaded", (gpointer)aDOMEvent);
+ nsresult rv;
+ nsEmbedString type;
+ rv = aDOMEvent->GetType (type);
+ NS_ENSURE_SUCCESS (rv, rv);
+
+ nsEmbedCString cType;
+ NS_UTF16ToCString (type, NS_CSTRING_ENCODING_UTF8, cType);
+
+ if (g_ascii_strcasecmp (cType.get(), "DOMContentLoaded") == 0)
+ {
+ g_signal_emit_by_name (mOwner->mEmbed, "dom_content_loaded",
+ (gpointer)aDOMEvent);
+ }
+ else if (g_ascii_strcasecmp (cType.get(), "DOMWindowClose") == 0)
+ {
+ gboolean prevent = FALSE;
+
+ g_signal_emit_by_name (mOwner->mEmbed, "close-request", &prevent);
+
+ if (prevent)
+ {
+ aDOMEvent->PreventDefault ();
+ }
+ }
return NS_OK;
}
@@ -484,7 +514,7 @@ EphyContextMenuListener::HandleEvent (nsIDOMEvent* aDOMEvent)
EphyBrowser::EphyBrowser ()
: mDOMLinkEventListener(nsnull)
-, mDOMContentLoadedEventListener(nsnull)
+, mMiscDOMEventsListener(nsnull)
, mDOMScrollEventListener(nsnull)
, mPopupBlockEventListener(nsnull)
, mModalAlertListener(nsnull)
@@ -524,8 +554,8 @@ nsresult EphyBrowser::Init (GtkMozEmbed *mozembed)
mDOMLinkEventListener = new EphyDOMLinkEventListener(this);
if (!mDOMLinkEventListener) return NS_ERROR_OUT_OF_MEMORY;
- mDOMContentLoadedEventListener = new EphyDOMContentLoadedEventListener(this);
- if (!mDOMContentLoadedEventListener) return NS_ERROR_OUT_OF_MEMORY;
+ mMiscDOMEventsListener = new EphyMiscDOMEventsListener(this);
+ if (!mMiscDOMEventsListener) return NS_ERROR_OUT_OF_MEMORY;
mDOMScrollEventListener = new EphyDOMScrollEventListener(this);
if (!mDOMScrollEventListener) return NS_ERROR_OUT_OF_MEMORY;
@@ -630,7 +660,9 @@ EphyBrowser::AttachListeners(void)
rv = target->AddEventListener(nsEmbedString(kDOMLinkAdded),
mDOMLinkEventListener, PR_FALSE, PR_FALSE);
rv |= target->AddEventListener(nsEmbedString(kDOMContentLoaded),
- mDOMContentLoadedEventListener, PR_FALSE, PR_FALSE);
+ mMiscDOMEventsListener, PR_FALSE, PR_FALSE);
+ rv |= target->AddEventListener(nsEmbedString(kDOMWindowClose),
+ mMiscDOMEventsListener, PR_FALSE, PR_FALSE);
rv |= target->AddEventListener(nsEmbedString(kDOMMouseScroll),
mDOMScrollEventListener, PR_TRUE /* capture */, PR_FALSE);
rv |= target->AddEventListener(nsEmbedString(kDOMPopupBlocked),
@@ -641,7 +673,7 @@ EphyBrowser::AttachListeners(void)
mModalAlertListener, PR_TRUE, PR_FALSE);
rv |= target->AddEventListener(nsEmbedString(kContextMenu),
mContextMenuListener, PR_TRUE /* capture */, PR_FALSE);
- NS_ENSURE_SUCCESS (rv, NS_ERROR_FAILURE);
+ NS_ENSURE_SUCCESS (rv, rv);
return NS_OK;
}
@@ -655,7 +687,9 @@ EphyBrowser::DetachListeners(void)
rv = mEventTarget->RemoveEventListener(nsEmbedString(kDOMLinkAdded),
mDOMLinkEventListener, PR_FALSE);
rv |= mEventTarget->RemoveEventListener(nsEmbedString(kDOMContentLoaded),
- mDOMContentLoadedEventListener, PR_FALSE);
+ mMiscDOMEventsListener, PR_FALSE);
+ rv |= mEventTarget->RemoveEventListener(nsEmbedString(kDOMWindowClose),
+ mMiscDOMEventsListener, PR_FALSE);
rv |= mEventTarget->RemoveEventListener(nsEmbedString(kDOMMouseScroll),
mDOMScrollEventListener, PR_TRUE); /* capture */
rv |= mEventTarget->RemoveEventListener(nsEmbedString(kDOMPopupBlocked),
@@ -1298,6 +1332,15 @@ EphyBrowser::GetDocumentType ()
return type;
}
+nsresult
+EphyBrowser::Close ()
+{
+ nsCOMPtr<nsIDOMWindowInternal> domWin (do_QueryInterface (mDOMWindow));
+ NS_ENSURE_TRUE (domWin, NS_ERROR_FAILURE);
+
+ return domWin->Close();
+}
+
#ifndef HAVE_GECKO_1_8
nsresult
EphyBrowser::FocusActivate ()
diff --git a/embed/mozilla/EphyBrowser.h b/embed/mozilla/EphyBrowser.h
index 3b4fb2284..2020cf4f1 100644
--- a/embed/mozilla/EphyBrowser.h
+++ b/embed/mozilla/EphyBrowser.h
@@ -93,12 +93,12 @@ public:
EphyModalAlertEventListener(EphyBrowser *aOwner) : EphyEventListener(aOwner) { };
};
-class EphyDOMContentLoadedEventListener : public EphyEventListener
+class EphyMiscDOMEventsListener : public EphyEventListener
{
public:
NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent);
- EphyDOMContentLoadedEventListener(EphyBrowser *aOwner) : EphyEventListener(aOwner) { };
+ EphyMiscDOMEventsListener(EphyBrowser *aOwner) : EphyEventListener(aOwner) { };
};
class EphyDOMScrollEventListener : public EphyEventListener
@@ -129,7 +129,7 @@ class EphyBrowser
{
friend class EphyEventListener;
friend class EphyDOMLinkEventListener;
-friend class EphyDOMContentLoadedEventListener;
+friend class EphyMiscDOMEventsListener;
friend class EphyDOMScrollEventListener;
friend class EphyPopupBlockEventListener;
friend class EphyModalAlertEventListener;
@@ -177,6 +177,8 @@ public:
nsresult GetSecurityInfo (PRUint32 *aState, nsACString &aDescription);
nsresult ShowCertificate ();
+ nsresult Close ();
+
EphyEmbedDocumentType GetDocumentType ();
#ifndef HAVE_GECKO_1_8
@@ -193,7 +195,7 @@ private:
nsCOMPtr<nsIDOMEventTarget> mEventTarget;
nsCOMPtr<nsIDOMWindow> mDOMWindow;
EphyDOMLinkEventListener *mDOMLinkEventListener;
- EphyDOMContentLoadedEventListener *mDOMContentLoadedEventListener;
+ EphyMiscDOMEventsListener *mMiscDOMEventsListener;
EphyDOMScrollEventListener *mDOMScrollEventListener;
EphyPopupBlockEventListener *mPopupBlockEventListener;
EphyModalAlertEventListener *mModalAlertListener;
diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp
index b0e9ed5ff..5116f12e3 100644
--- a/embed/mozilla/mozilla-embed.cpp
+++ b/embed/mozilla/mozilla-embed.cpp
@@ -223,6 +223,14 @@ child_focus_out_event_cb (GtkWidget *child,
#endif /* !HAVE_GECKO_1_8 */
static void
+impl_close (EphyEmbed *embed)
+{
+ MozillaEmbedPrivate *mpriv = MOZILLA_EMBED (embed)->priv;
+
+ mpriv->browser->Close ();
+}
+
+static void
mozilla_embed_realize (GtkWidget *widget)
{
MozillaEmbedPrivate *mpriv = MOZILLA_EMBED (widget)->priv;
@@ -1163,6 +1171,7 @@ ephy_embed_iface_init (EphyEmbedIface *iface)
iface->shistory_go_nth = impl_shistory_go_nth;
iface->get_security_level = impl_get_security_level;
iface->show_page_certificate = impl_show_page_certificate;
+ iface->close = impl_close;
iface->set_encoding = impl_set_encoding;
iface->get_encoding = impl_get_encoding;
iface->has_automatic_encoding = impl_has_automatic_encoding;