]> spindle.queued.net Git - midori/commitdiff
Provide action signals as javascript functions
authorChristian Dywan <christian@twotoasts.de>
Sat, 31 May 2008 22:21:08 +0000 (00:21 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sat, 31 May 2008 22:21:08 +0000 (00:21 +0200)
From javscript C functions cannot be called, but signals
are available through the GObject type system. So
we allow javascript to call action signals like functions.

At the same time we modify a few browser functions, so
that they are functions that are available as signals.

src/gjs.c
src/main.c
src/midori-app.c
src/midori-browser.c
src/midori-browser.h
src/midori-preferences.c
src/sokoke.c

index 7074f939191cda0f577043b943487ced70e6a76f..29148bbd1a7d1d07f49de37832419de41394ff88 100644 (file)
--- a/src/gjs.c
+++ b/src/gjs.c
@@ -86,6 +86,8 @@ gjs_script_from_file (JSContextRef js_context,
         *exception = g_strdup (error->message);
         g_error_free (error);
     }
+    else
+        *exception = g_strdup (_("An unknown error occured."));
     return result;
 }
 
@@ -106,17 +108,31 @@ _js_class_get_property_names_cb (JSContextRef                 js_context,
     GObject* object = JSObjectGetPrivate (js_object);
     if (object)
     {
-        guint n_properties;
+        guint n;
         GParamSpec** pspecs = g_object_class_list_properties (
-            G_OBJECT_GET_CLASS (object), &n_properties);
+            G_OBJECT_GET_CLASS (object), &n);
         gint i;
-        for (i = 0; i < n_properties; i++)
+        for (i = 0; i < n; i++)
         {
             const gchar* property = g_param_spec_get_name (pspecs[i]);
             JSStringRef js_property = JSStringCreateWithUTF8CString (property);
             JSPropertyNameAccumulatorAddName (js_properties, js_property);
             JSStringRelease (js_property);
         }
+        GType type = G_OBJECT_TYPE (object);
+        do
+        {
+            guint* signals = g_signal_list_ids (type, &n);
+            for (i = 0; i < n; i++)
+            {
+                const gchar* signal = g_signal_name (signals[i]);
+                JSStringRef js_signal = JSStringCreateWithUTF8CString (signal);
+                JSPropertyNameAccumulatorAddName (js_properties, js_signal);
+                JSStringRelease (js_signal);
+            }
+            type = g_type_parent (type);
+        }
+        while (type);
     }
 }
 
