Bug 455247: x11 backend of gtk+ embedding widget needs to be updated, r=mfinkle
authorJuan Pablo <juanpablougarte@gmail>
Thu, 26 Mar 2009 00:32:35 -0500
changeset 116 a6038143acd010f52f677cd7615117cc79ee0be9
parent 115 0878e47086b866995af01a42ae442c637af88a7c
child 117 0567bf985e06bf238c02d509e186fba5da1d2746
push id34
push usermfinkle@mozilla.com
push dateThu, 26 Mar 2009 05:32:51 +0000
reviewersmfinkle
bugs455247
Bug 455247: x11 backend of gtk+ embedding widget needs to be updated, r=mfinkle
gtk/common/moz-web-view-common.cpp
gtk/common/moz-web-view-common.h
gtk/include/moz-web-view.h
gtk/win32/moz-web-view.cpp
gtk/win32/win32gtk.vcproj
gtk/x11/moz-web-view.cpp
--- a/gtk/common/moz-web-view-common.cpp
+++ b/gtk/common/moz-web-view-common.cpp
@@ -31,20 +31,17 @@
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsError.h"
-
-#include "embed.h"
 #include "EmbeddingSetup.h"
-#include "moz-web-view.h"
 #include "moz-web-view-common.h"
 #include "moz-web-view-marshal.h"
 
 static MozApp *app = NULL;
 static gint init_count = 0;
 
 gboolean
 moz_web_view_init_embedding(const gchar *profile_path)
@@ -224,44 +221,45 @@ moz_viewable_get_type(void)
                                         0, NULL, (GTypeFlags)0);
 
         g_type_interface_add_prerequisite(viewable_type, G_TYPE_OBJECT);
     }
 
     return viewable_type;
 }
 
+static gchar *
+moz_web_view_get_prop(MozWebView *view, const gchar *prop)
+{
+    gchar *ret = NULL;
+    g_return_val_if_fail(MOZ_IS_WEB_VIEW(view), NULL);
+
+    g_object_get(G_OBJECT(view), prop, &ret, NULL);
+
+    return ret;
+}
 
 /*******************************************************
  *                MozWebView accessors                 *
  *******************************************************/
 gchar *
+moz_web_view_get_requested_uri(MozWebView *view)
+{
+    return moz_web_view_get_prop (view, "requested-uri");
+}
+
+gchar *
 moz_web_view_get_title(MozWebView *view)
 {
-    gchar *ret = NULL;
-    g_return_val_if_fail(MOZ_IS_WEB_VIEW(view), NULL);
-
-    g_object_get(G_OBJECT(view), "title", &ret, NULL);
-
-    return ret;
+    return moz_web_view_get_prop (view, "title");
 }
 
 gchar *
 moz_web_view_get_status(MozWebView *view)
 {
-    gchar *ret = NULL;
-    g_return_val_if_fail(MOZ_IS_WEB_VIEW(view), NULL);
-
-    g_object_get(G_OBJECT(view), "status", &ret, NULL);
-
-    return ret;
+    return moz_web_view_get_prop (view, "status");
 }
 
 gchar *
 moz_web_view_get_location(MozWebView *view)
 {
-    gchar *ret = NULL;
-    g_return_val_if_fail(MOZ_IS_WEB_VIEW(view), NULL);
-
-    g_object_get(G_OBJECT(view), "location", &ret, NULL);
-
-    return ret;
+    return moz_web_view_get_prop (view, "location");
 }
--- a/gtk/common/moz-web-view-common.h
+++ b/gtk/common/moz-web-view-common.h
@@ -1,11 +1,14 @@
 #ifndef MOZ_WEB_VIEW_GTK_COMMON_H
 #define MOZ_WEB_VIEW_GTK_COMMON_H
 
+#include <moz-web-view.h>
+#include <embed.h>
+
 G_BEGIN_DECLS
 
 #define MOZ_TYPE_VIEWABLE            (moz_viewable_get_type ())
 #define MOZ_VIEWABLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOZ_TYPE_VIEWABLE, MozViewable))
 #define MOZ_VIEWABLE_CLASS(obj)      (G_TYPE_CHECK_CLASS_CAST ((obj), MOZ_TYPE_VIEWABLE, MozViewableIface))
 #define MOZ_IS_VIEWABLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOZ_TYPE_VIEWABLE))
 #define MOZ_VIEWABLE_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MOZ_TYPE_VIEWABLE, MozViewableIface))
 
@@ -26,12 +29,28 @@ struct _MozViewableIface {
     void     (*status_changed) (MozViewable *view, const char *status);
     void     (*location_changed) (MozViewable *view, const char *uri);
     gboolean (*uri_requested)   (MozViewable *view, const char *uri);
     void     (*document_loaded) (MozViewable *view);
 };
 
 GType     moz_viewable_get_type               (void) G_GNUC_CONST;
 
+enum {
+    TITLE_CHANGED,
+    STATUS_CHANGED,
+    LOCATION_CHANGED,
+    URI_REQUESTED,
+    DOCUMENT_LOADED,
+    LAST_SIGNAL
+};
+
+enum {
+    PROP_0,
+    PROP_REQUESTED_URI,
+    PROP_TITLE,
+    PROP_STATUS,
+    PROP_LOCATION
+};
 
 G_END_DECLS
 
 #endif
--- a/gtk/include/moz-web-view.h
+++ b/gtk/include/moz-web-view.h
@@ -17,38 +17,33 @@ typedef struct _MozWebViewPriv  MozWebVi
 
 struct _MozWebView {
     GtkBin bin;
     MozWebViewPriv *priv;
 };
 
 struct _MozWebViewClass {
     GtkBinClass parent_class;
-
-    void     (*title_changed) (MozWebViewClass *view, const char *title);
-    void     (*status_changed) (MozWebViewClass *view, const char *status);
-    void     (*location_changed) (MozWebViewClass *view, const char *uri);
-    gboolean (*uri_requested) (MozWebViewClass  *view, const char *uri);
-    void     (*document_loaded) (MozWebViewClass *view);
 };
 
 GType      moz_web_view_get_type  (void);
 GtkWidget *moz_web_view_new       (void);
 
 void       moz_web_view_load_uri       (MozWebView  *view, const char *uri);
 void       moz_web_view_load_data      (MozWebView  *view,
                                         const gchar *base_uri,
                                         const gchar *content_type,
                                         const gchar *data,
                                         gsize        len);
 
 /* Apis implemented in common/moz-web-view-common.cpp follow */
