Summary Files Commits Branches @commit @diff @stats
path: root / badwolf.c
blob: a0729fba41df48e8a4fdb39c3a676f4a45b0e88f (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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// BadWolf: Minimalist and privacy-oriented WebKitGTK+ browser
// Copyright © 2019 Haelwenn (lanodan) Monnier <contact@hacktivis.me>
// SPDX-License-Identifier: BSD-3-Clause

#include <stdio.h> /* fprintf() */
#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;
}

static gboolean locationCb_activate(GtkEntry *location, gpointer user_data)
{
	const char *target_url;
	struct Client *browser = (struct Client *)user_data;

	target_url = gtk_entry_get_text(location);

	if(target_url != NULL) webkit_web_view_load_uri(browser->webView, target_url);

	return TRUE;
}

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

	gtk_init(&argc, &argv);

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

	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->location, "activate", G_CALLBACK(locationCb_activate), browser);
	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;
}