@@ -130,8 +146,8 @@ _js_class_has_property_cb (JSContextRef js_context,
     GObject* object = JSObjectGetPrivate (js_object);
     if (object)
     {
-        if (g_object_class_find_property (G_OBJECT_GET_CLASS (object),
-                                          property))
+        if (g_signal_lookup (property, G_OBJECT_TYPE (object)) ||
+            g_object_class_find_property (G_OBJECT_GET_CLASS (object), property))
             result = true;
     }
     else if (js_object == JSContextGetGlobalObject (js_context))
@@ -155,6 +171,107 @@ _js_object_set_property (JSContextRef js_context,
     JSStringRelease (js_name);
 }
 
+static JSValueRef
+_js_object_call_as_function_cb (JSContextRef     js_context,
+                                JSObjectRef      js_function,
+                                JSObjectRef      js_this,
+                                size_t           n_arguments,
+                                const JSValueRef js_arguments[],
+                                JSValueRef*      js_exception)
+{
+    GObject* object = JSObjectGetPrivate (js_this);
+    const gchar* function = JSObjectGetPrivate (js_function);
+
+    g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
+    g_return_val_if_fail (function, JSValueMakeNull (js_context));
+
+    guint signal_id = g_signal_lookup (function, G_OBJECT_TYPE (object));
+    GSignalQuery query;
+    g_signal_query (signal_id, &query);
+    GValue* values = g_new0 (GValue, n_arguments + 1);
+    g_value_init (&values[0], G_OBJECT_TYPE (object));
+    g_value_set_instance (&values[0], object);
+    gint i;
+    for (i = 0; i < n_arguments; i++)
+    {
+        GValue value = {0, };
+        GType gtype;
+        switch (JSValueGetType (js_context, js_arguments[i]))
+        {
+            case kJSTypeBoolean:
+                gtype = G_TYPE_BOOLEAN;
+                g_value_init (&value, gtype);
+                g_value_set_boolean (&value,
+                    JSValueToBoolean (js_context, js_arguments[i]) ? TRUE : FALSE);
+                break;
+            case kJSTypeNumber:
+                gtype = G_TYPE_DOUBLE;
+                g_value_init (&value, gtype);
+                g_value_set_double (&value,
+                    JSValueToNumber (js_context, js_arguments[i], NULL));
+                break;
+            case kJSTypeString:
+                gtype = G_TYPE_STRING;
+                g_value_init (&value, gtype);
+                JSStringRef js_string = JSValueToStringCopy (js_context,
+                    js_arguments[i], NULL);
+                gchar* string = gjs_string_utf8 (js_string);
+                g_value_set_string (&value, string);
+                g_free (string);
+                JSStringRelease (js_string);
+                break;
+            case kJSTypeObject:
+                gtype = G_TYPE_OBJECT;
+                g_value_init (&value, gtype);
+                JSObjectRef js_object = JSValueToObject (js_context,
+                    js_arguments[i], NULL);
+                GObject* object_value = JSObjectGetPrivate (js_object);
+                g_value_set_object (&value, object_value);
+                break;
+            case kJSTypeUndefined:
+            case kJSTypeNull:
+            default:
+                gtype = G_TYPE_NONE;
+                g_value_init (&value, gtype);
+        }
+        g_value_init (&values[i + 1], gtype);
+        if (query.n_params >= i
+            && g_value_type_compatible (gtype, query.param_types[i]))
+            // && g_value_type_transformable (gtype, query.param_types[i])
+            g_value_copy (&value, &values[i + 1]);
+            // g_value_transform (&value, &values[i + 1]);
+        else
+        {
+            gchar* value_type = g_strdup_value_contents (&value);
+            // FIXME: exception
+            printf ("wrong value, expected %s\n", value_type);
+            g_free (value_type);
+        }
+        g_value_unset (&value);
+    }
+    GValue return_value = {0, };
+    if (query.return_type != G_TYPE_NONE)
+        g_value_init (&return_value, query.return_type);
+    g_signal_emitv (values, signal_id, 0, &return_value);
+
+    for (i = 0; i < n_arguments; i++)
+        g_value_unset (&values[i]);
+    // FIXME: return value
+    return JSValueMakeUndefined (js_context);
+}
+
+static void
+_js_object_add_function (JSContextRef js_context,
+                         JSObjectRef  js_object,
+                         const gchar* func)
+{
+    JSStringRef js_func = JSStringCreateWithUTF8CString (func);
+    JSObjectRef js_function = JSObjectMakeFunctionWithCallback (
+        js_context, js_func, _js_object_call_as_function_cb);
+    JSStringRelease (js_func);
+    _js_object_set_property (js_context, js_object, func, js_function);
+}
+
 static JSValueRef
 _js_class_get_property_cb (JSContextRef js_context,
                            JSObjectRef  js_object,
@@ -163,13 +280,32 @@ _js_class_get_property_cb (JSContextRef js_context,
 {
     GObject* object = JSObjectGetPrivate (js_object);
 
-    g_return_val_if_fail (object, JSValueMakeNull (js_context));
+    g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
 
     JSValueRef js_result = NULL;
     gchar* property = gjs_string_utf8 (js_property);
-    GParamSpec* pspec = g_object_class_find_property (
-        G_OBJECT_GET_CLASS (object), property);
-    if (!pspec)
+    guint signal_id;
+    GParamSpec* pspec;
+    if ((signal_id = g_signal_lookup (property, G_OBJECT_TYPE (object))))
+    {
+        GSignalQuery query;
+        g_signal_query (signal_id, &query);
+        if (query.signal_flags & G_SIGNAL_ACTION)
+        {
+            // We can't use JSObjectMakeFunctionWithCallback
+            // because it doesn't allocate private data
+            JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+            js_class_def.className = g_strdup (property);
+            js_class_def.callAsFunction = _js_object_call_as_function_cb;
+            JSClassRef js_class = JSClassCreate (&js_class_def);
+            JSObjectRef js_function = JSObjectMake (js_context, js_class, property);
+            return js_function;
+        }
+        g_free (property);
+        return JSValueMakeUndefined (js_context);
+    }
+    else if (!(pspec = g_object_class_find_property (
+        G_OBJECT_GET_CLASS (object), property)))
     {
         gchar* message = g_strdup_printf (_("%s has no property '%s'"),
             G_OBJECT_NAME (object), property);
@@ -237,7 +373,7 @@ _js_class_set_property_cb (JSContextRef js_context,
 {
     GObject* object = JSObjectGetPrivate (js_object);
 
-    g_return_val_if_fail (object, false);
+    g_return_val_if_fail (G_IS_OBJECT (object), false);
 
     bool result = false;
     gchar* property = gjs_string_utf8 (js_property);
@@ -287,7 +423,7 @@ _js_class_set_property_cb (JSContextRef js_context,
         JSObjectRef js_object_value = JSValueToObject (
             js_context, js_value, NULL);
         GObject* object_value = JSObjectGetPrivate (js_object_value);
-        if (object_value)
+        if (G_IS_OBJECT (object_value))
             g_object_set (object, property, object_value, NULL);
         else
         {
@@ -312,42 +448,6 @@ _js_class_set_property_cb (JSContextRef js_context,
     return result;
 }
 
-static JSValueRef
-_js_object_call_as_function_cb (JSContextRef     js_context,
-                                JSObjectRef      js_function,
-                                JSObjectRef      js_this,
-                                size_t           n_arguments,
-                                const JSValueRef js_arguments[],
-                                JSValueRef*      js_exception)
-{
-    GObject* object = JSObjectGetPrivate (js_this);
-
-    g_return_val_if_fail (object, JSValueMakeNull (js_context));
-
-    if (!n_arguments)
-    {
-    }
-    else if (n_arguments == 1)
-    {
-        JSObjectRef js_arg1 = JSValueToObject (
-            js_context, js_arguments[0], NULL);
-    }
-
-    return JSValueMakeUndefined (js_context);
-}
-
-static void
-_js_object_add_function (JSContextRef js_context,
-                         JSObjectRef  js_object,
-                         const gchar* func)
-{
-    JSStringRef js_func = JSStringCreateWithUTF8CString (func);
-    JSObjectRef js_function = JSObjectMakeFunctionWithCallback (
-        js_context, js_func, _js_object_call_as_function_cb);
-    JSStringRelease (js_func);
-    _js_object_set_property (js_context, js_object, func, js_function);
-}
-
 JSObjectRef
 gjs_object_new (JSContextRef js_context,
                 const gchar* name,
@@ -364,14 +464,6 @@ gjs_object_new (JSContextRef js_context,
     js_class_def.setProperty = _js_class_set_property_cb;
     JSClassRef js_class = JSClassCreate (&js_class_def);
     JSObjectRef js_object = JSObjectMake (js_context, js_class, instance);
-    if (instance && G_IS_OBJECT (instance))
-    {
-        // TODO: Add functions dynamically
-        /*if (GTK_IS_WIDGET (instance))
-        {
-            _js_object_add_function (js_context, js_object, "show");
-        }*/
-    }
     return js_object;
 }
 
@@ -482,12 +574,18 @@ JSGlobalContextRef
 gjs_global_context_new (void)
 {
     JSGlobalContextRef js_context = JSGlobalContextCreate (NULL);
-    JSObjectRef js_gjs = gjs_object_new (js_context, "GJS", NULL);
+    JSObjectRef js_object = gjs_object_new (js_context, "GJS", NULL);
     _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
-                             "gjs", js_gjs);
+                             "gjs", js_object);
 
-    JSObjectRef js_gtk = gjs_module_new (js_context, "Gtk");
+    js_object = gjs_module_new (js_context, "Gtk");
+    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+                             "Gtk", js_object);
+    js_object = gjs_module_new (js_context, "WebKit");
+    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+                             "WebKit", js_object);
+    js_object = gjs_module_new (js_context, "Midori");
     _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
-                             "Gtk", js_gtk);
+                             "Midori", js_object);
     return js_context;
 }
index 7f11b5acc508669e5614e4eb6457239d4145d46c..07d3c987f1cd7a9c3847e487404139c9ae2d40ef 100644 (file)
@@ -425,7 +425,7 @@ main (int argc, char** argv)
     for (i = 0; i < n; i++)
     {
         KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, i);
-        midori_browser_append_xbel_item (browser, item);
+        midori_browser_add_xbel_item (browser, item);
     }
     // FIXME: Switch to the last active page
     KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, 0);
index afbc60b5319ca05affc78ca9ab7eee314c263ff3..5d41e2557a22959da3a88678a97e88e55e2897e6 100644 (file)
@@ -272,7 +272,7 @@ midori_browser_new_window_cb (MidoriBrowser* browser,
                                                "settings", priv->settings,
                                                "trash", priv->trash,
                                                NULL);
-    midori_browser_append_uri (new_browser, uri);
+    midori_browser_add_uri (new_browser, uri);
     gtk_widget_show (GTK_WIDGET (new_browser));
 
     g_signal_emit (app, signals[ADD_BROWSER], 0, new_browser);
index b3f2c2f60057a982f25413790f14ff2a12af49c2..453acd0a3e726899428e7fc1fb9552d6949f08de 100644 (file)
@@ -96,9 +96,13 @@ enum
     WINDOW_OBJECT_CLEARED,
     STATUSBAR_TEXT_CHANGED,
     ELEMENT_MOTION,
-    QUIT,
     NEW_WINDOW,
 
+    ADD_TAB,
+    ADD_URI,
+    ACTIVATE_ACTION,
+    QUIT,
+
     LAST_SIGNAL
 };
 
@@ -452,7 +456,7 @@ midori_web_view_new_tab_cb (GtkWidget*     web_view,
                             const gchar*   uri,
                             MidoriBrowser* browser)
 {
-    gint n = midori_browser_append_uri (browser, uri);
+    gint n = midori_browser_add_uri (browser, uri);
     _midori_browser_set_current_page_smartly (browser, n);
 }
 
@@ -534,6 +538,80 @@ midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER (GClosure*     closure,
               data2);
 }
 
