diff --git a/rose.c b/rose.c index f0d759e..c94384b 100644 --- a/rose.c +++ b/rose.c @@ -17,25 +17,25 @@ void setatom(int a, const char *v) XSync(glob_dpy, False); } -const char* getatom(int a) +char* getatom(int a) { - static char buf[BUFSIZ]; Atom adummy; int idummy; unsigned long ldummy; unsigned char *p = NULL; + char *ret; XSync(glob_dpy, False); XGetWindowProperty(glob_dpy, glob_xid, - glob_atoms[a], 0L, BUFSIZ, False, glob_atoms[AtomUTF8], - &adummy, &idummy, &ldummy, &ldummy, &p); - if (p) - strncpy(buf, (char *)p, LENGTH(buf) - 1); - else - buf[0] = '\0'; - XFree(p); + glob_atoms[a], 0L, BUFSIZ, False, glob_atoms[AtomUTF8], + &adummy, &idummy, &ldummy, &ldummy, &p); - return buf; + /* We need to strdup() the returned string, because the spec says we _have_ + to use XFree(). Although it's probably a regular free() call, we can make + sure by just strdup'ing it into our own buffer. */ + ret = strdup((char *) p); + XFree(p); + return ret; } static void setup() @@ -69,6 +69,7 @@ int main(int argc, char **argv) options[HOMEPAGE] = argv[1]; argv++; argc--; } + setup(); GtkApplication *app = gtk_application_new("org.gtk.rose", G_APPLICATION_NON_UNIQUE); g_signal_connect(app, "activate", G_CALLBACK(run), NULL); diff --git a/rose.h b/rose.h index 8a56410..d364b74 100644 --- a/rose.h +++ b/rose.h @@ -23,5 +23,7 @@ enum { extern Display *glob_dpy; /* declared in rose.c */ -const char* getatom(int a); -void setatom(int a, const char *v); +/* Set/get X11 window properties. `getatom` retuns an allocated string + which has to be free'd. */ +char *getatom(int aid); +void setatom(int aid, const char *val); diff --git a/webview.c b/webview.c index 4697bbc..b3935cd 100644 --- a/webview.c +++ b/webview.c @@ -2,10 +2,8 @@ struct _RoseWebView { WebKitWebView parent_instance; - GCancellable *cancellable; RoseWebViewNavigationFlags navigation; - char *address; }; @@ -15,9 +13,10 @@ enum { PROP_ADDRESS }; +G_DEFINE_TYPE(RoseWebView, rose_webview, WEBKIT_TYPE_WEB_VIEW) + static GParamSpec *obj_properties[LAST_PROP]; -G_DEFINE_TYPE(RoseWebView, rose_webview, WEBKIT_TYPE_WEB_VIEW) static void update_navigation_flags(RoseWebView *webview) { @@ -88,11 +87,8 @@ static void rose_webview_class_init(RoseWebViewClass *class) object_class->constructed = rose_webview_constructed; obj_properties[PROP_ADDRESS] = - g_param_spec_string ("address", - "Address", - "address", - "", - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + g_param_spec_string("address", "Address", "address", + "", G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); } static void rose_webview_init(RoseWebView *webview) @@ -106,20 +102,24 @@ void rose_webview_load_url(WebKitWebView *webview, const char *url) setatom(AtomUri, url); } -void rose_load_changed_callback(WebKitWebView *webview, - WebKitLoadEvent event) +void rose_load_changed_callback(WebKitWebView *webview, WebKitLoadEvent event) { + char *hist; + size_t nhist; + FILE *f; + if (event == WEBKIT_LOAD_FINISHED) { - const char *uri = webkit_web_view_get_uri(webview); - char *cookiefile = calloc(1, sizeof(char) * (strlen(options[CACHE]) + 32) + 1); - sprintf(cookiefile, "%s/history", options[CACHE]); + /* Append the current URL to the history file. */ + nhist = strlen(options[CACHE]) + 12; + hist = malloc(sizeof(char) * nhist); + snprintf(hist, nhist, "%s/history", options[CACHE]); - FILE *cookie = fopen(cookiefile, "a"); + f = fopen(hist, "a"); + fprintf(f, "%s\n", webkit_web_view_get_uri(webview)); + fclose(f); - fprintf(cookie, "%s\n", uri); - fclose(cookie); - free(cookiefile); - } + free(hist); + } } static void rose_download(const char* uri) @@ -129,6 +129,8 @@ static void rose_download(const char* uri) strcpy(url, uri); + /* TODO: replace this whole cruft with another alternative */ + int id = fork(); if (id == 0) { setsid(); @@ -142,14 +144,13 @@ static void rose_download(const char* uri) static void rose_response_reciver(WebKitDownload *download) { const char *uri = webkit_uri_response_get_uri(webkit_download_get_response(download)); - rose_download(uri); } static void rose_download_callback(WebKitDownload *download) { - g_signal_connect(G_OBJECT(download), "notify::response", - G_CALLBACK(rose_response_reciver), NULL); + g_signal_connect(G_OBJECT(download), "notify::response", + G_CALLBACK(rose_response_reciver), NULL); } GtkWidget* rose_webview_new() @@ -199,11 +200,11 @@ GtkWidget* rose_webview_new() webkit_cookie_manager_set_accept_policy(cookiemanager, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); g_signal_connect(G_OBJECT(context), "download-started", - G_CALLBACK(rose_download_callback), NULL); + G_CALLBACK(rose_download_callback), NULL); return g_object_new( - WEBKIT_TYPE_WEB_VIEW, - "settings", settings, - "user-content-manager", contentmanager, - "web-context", context, NULL); + WEBKIT_TYPE_WEB_VIEW, + "settings", settings, + "user-content-manager", contentmanager, + "web-context", context, NULL); } diff --git a/webview.h b/webview.h index 8a4db61..ef8f7f1 100644 --- a/webview.h +++ b/webview.h @@ -9,21 +9,18 @@ G_DECLARE_FINAL_TYPE(RoseWebView, rose_webview, ROSE, WEBVIEW, WebKitWebView) -typedef enum -{ +typedef enum { ROSE_WEBVIEW_NAV_BACK = 1 << 0, ROSE_WEBVIEW_FORWARD = 1 << 1 } RoseWebViewNavigationFlags; +/* Create a new webview in the form of a Gtk Object. */ GtkWidget* rose_webview_new(); + +/* Load the given `url` into the webview. */ void rose_webview_load_url(WebKitWebView *webview, const char *url); -RoseWebViewNavigationFlags rose_webview_get_navigation_flags(RoseWebView *webview); - -void rose_webview_go_back(RoseWebView *window); -void rose_webview_go_forward(RoseWebView *window); - +/* Called when the URL changes, adds a new entry to the history + file. */ void rose_load_changed_callback(WebKitWebView *webview, WebKitLoadEvent event); - -const char* rose_webview_get_address(RoseWebView *webview); diff --git a/window.c b/window.c index 6e608be..1914d49 100644 --- a/window.c +++ b/window.c @@ -21,9 +21,7 @@ static float zoom = 1.0; G_DEFINE_TYPE(RoseWindow, rose_window, GTK_TYPE_APPLICATION_WINDOW) -static void read_clipboard(GObject *object, - GAsyncResult *res, - gpointer webview) +static void read_clipboard(GObject *object, GAsyncResult *res, gpointer webview) { GdkClipboard *clipboard = GDK_CLIPBOARD(object); webkit_web_view_load_uri( @@ -32,16 +30,13 @@ static void read_clipboard(GObject *object, ); } -static gboolean key_press_callback(RoseWindow *window, - guint keyval, - guint keycode, - GdkModifierType state) +static gboolean key_press_callback(RoseWindow *window, guint keyval, + guint keycode, GdkModifierType state) { (void) keycode; for (int i = 0; i < LENGTH(keys); i++) { - if (keys[i].modkey == state - && keys[i].keycod == keyval) { + if (keys[i].modkey == state && keys[i].keycod == keyval) { switch (keys[i].funcid) { case goback: webkit_web_view_go_back(window->webview); @@ -191,7 +186,6 @@ static gboolean key_press_callback(RoseWindow *window, } } - return GDK_EVENT_PROPAGATE; } @@ -222,13 +216,13 @@ guint rose_window_show(GtkApplication *app, RoseWindow *window, const char *url) window->webview = WEBKIT_WEB_VIEW(webview); g_signal_connect(G_OBJECT(w), "destroy", - G_CALLBACK(destroy), NULL); + G_CALLBACK(destroy), NULL); g_signal_connect(G_OBJECT(window->webview), "web-process-terminated", - G_CALLBACK(destroy), NULL); + G_CALLBACK(destroy), NULL); g_signal_connect(G_OBJECT(window->webview), "load-changed", - G_CALLBACK(rose_load_changed_callback), window); + G_CALLBACK(rose_load_changed_callback), window); if (url) { rose_webview_load_url(WEBKIT_WEB_VIEW(webview), url); @@ -263,15 +257,14 @@ void rose_window_set_webview(RoseWindow *window, GtkWidget *webview) static void rose_window_class_init(RoseWindowClass *class) { GObjectClass *object_class = G_OBJECT_CLASS(class); - object_class->constructed = rose_window_constructed; } RoseWindow* rose_window_new(GtkApplication *app) { - return g_object_new( - GTK_TYPE_APPLICATION_WINDOW, - "application", GTK_APPLICATION(app), - NULL - ); + return g_object_new( + GTK_TYPE_APPLICATION_WINDOW, + "application", GTK_APPLICATION(app), + NULL + ); } diff --git a/window.h b/window.h index 0207aeb..edd5287 100644 --- a/window.h +++ b/window.h @@ -9,11 +9,10 @@ G_DECLARE_FINAL_TYPE(RoseWindow, rose_window, ROSE, WINDOW, GtkApplicationWindow) +/* Create a new GObject, which is our window. */ RoseWindow* rose_window_new(); + +/* Set up all the things and show the window. */ guint rose_window_show(GtkApplication *app, RoseWindow *window, const char *url); -gboolean rose_window_close(RoseWindow *window); void rose_window_set_webview(RoseWindow *window, GtkWidget *webview); - -GActionGroup* rose_window_get_action_group(RoseWindow *window, - const char *prefix);