- /* prevents endless loop */
- if (strcmp(u, geturi(c)) == 0) {
- reload(c, &a);
- } else {
- webkit_web_view_load_uri(c->view, u);
- c->progress = 0;
- c->title = copystr(&c->title, u);
- updatetitle(c);
- }
- g_free(u);
-}
-
-void
-navigate(Client *c, const Arg *arg)
-{
- int steps = *(int *)arg;
- webkit_web_view_go_back_or_forward(c->view, steps);
-}
-
-Client *
-newclient(void)
-{
- Client *c;
- WebKitWebSettings *settings;
- WebKitWebFrame *frame;
- GdkGeometry hints = { 1, 1 };
- GdkScreen *screen;
- gdouble dpi;
- char *ua;
-
- if (!(c = calloc(1, sizeof(Client))))
- die("Cannot malloc!\n");
-
- c->title = NULL;
- c->progress = 100;
-
- /* Window */
- if (embed) {
- c->win = gtk_plug_new(embed);
- } else {
- c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- /* TA: 20091214: Despite what the GNOME docs say, the ICCCM
- * is always correct, so we should still call this function.
- * But when doing so, we *must* differentiate between a
- * WM_CLASS and a resource on the window. By convention, the
- * window class (WM_CLASS) is capped, while the resource is in
- * lowercase. Both these values come as a pair.
- */
- gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "Surf");
-
- /* TA: 20091214: And set the role here as well -- so that
- * sessions can pick this up.
- */
- gtk_window_set_role(GTK_WINDOW(c->win), "Surf");
- }
- gtk_window_set_default_size(GTK_WINDOW(c->win), 800, 600);
- g_signal_connect(G_OBJECT(c->win),
- "destroy",
- G_CALLBACK(destroywin), c);
- g_signal_connect(G_OBJECT(c->win),
- "leave_notify_event",
- G_CALLBACK(titlechangeleave), c);
-
- if (!kioskmode)
- addaccelgroup(c);
-
- /* Pane */
- c->pane = gtk_vpaned_new();
-
- /* VBox */
- c->vbox = gtk_vbox_new(FALSE, 0);
- gtk_paned_pack1(GTK_PANED(c->pane), c->vbox, TRUE, TRUE);
-
- /* Webview */
- c->view = WEBKIT_WEB_VIEW(webkit_web_view_new());
-
- g_signal_connect(G_OBJECT(c->view),
- "notify::title",
- G_CALLBACK(titlechange), c);
- g_signal_connect(G_OBJECT(c->view),
- "hovering-over-link",
- G_CALLBACK(linkhover), c);
- g_signal_connect(G_OBJECT(c->view),
- "geolocation-policy-decision-requested",
- G_CALLBACK(geopolicyrequested), c);
- g_signal_connect(G_OBJECT(c->view),
- "create-web-view",
- G_CALLBACK(createwindow), c);
- g_signal_connect(G_OBJECT(c->view),
- "new-window-policy-decision-requested",
- G_CALLBACK(decidewindow), c);
- g_signal_connect(G_OBJECT(c->view),
- "mime-type-policy-decision-requested",
- G_CALLBACK(decidedownload), c);
- g_signal_connect(G_OBJECT(c->view),
- "window-object-cleared",
- G_CALLBACK(windowobjectcleared), c);
- g_signal_connect(G_OBJECT(c->view),
- "notify::load-status",
- G_CALLBACK(loadstatuschange), c);
- g_signal_connect(G_OBJECT(c->view),
- "notify::progress",
- G_CALLBACK(progresschange), c);
- g_signal_connect(G_OBJECT(c->view),
- "download-requested",
- G_CALLBACK(initdownload), c);
- g_signal_connect(G_OBJECT(c->view),
- "button-release-event",
- G_CALLBACK(buttonrelease), c);
- g_signal_connect(G_OBJECT(c->view),
- "context-menu",
- G_CALLBACK(contextmenu), c);
- g_signal_connect(G_OBJECT(c->view),
- "resource-request-starting",
- G_CALLBACK(beforerequest), c);
- g_signal_connect(G_OBJECT(c->view),
- "should-show-delete-interface-for-element",
- G_CALLBACK(deletion_interface), c);
-
- /* Scrolled Window */
- c->scroll = gtk_scrolled_window_new(NULL, NULL);
-
- frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(c->view));
- g_signal_connect(G_OBJECT(frame), "scrollbars-policy-changed",
- G_CALLBACK(gtk_true), NULL);
-
- if (!enablescrollbars) {
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll),
- GTK_POLICY_NEVER,
- GTK_POLICY_NEVER);
- } else {
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->scroll),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- }
-
- /* Arranging */
- gtk_container_add(GTK_CONTAINER(c->scroll), GTK_WIDGET(c->view));
- gtk_container_add(GTK_CONTAINER(c->win), c->pane);
- gtk_container_add(GTK_CONTAINER(c->vbox), c->scroll);
-
- /* Setup */
- gtk_box_set_child_packing(GTK_BOX(c->vbox), c->scroll, TRUE, TRUE, 0,
- GTK_PACK_START);
- gtk_widget_grab_focus(GTK_WIDGET(c->view));
- gtk_widget_show(c->pane);
- gtk_widget_show(c->vbox);
- gtk_widget_show(c->scroll);
- gtk_widget_show(GTK_WIDGET(c->view));
- gtk_widget_show(c->win);
- gtk_window_set_geometry_hints(GTK_WINDOW(c->win), NULL, &hints,
- GDK_HINT_MIN_SIZE);
- gdk_window_set_events(GTK_WIDGET(c->win)->window, GDK_ALL_EVENTS_MASK);
- gdk_window_add_filter(GTK_WIDGET(c->win)->window, processx, c);
- webkit_web_view_set_full_content_zoom(c->view, TRUE);
-
- runscript(frame);
-
- settings = webkit_web_view_get_settings(c->view);
- if (!(ua = getenv("SURF_USERAGENT")))
- ua = useragent;
- g_object_set(G_OBJECT(settings), "user-agent", ua, NULL);
- if (enablestyles) {
- g_object_set(G_OBJECT(settings),
- "user-stylesheet-uri", getstyle("about:blank"),
- NULL);
- }
- g_object_set(G_OBJECT(settings),
- "auto-load-images", loadimages, NULL);
- g_object_set(G_OBJECT(settings),
- "enable-plugins", enableplugins, NULL);
- g_object_set(G_OBJECT(settings),
- "enable-scripts", enablescripts, NULL);
- g_object_set(G_OBJECT(settings),
- "enable-spatial-navigation", enablespatialbrowsing, NULL);
- g_object_set(G_OBJECT(settings),
- "enable-developer-extras", enableinspector, NULL);
- g_object_set(G_OBJECT(settings),
- "enable-default-context-menu", kioskmode ^ 1, NULL);
- g_object_set(G_OBJECT(settings),
- "default-font-size", defaultfontsize, NULL);
- g_object_set(G_OBJECT(settings),
- "resizable-text-areas", 1, NULL);
-
- /*
- * While stupid, CSS specifies that a pixel represents 1/96 of an inch.
- * This ensures websites are not unusably small with a high DPI screen.
- * It is equivalent to firefox's "layout.css.devPixelsPerPx" setting.
- */
- if (zoomto96dpi) {
- screen = gdk_window_get_screen(GTK_WIDGET(c->win)->window);
- dpi = gdk_screen_get_resolution(screen);
- if (dpi != -1) {
- g_object_set(G_OBJECT(settings),
- "enforce-96-dpi", true, NULL);
- webkit_web_view_set_zoom_level(c->view, dpi/96);
- }
- }
- /* This might conflict with _zoomto96dpi_. */
- if (zoomlevel != 1.0)
- webkit_web_view_set_zoom_level(c->view, zoomlevel);
-
- if (enableinspector) {
- c->inspector = webkit_web_view_get_inspector(c->view);
- g_signal_connect(G_OBJECT(c->inspector), "inspect-web-view",
- G_CALLBACK(inspector_new), c);
- g_signal_connect(G_OBJECT(c->inspector), "show-window",
- G_CALLBACK(inspector_show), c);
- g_signal_connect(G_OBJECT(c->inspector), "close-window",
- G_CALLBACK(inspector_close), c);
- g_signal_connect(G_OBJECT(c->inspector), "finished",
- G_CALLBACK(inspector_finished), c);
- c->isinspecting = false;
- }
-
- if (runinfullscreen) {
- c->fullscreen = 0;
- fullscreen(c, NULL);
- }
-
- setatom(c, AtomFind, "");
- setatom(c, AtomUri, "about:blank");
- if (hidebackground)
- webkit_web_view_set_transparent(c->view, TRUE);
-
- c->next = clients;
- clients = c;
-
- if (showxid) {
- gdk_display_sync(gtk_widget_get_display(c->win));
- printf("%u\n",
- (guint)GDK_WINDOW_XID(GTK_WIDGET(c->win)->window));
- fflush(NULL);
- if (fclose(stdout) != 0) {
- die("Error closing stdout");
- }
- }
-
- return c;
-}
-
-void
-newwindow(Client *c, const Arg *arg, gboolean noembed)
-{
- guint i = 0;
- const char *cmd[18], *uri;
- const Arg a = { .v = (void *)cmd };
- char tmp[64];
-
- cmd[i++] = argv0;
- cmd[i++] = "-a";
- cmd[i++] = cookiepolicies;
- if (!enablescrollbars)
- cmd[i++] = "-b";
- if (embed && !noembed) {
- cmd[i++] = "-e";
- snprintf(tmp, LENGTH(tmp), "%u", (int)embed);
- cmd[i++] = tmp;
- }
- if (!allowgeolocation)
- cmd[i++] = "-g";
- if (!loadimages)
- cmd[i++] = "-i";
- if (kioskmode)
- cmd[i++] = "-k";
- if (!enableplugins)
- cmd[i++] = "-p";
- if (!enablescripts)
- cmd[i++] = "-s";
- if (showxid)
- cmd[i++] = "-x";
- if (enablediskcache)
- cmd[i++] = "-D";
- cmd[i++] = "-c";
- cmd[i++] = cookiefile;
- cmd[i++] = "--";
- uri = arg->v ? (char *)arg->v : c->linkhover;
- if (uri)
- cmd[i++] = uri;
- cmd[i++] = NULL;
- spawn(NULL, &a);