+static void
+midori_cclosure_marshal_INT__OBJECT (GClosure*     closure,
+                                     GValue*       return_value,
+                                     guint         n_param_values,
+                                     const GValue* param_values,
+                                     gpointer      invocation_hint,
+                                     gpointer      marshal_data)
+{
+    typedef gint(*GMarshalFunc_INT__OBJECT) (gpointer  data1,
+                                             gpointer  arg_1,
+                                             gpointer  data2);
+    register GMarshalFunc_INT__OBJECT callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+    gint v_return;
+
+    g_return_if_fail (return_value != NULL);
+    g_return_if_fail (n_param_values == 2);
+
+    if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+        data1 = closure->data;
+        data2 = g_value_peek_pointer (param_values + 0);
+    }
+    else
+    {
+        data1 = g_value_peek_pointer (param_values + 0);
+        data2 = closure->data;
+    }
+    callback = (GMarshalFunc_INT__OBJECT) (marshal_data
+        ? marshal_data : cc->callback);
+    v_return = callback (data1,
+                         g_value_get_object (param_values + 1),
+                         data2);
+    g_value_set_int (return_value, v_return);
+}
+
+static void
+midori_cclosure_marshal_INT__STRING (GClosure*     closure,
+                                     GValue*       return_value,
+                                     guint         n_param_values,
+                                     const GValue* param_values,
+                                     gpointer      invocation_hint,
+                                     gpointer      marshal_data)
+{
+    typedef gint(*GMarshalFunc_INT__STRING) (gpointer      data1,
+                                             const gchar*  arg_1,
+                                             gpointer      data2);
+    register GMarshalFunc_INT__STRING callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+    gint v_return;
+
+    g_return_if_fail (return_value != NULL);
+    g_return_if_fail (n_param_values == 2);
+
+    if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+        data1 = closure->data;
+        data2 = g_value_peek_pointer (param_values + 0);
+    }
+    else
+    {
+        data1 = g_value_peek_pointer (param_values + 0);
+        data2 = closure->data;
+    }
+    callback = (GMarshalFunc_INT__STRING) (marshal_data
+        ? marshal_data : cc->callback);
+    v_return = callback (data1,
+                         g_value_get_string (param_values + 1),
+                         data2);
+    g_value_set_int (return_value, v_return);
+}
+
 static void
 midori_browser_class_init (MidoriBrowserClass* class)
 {
@@ -572,27 +650,65 @@ midori_browser_class_init (MidoriBrowserClass* class)
         G_TYPE_NONE, 1,
         G_TYPE_STRING);
 
