Summary Files Commits Branches @commit @diff @stats
path: root / badwolf.c
blob: 9e82a9465b92a016b3bb2c75875d904e64a0318c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
// BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser
// Copyright © 2019 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
// SPDX-License-Identifier: BSD-3-Clause

#include <gtk/gtk.h>
#include <webkit2/webkit2.h>

struct Client
{
	GtkWidget *main_window;
	GtkWidget *box;
	GtkWidget *location;
	WebKitWebView *webView;
};

static gboolean WebViewCb_close(WebKitWebView *_webView, GtkWidget *window)
{
	gtk_widget_destroy(window);
	return TRUE;
}

static gboolean WebViewCb_web_process_terminated(WebKitWebView *webView,
                                                 WebKitWebProcessTerminationReason reason,
                                                 gpointer user_data)
{
	char *str_reason;

	switch(reason)
	{
	case WEBKIT_WEB_PROCESS_CRASHED:
		str_reason = "the web process crashed.";
		break;
	case WEBKIT_WEB_PROCESS_EXCEEDED_MEMORY_LIMIT:
		str_reason = "the web process exceeded the memory limit.";
		break;
	default:
		str_reason = "the web process terminated for an unknown reason.";
	}

	fprintf(stderr, "BadWolf [signal: web-process-terminated]: %s", str_reason);
	return TRUE;
}

static gboolean WebViewCb_notify__uri(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data)
{
	const gchar *location_uri;
	struct Client *browser = (struct Client *)user_data;

	location_uri = webkit_web_view_get_uri(browser->webView);

	gtk_entry_set_text(GTK_ENTRY(browser->location), location_uri);

	return TRUE;
}

static gboolean
WebViewCb_notify__title(WebKitWebView *webView, GParamSpec *pspec, gpointer user_data)
{
	const gchar *title;
	struct Client *browser = (struct Client *)user_data;

	title = webkit_web_view_get_title(browser->webView);

	if(title == NULL) title = webkit_web_view_get_uri(browser->webView);

	if(title == NULL) title = "BadWolf";

	gtk_window_set_title(GTK_WINDOW(browser->main_window), title);

	return TRUE;
}

int main(int argc, char *argv[])
{
	struct Client *browser = calloc(1, sizeof(struct Client));
	char *target_url       = "about:blank";

	if(argv[1]) target_url = argv[1];

	gtk_init(0, 0);

	browser->main_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	browser->location    = gtk_entry_new();
	browser->box         = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
	browser->webView     = WEBKIT_WEB_VIEW(webkit_web_view_new());

	gtk_container_add(GTK_CONTAINER(browser->main_window), browser->box);
	gtk_box_pack_start(GTK_BOX(browser->box), GTK_WIDGET(browser->location), FALSE, FALSE, 0);
	gtk_box_pack_end(GTK_BOX(browser->box), GTK_WIDGET(browser->webView), TRUE, TRUE, 0);

	gtk_entry_set_text(GTK_ENTRY(browser->location), target_url);

	g_signal_connect(browser->main_window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
	g_signal_connect(browser->webView, "close", G_CALLBACK(WebViewCb_close), browser->main_window);
	g_signal_connect(browser->webView,
	                 "web-process-terminated",
	                 G_CALLBACK(WebViewCb_web_process_terminated),
	                 NULL);
	g_signal_connect(browser->webView, "notify::uri", G_CALLBACK(WebViewCb_notify__uri), browser);
	g_signal_connect(browser->webView, "notify::title", G_CALLBACK(WebViewCb_notify__title), browser);

	WebKitSettings *settings = webkit_web_view_get_settings(browser->webView);

	webkit_settings_set_javascript_can_access_clipboard(settings, FALSE);
	webkit_settings_set_enable_developer_extras(settings, TRUE);
	webkit_settings_set_default_charset(settings, "utf-8");

	webkit_web_view_set_settings(browser->webView, settings);

	webkit_web_view_load_uri(browser->webView, target_url);

	gtk_widget_grab_focus(GTK_WIDGET(browser->webView));
	gtk_widget_show_all(browser->main_window);
	gtk_main();
	return 0;
}