From 8e494ba206f49d457a2d7ce2634cc1fcb3ad6a43 Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Sun, 1 Jun 2008 00:21:08 +0200 Subject: [PATCH] Provide action signals as javascript functions 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 | 216 ++++++++++++++++++++++++++++----------- src/main.c | 2 +- src/midori-app.c | 2 +- src/midori-browser.c | 214 ++++++++++++++++++++++++++++---------- src/midori-browser.h | 23 ++++- src/midori-preferences.c | 3 - src/sokoke.c | 70 ++++++++----- 7 files changed, 381 insertions(+), 149 deletions(-) diff --git a/src/gjs.c b/src/gjs.c index 7074f939..29148bbd 100644 --- 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_gtk); + "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), + "Midori", js_object); return js_context; } diff --git a/src/main.c b/src/main.c index 7f11b5ac..07d3c987 100644 --- a/src/main.c +++ b/src/main.c @@ -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); diff --git a/src/midori-app.c b/src/midori-app.c index afbc60b5..5d41e255 100644 --- a/src/midori-app.c +++ b/src/midori-app.c @@ -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); diff --git a/src/midori-browser.c b/src/midori-browser.c index b3f2c2f6..453acd0a 100644 --- a/src/midori-browser.c +++ b/src/midori-browser.c @@ -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,16 +650,6 @@ midori_browser_class_init (MidoriBrowserClass* class) 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), - 0, - 0, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - signals[NEW_WINDOW] = g_signal_new ( "new-window", G_TYPE_FROM_CLASS (class), @@ -593,6 +661,54 @@ midori_browser_class_init (MidoriBrowserClass* class) 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, + midori_cclosure_marshal_INT__STRING, + G_TYPE_INT, 1, + G_TYPE_STRING); + + signals[ACTIVATE_ACTION] = g_signal_new ( + "activate-action", + G_TYPE_FROM_CLASS (class), + (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); +} diff --git a/src/midori-browser.h b/src/midori-browser.h index a0af0a8b..d029e6a1 100644 --- a/src/midori-browser.h +++ b/src/midori-browser.h @@ -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__ */ diff --git a/src/midori-preferences.c b/src/midori-preferences.c index 6a4c7d73..b3ddc9e7 100644 --- a/src/midori-preferences.c +++ b/src/midori-preferences.c @@ -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: diff --git a/src/sokoke.c b/src/sokoke.c index 48ab43df..72706bc7 100644 --- a/src/sokoke.c +++ b/src/sokoke.c @@ -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