-    signals[QUIT] = g_signal_new (
-        "quit",
+    signals[NEW_WINDOW] = g_signal_new (
+        "new-window",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[ADD_TAB] = g_signal_new (
+        "add-tab",
         G_TYPE_FROM_CLASS (class),
         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, add_tab),
         0,
+        NULL,
+        midori_cclosure_marshal_INT__OBJECT,
+        G_TYPE_INT, 1,
+        GTK_TYPE_WIDGET);
+
+    signals[ADD_URI] = g_signal_new (
+        "add-uri",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, add_uri),
         0,
         NULL,
-        g_cclosure_marshal_VOID__VOID,
-        G_TYPE_NONE, 0);
+        midori_cclosure_marshal_INT__STRING,
+        G_TYPE_INT, 1,
+        G_TYPE_STRING);
 
-    signals[NEW_WINDOW] = g_signal_new (
-        "new-window",
+    signals[ACTIVATE_ACTION] = g_signal_new (
+        "activate-action",
         G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, activate_action),
         0,
         NULL,
         g_cclosure_marshal_VOID__STRING,
         G_TYPE_NONE, 1,
         G_TYPE_STRING);
 
+    signals[QUIT] = g_signal_new (
+        "quit",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, quit),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__VOID,
+        G_TYPE_NONE, 0);
+
+    class->add_tab = midori_browser_add_tab;
+    class->add_uri = midori_browser_add_uri;
+    class->activate_action = midori_browser_activate_action;
+    class->quit = midori_browser_quit;
+
     GObjectClass* gobject_class = G_OBJECT_CLASS (class);
     gobject_class->finalize = midori_browser_finalize;
     gobject_class->set_property = midori_browser_set_property;
