add code to handle the destruction of a window via JS, add support for FindNamedBrowserItem and fix some destruction related bugs in the widget.

This commit is contained in:
blizzard%redhat.com 2000-05-12 03:14:42 +00:00
parent fbe70352f0
commit 58dda5544f
5 changed files with 154 additions and 22 deletions

View File

@ -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<nsIWebBrowser> webBrowser;
NS_ENSURE_SUCCESS(chrome->GetWebBrowser(getter_AddRefs(webBrowser)), NS_ERROR_FAILURE);
nsCOMPtr<nsIDocShellTreeItem> 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)

View File

@ -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<nsIWebBrowser> 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 */

View File

@ -42,8 +42,6 @@ public:
nsCOMPtr<nsIWebBrowser> webBrowser;
nsCOMPtr<nsIWebNavigation> navigation;
nsCOMPtr<nsIGtkEmbed> embed;
nsCOMPtr<nsISupportsArray> 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<nsIWebBrowserChrome> 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<nsIWebBrowserChrome> 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<nsIBaseWindow> 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]);
}

View File

@ -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 */

View File

@ -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