-gchar *    moz_web_view_get_title      (MozWebView  *view);
-gchar *    moz_web_view_get_status     (MozWebView  *view);
-gchar *    moz_web_view_get_location   (MozWebView  *view);
+gchar *    moz_web_view_get_requested_uri (MozWebView  *view);
+gchar *    moz_web_view_get_title         (MozWebView  *view);
+gchar *    moz_web_view_get_status        (MozWebView  *view);
+gchar *    moz_web_view_get_location      (MozWebView  *view);
 
 gboolean   moz_web_view_init_embedding (const gchar *profile_path);
 gboolean   moz_web_view_term_embedding (void);
 
 /* Be sure to have embedding initialized before setting prefs */
 gboolean   moz_web_view_set_char_pref  (const char  *name,
                                         const char  *value);
 gboolean   moz_web_view_set_bool_pref  (const char  *name,
--- a/gtk/win32/moz-web-view.cpp
+++ b/gtk/win32/moz-web-view.cpp
@@ -30,76 +30,64 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-
 // Glib/System includes
 #include <string.h>
 #include <gdk/gdkwin32.h>
-#include <gtk/gtk.h>
-
-// Mozilla header files
-#include "embed.h"
 
 // Local includes
-#include "moz-web-view.h"
 #include "moz-web-view-common.h"
 
 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), MOZ_TYPE_WEB_VIEW, MozWebViewPriv))
 
 //#define TRACING
 
 #ifdef TRACING
 #  define DBG(x) x
 #else
 #  define DBG(x)
 #endif
 
 
 /* GObjectClass */
-static void     moz_web_view_finalize            (GObject           *object);
-static void     moz_web_view_set_property        (GObject           *object,
-						  guint              prop_id,
-						  const GValue      *value,
-						  GParamSpec        *pspec);
-static void     moz_web_view_get_property        (GObject           *object,
-						  guint              prop_id,
-						  GValue            *value,
-						  GParamSpec        *pspec);
+static void moz_web_view_finalize     (GObject      *object);
+static void moz_web_view_set_property (GObject      *object,
+                                       guint         prop_id,
+                                       const GValue *value,
+                                       GParamSpec   *pspec);
+static void moz_web_view_get_property (GObject      *object,
+                                       guint         prop_id,
+                                       GValue       *value,
+                                       GParamSpec   *pspec);
 
 /* GtkWidgetClass */
-static void     moz_web_view_realize             (GtkWidget         *widget);
-static void     moz_web_view_unrealize           (GtkWidget         *widget);
-static void     moz_web_view_hierarchy_changed   (GtkWidget         *widget,
-						  GtkWidget         *previous_toplevel);
-static void     moz_web_view_size_allocate       (GtkWidget         *widget,
-						  GtkAllocation     *allocation);
-static void     moz_web_view_map                 (GtkWidget         *widget);
-static void     moz_web_view_unmap               (GtkWidget         *widget);
-
-/* MozViewableIface */
-static void     moz_web_view_viewable_init       (MozViewableIface  *iface);
+static void moz_web_view_realize           (GtkWidget         *widget);
+static void moz_web_view_unrealize         (GtkWidget         *widget);
+static void moz_web_view_hierarchy_changed (GtkWidget         *widget,
+                                            GtkWidget         *previous_toplevel);
+static void moz_web_view_size_allocate     (GtkWidget         *widget,
+                                            GtkAllocation     *allocation);
+static void moz_web_view_map               (GtkWidget         *widget);
+static void moz_web_view_unmap             (GtkWidget         *widget);
 
 /* various local stubs */