@@ -600,11 +716,6 @@ midori_browser_class_init (MidoriBrowserClass* class)
 
     GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
 
-    /**
-    * MidoriBrowser::menubar
-    *
-    * The menubar.
-    */
     g_object_class_install_property (gobject_class,
                                      PROP_MENUBAR,
                                      g_param_spec_object (
@@ -614,11 +725,6 @@ midori_browser_class_init (MidoriBrowserClass* class)
                                      GTK_TYPE_MENU_BAR,
                                      G_PARAM_READABLE));
 
-    /**
-    * MidoriBrowser::navigationbar
-    *
-    * The navigationbar.
-    */
     g_object_class_install_property (gobject_class,
                                      PROP_NAVIGATIONBAR,
                                      g_param_spec_object (
@@ -628,11 +734,6 @@ midori_browser_class_init (MidoriBrowserClass* class)
                                      GTK_TYPE_TOOLBAR,
                                      G_PARAM_READABLE));
 
-    /**
-    * MidoriBrowser::tab
-    *
-    * The current tab.
-    */
     g_object_class_install_property (gobject_class,
                                      PROP_TAB,
                                      g_param_spec_object (
@@ -642,11 +743,6 @@ midori_browser_class_init (MidoriBrowserClass* class)
                                      GTK_TYPE_WIDGET,
                                      G_PARAM_READWRITE));
 
