diff --git a/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.cpp b/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.cpp index ce37205787a..1dbb16a6d63 100644 --- a/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.cpp +++ b/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.cpp @@ -22,6 +22,7 @@ #include "GtkMozEmbedChrome.h" #include "nsCWebBrowser.h" #include "nsIURI.h" +#include "nsIDocShellTreeItem.h" #include "nsCRT.h" #include "prlog.h" @@ -36,10 +37,14 @@ static PRLogModuleInfo *mozEmbedLm = NULL; +nsVoidArray *GtkMozEmbedChrome::sBrowsers = NULL; + // constructor and destructor GtkMozEmbedChrome::GtkMozEmbedChrome() { NS_INIT_REFCNT(); + mOwningGtkWidget = nsnull; + mWebBrowser = nsnull; mNewBrowserCB = nsnull; mNewBrowserCBData = nsnull; mDestroyCB = nsnull; @@ -67,12 +72,19 @@ GtkMozEmbedChrome::GtkMozEmbedChrome() mJSStatus = NULL; mLocation = NULL; mTitle = NULL; + mChromeMask = 0; if (!mozEmbedLm) mozEmbedLm = PR_NewLogModule("GtkMozEmbedChrome"); + if (!sBrowsers) + sBrowsers = new nsVoidArray(); + sBrowsers->AppendElement((void *)this); + PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::GtkMozEmbedChrome %p\n", this)); } GtkMozEmbedChrome::~GtkMozEmbedChrome() { + PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::~GtkMozEmbedChrome %p\n", this)); + sBrowsers->RemoveElement((void *)this); } // nsISupports interface @@ -96,7 +108,7 @@ NS_IMETHODIMP GtkMozEmbedChrome::Init(GtkWidget *aOwningWidget) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::Init\n")); mOwningGtkWidget = aOwningWidget; - return NS_ERROR_NOT_IMPLEMENTED; + return NS_OK; } NS_IMETHODIMP GtkMozEmbedChrome::SetNewBrowserCallback(GtkMozEmbedChromeCB *aCallback, void *aData) @@ -254,25 +266,38 @@ NS_IMETHODIMP GtkMozEmbedChrome::SetOverLink(const PRUnichar *link) NS_IMETHODIMP GtkMozEmbedChrome::GetWebBrowser(nsIWebBrowser * *aWebBrowser) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::GetWebBrowser\n")); - return NS_ERROR_NOT_IMPLEMENTED; + + NS_ENSURE_ARG_POINTER(aWebBrowser); + *aWebBrowser = mWebBrowser; + NS_IF_ADDREF(*aWebBrowser); + + return NS_OK; + } NS_IMETHODIMP GtkMozEmbedChrome::SetWebBrowser(nsIWebBrowser * aWebBrowser) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::SetWebBrowser\n")); - return NS_ERROR_NOT_IMPLEMENTED; + + NS_ENSURE_ARG_POINTER(aWebBrowser); + mWebBrowser = aWebBrowser; + + return NS_OK; } NS_IMETHODIMP GtkMozEmbedChrome::GetChromeMask(PRUint32 *aChromeMask) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::GetChromeMask\n")); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(aChromeMask); + *aChromeMask = mChromeMask; + return NS_OK; } NS_IMETHODIMP GtkMozEmbedChrome::SetChromeMask(PRUint32 aChromeMask) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::SetChromeMask\n")); - return NS_ERROR_NOT_IMPLEMENTED; + mChromeMask = aChromeMask; + return NS_OK; } NS_IMETHODIMP GtkMozEmbedChrome::GetNewBrowser(PRUint32 chromeMask, @@ -282,14 +307,34 @@ NS_IMETHODIMP GtkMozEmbedChrome::GetNewBrowser(PRUint32 chromeMask, if (mNewBrowserCB) return mNewBrowserCB(chromeMask, _retval, mNewBrowserCBData); else - return NS_ERROR_NOT_IMPLEMENTED; + return NS_ERROR_FAILURE; } NS_IMETHODIMP GtkMozEmbedChrome::FindNamedBrowserItem(const PRUnichar *aName, nsIDocShellTreeItem **_retval) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::FindNamedBrowserItem\n")); - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG_POINTER(_retval); + *_retval = nsnull; + + PRInt32 i = 0; + PRInt32 numBrowsers = sBrowsers->Count(); + + for (i = 0; i < numBrowsers; i++) + { + GtkMozEmbedChrome *chrome = (GtkMozEmbedChrome *)sBrowsers->ElementAt(i); + nsCOMPtr webBrowser; + NS_ENSURE_SUCCESS(chrome->GetWebBrowser(getter_AddRefs(webBrowser)), NS_ERROR_FAILURE); + + nsCOMPtr docShellAsItem(do_QueryInterface(webBrowser)); + NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); + + docShellAsItem->FindItemWithName(aName, NS_STATIC_CAST(nsIWebBrowserChrome *, this), _retval); + if (!*_retval) + return NS_OK; + } + + return NS_OK; } NS_IMETHODIMP GtkMozEmbedChrome::SizeBrowserTo(PRInt32 aCX, PRInt32 aCY) @@ -493,7 +538,9 @@ NS_IMETHODIMP GtkMozEmbedChrome::Create(void) NS_IMETHODIMP GtkMozEmbedChrome::Destroy(void) { PR_LOG(mozEmbedLm, PR_LOG_DEBUG, ("GtkMozEmbedChrome::Destory\n")); - return NS_ERROR_NOT_IMPLEMENTED; + if (mDestroyCB) + mDestroyCB(mDestroyCBData); + return NS_OK; } NS_IMETHODIMP GtkMozEmbedChrome::SetPosition(PRInt32 x, PRInt32 y) diff --git a/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.h b/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.h index d6340c66443..3b950c1731e 100644 --- a/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.h +++ b/mozilla/embedding/browser/gtk/src/GtkMozEmbedChrome.h @@ -37,6 +37,7 @@ // utility classes #include "nsXPIDLString.h" #include "nsString.h" +#include "nsVoidArray.h" // include our gtk stuff here #include "gdksuperwin.h" @@ -84,6 +85,7 @@ public: private: GtkWidget *mOwningGtkWidget; + nsCOMPtr mWebBrowser; GtkMozEmbedChromeCB *mNewBrowserCB; void *mNewBrowserCBData; GtkMozEmbedDestroyCB *mDestroyCB; @@ -109,6 +111,8 @@ private: nsXPIDLCString mLocation; nsXPIDLCString mTitle; nsString mTitleUnicode; + PRUint32 mChromeMask; + static nsVoidArray *sBrowsers; }; #endif /* __GtkMozEmbedChrome_h */ diff --git a/mozilla/embedding/browser/gtk/src/gtkmozembed.cpp b/mozilla/embedding/browser/gtk/src/gtkmozembed.cpp index 104b987e686..91fea25faf7 100644 --- a/mozilla/embedding/browser/gtk/src/gtkmozembed.cpp +++ b/mozilla/embedding/browser/gtk/src/gtkmozembed.cpp @@ -42,8 +42,6 @@ public: nsCOMPtr webBrowser; nsCOMPtr navigation; nsCOMPtr embed; - nsCOMPtr topLevelWindowWebShells; - nsVoidArray topLevelWindows; nsCString mInitialURL; }; @@ -60,6 +58,7 @@ enum { NET_STOP, NEW_WINDOW, VISIBILITY, + DESTROY_BROWSER, LAST_SIGNAL }; @@ -126,6 +125,9 @@ gtk_moz_embed_handle_new_window(PRUint32 chromeMask, nsIWebBrowser **_retval, vo static void gtk_moz_embed_handle_visibility(PRBool aVisibility, void *aData); +static void +gtk_moz_embed_handle_destroy(void *aData); + static GtkBinClass *parent_class; static PRBool NS_SetupRegistryCalled = PR_FALSE; @@ -286,6 +288,13 @@ gtk_moz_embed_class_init(GtkMozEmbedClass *klass) GTK_SIGNAL_OFFSET(GtkMozEmbedClass, visibility), gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1, GTK_TYPE_BOOL); + moz_embed_signals[DESTROY_BROWSER] = + gtk_signal_new("destroy_browser", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET(GtkMozEmbedClass, destroy_brsr), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); gtk_object_class_add_signals(object_class, moz_embed_signals, LAST_SIGNAL); @@ -316,7 +325,10 @@ gtk_moz_embed_init(GtkMozEmbed *embed) // set the toplevel window embed_private->webBrowser->SetTopLevelWindow(browserChrome); // set the widget as the owner of the object - embed_private->embed->Init((GtkWidget *)embed); + embed_private->embed->Init(GTK_WIDGET(embed)); + + // so the embedding widget can find it's owning nsIWebBrowser object + browserChrome->SetWebBrowser(embed_private->webBrowser); // track the window changes embed_private->embed->SetLinkChangeCallback((generic_cb_with_data)gtk_moz_embed_handle_link_change, @@ -333,6 +345,7 @@ gtk_moz_embed_init(GtkMozEmbed *embed) embed); embed_private->embed->SetNewBrowserCallback(gtk_moz_embed_handle_new_window, embed); embed_private->embed->SetVisibilityCallback(gtk_moz_embed_handle_visibility, embed); + embed_private->embed->SetDestroyCallback(gtk_moz_embed_handle_destroy, embed); // get our hands on a copy of the nsIWebNavigation interface for later embed_private->navigation = do_QueryInterface(embed_private->webBrowser); g_return_if_fail(embed_private->navigation); @@ -446,6 +459,38 @@ gtk_moz_embed_reload (GtkMozEmbed *embed, gint32 flags) embed_private->navigation->Reload(flags); } +void +gtk_moz_embed_set_chrome_mask (GtkMozEmbed *embed, guint32 flags) +{ + GtkMozEmbedPrivate *embed_private; + + g_return_if_fail (embed != NULL); + g_return_if_fail (GTK_IS_MOZ_EMBED(embed)); + + embed_private = (GtkMozEmbedPrivate *)embed->data; + nsCOMPtr browserChrome = do_QueryInterface(embed_private->embed); + g_return_if_fail(browserChrome); + browserChrome->SetChromeMask(flags); +} + +guint32 +gtk_moz_embed_get_chrome_mask (GtkMozEmbed *embed) +{ + GtkMozEmbedPrivate *embed_private; + PRUint32 curMask = 0; + + g_return_val_if_fail ((embed != NULL), 0); + g_return_val_if_fail (GTK_IS_MOZ_EMBED(embed), 0); + + embed_private = (GtkMozEmbedPrivate *)embed->data; + nsCOMPtr browserChrome = do_QueryInterface(embed_private->embed); + g_return_val_if_fail(browserChrome, 0); + if (browserChrome->GetChromeMask(&curMask) == NS_OK) + return curMask; + else + return 0; +} + char * gtk_moz_embed_get_link_message (GtkMozEmbed *embed) { @@ -662,6 +707,9 @@ gtk_moz_embed_destroy(GtkObject *object) if (embed_private) { + nsCOMPtr webBrowserBaseWindow = do_QueryInterface(embed_private->webBrowser); + g_return_if_fail(webBrowserBaseWindow); + webBrowserBaseWindow->Destroy(); embed_private->webBrowser = nsnull; embed_private->embed = nsnull; // XXX XXX delete all the members of the topLevelWindows @@ -781,3 +829,11 @@ gtk_moz_embed_handle_visibility(PRBool aVisibility, void *aData) g_return_if_fail(GTK_IS_MOZ_EMBED(embed)); gtk_signal_emit(GTK_OBJECT(embed), moz_embed_signals[VISIBILITY], aVisibility); } + +static void +gtk_moz_embed_handle_destroy(void *aData) +{ + GtkMozEmbed *embed = (GtkMozEmbed *)aData; + g_return_if_fail(GTK_IS_MOZ_EMBED(embed)); + gtk_signal_emit(GTK_OBJECT(embed), moz_embed_signals[DESTROY_BROWSER]); +} diff --git a/mozilla/embedding/browser/gtk/src/gtkmozembed.h b/mozilla/embedding/browser/gtk/src/gtkmozembed.h index 5882ed6474a..bbca00f22dd 100644 --- a/mozilla/embedding/browser/gtk/src/gtkmozembed.h +++ b/mozilla/embedding/browser/gtk/src/gtkmozembed.h @@ -58,6 +58,7 @@ struct _GtkMozEmbedClass void (* net_stop) (GtkMozEmbed *embed); void (* new_window) (GtkMozEmbed *embed, GtkMozEmbed **newEmbed, guint chromemask); void (* visibility) (GtkMozEmbed *embed, gboolean visibility); + void (* destroy_brsr) (GtkMozEmbed *embed); }; extern GtkType gtk_moz_embed_get_type (void); @@ -68,12 +69,13 @@ extern gboolean gtk_moz_embed_can_go_back (GtkMozEmbed *embed); extern gboolean gtk_moz_embed_can_go_forward (GtkMozEmbed *embed); extern void gtk_moz_embed_go_back (GtkMozEmbed *embed); extern void gtk_moz_embed_go_forward (GtkMozEmbed *embed); -extern void gtk_moz_embed_reload (GtkMozEmbed *embed, gint32 flags); extern char *gtk_moz_embed_get_link_message (GtkMozEmbed *embed); extern char *gtk_moz_embed_get_js_status (GtkMozEmbed *embed); extern char *gtk_moz_embed_get_title (GtkMozEmbed *embed); extern char *gtk_moz_embed_get_location (GtkMozEmbed *embed); extern void gtk_moz_embed_reload (GtkMozEmbed *embed, gint32 flags); +extern void gtk_moz_embed_set_chrome_mask (GtkMozEmbed *embed, guint32 flags); +extern guint32 gtk_moz_embed_get_chrome_mask (GtkMozEmbed *embed); /* These are straight out of nsIWebProgress.h */ diff --git a/mozilla/embedding/browser/gtk/tests/TestGtkEmbed.cpp b/mozilla/embedding/browser/gtk/tests/TestGtkEmbed.cpp index 0d2d40bef77..574d5b88902 100644 --- a/mozilla/embedding/browser/gtk/tests/TestGtkEmbed.cpp +++ b/mozilla/embedding/browser/gtk/tests/TestGtkEmbed.cpp @@ -44,7 +44,7 @@ typedef struct _TestGtkBrowser { char *tempMessage; } TestGtkBrowser; -static TestGtkBrowser *new_gtk_browser (void); +static TestGtkBrowser *new_gtk_browser (guint32 chromeMask); static int num_browsers = 0; @@ -54,8 +54,9 @@ static void stop_clicked_cb (GtkButton *button, TestGtkBrowser *browser static void forward_clicked_cb (GtkButton *button, TestGtkBrowser *browser); static void reload_clicked_cb (GtkButton *button, TestGtkBrowser *browser); static void url_activate_cb (GtkEditable *widget, TestGtkBrowser *browser); -static gboolean destroy_cb (GtkWidget *widget, GdkEventAny *event, +static gboolean delete_cb (GtkWidget *widget, GdkEventAny *event, TestGtkBrowser *browser); +static void destroy_cb (GtkWidget *widget, TestGtkBrowser *browser); // callbacks from the widget static void location_changed_cb (GtkMozEmbed *embed, TestGtkBrowser *browser); @@ -70,6 +71,7 @@ static void js_status_cb (GtkMozEmbed *embed, TestGtkBrowser *browser); static void new_window_cb (GtkMozEmbed *embed, GtkMozEmbed **retval, guint chromemask, TestGtkBrowser *browser); static void visibility_cb (GtkMozEmbed *embed, gboolean visibility, TestGtkBrowser *browser); +static void destroy_brsr_cb (GtkMozEmbed *embed, TestGtkBrowser *browser); // some utility functions static void update_status_bar_text (TestGtkBrowser *browser); @@ -81,7 +83,7 @@ main(int argc, char **argv) { gtk_init(&argc, &argv); - TestGtkBrowser *browser = new_gtk_browser(); + TestGtkBrowser *browser = new_gtk_browser(gtk_moz_embed_flag_defaultChrome); // set our minimum size gtk_widget_set_usize(browser->topLevelWindow, 400, 400); @@ -95,7 +97,7 @@ main(int argc, char **argv) } static TestGtkBrowser * -new_gtk_browser(void) +new_gtk_browser(guint32 chromeMask) { TestGtkBrowser *browser = 0; @@ -200,7 +202,7 @@ new_gtk_browser(void) // catch the destruction of the toplevel window gtk_signal_connect(GTK_OBJECT(browser->topLevelWindow), "delete_event", - GTK_SIGNAL_FUNC(destroy_cb), browser); + GTK_SIGNAL_FUNC(delete_cb), browser); // hook up the activate signal to the right callback gtk_signal_connect(GTK_OBJECT(browser->urlEntry), "activate", GTK_SIGNAL_FUNC(url_activate_cb), browser); @@ -233,6 +235,14 @@ new_gtk_browser(void) // hookup to any requested visibility changes gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "visibility", GTK_SIGNAL_FUNC(visibility_cb), browser); + gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "destroy_browser", + GTK_SIGNAL_FUNC(destroy_brsr_cb), browser); + // hookup to when the window is destroyed + gtk_signal_connect(GTK_OBJECT(browser->mozEmbed), "destroy", + GTK_SIGNAL_FUNC(destroy_cb), browser); + + // set the chrome type so it's stored in the object + gtk_moz_embed_set_chrome_mask(GTK_MOZ_EMBED(browser->mozEmbed), chromeMask); return browser; } @@ -272,16 +282,22 @@ url_activate_cb (GtkEditable *widget, TestGtkBrowser *browser) } gboolean -destroy_cb(GtkWidget *widget, GdkEventAny *event, TestGtkBrowser *browser) +delete_cb(GtkWidget *widget, GdkEventAny *event, TestGtkBrowser *browser) +{ + g_print("delete_cb\n"); + gtk_widget_destroy(widget); + return TRUE; +} + +void +destroy_cb (GtkWidget *widget, TestGtkBrowser *browser) { g_print("destroy_cb\n"); + num_browsers--; if (browser->tempMessage) g_free(browser->tempMessage); - num_browsers--; - gtk_widget_destroy(widget); if (num_browsers == 0) gtk_main_quit(); - return TRUE; } void @@ -434,7 +450,7 @@ new_window_cb (GtkMozEmbed *embed, GtkMozEmbed **newEmbed, guint chromemask, Tes { g_print("new_window_cb\n"); g_print("embed is %p chromemask is %d\n", embed, chromemask); - TestGtkBrowser *newBrowser = new_gtk_browser(); + TestGtkBrowser *newBrowser = new_gtk_browser(chromemask); gtk_widget_set_usize(newBrowser->topLevelWindow, 400, 400); *newEmbed = GTK_MOZ_EMBED(newBrowser->mozEmbed); g_print("new browser is %p\n", *newEmbed); @@ -450,6 +466,13 @@ visibility_cb (GtkMozEmbed *embed, gboolean visibility, TestGtkBrowser *browser) gtk_widget_hide_all(browser->topLevelWindow); } +void +destroy_brsr_cb (GtkMozEmbed *embed, TestGtkBrowser *browser) +{ + g_print("destroy_brsr_cb\n"); + gtk_widget_destroy(browser->topLevelWindow); +} + // utility functions void