From 7b9c014289bd4df93882e6ac0c2a717fdb81f196 Mon Sep 17 00:00:00 2001 From: Mason Larobina Date: Sat, 14 Aug 2010 21:59:10 +0800 Subject: [PATCH] Refactor webview.c, use catchall "signal::notify" for prop signals Summary of changes: 1. Several variable name changes. 2. Precompile "property::name" signal names for each property. 3. Replaced old "property::name" code with `notify_cb`. 4. Use case macros to avoid repeating ourselves. --- rc.lua | 2 +- widgets/webview.c | 512 +++++++++++++++++++++++++----------------------------- 2 files changed, 236 insertions(+), 278 deletions(-) diff --git a/rc.lua b/rc.lua index d954064..9398d10 100755 --- a/rc.lua +++ b/rc.lua @@ -390,7 +390,7 @@ end -- Attach signal handlers to a new tab's webview function attach_webview_signals(w, view) - view:add_signal("title-changed", function (v) + view:add_signal("property::title", function (v) w:update_tab_labels() if w:is_current(v) then w:update_win_title(v) diff --git a/widgets/webview.c b/widgets/webview.c index f19974a..9b8845c 100644 --- a/widgets/webview.c +++ b/widgets/webview.c @@ -31,8 +31,20 @@ static struct { SoupCookieJar *cookiejar; } Soup = { NULL, NULL }; -typedef enum { BOOL, CHAR, INT, FLOAT, DOUBLE, URI } property_value_type; -typedef enum { SETTINGS, WEBKITVIEW, SOUPSESSION } property_value_scope; +typedef enum { + BOOL, + CHAR, + INT, + FLOAT, + DOUBLE, + URI, +} property_value_t; + +typedef enum { + SETTINGS, + WEBKITVIEW, + SOUPSESSION, +} property_scope; typedef union { gchar *c; @@ -40,89 +52,92 @@ typedef union { gdouble d; gfloat f; gint i; -} property_tmp_values; - -typedef struct { - property_value_type type; - property_value_scope scope; - gboolean writable; -} property_value_t; +} temp_value_t; GHashTable *properties = NULL; -static const struct property_t { - const gchar *name; - property_value_t v; -} properties_table[] = { - { "accept-language", { CHAR, SOUPSESSION, TRUE } }, - { "accept-language-auto", { BOOL, SOUPSESSION, TRUE } }, - { "auto-load-images", { BOOL, SETTINGS, TRUE } }, - { "auto-resize-window", { BOOL, SETTINGS, TRUE } }, - { "auto-shrink-images", { BOOL, SETTINGS, TRUE } }, - { "cursive-font-family", { CHAR, SETTINGS, TRUE } }, - { "custom-encoding", { CHAR, WEBKITVIEW, TRUE } }, - { "default-encoding", { CHAR, SETTINGS, TRUE } }, - { "default-font-family", { CHAR, SETTINGS, TRUE } }, - { "default-font-size", { INT, SETTINGS, TRUE } }, - { "default-monospace-font-size", { INT, SETTINGS, TRUE } }, - { "editable", { BOOL, WEBKITVIEW, TRUE } }, - { "enable-caret-browsing", { BOOL, SETTINGS, TRUE } }, - { "enable-default-context-menu", { BOOL, SETTINGS, TRUE } }, - { "enable-developer-extras", { BOOL, SETTINGS, TRUE } }, - { "enable-dom-paste", { BOOL, SETTINGS, TRUE } }, - { "enable-file-access-from-file-uris", { BOOL, SETTINGS, TRUE } }, - { "enable-html5-database", { BOOL, SETTINGS, TRUE } }, - { "enable-html5-local-storage", { BOOL, SETTINGS, TRUE } }, - { "enable-java-applet", { BOOL, SETTINGS, TRUE } }, - { "enable-offline-web-application-cache", { BOOL, SETTINGS, TRUE } }, - { "enable-page-cache", { BOOL, SETTINGS, TRUE } }, - { "enable-plugins", { BOOL, SETTINGS, TRUE } }, - { "enable-private-browsing", { BOOL, SETTINGS, TRUE } }, - { "enable-scripts", { BOOL, SETTINGS, TRUE } }, - { "enable-site-specific-quirks", { BOOL, SETTINGS, TRUE } }, - { "enable-spatial-navigation", { BOOL, SETTINGS, TRUE } }, - { "enable-spell-checking", { BOOL, SETTINGS, TRUE } }, - { "enable-universal-access-from-file-uris", { BOOL, SETTINGS, TRUE } }, - { "enable-xss-auditor", { BOOL, SETTINGS, TRUE } }, - { "encoding", { CHAR, WEBKITVIEW, FALSE } }, - { "enforce-96-dpi", { BOOL, SETTINGS, TRUE } }, - { "fantasy-font-family", { CHAR, SETTINGS, TRUE } }, - { "full-content-zoom", { BOOL, WEBKITVIEW, TRUE } }, - { "idle-timeout", { INT, SOUPSESSION, TRUE } }, - { "icon-uri", { CHAR, WEBKITVIEW, FALSE } }, - { "javascript-can-access-clipboard", { BOOL, SETTINGS, TRUE } }, - { "javascript-can-open-windows-automatically", { BOOL, SETTINGS, TRUE } }, - { "max-conns", { INT, SOUPSESSION, TRUE } }, - { "max-conns-per-host", { INT, SOUPSESSION, TRUE } }, - { "minimum-font-size", { INT, SETTINGS, TRUE } }, - { "minimum-logical-font-size", { INT, SETTINGS, TRUE } }, - { "monospace-font-family", { CHAR, SETTINGS, TRUE } }, - { "print-backgrounds", { BOOL, SETTINGS, TRUE } }, - { "progress", { DOUBLE, WEBKITVIEW, FALSE } }, - { "proxy-uri", { URI, SOUPSESSION, TRUE } }, - { "resizable-text-areas", { BOOL, SETTINGS, TRUE } }, - { "sans-serif-font-family", { CHAR, SETTINGS, TRUE } }, - { "serif-font-family", { CHAR, SETTINGS, TRUE } }, - { "spell-checking-languages", { CHAR, SETTINGS, TRUE } }, - { "ssl-ca-file", { CHAR, SOUPSESSION, TRUE } }, - { "ssl-strict", { BOOL, SOUPSESSION, TRUE } }, - { "tab-key-cycles-through-elements", { BOOL, SETTINGS, TRUE } }, - { "timeout", { INT, SOUPSESSION, TRUE } }, - { "title", { CHAR, WEBKITVIEW, FALSE } }, - { "transparent", { BOOL, WEBKITVIEW, TRUE } }, - { "use-ntlm", { BOOL, SOUPSESSION, TRUE } }, - { "user-agent", { CHAR, SETTINGS, TRUE } }, - { "user-stylesheet-uri", { CHAR, SETTINGS, TRUE } }, - { "zoom-level", { FLOAT, WEBKITVIEW, TRUE } }, - { "zoom-step", { FLOAT, SETTINGS, TRUE } }, - { NULL, { 0, 0, 0 } }, +typedef struct { + const gchar *name; + property_value_t type; + property_scope scope; + gboolean writable; + const gchar *signame; +} property_t; + +property_t properties_table[] = { + { "accept-language", CHAR, SOUPSESSION, TRUE, NULL }, + { "accept-language-auto", BOOL, SOUPSESSION, TRUE, NULL }, + { "auto-load-images", BOOL, SETTINGS, TRUE, NULL }, + { "auto-resize-window", BOOL, SETTINGS, TRUE, NULL }, + { "auto-shrink-images", BOOL, SETTINGS, TRUE, NULL }, + { "cursive-font-family", CHAR, SETTINGS, TRUE, NULL }, + { "custom-encoding", CHAR, WEBKITVIEW, TRUE, NULL }, + { "default-encoding", CHAR, SETTINGS, TRUE, NULL }, + { "default-font-family", CHAR, SETTINGS, TRUE, NULL }, + { "default-font-size", INT, SETTINGS, TRUE, NULL }, + { "default-monospace-font-size", INT, SETTINGS, TRUE, NULL }, + { "editable", BOOL, WEBKITVIEW, TRUE, NULL }, + { "enable-caret-browsing", BOOL, SETTINGS, TRUE, NULL }, + { "enable-default-context-menu", BOOL, SETTINGS, TRUE, NULL }, + { "enable-developer-extras", BOOL, SETTINGS, TRUE, NULL }, + { "enable-dom-paste", BOOL, SETTINGS, TRUE, NULL }, + { "enable-file-access-from-file-uris", BOOL, SETTINGS, TRUE, NULL }, + { "enable-html5-database", BOOL, SETTINGS, TRUE, NULL }, + { "enable-html5-local-storage", BOOL, SETTINGS, TRUE, NULL }, + { "enable-java-applet", BOOL, SETTINGS, TRUE, NULL }, + { "enable-offline-web-application-cache", BOOL, SETTINGS, TRUE, NULL }, + { "enable-page-cache", BOOL, SETTINGS, TRUE, NULL }, + { "enable-plugins", BOOL, SETTINGS, TRUE, NULL }, + { "enable-private-browsing", BOOL, SETTINGS, TRUE, NULL }, + { "enable-scripts", BOOL, SETTINGS, TRUE, NULL }, + { "enable-site-specific-quirks", BOOL, SETTINGS, TRUE, NULL }, + { "enable-spatial-navigation", BOOL, SETTINGS, TRUE, NULL }, + { "enable-spell-checking", BOOL, SETTINGS, TRUE, NULL }, + { "enable-universal-access-from-file-uris", BOOL, SETTINGS, TRUE, NULL }, + { "enable-xss-auditor", BOOL, SETTINGS, TRUE, NULL }, + { "encoding", CHAR, WEBKITVIEW, FALSE, NULL }, + { "enforce-96-dpi", BOOL, SETTINGS, TRUE, NULL }, + { "fantasy-font-family", CHAR, SETTINGS, TRUE, NULL }, + { "full-content-zoom", BOOL, WEBKITVIEW, TRUE, NULL }, + { "icon-uri", CHAR, WEBKITVIEW, FALSE, NULL }, + { "idle-timeout", INT, SOUPSESSION, TRUE, NULL }, + { "javascript-can-access-clipboard", BOOL, SETTINGS, TRUE, NULL }, + { "javascript-can-open-windows-automatically", BOOL, SETTINGS, TRUE, NULL }, + { "max-conns", INT, SOUPSESSION, TRUE, NULL }, + { "max-conns-per-host", INT, SOUPSESSION, TRUE, NULL }, + { "minimum-font-size", INT, SETTINGS, TRUE, NULL }, + { "minimum-logical-font-size", INT, SETTINGS, TRUE, NULL }, + { "monospace-font-family", CHAR, SETTINGS, TRUE, NULL }, + { "print-backgrounds", BOOL, SETTINGS, TRUE, NULL }, + { "progress", DOUBLE, WEBKITVIEW, FALSE, NULL }, + { "proxy-uri", URI, SOUPSESSION, TRUE, NULL }, + { "resizable-text-areas", BOOL, SETTINGS, TRUE, NULL }, + { "sans-serif-font-family", CHAR, SETTINGS, TRUE, NULL }, + { "serif-font-family", CHAR, SETTINGS, TRUE, NULL }, + { "spell-checking-languages", CHAR, SETTINGS, TRUE, NULL }, + { "ssl-ca-file", CHAR, SOUPSESSION, TRUE, NULL }, + { "ssl-strict", BOOL, SOUPSESSION, TRUE, NULL }, + { "tab-key-cycles-through-elements", BOOL, SETTINGS, TRUE, NULL }, + { "timeout", INT, SOUPSESSION, TRUE, NULL }, + { "title", CHAR, WEBKITVIEW, FALSE, NULL }, + { "transparent", BOOL, WEBKITVIEW, TRUE, NULL }, + { "uri", CHAR, WEBKITVIEW, TRUE, NULL }, + { "use-ntlm", BOOL, SOUPSESSION, TRUE, NULL }, + { "user-agent", CHAR, SETTINGS, TRUE, NULL }, + { "user-stylesheet-uri", CHAR, SETTINGS, TRUE, NULL }, + { "zoom-level", FLOAT, WEBKITVIEW, TRUE, NULL }, + { "zoom-step", FLOAT, SETTINGS, TRUE, NULL }, + { NULL, 0, 0, 0, NULL }, }; static void webview_init_properties() { properties = g_hash_table_new(g_str_hash, g_str_equal); - for (const struct property_t *p = properties_table; p->name; p++) - g_hash_table_insert(properties, (gpointer) p->name, (gpointer) &p->v); + for (property_t *p = properties_table; p->name; p++) { + /* pre-compile "property::name" signals for each property */ + if (!p->signame) p->signame = g_strdup_printf("property::%s", p->name); + g_hash_table_insert(properties, (gpointer) p->name, (gpointer) p); + } } static const gchar* @@ -222,73 +237,44 @@ luaH_webview_eval_js(lua_State *L) } static void -notify_progress_cb(WebKitWebView *v, GParamSpec *s, widget_t *w) +notify_cb(WebKitWebView *v, GParamSpec *ps, widget_t *w) { (void) v; - (void) s; - - lua_State *L = globalconf.L; - luaH_object_push(L, w->ref); - luaH_object_emit_signal(L, -1, "property::progress", 0, 0); - lua_pop(L, 1); -} - -static void -title_changed_cb(WebKitWebView *v, WebKitWebFrame *f, const gchar *title, widget_t *w) -{ - (void) f; - (void) v; - (void) title; - - lua_State *L = globalconf.L; - luaH_object_push(L, w->ref); - luaH_object_emit_signal(L, -1, "title-changed", 0, 0); - lua_pop(L, 1); -} - -inline static void -update_uri(GtkWidget *view, const gchar *uri, widget_t *w) -{ - /* return if uri has not changed */ - if (!g_strcmp0(uri, g_object_get_data(G_OBJECT(view), "uri"))) - return; - - g_object_set_data_full(G_OBJECT(view), "uri", g_strdup(uri), g_free); - lua_State *L = globalconf.L; - luaH_object_push(L, w->ref); - luaH_object_emit_signal(L, -1, "property::uri", 0, 0); - lua_pop(L, 1); + property_t *p; + /* emit "property::name" signal if found in properties table */ + if ((p = g_hash_table_lookup(properties, ps->name))) { + lua_State *L = globalconf.L; + luaH_object_push(L, w->ref); + luaH_object_emit_signal(L, -1, p->signame, 0, 0); + lua_pop(L, 1); + } } static void -notify_load_status_cb(WebKitWebView *v, GParamSpec *s, widget_t *w) +notify_load_status_cb(WebKitWebView *v, GParamSpec *ps, widget_t *w) { - (void) s; - - update_uri(GTK_WIDGET(v), webkit_web_view_get_uri(v), w); + (void) ps; /* Get load status */ WebKitLoadStatus status; g_object_get(G_OBJECT(v), "load-status", &status, NULL); + /* get load status literal */ gchar *name = NULL; - switch(status) { - case WEBKIT_LOAD_PROVISIONAL: - name = "provisional"; - break; - case WEBKIT_LOAD_COMMITTED: - name = "committed"; - break; - case WEBKIT_LOAD_FINISHED: - name = "finished"; - break; - case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT: - name = "first-visual"; - break; - case WEBKIT_LOAD_FAILED: - name = "failed"; - break; + switch (status) { + +#define LT_CASE(atom, literal) case WEBKIT_LOAD_##atom: name = literal; break; + + LT_CASE(PROVISIONAL, "provisional") + LT_CASE(COMMITTED, "committed") + LT_CASE(FINISHED, "finished") + LT_CASE(FIRST_VISUALLY_NON_EMPTY_LAYOUT, "first-visual") + LT_CASE(FAILED, "failed") + +#undef LT_CASE + default: + warn("programmer error, unable to get load status literal"); break; } @@ -413,11 +399,11 @@ navigation_decision_cb(WebKitWebView *v, WebKitWebFrame *f, } inline static gint -push_adjustment_values(lua_State *L, GtkAdjustment *adjustment) +luaH_adjustment_push_values(lua_State *L, GtkAdjustment *a) { - gdouble view_size = gtk_adjustment_get_page_size(adjustment); - gdouble value = gtk_adjustment_get_value(adjustment); - gdouble max = gtk_adjustment_get_upper(adjustment) - view_size; + gdouble view_size = gtk_adjustment_get_page_size(a); + gdouble value = gtk_adjustment_get_value(a); + gdouble max = gtk_adjustment_get_upper(a) - view_size; lua_pushnumber(L, value); lua_pushnumber(L, (max < 0 ? 0 : max)); lua_pushnumber(L, view_size); @@ -428,24 +414,24 @@ static gint luaH_webview_get_vscroll(lua_State *L) { widget_t *w = luaH_checkudata(L, 1, &widget_class); - GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(w->widget)); - return push_adjustment_values(L, adjustment); + GtkAdjustment *a = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(w->widget)); + return luaH_adjustment_push_values(L, a); } static gint luaH_webview_get_hscroll(lua_State *L) { widget_t *w = luaH_checkudata(L, 1, &widget_class); - GtkAdjustment *adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(w->widget)); - return push_adjustment_values(L, adjustment); + GtkAdjustment *a = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(w->widget)); + return luaH_adjustment_push_values(L, a); } inline static void -set_adjustment(GtkAdjustment *adjustment, gdouble new) +adjustment_set(GtkAdjustment *a, gdouble new) { - gdouble view_size = gtk_adjustment_get_page_size(adjustment); - gdouble max = gtk_adjustment_get_upper(adjustment) - view_size; - gtk_adjustment_set_value(adjustment, ((new < 0 ? 0 : new) > max ? max : new)); + gdouble view_size = gtk_adjustment_get_page_size(a); + gdouble max = gtk_adjustment_get_upper(a) - view_size; + gtk_adjustment_set_value(a, ((new < 0 ? 0 : new) > max ? max : new)); } static gint @@ -453,8 +439,8 @@ luaH_webview_set_scroll_vert(lua_State *L) { widget_t *w = luaH_checkudata(L, 1, &widget_class); gdouble value = (gdouble) luaL_checknumber(L, 2); - GtkAdjustment *adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(w->widget)); - set_adjustment(adjustment, value); + GtkAdjustment *a = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(w->widget)); + adjustment_set(a, value); return 0; } @@ -463,8 +449,8 @@ luaH_webview_set_scroll_horiz(lua_State *L) { widget_t *w = luaH_checkudata(L, 1, &widget_class); gdouble value = (gdouble) luaL_checknumber(L, 2); - GtkAdjustment *adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(w->widget)); - set_adjustment(adjustment, value); + GtkAdjustment *a = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(w->widget)); + adjustment_set(a, value); return 0; } @@ -515,9 +501,9 @@ luaH_webview_clear_search(lua_State *L) } inline static GObject* -get_settings_object(GtkWidget *view, property_value_scope scope) +get_settings_object(GtkWidget *view, property_t *p) { - switch (scope) { + switch (p->scope) { case SETTINGS: return G_OBJECT(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(view))); case WEBKITVIEW: @@ -527,53 +513,56 @@ get_settings_object(GtkWidget *view, property_value_scope scope) default: break; } + warn("programmer error: unknown settings scope for property: %s", p->name); return NULL; } static gint luaH_webview_get_prop(lua_State *L) { - widget_t *w = luaH_checkudata(L, 1, &widget_class); - const gchar *prop = luaL_checkstring(L, 2); - GtkWidget *view = GTK_WIDGET(g_object_get_data(G_OBJECT(w->widget), "webview")); - GObject *ws; - property_value_t *prop_v; - property_tmp_values tmp; + GObject *so; SoupURI *u; + property_t *p; + temp_value_t tmp; - if ((prop_v = g_hash_table_lookup(properties, prop))) { + /* get webview widget */ + widget_t *w = luaH_checkudata(L, 1, &widget_class); + GtkWidget *view = GTK_WIDGET(g_object_get_data(G_OBJECT(w->widget), "webview")); - ws = get_settings_object(view, prop_v->scope); + /* get property struct */ + const gchar *name = luaL_checkstring(L, 2); + if ((p = g_hash_table_lookup(properties, name))) { + so = get_settings_object(view, p); - switch(prop_v->type) { + switch(p->type) { case BOOL: - g_object_get(ws, prop, &tmp.b, NULL); + g_object_get(so, p->name, &tmp.b, NULL); lua_pushboolean(L, tmp.b); return 1; - case CHAR: - g_object_get(ws, prop, &tmp.c, NULL); - lua_pushstring(L, tmp.c); - g_free(tmp.c); - return 1; - case INT: - g_object_get(ws, prop, &tmp.i, NULL); + g_object_get(so, p->name, &tmp.i, NULL); lua_pushnumber(L, tmp.i); return 1; case FLOAT: - g_object_get(ws, prop, &tmp.f, NULL); + g_object_get(so, p->name, &tmp.f, NULL); lua_pushnumber(L, tmp.f); return 1; case DOUBLE: - g_object_get(ws, prop, &tmp.d, NULL); + g_object_get(so, p->name, &tmp.d, NULL); lua_pushnumber(L, tmp.d); return 1; + case CHAR: + g_object_get(so, p->name, &tmp.c, NULL); + lua_pushstring(L, tmp.c); + g_free(tmp.c); + return 1; + case URI: - g_object_get(ws, prop, &u, NULL); + g_object_get(so, p->name, &u, NULL); tmp.c = soup_uri_to_string(u, 0); lua_pushstring(L, tmp.c); soup_uri_free(u); @@ -581,77 +570,77 @@ luaH_webview_get_prop(lua_State *L) return 1; default: - warn("unknown property type for: %s", prop); + warn("programmer error: unknown property type for: %s", p->name); break; } } - warn("unknown property: %s", prop); + warn("unknown property: %s", name); return 0; } static gint luaH_webview_set_prop(lua_State *L) { - size_t len; - widget_t *w = luaH_checkudata(L, 1, &widget_class); - const gchar *prop = luaL_checklstring(L, 2, &len); - GtkWidget *view = g_object_get_data(G_OBJECT(w->widget), "webview"); - GObject *ws; - property_value_t *prop_v; - property_tmp_values tmp; + GObject *so; SoupURI *u; + property_t *p; + temp_value_t tmp; - if ((prop_v = g_hash_table_lookup(properties, prop))) { + /* get webview widget */ + widget_t *w = luaH_checkudata(L, 1, &widget_class); + GtkWidget *view = g_object_get_data(G_OBJECT(w->widget), "webview"); - if (!prop_v->writable) { - warn("attempt to set read-only property: %s", prop); + /* get property struct */ + const gchar *name = luaL_checkstring(L, 2); + if ((p = g_hash_table_lookup(properties, name))) { + if (!p->writable) { + warn("attempt to set read-only property: %s", p->name); return 0; } - ws = get_settings_object(view, prop_v->scope); - - switch(prop_v->type) { + so = get_settings_object(view, p); + switch(p->type) { case BOOL: tmp.b = luaH_checkboolean(L, 3); - g_object_set(ws, prop, tmp.b, NULL); - return 0; - - case CHAR: - tmp.c = (gchar*) luaL_checklstring(L, 3, &len); - g_object_set(ws, prop, tmp.c, NULL); + g_object_set(so, p->name, tmp.b, NULL); return 0; case INT: tmp.i = (gint) luaL_checknumber(L, 3); - g_object_set(ws, prop, tmp.i, NULL); + g_object_set(so, p->name, tmp.i, NULL); return 0; case FLOAT: tmp.f = (gfloat) luaL_checknumber(L, 3); - g_object_set(ws, prop, tmp.f, NULL); + g_object_set(so, p->name, tmp.f, NULL); return 0; case DOUBLE: tmp.d = (gdouble) luaL_checknumber(L, 3); - g_object_set(ws, prop, tmp.d, NULL); + g_object_set(so, p->name, tmp.d, NULL); + return 0; + + case CHAR: + tmp.c = (gchar*) luaL_checkstring(L, 3); + g_object_set(so, p->name, tmp.c, NULL); return 0; case URI: tmp.c = (gchar*) luaL_checkstring(L, 3); u = soup_uri_new(tmp.c); if (SOUP_URI_VALID_FOR_HTTP(u)) - g_object_set(ws, prop, u, NULL); + g_object_set(so, p->name, u, NULL); else - luaL_error(L, "cannot parse uri: %s", tmp.c); + luaL_error(L, "cannot parse uri: %s", tmp.c); soup_uri_free(u); return 0; default: - warn("unknown property type for: %s", prop); + warn("programmer error: unknown property type for: %s", p->name); break; } } - warn("unknown property: %s", prop); + warn("unknown property: %s", name); return 0; } @@ -700,79 +689,45 @@ luaH_webview_index(lua_State *L, luakit_token_t token) { widget_t *w = luaH_checkudata(L, 1, &widget_class); GtkWidget *view = g_object_get_data(G_OBJECT(w->widget), "webview"); - - switch(token) - { - case L_TK_DESTROY: - lua_pushcfunction(L, luaH_widget_destroy); - return 1; - - case L_TK_GET_SCROLL_VERT: - lua_pushcfunction(L, luaH_webview_get_vscroll); - return 1; - - case L_TK_GET_SCROLL_HORIZ: - lua_pushcfunction(L, luaH_webview_get_hscroll); - return 1; - - case L_TK_SET_SCROLL_VERT: - lua_pushcfunction(L, luaH_webview_set_scroll_vert); - return 1; - - case L_TK_SET_SCROLL_HORIZ: - lua_pushcfunction(L, luaH_webview_set_scroll_horiz); - return 1; - - case L_TK_EVAL_JS: - lua_pushcfunction(L, luaH_webview_eval_js); - return 1; - - case L_TK_SEARCH: - lua_pushcfunction(L, luaH_webview_search); - return 1; - - case L_TK_CLEAR_SEARCH: - lua_pushcfunction(L, luaH_webview_clear_search); - return 1; - - case L_TK_SET_PROP: - lua_pushcfunction(L, luaH_webview_set_prop); - return 1; - - case L_TK_GET_PROP: - lua_pushcfunction(L, luaH_webview_get_prop); - return 1; + temp_value_t tmp; + + switch(token) { + +#define PF_CASE(tok, func) case L_TK_##tok: lua_pushcfunction(L, func); return 1; + + /* property methods */ + PF_CASE(GET_PROP, luaH_webview_get_prop) + PF_CASE(SET_PROP, luaH_webview_set_prop) + /* scroll adjustment methods */ + PF_CASE(GET_SCROLL_HORIZ, luaH_webview_get_hscroll) + PF_CASE(GET_SCROLL_VERT, luaH_webview_get_vscroll) + PF_CASE(SET_SCROLL_HORIZ, luaH_webview_set_scroll_horiz) + PF_CASE(SET_SCROLL_VERT, luaH_webview_set_scroll_vert) + /* search methods */ + PF_CASE(CLEAR_SEARCH, luaH_webview_clear_search) + PF_CASE(SEARCH, luaH_webview_search) + /* history navigation methods */ + PF_CASE(GO_BACK, luaH_webview_go_back) + PF_CASE(GO_FORWARD, luaH_webview_go_forward) + /* misc webview methods */ + PF_CASE(EVAL_JS, luaH_webview_eval_js) + PF_CASE(LOADING, luaH_webview_loading) + /* widget methods */ + PF_CASE(DESTROY, luaH_widget_destroy) + PF_CASE(FOCUS, luaH_widget_focus) + PF_CASE(HIDE, luaH_widget_hide) + PF_CASE(SHOW, luaH_widget_show) + +#undef PF_CASE case L_TK_HOVERED_URI: lua_pushstring(L, g_object_get_data(G_OBJECT(view), "hovered-uri")); return 1; case L_TK_URI: - lua_pushstring(L, g_object_get_data(G_OBJECT(view), "uri")); - return 1; - - case L_TK_SHOW: - lua_pushcfunction(L, luaH_widget_show); - return 1; - - case L_TK_HIDE: - lua_pushcfunction(L, luaH_widget_hide); - return 1; - - case L_TK_FOCUS: - lua_pushcfunction(L, luaH_widget_focus); - return 1; - - case L_TK_LOADING: - lua_pushcfunction(L, luaH_webview_loading); - return 1; - - case L_TK_GO_BACK: - lua_pushcfunction(L, luaH_webview_go_back); - return 1; - - case L_TK_GO_FORWARD: - lua_pushcfunction(L, luaH_webview_go_forward); + g_object_get(G_OBJECT(view), "uri", &tmp.c, NULL); + lua_pushstring(L, tmp.c); + g_free(tmp.c); return 1; default: @@ -790,18 +745,18 @@ luaH_webview_newindex(lua_State *L, luakit_token_t token) size_t len; widget_t *w = luaH_checkudata(L, 1, &widget_class); GtkWidget *view = g_object_get_data(G_OBJECT(w->widget), "webview"); - gchar *uri; + temp_value_t tmp; switch(token) { case L_TK_URI: - uri = (gchar*) luaL_checklstring(L, 3, &len); - if (g_strrstr(uri, "://") || !g_strcmp0(uri, "about:blank")) - uri = g_strdup(uri); + tmp.c = (gchar*) luaL_checklstring(L, 3, &len); + if (g_strrstr(tmp.c, "://") || !g_strcmp0(tmp.c, "about:blank")) + tmp.c = g_strdup(tmp.c); else - uri = g_strdup_printf("http://%s", uri); - webkit_web_view_load_uri(WEBKIT_WEB_VIEW(view), uri); - g_object_set_data_full(G_OBJECT(view), "uri", uri, g_free); + tmp.c = g_strdup_printf("http://%s", tmp.c); + webkit_web_view_load_uri(WEBKIT_WEB_VIEW(view), tmp.c); + g_free(tmp.c); break; case L_TK_SHOW_SCROLLBARS: @@ -855,9 +810,12 @@ wv_button_press_cb(GtkWidget *view, GdkEventButton *ev, widget_t *w) static void webview_destructor(widget_t *w) { - GtkWidget *view = g_object_get_data(G_OBJECT(w->widget), "webview"); - gtk_widget_destroy(GTK_WIDGET(view)); - gtk_widget_destroy(GTK_WIDGET(w->widget)); + if (w->widget) { + GtkWidget *view = g_object_get_data(G_OBJECT(w->widget), "webview"); + gtk_widget_destroy(GTK_WIDGET(view)); + gtk_widget_destroy(GTK_WIDGET(w->widget)); + } else + warn("webview widget already destroyed"); } widget_t * @@ -886,6 +844,7 @@ widget_webview(widget_t *w) g_object_set_data(G_OBJECT(w->widget), "webview", view); gtk_container_add(GTK_CONTAINER(w->widget), view); + /* set initial scrollbars state */ show_scrollbars(w, TRUE); /* connect webview signals */ @@ -900,13 +859,12 @@ widget_webview(widget_t *w) "signal::key-press-event", (GCallback)key_press_cb, w, "signal::mime-type-policy-decision-requested", (GCallback)mime_type_decision_cb, w, "signal::navigation-policy-decision-requested", (GCallback)navigation_decision_cb, w, + "signal::notify", (GCallback)notify_cb, w, "signal::notify::load-status", (GCallback)notify_load_status_cb, w, - "signal::notify::progress", (GCallback)notify_progress_cb, w, "signal::parent-set", (GCallback)parent_set_cb, w, - "signal::title-changed", (GCallback)title_changed_cb, w, NULL); - /* setup */ + /* show widgets */ gtk_widget_show(view); gtk_widget_show(w->widget); -- 2.11.4.GIT