-    /**
-    * MidoriBrowser::statusbar
-    *
-    * The statusbar.
-    */
     g_object_class_install_property (gobject_class,
                                      PROP_STATUSBAR,
                                      g_param_spec_object (
@@ -657,7 +753,7 @@ midori_browser_class_init (MidoriBrowserClass* class)
                                      G_PARAM_READABLE));
 
     /**
-    * MidoriBrowser::settings
+    * MidoriBrowser:settings:
     *
     * An associated settings instance that is shared among all web views.
     *
@@ -674,7 +770,7 @@ midori_browser_class_init (MidoriBrowserClass* class)
                                      G_PARAM_READWRITE));
 
     /**
-    * MidoriBrowser::statusbar-text
+    * MidoriBrowser:statusbar-text:
     *
     * The text that is displayed in the statusbar.
     *
@@ -694,7 +790,7 @@ midori_browser_class_init (MidoriBrowserClass* class)
                                      flags));
 
     /**
-    * MidoriBrowser::trash
+    * MidoriBrowser:trash:
     *
     * The trash, that collects all closed tabs and windows.
     *
@@ -728,7 +824,7 @@ _action_tab_new_activate (GtkAction*     action,
 {
     MidoriBrowserPrivate* priv = browser->priv;
 
-    gint n = midori_browser_append_uri (browser, "");
+    gint n = midori_browser_add_uri (browser, "");
     midori_browser_set_current_page (browser, n);
     gtk_widget_grab_focus (priv->location);
 }
@@ -1015,7 +1111,7 @@ midori_browser_menu_trash_item_activate_cb (GtkWidget*     menuitem,
     KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
                                              "KatzeXbelItem");
     const gchar* uri = katze_xbel_bookmark_get_href (item);
-    gint n = midori_browser_append_uri (browser, uri);
+    gint n = midori_browser_add_uri (browser, uri);
     midori_browser_set_current_page (browser, n);
     katze_xbel_item_unref (item);
 }
@@ -1521,7 +1617,7 @@ midori_panel_bookmarks_button_release_event_cb (GtkWidget*      widget,
             if (event->button == 2 && katze_xbel_item_is_bookmark (item))
             {
                 const gchar* uri = katze_xbel_bookmark_get_href (item);
-                gint n = midori_browser_append_uri (browser, uri);
+                gint n = midori_browser_add_uri (browser, uri);
                 midori_browser_set_current_page (browser, n);
             }
             else
@@ -1943,7 +2039,7 @@ _action_bookmark_open_tab_activate (GtkAction*     action,
             gtk_tree_model_get (model, &iter, 0, &item, -1);
             if (katze_xbel_item_is_bookmark (item))
             {
-                gint n = midori_browser_append_xbel_item (browser, item);
+                gint n = midori_browser_add_xbel_item (browser, item);
                 _midori_browser_set_current_page_smartly (browser, n);
             }
         }
@@ -1968,7 +2064,7 @@ _action_bookmark_open_window_activate (GtkAction*     action,
             gtk_tree_model_get (model, &iter, 0, &item, -1);
             if (katze_xbel_item_is_bookmark (item))
             {
-                gint n = midori_browser_append_xbel_item (browser, item);
+                gint n = midori_browser_add_xbel_item (browser, item);
                 _midori_browser_set_current_page_smartly (browser, n);
             }
         }
@@ -2005,7 +2101,7 @@ _action_undo_tab_close_activate (GtkAction*     action,
 
     // Reopen the most recent trash item
     KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, 0);
-    gint n = midori_browser_append_xbel_item (browser, item);
+    gint n = midori_browser_add_xbel_item (browser, item);
     midori_browser_set_current_page (browser, n);
     midori_trash_remove_nth_item (priv->trash, 0);
     _midori_browser_update_actions (browser);
@@ -3141,7 +3237,7 @@ midori_browser_new (void)
 }
 
 /**
- * midori_browser_append_tab:
+ * midori_browser_add_tab:
  * @browser: a #MidoriBrowser
  * @widget: a tab
  *
@@ -3151,8 +3247,8 @@ midori_browser_new (void)
  * Return value: the index of the new tab, or -1 in case of an error
  **/
 gint
