-client_new(const gchar *uri)
-{
- struct Client *c;
- gchar *f;
-
- if (uri != NULL && cooperative_instances && !cooperative_alone)
- {
- write(cooperative_pipe_fp, uri, strlen(uri));
- write(cooperative_pipe_fp, "\n", 1);
- return NULL;
- }
-
- c = malloc(sizeof(struct Client));
- if (!c)
- {
- fprintf(stderr, __NAME__": fatal: malloc failed\n");
- exit(EXIT_FAILURE);
- }
-
- c->win = NULL;
- if (embed != 0)
- {
- c->win = gtk_plug_new(embed);
- if (!gtk_plug_get_embedded(GTK_PLUG(c->win)))
- {
- fprintf(stderr, __NAME__": Can't plug-in to XID %ld.\n", embed);
- gtk_widget_destroy(c->win);
- c->win = NULL;
- embed = 0;
- }
- }
-
- if (c->win == NULL)
- {
- c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_wmclass(GTK_WINDOW(c->win), __NAME__, __NAME_CAPITALIZED__);
- }
-
- /* When using Gtk2, it only shows a white area when run in suckless'
- * tabbed. It appears we need to set a default window size for this
- * to work. This is not needed when using Gtk3. */
- gtk_window_set_default_size(GTK_WINDOW(c->win), 1024, 768);
-
- g_signal_connect(G_OBJECT(c->win), "destroy", G_CALLBACK(client_destroy), c);
- gtk_window_set_title(GTK_WINDOW(c->win), __NAME__);
-
- c->web_view = webkit_web_view_new();
-
- /* XXX I really do want to enable this option. However, I get
- * reproducible crashes with it enabled. I've seen bug reports from
- * 2010 about this... WebKit crashes in libpixman, so maybe it's not
- * a WebKit issue.
- * Yeah, well. I'll turn it off for now. */
- /*webkit_web_view_set_full_content_zoom(WEBKIT_WEB_VIEW(c->web_view), TRUE);*/
-
- webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), global_zoom);
- g_signal_connect(G_OBJECT(c->web_view), "notify::title",
- G_CALLBACK(changed_title), c);
- g_signal_connect(G_OBJECT(c->web_view), "notify::uri",
- G_CALLBACK(changed_uri), c);
- g_signal_connect(G_OBJECT(c->web_view), "notify::progress",
- G_CALLBACK(changed_load_progress), c);
- g_signal_connect(G_OBJECT(c->web_view), "create-web-view",
- G_CALLBACK(client_new_request), NULL);
- g_signal_connect(G_OBJECT(c->web_view), "close-web-view",
- G_CALLBACK(client_destroy_request), c);
- g_signal_connect(G_OBJECT(c->web_view),
- "mime-type-policy-decision-requested",
- G_CALLBACK(download_request), NULL);
- g_signal_connect(G_OBJECT(c->web_view), "download-requested",
- G_CALLBACK(download_handle), c);
- g_signal_connect(G_OBJECT(c->web_view), "key-press-event",
- G_CALLBACK(key_web_view), c);
- g_signal_connect(G_OBJECT(c->web_view), "button-press-event",
- G_CALLBACK(key_web_view), c);
- g_signal_connect(G_OBJECT(c->web_view), "scroll-event",
- G_CALLBACK(key_web_view), c);
- g_signal_connect(G_OBJECT(c->web_view), "hovering-over-link",
- G_CALLBACK(hover_web_view), c);
- g_signal_connect(G_OBJECT(c->web_view), "resource-request-starting",
- G_CALLBACK(adblock), NULL);
-
- if (!language_is_set)
- {
- g_object_set(webkit_get_default_session(), "accept-language",
- accepted_language, NULL);
- language_is_set = TRUE;
- }
-
- g_object_set(G_OBJECT(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(c->web_view))),
- "user-agent", user_agent, NULL);
-
- c->scroll = gtk_scrolled_window_new(NULL, NULL);
-
- gtk_container_add(GTK_CONTAINER(c->scroll), c->web_view);
-
- c->location = gtk_entry_new();
- g_signal_connect(G_OBJECT(c->location), "key-press-event",
- G_CALLBACK(key_location), c);
-
- c->progress = gtk_progress_bar_new();
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(c->progress), 0);
-
- c->status = gtk_progress_bar_new();
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(c->status), 0);
- gtk_widget_set_size_request(c->status, 20, -1);
-
- c->top_box = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(c->top_box), c->status, FALSE, FALSE, 2);
- gtk_box_pack_start(GTK_BOX(c->top_box), c->location, TRUE, TRUE, 0);
- gtk_box_pack_end(GTK_BOX(c->top_box), c->progress, FALSE, TRUE, 2);
-
- c->vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(c->vbox), c->top_box, FALSE, FALSE, 2);
- gtk_container_add(GTK_CONTAINER(c->vbox), c->scroll);
-
- gtk_container_add(GTK_CONTAINER(c->win), c->vbox);
-
- gtk_widget_grab_focus(c->web_view);
- gtk_widget_show_all(c->win);
-
- if (uri != NULL)
- {
- f = ensure_uri_scheme(uri);
- if (show_all_requests)
- fprintf(stderr, "====> %s\n", uri);
- webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), f);
- g_free(f);
- }
-
- clients++;
-
- return WEBKIT_WEB_VIEW(c->web_view);
+client_new(const gchar *uri, WebKitWebView *related_wv, gboolean show,
+ gboolean focus_tab)
+{
+ struct Client *c;
+ WebKitWebContext *wc;
+ gchar *f;
+ GtkWidget *evbox, *tabbox;
+
+ if (uri != NULL && cooperative_instances && !cooperative_alone)
+ {
+ f = ensure_uri_scheme(uri);
+ write(cooperative_pipe_fp, f, strlen(f));
+ write(cooperative_pipe_fp, "\n", 1);
+ g_free(f);
+ return NULL;
+ }
+
+ c = calloc(1, sizeof(struct Client));
+ if (!c)
+ {
+ fprintf(stderr, __NAME__": fatal: calloc failed\n");
+ exit(EXIT_FAILURE);
+ }
+
+ c->focus_new_tab = focus_tab;
+
+ if (related_wv == NULL)
+ c->web_view = webkit_web_view_new();
+ else
+ c->web_view = webkit_web_view_new_with_related_view(related_wv);
+ wc = webkit_web_view_get_context(WEBKIT_WEB_VIEW(c->web_view));
+
+ webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), global_zoom);
+ g_signal_connect(G_OBJECT(c->web_view), "notify::favicon",
+ G_CALLBACK(changed_favicon), c);
+ g_signal_connect(G_OBJECT(c->web_view), "notify::title",
+ G_CALLBACK(changed_title), c);
+ g_signal_connect(G_OBJECT(c->web_view), "notify::uri",
+ G_CALLBACK(changed_uri), c);
+ g_signal_connect(G_OBJECT(c->web_view), "notify::estimated-load-progress",
+ G_CALLBACK(changed_load_progress), c);
+ g_signal_connect(G_OBJECT(c->web_view), "create",
+ G_CALLBACK(client_new_request), NULL);
+ g_signal_connect(G_OBJECT(c->web_view), "context-menu",
+ G_CALLBACK(menu_web_view), c);
+ g_signal_connect(G_OBJECT(c->web_view), "close",
+ G_CALLBACK(client_destroy), c);
+ g_signal_connect(G_OBJECT(c->web_view), "decide-policy",
+ G_CALLBACK(decide_policy), NULL);
+ g_signal_connect(G_OBJECT(c->web_view), "key-press-event",
+ G_CALLBACK(key_web_view), c);
+ g_signal_connect(G_OBJECT(c->web_view), "button-release-event",
+ G_CALLBACK(key_web_view), c);
+ g_signal_connect(G_OBJECT(c->web_view), "scroll-event",
+ G_CALLBACK(key_web_view), c);
+ g_signal_connect(G_OBJECT(c->web_view), "mouse-target-changed",
+ G_CALLBACK(hover_web_view), c);
+ g_signal_connect(G_OBJECT(c->web_view), "web-process-crashed",
+ G_CALLBACK(crashed_web_view), c);
+
+ if (!initial_wc_setup_done)
+ {
+ if (accepted_language[0] != NULL)
+ webkit_web_context_set_preferred_languages(wc, accepted_language);
+
+ g_signal_connect(G_OBJECT(wc), "download-started",
+ G_CALLBACK(download_handle_start), NULL);
+
+ trust_user_certs(wc);
+
+ webkit_web_context_set_favicon_database_directory(wc, NULL);
+
+ initial_wc_setup_done = TRUE;
+ }
+
+ if (user_agent != NULL)
+ g_object_set(G_OBJECT(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(c->web_view))),
+ "user-agent", user_agent, NULL);
+
+ if (enable_console_to_stdout)
+ webkit_settings_set_enable_write_console_messages_to_stdout(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(c->web_view)), TRUE);
+
+ webkit_settings_set_enable_developer_extras(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(c->web_view)), TRUE);
+
+ c->location = gtk_entry_new();
+ g_signal_connect(G_OBJECT(c->location), "key-press-event",
+ G_CALLBACK(key_location), c);
+ g_signal_connect(G_OBJECT(c->location), "icon-release",
+ G_CALLBACK(icon_location), c);
+ /* XXX This is a workaround. Setting this to NULL (which is done in
+ * grab_feeds_finished() if no feed has been detected) adds a little
+ * padding left of the text. Not sure why. The point of this call
+ * right here is to have that padding right from the start. This
+ * avoids a graphical artifact. */
+ gtk_entry_set_icon_from_icon_name(GTK_ENTRY(c->location),
+ GTK_ENTRY_ICON_PRIMARY,
+ NULL);
+
+ c->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ gtk_box_pack_start(GTK_BOX(c->vbox), c->location, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(c->vbox), c->web_view, TRUE, TRUE, 0);
+
+ c->tabicon = gtk_image_new_from_icon_name("text-html", GTK_ICON_SIZE_SMALL_TOOLBAR);
+
+ c->tablabel = gtk_label_new(__NAME__);
+ gtk_label_set_ellipsize(GTK_LABEL(c->tablabel), PANGO_ELLIPSIZE_END);
+ gtk_label_set_width_chars(GTK_LABEL(c->tablabel), tab_width_chars);
+
+ /* XXX I don't own a HiDPI screen, so I don't know if scale_factor
+ * does the right thing. */
+ tabbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,
+ 5 * gtk_widget_get_scale_factor(mw.win));
+ gtk_box_pack_start(GTK_BOX(tabbox), c->tabicon, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(tabbox), c->tablabel, TRUE, TRUE, 0);
+
+ evbox = gtk_event_box_new();
+ gtk_container_add(GTK_CONTAINER(evbox), tabbox);
+ g_signal_connect(G_OBJECT(evbox), "button-release-event",
+ G_CALLBACK(button_tablabel), c);
+
+ /* This only shows the event box and the label inside, nothing else.
+ * Needed because the evbox/label is "internal" to the notebook and
+ * not part of the normal "widget tree" (IIUC). */
+ gtk_widget_show_all(evbox);
+
+ gtk_notebook_insert_page(GTK_NOTEBOOK(mw.notebook), c->vbox, evbox,
+ gtk_notebook_get_current_page(GTK_NOTEBOOK(mw.notebook)) + 1);
+ gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(mw.notebook), c->vbox, TRUE);
+
+ if (show)
+ show_web_view(NULL, c);
+ else
+ g_signal_connect(G_OBJECT(c->web_view), "ready-to-show",
+ G_CALLBACK(show_web_view), c);
+
+ if (uri != NULL)
+ {
+ f = ensure_uri_scheme(uri);
+ webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), f);
+ g_free(f);
+ }
+
+ clients++;
+
+ return WEBKIT_WEB_VIEW(c->web_view);