-static gboolean handle_toplevel_configure    (GtkWidget         *toplevel,
-					      GdkEventConfigure *event,
-					      GtkWidget         *widget);
-static HWND     create_native_window         (GtkWidget         *widget);
-static LRESULT  window_procedure             (HWND               hwnd,
-					      UINT               message,
-					      WPARAM             wparam,
-					      LPARAM             lparam);
-static void     update_property              (MozWebView        *view,
-					      gint               prop_id,
-					      const gchar       *new_value);
+static gboolean handle_toplevel_configure (GtkWidget         *toplevel,
+                                           GdkEventConfigure *event,
+                                           GtkWidget         *widget);
+static HWND     create_native_window      (GtkWidget         *widget);
+static LRESULT  window_procedure          (HWND               hwnd,
+                                           UINT               message,
+                                           WPARAM             wparam,
+                                           LPARAM             lparam);
 
 class ViewListener;
 struct _MozWebViewPriv {
     /* Essential api to the gecko */
     MozApp       *app;
     MozView      *view;
     ViewListener *listener;
 
@@ -108,66 +96,85 @@ struct _MozWebViewPriv {
 
     /* Record some properties here */
     gchar       *requested_uri;
     gchar       *title;
     gchar       *status;
     gchar       *location;
 };
 
-enum {
-    PROP_0,
-    PROP_REQUESTED_URI,
-    PROP_TITLE,
-    PROP_STATUS,
-    PROP_LOCATION
-};
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+moz_web_view_viewable_init (MozViewableIface *iface) {}
 
 G_DEFINE_TYPE_WITH_CODE (MozWebView, moz_web_view, GTK_TYPE_BIN,
-			 G_IMPLEMENT_INTERFACE (MOZ_TYPE_VIEWABLE,
-						moz_web_view_viewable_init))
+                         G_IMPLEMENT_INTERFACE (MOZ_TYPE_VIEWABLE,
+                                                moz_web_view_viewable_init))
+
+static void
+update_property (MozWebView  *view, gint prop_id, const gchar *new_value)
+{
+    MozWebViewPriv *priv = view->priv;
+    const gchar *name = NULL; 
+    gchar **ptr;
 
-/*******************************************************************
- *                      ViewListener here                           *
- *******************************************************************/
+    switch (prop_id) {
+        case PROP_REQUESTED_URI: ptr = &(priv->requested_uri); name = "requested-uri";  break;
+        case PROP_TITLE:         ptr = &(priv->title);         name = "title";  break;
+        case PROP_STATUS:        ptr = &(priv->status);        name = "status";  break;
+        case PROP_LOCATION:      ptr = &(priv->location);      name = "location";  break;
+        default:
+            g_assert_not_reached ();
+        break;
+    }
+
+    g_free (*ptr);
+    *ptr = g_strdup (new_value);
+    g_object_notify (G_OBJECT (view), name);
+}
+
 class ViewListener : public MozViewListener {
 public:
     ViewListener(MozWebView *view) : mView(view) {}
     virtual ~ViewListener() {}
 
     virtual void SetTitle(const char *new_title) {
-	update_property(mView, PROP_TITLE, new_title);
-	g_signal_emit_by_name(G_OBJECT(mView), "title-changed", new_title);
+        update_property (mView, PROP_TITLE, new_title);
+        g_signal_emit (mView, signals[TITLE_CHANGED],
+                       NULL, new_title);
     }
 
     virtual void StatusChanged(const char *new_status, PRUint32 flags) {
-	update_property(mView, PROP_STATUS, new_status);
-	g_signal_emit_by_name(G_OBJECT(mView), "status-changed", new_status);
+        update_property (mView, PROP_STATUS, new_status);
+        g_signal_emit (mView, signals[STATUS_CHANGED],
+                       NULL, new_status);
     }
 
     virtual void LocationChanged(const char *new_uri) {
-	update_property(mView, PROP_LOCATION, new_uri);
-	g_signal_emit_by_name(G_OBJECT(mView), "location-changed", new_uri);
+        update_property (mView, PROP_LOCATION, new_uri);
+        g_signal_emit (mView, signals[LOCATION_CHANGED],
+                       NULL, new_uri);
     }
 
-    virtual PRBool ViewListener::OpenURI(const char* new_uri) {
-	gboolean   abort_load = FALSE;
-	
-	g_signal_emit_by_name(G_OBJECT(mView), "uri-requested", 
-			      new_uri, &abort_load);
-	
-	return abort_load;
+    virtual PRBool OpenURI(const char* new_uri) {
+        gboolean   abort_load = FALSE;
+        update_property (mView, PROP_REQUESTED_URI, new_uri);
+        g_signal_emit (mView, signals[URI_REQUESTED],
+                       NULL, new_uri, &abort_load);
+
+        return abort_load;
     }
-    
-    virtual void ViewListener::DocumentLoaded() {
-	g_signal_emit_by_name(G_OBJECT(mView), "document-loaded");
+
+    virtual void DocumentLoaded() {
+        g_signal_emit (mView, signals[DOCUMENT_LOADED], NULL);
     }
-    
-private:
-    MozWebView *mView;
+
+    private:
+        MozWebView *mView;
 };
 
 /*******************************************************************
  *                      Class Initialization                       *
  *******************************************************************/
 static void
 moz_web_view_class_init(MozWebViewClass *klass)
 {
@@ -179,16 +186,22 @@ moz_web_view_class_init(MozWebViewClass 
     
     widget_klass->realize           = moz_web_view_realize;
     widget_klass->unrealize         = moz_web_view_unrealize;
     widget_klass->hierarchy_changed = moz_web_view_hierarchy_changed;
     widget_klass->size_allocate     = moz_web_view_size_allocate;
     widget_klass->map               = moz_web_view_map;
     widget_klass->unmap             = moz_web_view_unmap;
 
+    signals[TITLE_CHANGED] = g_signal_lookup ("title-changed", MOZ_TYPE_WEB_VIEW);
+    signals[STATUS_CHANGED] = g_signal_lookup ("status-changed", MOZ_TYPE_WEB_VIEW);
+    signals[LOCATION_CHANGED] = g_signal_lookup ("location-changed", MOZ_TYPE_WEB_VIEW);
+    signals[URI_REQUESTED] = g_signal_lookup ("uri-requested", MOZ_TYPE_WEB_VIEW);
+    signals[DOCUMENT_LOADED] = g_signal_lookup ("document-loaded", MOZ_TYPE_WEB_VIEW);
+
     /* Implement MozViewable properties */
     g_object_class_override_property(object_klass, PROP_REQUESTED_URI, "requested-uri");
     g_object_class_override_property(object_klass, PROP_TITLE, "title");
     g_object_class_override_property(object_klass, PROP_STATUS, "status");
     g_object_class_override_property(object_klass, PROP_LOCATION, "location");
 
     g_type_class_add_private(object_klass, sizeof(MozWebViewPriv));
 }
@@ -204,116 +217,77 @@ moz_web_view_init(MozWebView *view)
     GTK_WIDGET_SET_FLAGS(view, GTK_CAN_FOCUS);
     
     priv->app = new MozApp();
     priv->view = new MozView();
     priv->listener = new ViewListener(view);
     priv->view->SetListener(priv->listener);
 }
 
-static void
-moz_web_view_viewable_init(MozViewableIface *iface)
-{
-
-}
-
 /*******************************************************************
  *                           GObjectClass                          *
  *******************************************************************/
 static void
 moz_web_view_finalize(GObject *object)
 {
-    MozWebViewPriv *priv;
-    
-    priv = GET_PRIV(object);
-    
-    if (priv->view)
-	delete priv->view;
+    g_return_if_fail(object != NULL);
+    g_return_if_fail(MOZ_IS_WEB_VIEW(object));
 
-    if (priv->listener)
-	delete priv->listener;
+    MozWebView *view = MOZ_WEB_VIEW(object);
 
-    if (priv->app)
-	delete priv->app;
+    g_free (view->priv->requested_uri);
+    g_free (view->priv->title);
+    g_free (view->priv->status);
+    g_free (view->priv->location);
 
-    if (priv->requested_uri)
-	g_free(priv->requested_uri);
+    delete view->priv->app;
+    delete view->priv->view;
+    delete view->priv->listener;
 
-    if (priv->title)
-	g_free(priv->title);
-    
     (G_OBJECT_CLASS(moz_web_view_parent_class)->finalize)(object);
 }
 
 static void 
-moz_web_view_get_property(GObject     *object,
-			  guint        prop_id,
-			  GValue      *value,
-			  GParamSpec  *pspec)
+moz_web_view_get_property (GObject     *object,
+                           guint        prop_id,
+                           GValue      *value,
+                           GParamSpec  *pspec)
 { 
-    MozWebViewPriv *priv;
-    
-    priv = GET_PRIV(object);
-    
-    switch (prop_id) {
-    case PROP_REQUESTED_URI:
-	g_value_set_string(value, priv->requested_uri);
-	break;
-    case PROP_TITLE:
-	g_value_set_string(value, priv->title);
-	break;
-    case PROP_STATUS:
-	g_value_set_string(value, priv->status);
-	break;
-    case PROP_LOCATION:
-	g_value_set_string(value, priv->location);
-	break;
-
-    default:
-	G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
-	break;
-    }
-}
-
-static void
-update_property(MozWebView  *view,
-                gint         prop_id,
-                const gchar *new_value)
-{
-    MozWebViewPriv *priv = GET_PRIV(view);
-    gchar **ptr;
-    gchar  *name = NULL; 
+    MozWebViewPriv *priv = MOZ_WEB_VIEW (object)->priv;
 
     switch (prop_id) {
-    case PROP_REQUESTED_URI: ptr = &(priv->requested_uri); name = "requested-uri";  break;
-    case PROP_TITLE:         ptr = &(priv->title);         name = "title";  break;
-    case PROP_STATUS:        ptr = &(priv->status);        name = "status";  break;
-    case PROP_LOCATION:      ptr = &(priv->location);      name = "location";  break;
-    default:
-	g_assert_not_reached();
-	break;
-    }
+        case PROP_REQUESTED_URI:
+            g_value_set_string (value, priv->requested_uri);
+        break;
+        case PROP_TITLE:
+            g_value_set_string (value, priv->title);
+        break;
+        case PROP_STATUS:
+            g_value_set_string (value, priv->status);
+        break;
+        case PROP_LOCATION:
+            g_value_set_string (value, priv->location);
+        break;
 
-    if (*ptr) g_free(*ptr);
-    *ptr = g_strdup(new_value);
-    g_object_notify(G_OBJECT(view), name);
+       default:
+           G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       break;
+	}
 }
 
 /*******************************************************************
  *                            GtkWidgetClass                       *
  *******************************************************************/
 static void
 moz_web_view_realize(GtkWidget *widget)
 {
-    MozWebViewPriv *priv;
+    MozWebViewPriv *priv = GET_PRIV(widget);
     GdkWindowAttr attributes;
     gint attributes_mask;
-    
-    priv = GET_PRIV(widget);
-    
+
     GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
     
     attributes.window_type = GDK_WINDOW_CHILD;
     attributes.x = widget->allocation.x;
     attributes.y = widget->allocation.y;
     attributes.width = widget->allocation.width;
     attributes.height = widget->allocation.height;
     attributes.wclass = GDK_INPUT_OUTPUT;
@@ -333,17 +307,17 @@ moz_web_view_realize(GtkWidget *widget)
     
     priv->view->CreateBrowser(priv->native_window, 0, 0,
 			      widget->allocation.width, widget->allocation.height);
     
     widget->style = gtk_style_attach(widget->style, widget->window);
     gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
     
     if (priv->requested_uri)
-	moz_web_view_load_uri(MOZ_WEB_VIEW(widget), priv->requested_uri);
+        moz_web_view_load_uri(MOZ_WEB_VIEW(widget), priv->requested_uri);
 }
 
 static void
 moz_web_view_unrealize(GtkWidget *widget)
 {
     MozWebViewPriv *priv = GET_PRIV(widget);
 
     RemoveProp(priv->native_window, "moz-view-widget");
@@ -363,50 +337,49 @@ moz_web_view_hierarchy_changed(GtkWidget
     GtkWidget *toplevel = gtk_widget_get_toplevel(widget);
 
     /* At least toplevel or previous_toplevel should exist */
     g_assert(toplevel || previous_toplevel);
 
     DBG(g_print("Hierarchy changed ! toplevel %p previous_toplevel %p\n", toplevel, previous_toplevel));
     
     if (GTK_IS_WINDOW(toplevel)) {
-	g_signal_connect(G_OBJECT(toplevel), "configure-event",
-			  G_CALLBACK(handle_toplevel_configure), widget);
-    }	
+        g_signal_connect(G_OBJECT(toplevel), "configure-event",
+                         G_CALLBACK(handle_toplevel_configure), widget);
+    }
     
     if (GTK_IS_WINDOW(previous_toplevel)) {
-	g_signal_handlers_disconnect_by_func
-	    (G_OBJECT(previous_toplevel), 
-	     (gpointer)handle_toplevel_configure, widget);
+        g_signal_handlers_disconnect_by_func(G_OBJECT(previous_toplevel), 
+                                             (gpointer)handle_toplevel_configure,
+                                             widget);
     }
 }
 
 static void
 moz_web_view_size_allocate(GtkWidget     *widget,
                            GtkAllocation *allocation)
 {
     MozWebViewPriv *priv = GET_PRIV(widget);
     
     g_return_if_fail(allocation != NULL);
     
     widget->allocation = *allocation;
     
     if (GTK_WIDGET_REALIZED(widget)) {
-	gint x, y;
-	
-	gdk_window_get_position(widget->window, &x, &y);
-	x += allocation->x;
-	y += allocation->y;
+        gint x, y;
 	
-	SetWindowPos(priv->native_window, NULL,
-		     x, y,
-		     allocation->width, allocation->height,
-		     SWP_NOACTIVATE | SWP_NOZORDER);
-	
-	priv->view->SetPositionAndSize(0, 0, allocation->width, allocation->height);
+        gdk_window_get_position(widget->window, &x, &y);
+        x += allocation->x;
+        y += allocation->y;
+
+        SetWindowPos(priv->native_window, NULL, x, y,
+                     allocation->width, allocation->height,
+                     SWP_NOACTIVATE | SWP_NOZORDER);
+
+        priv->view->SetPositionAndSize(0, 0, allocation->width, allocation->height);
     }
 }
 
 static void
 moz_web_view_map(GtkWidget *widget)
 {
     MozWebViewPriv *priv = GET_PRIV(widget);
     
@@ -417,44 +390,43 @@ moz_web_view_map(GtkWidget *widget)
 }
 
 static void
 moz_web_view_unmap(GtkWidget *widget)
 {
     MozWebViewPriv *priv = GET_PRIV(widget);
     
     GTK_WIDGET_CLASS(moz_web_view_parent_class)->unmap(widget);
-    
+    	
     ShowWindow(priv->native_window, SW_HIDE);
 }
 
 /* We handle configure events on the toplevel in order to
  * reposition our window when the toplevel moves.
  */
 static gboolean 
 handle_toplevel_configure(GtkWidget         *toplevel,
                           GdkEventConfigure *event,
                           GtkWidget         *widget)
 {
     MozWebViewPriv *priv;
     gint x, y;
 
     priv = GET_PRIV(widget);
 
-    DBG(g_print("Configure event !\n"));
-    
+    DBG(g_print("Configure event !\n"));    
+
     gdk_window_get_position(widget->window, &x, &y);
     x += widget->allocation.x;
     y += widget->allocation.y;
-    
-    SetWindowPos(priv->native_window, NULL,
-		 x, y,
-		 widget->allocation.width, widget->allocation.height,
-		 SWP_NOACTIVATE | SWP_NOZORDER);
-    
+
+    SetWindowPos(priv->native_window, NULL, x, y,
+                 widget->allocation.width, widget->allocation.height,
+                 SWP_NOACTIVATE | SWP_NOZORDER);
+
     return FALSE;
 }
 
 /* Handle the window procedure by the window class directly
  * in order to call SetFocus() at the appropriate times.
  */
 static LRESULT 
 window_procedure(HWND   hwnd,
@@ -469,46 +441,44 @@ window_procedure(HWND   hwnd,
 
     DBG(g_print("Procedure called ! widget %p\n", widget));
 
 
     /* The first few messages are fired inside CreateWindowEx(), so we
      * havent set the widget data yet.
      */
     if (widget)
-	priv = GET_PRIV(widget);
-    else {
-	return DefWindowProcW(hwnd, message, wparam, lparam);
-    }
-    
+        priv = GET_PRIV(widget);
+    else
+        return DefWindowProcW(hwnd, message, wparam, lparam);
+
     switch (message) {
-    case WM_INITDIALOG:
-    case WM_INITMENU: 
-    case WM_DESTROY:
-	return TRUE;
-    case WM_SYSCOMMAND:
-	if (wparam == SC_CLOSE) {
-	    DBG(g_print("Close message..\n"));
-	    return TRUE;
-	}
-	break;
-	
-    case WM_ACTIVATE:
-	switch (wparam) {
-	case WA_ACTIVE:
-	case WA_CLICKACTIVE:
-	    priv->view->SetFocus(true);
-	    break;
-	case WA_INACTIVE:
-	    priv->view->SetFocus(false);
-	    break;
-	default:
-	    break;
-	}
-	break;
+        case WM_INITDIALOG:
+        case WM_INITMENU: 
+        case WM_DESTROY:
+            return TRUE;
+        case WM_SYSCOMMAND:
+            if (wparam == SC_CLOSE) {
+                DBG(g_print("Close message..\n"));
+                return TRUE;
+            }
+        break;
+        case WM_ACTIVATE:
+            switch (wparam) {
+                case WA_ACTIVE:
+                case WA_CLICKACTIVE:
+                    priv->view->SetFocus(true);
+                break;
+                case WA_INACTIVE:
+                    priv->view->SetFocus(false);
+                break;
+                default:
+                break;
+            }
+        break;
     }
     return DefWindowProcW(hwnd, message, wparam, lparam);
 }
 
 /*****************************************************
  * Hack ahead !!!
  *
  * Problems here have to do with focus handling, i.e.
@@ -536,102 +506,94 @@ window_procedure(HWND   hwnd,
 static HWND
 create_native_window(GtkWidget *widget)
 {
     static ATOM klass = 0;
     HWND window_handle, parent_handle;
     DWORD dwStyle, dwExStyle;
 
     if (!klass) {
-	static WNDCLASSEXW wcl; 
+         static WNDCLASSEXW wcl; 
 	
-	wcl.cbSize = sizeof(WNDCLASSEX);
-	wcl.style = 0;
+         wcl.cbSize = sizeof(WNDCLASSEX);
+         wcl.style = 0;
 
-	/* DON'T set CS_<H,V>REDRAW. It causes total redraw
-	 * on WM_SIZE and WM_MOVE. Flicker, Performance!
-	 */
-	wcl.lpfnWndProc = (WNDPROC)window_procedure;
-	wcl.cbClsExtra = 0;
-	wcl.cbWndExtra = 0;
-	wcl.hInstance = GetModuleHandle(NULL);
-	wcl.hIcon = 0;
-	wcl.hIconSm = 0;
-	wcl.lpszMenuName = NULL;
-	wcl.hIcon = NULL;
-	wcl.hIconSm = NULL;
-	wcl.hbrBackground = NULL;
-	wcl.hCursor = LoadCursor(NULL, IDC_ARROW); 
-	wcl.lpszClassName = L"MozWindow";
-	
-	klass = RegisterClassExW(&wcl);
-	
+        /* DON'T set CS_<H,V>REDRAW. It causes total redraw
+         * on WM_SIZE and WM_MOVE. Flicker, Performance!
+         */
+         wcl.lpfnWndProc = (WNDPROC)window_procedure;
+         wcl.cbClsExtra = 0;
+         wcl.cbWndExtra = 0;
+         wcl.hInstance = GetModuleHandle(NULL);
+         wcl.hIcon = 0;
+         wcl.hIconSm = 0;
+         wcl.lpszMenuName = NULL;
+         wcl.hIcon = NULL;
+         wcl.hIconSm = NULL;
+         wcl.hbrBackground = NULL;
+         wcl.hCursor = LoadCursor(NULL, IDC_ARROW); 
+         wcl.lpszClassName = L"MozWindow";
+
+         klass = RegisterClassExW(&wcl);
     }
-    
+
     dwExStyle = WS_EX_TOOLWINDOW; // for popup windows 
     dwStyle = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; // popup window
     
     parent_handle = (HWND)GDK_WINDOW_HWND(gtk_widget_get_parent_window(widget));
     window_handle = CreateWindowExW(dwExStyle,
-				    MAKEINTRESOURCEW(klass),
-				    L"",
-				    dwStyle,
-				    0, 0, 1, 1,
-				    parent_handle,
-				    NULL,
-				    GetModuleHandle(NULL),
-				    NULL);
+                                    MAKEINTRESOURCEW(klass),
+                                    L"",
+                                    dwStyle,
+                                    0, 0, 1, 1,
+                                    parent_handle,
+                                    NULL,
+                                    GetModuleHandle(NULL),
+                                    NULL);
 
     SetProp(window_handle, "moz-view-widget", (HANDLE)widget);