-midori_browser_append_tab (MidoriBrowser* browser,
-                           GtkWidget*     widget)
+midori_browser_add_tab (MidoriBrowser* browser,
+                        GtkWidget*     widget)
 {
     g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
 
@@ -3274,7 +3370,7 @@ midori_browser_remove_tab (MidoriBrowser* browser,
 }
 
 /**
- * midori_browser_append_xbel_item:
+ * midori_browser_add_xbel_item:
  * @browser: a #MidoriBrowser
  * @xbel_item: a bookmark
  *
@@ -3283,8 +3379,8 @@ midori_browser_remove_tab (MidoriBrowser* browser,
  * Return value: the index of the new tab, or -1 in case of an error
  **/
 gint
-midori_browser_append_xbel_item (MidoriBrowser* browser,
-                                 KatzeXbelItem* xbel_item)
+midori_browser_add_xbel_item (MidoriBrowser* browser,
+                              KatzeXbelItem* xbel_item)
 {
     MidoriBrowserPrivate* priv = browser->priv;
 
@@ -3299,11 +3395,11 @@ midori_browser_append_xbel_item (MidoriBrowser* browser,
                                         NULL);
     gtk_widget_show (web_view);
 
-    return midori_browser_append_tab (browser, web_view);
+    return midori_browser_add_tab (browser, web_view);
 }
 
 /**
- * midori_browser_append_uri:
+ * midori_browser_add_uri:
  * @browser: a #MidoriBrowser
  * @uri: an URI
  *
@@ -3312,8 +3408,8 @@ midori_browser_append_xbel_item (MidoriBrowser* browser,
  * Return value: the index of the new tab, or -1
  **/
 gint
-midori_browser_append_uri (MidoriBrowser* browser,
-                           const gchar*   uri)
+midori_browser_add_uri (MidoriBrowser* browser,
+                        const gchar*   uri)
 {
     MidoriBrowserPrivate* priv = browser->priv;
 
@@ -3323,7 +3419,7 @@ midori_browser_append_uri (MidoriBrowser* browser,
                                         NULL);
     gtk_widget_show (web_view);
 
-    return midori_browser_append_tab (browser, web_view);
+    return midori_browser_add_tab (browser, web_view);
 }
 
 /**
@@ -3494,3 +3590,17 @@ midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
     }
     return priv->proxy_xbel_folder;
 }
+
+/**
+ * midori_browser_quit:
+ * @browser: a #MidoriBrowser
+ *
+ * Quits the browser, including any other browser windows.
+ **/
+void
+midori_browser_quit (MidoriBrowser* browser)
+{
+    g_return_if_fail (MIDORI_IS_BROWSER (browser));
+
+    g_signal_emit (browser, signals[QUIT], 0);
+}
index a0af0a8b56ec1edf9ec65964c7cb76c14a16829d..d029e6a1877cec9e9ed9874235d85b6385a7c748 100644 (file)
@@ -59,10 +59,20 @@ struct _MidoriBrowserClass
     (*element_motion)          (MidoriBrowser*       browser,
                                 const gchar*         link_uri);
     void
-    (*quit)                    (MidoriBrowser*       browser);
-    void
     (*new_window)              (MidoriBrowser*       browser,
                                 const gchar*         uri);
+
+    void
+    (*add_tab)                 (MidoriBrowser*       browser,
+                                GtkWidget*           widget);
+    void
+    (*add_uri)                 (MidoriBrowser*       browser,
+                                const gchar*         uri);
+    void
+    (*activate_action)         (MidoriBrowser*       browser,
+                                const gchar*         name);
+    void
+    (*quit)                    (MidoriBrowser*       browser);
 };
 
 GType
@@ -72,7 +82,7 @@ MidoriBrowser*
 midori_browser_new                    (void);
 
 gint