-    
+
     return window_handle;
 }
 
 /*******************************************************************
  *                                API                              *
  *******************************************************************/
 GtkWidget *
 moz_web_view_new(void)
 {
     return GTK_WIDGET(g_object_new(MOZ_TYPE_WEB_VIEW, NULL));
 }
 
 void
-moz_web_view_load_uri(MozWebView *view, const gchar  *uri)
-{	
-    MozWebViewPriv *priv; 
-    
+moz_web_view_load_uri(MozWebView *view, const gchar *uri)
+{
     g_return_if_fail(MOZ_IS_WEB_VIEW(view));
     g_return_if_fail(uri && uri[0]);
 
-    priv = GET_PRIV(view);
-
-    if (priv->requested_uri && priv->requested_uri != uri)
-	g_free(priv->requested_uri);
-    
-    priv->requested_uri = g_strdup(uri);
-    
-    if (GTK_WIDGET_REALIZED(view))
-	priv->view->LoadURI(priv->requested_uri);
-    
-    g_object_notify(G_OBJECT(view), "requested-uri");
+	if (GTK_WIDGET_REALIZED (view))
+	{
+	    view->priv->view->LoadURI(uri);
+	}
+	else
+	{
+		/* widget not realized, the requested uri will be loaded when realized */
+		g_free (view->priv->requested_uri);
+		view->priv->requested_uri = g_strdup (uri);
+	}
 }
 
 void
 moz_web_view_load_data(MozWebView  *view,
                        const gchar *base_uri,
                        const gchar *content_type,
                        const gchar *data,
                        gsize        len)
 {
-    MozWebViewPriv *priv; 
-    
     g_return_if_fail(MOZ_IS_WEB_VIEW(view));
     g_return_if_fail(base_uri != NULL);
     g_return_if_fail(content_type != NULL);
     g_return_if_fail(data != NULL);
     g_return_if_fail(len > 0);
 
-    priv = GET_PRIV(view);
-
     if (GTK_WIDGET_REALIZED(view))
-	priv->view->LoadData(base_uri, content_type, (PRUint8 *)data, (PRUint32)len);
+        view->priv->view->LoadData(base_uri, content_type, (PRUint8 *)data, (PRUint32)len);
 }
--- a/gtk/win32/win32gtk.vcproj
+++ b/gtk/win32/win32gtk.vcproj
@@ -191,20 +191,16 @@
 				RelativePath="..\..\common\embed.h"
 				>
 			</File>
 			<File
 				RelativePath="..\..\common\EmbeddingSetup.h"
 				>
 			</File>
 			<File
-				RelativePath="..\common\moz-web-view-common.cpp"
-				>
-			</File>
-			<File
 				RelativePath="..\common\moz-web-view-common.h"
 				>
 			</File>
 			<File
 				RelativePath="..\common\moz-web-view-marshal.h"
 				>
 			</File>
 			<File
@@ -219,40 +215,52 @@
 			>
 		</Filter>
 		<Filter
 			Name="Source Files"
 			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
 			<File
+				RelativePath="..\..\common\ConsoleListener.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\common\ContentListener.cpp"
 				>
 			</File>
 			<File
+				RelativePath="..\..\common\DOMEventListener.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\..\common\embed.cpp"
 				>
 			</File>
 			<File
 				RelativePath="..\..\common\EmbeddingSetup.cpp"
 				>
 			</File>
 			<File
+				RelativePath="..\common\moz-web-view-common.cpp"
+				>
+			</File>
+			<File
 				RelativePath="..\common\moz-web-view-marshal.c"
 				>
 			</File>
 			<File
 				RelativePath=".\moz-web-view.cpp"
 				>
 			</File>
 			<File
 				RelativePath="..\..\common\WebBrowserChrome.cpp"
 				>
 			</File>
 			<File
-				RelativePath=".\win32gtk.def"
+				RelativePath=".\mozwebview.def"
 				>
 			</File>
 		</Filter>
 	</Files>
 	<Globals>
 	</Globals>
 </VisualStudioProject>
--- a/gtk/x11/moz-web-view.cpp
+++ b/gtk/x11/moz-web-view.cpp
@@ -1,52 +1,94 @@
-#include "moz-web-view.h"
-
-#include <gtk/gtkwindow.h>
-#include "embed.h"
+#include "moz-web-view-common.h"
 
-enum {
-    TITLE_CHANGED,
-    STATUS_CHANGED,
-    LOCATION_CHANGED,
-    LAST_SIGNAL
+class ViewListener;
+struct _MozWebViewPriv {
+    MozView *view;
+    GtkWidget *offscreen;
+    GtkWidget *mozWidget;
+    ViewListener *listener;
+  
+    /* Record some properties here */
+    gchar *requested_uri;
+    gchar *title;
+    gchar *status;
+    gchar *location;
 };
 
 static guint signals[LAST_SIGNAL] = { 0 };
 
+static void
+update_property (MozWebView  *view, gint prop_id, const gchar *new_value)
+{
+    MozWebViewPriv *priv = view->priv;
+    const gchar *name = NULL; 
+    gchar **ptr;
+
+    switch (prop_id) {
+        case PROP_REQUESTED_URI: ptr = &(priv->requested_uri); name = "requested-uri";  break;
+        case PROP_TITLE:         ptr = &(priv->title);         name = "title";  break;
+        case PROP_STATUS:        ptr = &(priv->status);        name = "status";  break;
+        case PROP_LOCATION:      ptr = &(priv->location);      name = "location";  break;
+        default:
+            g_assert_not_reached ();
+        break;
+    }
+
+    g_free (*ptr);
+    *ptr = g_strdup (new_value);
+    g_object_notify (G_OBJECT (view), name);
+}
+
 class ViewListener : public MozViewListener {
 public:
     ViewListener(MozWebView *view) : mView(view) {}
     virtual ~ViewListener() {}
 
     virtual void SetTitle(const char *new_title) {
-        g_signal_emit(G_OBJECT(mView), signals[TITLE_CHANGED], 0, new_title);
+        update_property (mView, PROP_TITLE, new_title);
+        g_signal_emit (mView, signals[TITLE_CHANGED],
+                       NULL, new_title);
     }
 
     virtual void StatusChanged(const char *new_status, PRUint32 flags) {
-        g_signal_emit(G_OBJECT(mView), signals[STATUS_CHANGED], 0, new_status);
+        update_property (mView, PROP_STATUS, new_status);
+        g_signal_emit (mView, signals[STATUS_CHANGED],
+                       NULL, new_status);
     }
 
     virtual void LocationChanged(const char *new_uri) {
-        g_signal_emit(G_OBJECT(mView), signals[LOCATION_CHANGED], 0, new_uri);
+        update_property (mView, PROP_LOCATION, new_uri);
+        g_signal_emit (mView, signals[LOCATION_CHANGED],
+                       NULL, new_uri);
     }
 
-private:
-    MozWebView *mView;
+    virtual PRBool OpenURI(const char* new_uri) {
+        gboolean   abort_load = FALSE;
+        update_property (mView, PROP_REQUESTED_URI, new_uri);
+        g_signal_emit (mView, signals[URI_REQUESTED],
+                       NULL, new_uri, &abort_load);
+
+        return abort_load;
+    }
+
+    virtual void DocumentLoaded() {
+        g_signal_emit (mView, signals[DOCUMENT_LOADED], NULL);
+    }
+
+    private:
+        MozWebView *mView;
 };
 
-struct _MozWebViewPriv {
-    MozView *view;
-    GtkWidget *offscreen;
-    GtkWidget *offscreen_window;
-    GtkWidget *mozWidget;
-    ViewListener *listener;
-};
+static void
+moz_web_view_viewable_init (MozViewableIface *iface) {}
 
-G_DEFINE_TYPE(MozWebView, moz_web_view, GTK_TYPE_BIN)
+G_DEFINE_TYPE_WITH_CODE (MozWebView, moz_web_view, GTK_TYPE_BIN,
+                         G_IMPLEMENT_INTERFACE (MOZ_TYPE_VIEWABLE,
+                                                moz_web_view_viewable_init))
 
 static void
 moz_web_view_map(GtkWidget *widget)
 {
     g_return_if_fail(widget != NULL);
     g_return_if_fail(MOZ_IS_WEB_VIEW(widget));
 
     MozWebView *view = MOZ_WEB_VIEW(widget);
@@ -105,18 +147,18 @@ moz_web_view_realize(GtkWidget *widget)
     attributes.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK;
 
     attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
     widget->window = gdk_window_new(gtk_widget_get_parent_window(widget),
                                     &attributes, attributes_mask);
     gdk_window_set_user_data(widget->window, view);
 
-    widget->style = gtk_style_attach(widget->style, widget->window);
     gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL);
+    widget->style = gtk_style_attach (widget->style, widget->window);
 }
 
 static void
 moz_web_view_unrealize(GtkWidget *widget)
 {
     g_return_if_fail(widget != NULL);
     g_return_if_fail(MOZ_IS_WEB_VIEW(widget));
 
@@ -139,125 +181,158 @@ moz_web_view_size_allocate(GtkWidget *wi
     g_return_if_fail(widget != NULL);
     g_return_if_fail(MOZ_IS_WEB_VIEW(widget));
 
     MozWebView *view = MOZ_WEB_VIEW(widget);
 
     widget->allocation = *alloc;
 
     if (GTK_WIDGET_REALIZED(widget)) {
-        gdk_window_move_resize(widget->window,
-                               alloc->x, alloc->y, alloc->width, alloc->height);
+        gdk_window_move_resize(widget->window, alloc->x, alloc->y,
+                               alloc->width, alloc->height);
         view->priv->view->SetPositionAndSize(0, 0, alloc->width, alloc->height);
     }
 }
 
 static void
 moz_web_view_destroy(GtkObject *object)
 {
     g_return_if_fail(object != NULL);
     g_return_if_fail(MOZ_IS_WEB_VIEW(object));
 
     MozWebView *view = MOZ_WEB_VIEW(object);
 
-    if (view->priv->view) {
-        delete view->priv->view;
-        view->priv->view = NULL;
-    }
-
-    if (view->priv->listener) {
-        delete view->priv->listener;
-        view->priv->listener = NULL;
-    }
-
     if (view->priv->offscreen) {
         gtk_widget_destroy(view->priv->offscreen);
         view->priv->offscreen = NULL;
     }
 }
 
 static void
 moz_web_view_finalize(GObject *object)
 {
     g_return_if_fail(object != NULL);
     g_return_if_fail(MOZ_IS_WEB_VIEW(object));
 
     MozWebView *view = MOZ_WEB_VIEW(object);
 
-    delete view->priv;
+    g_free (view->priv->requested_uri);
+    g_free (view->priv->title);
+    g_free (view->priv->status);
+    g_free (view->priv->location);
+	
+    delete view->priv->view;
+    delete view->priv->listener;
+
+    (G_OBJECT_CLASS(moz_web_view_parent_class)->finalize)(object);
+}
+
+static void 
+moz_web_view_get_property (GObject     *object,
+                           guint        prop_id,
+                           GValue      *value,
+                           GParamSpec  *pspec)
+{ 
+    MozWebViewPriv *priv = MOZ_WEB_VIEW (object)->priv;
+
+    switch (prop_id) {
+        case PROP_REQUESTED_URI:
+            g_value_set_string (value, priv->requested_uri);
+        break;
+        case PROP_TITLE:
+            g_value_set_string (value, priv->title);
+        break;
+        case PROP_STATUS:
+            g_value_set_string (value, priv->status);
+        break;
+        case PROP_LOCATION:
+            g_value_set_string (value, priv->location);
+        break;
+
+       default:
+           G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       break;
+	}
 }
 
 static void
 moz_web_view_class_init(MozWebViewClass *klass)
 {
     GtkContainerClass *container_class = GTK_CONTAINER_CLASS(klass);
     GtkWidgetClass    *widget_class    = GTK_WIDGET_CLASS(klass);
     GtkObjectClass    *object_class    = GTK_OBJECT_CLASS(klass);
     GObjectClass      *gobject_class   = G_OBJECT_CLASS(klass);
 
+    gobject_class->get_property  = moz_web_view_get_property;
+  
     widget_class->realize = moz_web_view_realize;
     widget_class->unrealize = moz_web_view_unrealize;
     widget_class->map = moz_web_view_map;
     widget_class->unmap = moz_web_view_unmap;
     widget_class->size_allocate = moz_web_view_size_allocate;
 
     object_class->destroy = moz_web_view_destroy;
 
     gobject_class->finalize = moz_web_view_finalize;
 
-    signals[TITLE_CHANGED] =
-        g_signal_new("title-changed",
-                     G_TYPE_FROM_CLASS(klass),
-                     G_SIGNAL_RUN_FIRST,
-                     G_STRUCT_OFFSET(MozWebViewClass, title_changed),
-                     NULL, NULL,
-                     g_cclosure_marshal_VOID__STRING,
-                     G_TYPE_NONE, 1, G_TYPE_STRING);
+    signals[TITLE_CHANGED] = g_signal_lookup ("title-changed", MOZ_TYPE_WEB_VIEW);
+    signals[STATUS_CHANGED] = g_signal_lookup ("status-changed", MOZ_TYPE_WEB_VIEW);
+    signals[LOCATION_CHANGED] = g_signal_lookup ("location-changed", MOZ_TYPE_WEB_VIEW);
+    signals[URI_REQUESTED] = g_signal_lookup ("uri-requested", MOZ_TYPE_WEB_VIEW);
+    signals[DOCUMENT_LOADED] = g_signal_lookup ("document-loaded", MOZ_TYPE_WEB_VIEW);
 
-    signals[STATUS_CHANGED] =
-        g_signal_new("status-changed",
-                     G_TYPE_FROM_CLASS(klass),
-                     G_SIGNAL_RUN_FIRST,
-                     G_STRUCT_OFFSET(MozWebViewClass, status_changed),
-                     NULL, NULL,
-                     g_cclosure_marshal_VOID__STRING,
-                     G_TYPE_NONE, 1, G_TYPE_STRING);
-
-    signals[LOCATION_CHANGED] =
-        g_signal_new("location-changed",
-                     G_TYPE_FROM_CLASS(klass),
-                     G_SIGNAL_RUN_FIRST,
-                     G_STRUCT_OFFSET(MozWebViewClass, location_changed),
-                     NULL, NULL,
-                     g_cclosure_marshal_VOID__STRING,
-                     G_TYPE_NONE, 1, G_TYPE_STRING);
-
+    /* Implement MozViewable properties */   
+    g_object_class_override_property (gobject_class, PROP_REQUESTED_URI, "requested-uri");
+    g_object_class_override_property (gobject_class, PROP_TITLE, "title");
+    g_object_class_override_property (gobject_class, PROP_STATUS, "status");
+    g_object_class_override_property (gobject_class, PROP_LOCATION, "location");
 }
 
 static void
 moz_web_view_init(MozWebView *view)
 {
-    view->priv = new MozWebViewPriv();
+    view->priv = g_new0 (MozWebViewPriv, 1);
     view->priv->view = new MozView();
     view->priv->listener = new ViewListener(view);
     view->priv->view->SetListener(view->priv->listener);
 
     // XXX: should do one offscreen, not one-per-widget.
     view->priv->offscreen = gtk_window_new(GTK_WINDOW_TOPLEVEL);
     gtk_widget_realize(view->priv->offscreen);
 
     view->priv->view->CreateBrowser(view->priv->offscreen, 0, 0, 500, 500);
     view->priv->mozWidget = gtk_bin_get_child(GTK_BIN(view->priv->offscreen));
 }
 
-// Public
+/*******************************************************************
+ *                                API                              *
+ *******************************************************************/
 
 GtkWidget *
 moz_web_view_new()
 {
     return GTK_WIDGET(g_object_new(MOZ_TYPE_WEB_VIEW, NULL));
 }
 
 void
-moz_web_view_load_uri(MozWebView *view, const char *uri)
+moz_web_view_load_uri(MozWebView *view, const gchar *uri)
 {
+    g_return_if_fail(MOZ_IS_WEB_VIEW(view));
+    g_return_if_fail(uri && uri[0]);
+
     view->priv->view->LoadURI(uri);
 }
+
+void
+moz_web_view_load_data(MozWebView  *view,
+                       const gchar *base_uri,
+                       const gchar *content_type,
+                       const gchar *data,
+                       gsize        len)
+{
+    g_return_if_fail(MOZ_IS_WEB_VIEW(view));
+    g_return_if_fail(base_uri != NULL);
+    g_return_if_fail(content_type != NULL);
+    g_return_if_fail(data != NULL);
+    g_return_if_fail(len > 0);
+
+    view->priv->view->LoadData(base_uri, content_type, (PRUint8 *)data, (PRUint32)len);
+}