-midori_browser_append_tab             (MidoriBrowser*     browser,
+midori_browser_add_tab                (MidoriBrowser*     browser,
                                        GtkWidget*         widget);
 
 void
@@ -80,11 +90,11 @@ midori_browser_remove_tab             (MidoriBrowser*     browser,
                                        GtkWidget*         widget);
 
 gint
-midori_browser_append_xbel_item       (MidoriBrowser*     browser,
+midori_browser_add_xbel_item          (MidoriBrowser*     browser,
                                        KatzeXbelItem*     xbel_item);
 
 gint
-midori_browser_append_uri             (MidoriBrowser*     browser,
+midori_browser_add_uri                (MidoriBrowser*     browser,
                                        const gchar*       uri);
 
 void
@@ -111,6 +121,9 @@ midori_browser_get_current_web_view   (MidoriBrowser*     browser);
 KatzeXbelItem*
 midori_browser_get_proxy_xbel_folder  (MidoriBrowser*     browser);
 
+void
+midori_browser_quit                   (MidoriBrowser*     browser);
+
 G_END_DECLS
 
 #endif /* __MIDORI_BROWSER_H__ */
index 6a4c7d73cdc8b73b2c31f71069d0a73476d553b3..b3ddc9e7cd41bbf8f6fe4f3f3a6557bd1c939a49 100644 (file)
@@ -147,9 +147,6 @@ midori_preferences_get_property (GObject*    object,
                                  GValue*     value,
                                  GParamSpec* pspec)
 {
-    MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
-    MidoriPreferencesPrivate* priv = preferences->priv;
-
     switch (prop_id)
     {
     default:
index 48ab43df8cdcb94ce121fd114c2ca3a9b978fd9f..72706bc79289266dead8fc3265014e4da16aee6d 100644 (file)
@@ -328,50 +328,64 @@ void sokoke_widget_set_pango_font_style(GtkWidget* widget, PangoStyle style)
     }
 }
 
-static gboolean sokoke_on_entry_focus_in_event(GtkEntry* entry, GdkEventFocus *event
- , gpointer userdata)
+static gboolean
+sokoke_on_entry_focus_in_event (GtkEntry*      entry,
+                                GdkEventFocus* event,
+                                gpointer       userdata)
 {
-    gboolean defaultText = (gboolean)g_object_get_data(G_OBJECT(entry)
-     , "sokoke_hasDefaultText");
-    if(defaultText)
+    gint default_text = GPOINTER_TO_INT (
+        g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
+    if (default_text)
     {
-        gtk_entry_set_text(entry, "");
-        g_object_set_data(G_OBJECT(entry), "sokoke_hasDefaultText", (gpointer)FALSE);
-        sokoke_widget_set_pango_font_style(GTK_WIDGET(entry), PANGO_STYLE_NORMAL);
+        gtk_entry_set_text (entry, "");
+        g_object_set_data (G_OBJECT(entry), "sokoke_has_default",
+                           GINT_TO_POINTER (0));
+        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
+                                            PANGO_STYLE_NORMAL);
     }
     return FALSE;
 }
 
-static gboolean sokoke_on_entry_focus_out_event(GtkEntry* entry, GdkEventFocus* event
- , gpointer userdata)
+static gboolean
+sokoke_on_entry_focus_out_event (GtkEntry*      entry,
+                                 GdkEventFocus* event,
+                                 gpointer       userdata)
 {
-    const gchar* text = gtk_entry_get_text(entry);
-    if(text && !*text)
+    const gchar* text = gtk_entry_get_text (entry);
+    if (text && !*text)
     {
-        const gchar* defaultText = (const gchar*)g_object_get_data(
-         G_OBJECT(entry), "sokoke_defaultText");
-        gtk_entry_set_text(entry, defaultText);
-        g_object_set_data(G_OBJECT(entry), "sokoke_hasDefaultText", (gpointer)TRUE);
-        sokoke_widget_set_pango_font_style(GTK_WIDGET(entry), PANGO_STYLE_ITALIC);
+        const gchar* defaultText = (const gchar*)g_object_get_data (
+         G_OBJECT (entry), "sokoke_default_text");
+        gtk_entry_set_text (entry, defaultText);
+        g_object_set_data (G_OBJECT(entry),
+                           "sokoke_has_default", GINT_TO_POINTER (1));
+        sokoke_widget_set_pango_font_style (GTK_WIDGET(entry),
+                                            PANGO_STYLE_ITALIC);
     }
     return FALSE;
 }
 
-void sokoke_entry_set_default_text(GtkEntry* entry, const gchar* defaultText)
+void
+sokoke_entry_set_default_text (GtkEntry*    entry,
+                               const gchar* default_text)
 {
     // Note: The default text initially overwrites any previous text
-    gchar* oldValue = g_object_get_data(G_OBJECT(entry), "sokoke_defaultText");
-    if(!oldValue)
+    gchar* old_value = g_object_get_data (G_OBJECT (entry),
+                                          "sokoke_default_text");
+    if (!old_value)
     {
-        g_object_set_data(G_OBJECT(entry), "sokoke_hasDefaultText", (gpointer)TRUE);
-        sokoke_widget_set_pango_font_style(GTK_WIDGET(entry), PANGO_STYLE_ITALIC);
-        gtk_entry_set_text(entry, defaultText);
+        g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
+                           GINT_TO_POINTER (1));
+        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
+                                            PANGO_STYLE_ITALIC);
+        gtk_entry_set_text (entry, default_text);
     }
-    g_object_set_data(G_OBJECT(entry), "sokoke_defaultText", (gpointer)defaultText);
-    g_signal_connect(entry, "focus-in-event"
-     , G_CALLBACK(sokoke_on_entry_focus_in_event), NULL);
-    g_signal_connect(entry, "focus-out-event"
-     , G_CALLBACK(sokoke_on_entry_focus_out_event), NULL);
+    g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
+                       (gpointer)default_text);
+    g_signal_connect (entry, "focus-in-event",
+        G_CALLBACK (sokoke_on_entry_focus_in_event), NULL);
+    g_signal_connect (entry, "focus-out-event",
+        G_CALLBACK (sokoke_on_entry_focus_out_event), NULL);
 }
 
 gchar* sokoke_key_file_get_string_default(GKeyFile* keyFile