tazweb view src/main.c @ rev 81

Make new webview definitly work! We can now open new window from menu. By the way, removed loader (buggy with new webviw) and bloated... remove colors (use gtk theme)
author Christophe Lincoln <pankso@slitaz.org>
date Mon Apr 25 01:17:19 2011 +0200 (2011-04-25)
parents 32ceefc08f61
children 5b1045c7842b
line source
1 /*
2 * TazWeb is a radically simple web browser providing a single window
3 * with a single toolbar with buttons, an URL entry and search as well
4 * as a contextual menu, but no menu bar or tabs. Commented line code
5 * starts with // and comments are between * *
6 *
7 * Copyright(C) 2011 SliTaz GNU/Linux - BSD License
8 * See AUTHORS and LICENSE for detailed information
9 *
10 */
12 #include <gtk/gtk.h>
13 #include <webkit/webkit.h>
15 #define CONFIG g_strdup_printf("%s/.config/tazweb", g_get_home_dir())
16 #define START "file:///usr/share/webhome/index.html"
18 /* Needs AppleWebKit/531.2+ to handle all sites ? */
19 static gchar *useragent = "TazWeb (X11; SliTaz GNU/Linux; U; en_US)";
21 static GtkWidget* create_window(WebKitWebView** newwebview);
22 static GtkWidget *mainwindow, *vbox, *browser, *toolbar;
23 static GtkWidget *urientry, *search;
24 static WebKitWebView* webview;
25 static WebKitWebFrame* frame;
26 static gint count = 0;
27 const gchar* uri;
29 /* Create an icon */
30 static GdkPixbuf*
31 create_pixbuf(const gchar* image)
32 {
33 GdkPixbuf *pixbuf;
34 pixbuf = gdk_pixbuf_new_from_file(image, NULL);
35 return pixbuf;
36 }
38 /* Can be: http://hg.slitaz.org or hg.slitaz.org */
39 static void
40 check_requested_uri()
41 {
42 uri = g_strrstr(uri, "://") ? g_strdup(uri)
43 : g_strdup_printf("http://%s", uri);
44 }
46 /* Update title */
47 static void
48 update_title(GtkWindow* window, WebKitWebView* webview)
49 {
50 GString *string;
51 gdouble progress;
52 gchar *title;
54 string = g_string_new(webkit_web_view_get_title(webview));
55 progress = webkit_web_view_get_progress(webview) * 100;
56 if (progress < 100)
57 g_string_append_printf(string, " [ %f%% ] ", progress);
59 title = g_string_free(string, FALSE);
60 gtk_window_set_title(window, title);
61 g_free(title);
62 }
64 /* Get the page title */
65 static void
66 notify_title_cb(WebKitWebView* webview, GParamSpec* pspec, GtkWidget* window)
67 {
68 update_title(GTK_WINDOW(window), webview);
69 }
71 /* Request progress in window title */
72 static void
73 notify_progress_cb(WebKitWebView* webview, GParamSpec* pspec, GtkWidget* window)
74 {
75 update_title(GTK_WINDOW(window), webview);
76 }
78 /* Notify loader and url entry */
79 static void
80 notify_load_status_cb(WebKitWebView* webview, GParamSpec* pspec, gpointer data)
81 {
82 if (webkit_web_view_get_load_status(webview) == WEBKIT_LOAD_COMMITTED) {
83 frame = webkit_web_view_get_main_frame(webview);
84 uri = webkit_web_frame_get_uri(frame);
85 if (uri)
86 gtk_entry_set_text(GTK_ENTRY(urientry), uri);
87 }
88 }
90 /* Destroy the window */
91 static void
92 destroy_cb(GtkWidget* widget, GtkWindow* window)
93 {
94 if (g_atomic_int_dec_and_test(&count))
95 gtk_main_quit();
96 }
98 /* Show page source */
99 static void
100 view_source_cb()
101 {
102 gboolean source;
104 frame = webkit_web_view_get_main_frame(webview);
105 uri = webkit_web_frame_get_uri(frame);
106 source = webkit_web_view_get_view_source_mode(webview);
108 webkit_web_view_set_view_source_mode(webview, !source);
109 webkit_web_view_reload(webview);
110 }
112 /* URL entry callback function */
113 static void
114 uri_entry_cb(GtkWidget* entry, gpointer data)
115 {
116 uri = gtk_entry_get_text(GTK_ENTRY(entry));
117 g_assert(uri);
118 check_requested_uri();
119 webkit_web_view_load_uri(webview, uri);
120 }
122 /* Search entry callback function */
123 static void
124 search_entry_cb(GtkWidget* entry, gpointer data)
125 {
126 uri = g_strdup_printf("http://www.google.com/search?q=%s",
127 gtk_entry_get_text(GTK_ENTRY(entry)));
128 g_assert(uri);
129 webkit_web_view_load_uri(webview, uri);
130 }
132 /* Home button callback function */
133 static void
134 go_home_cb(GtkWidget* widget, gpointer data)
135 {
136 uri = g_strdup_printf("file://%s/home.html", CONFIG);
137 g_assert(uri);
138 webkit_web_view_load_uri(webview, uri);
139 }
141 /* Navigation button function */
142 static void
143 go_back_cb(GtkWidget* widget, gpointer data)
144 {
145 webkit_web_view_go_back(webview);
146 }
148 static void
149 go_forward_cb(GtkWidget* widget, gpointer data)
150 {
151 webkit_web_view_go_forward(webview);
152 }
154 /* Fullscreen and unfullscreen callback function */
155 static void
156 fullscreen_cb(GtkWindow* window, gpointer data)
157 {
158 GdkWindowState state;
159 state = gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(mainwindow)));
161 if(state & GDK_WINDOW_STATE_FULLSCREEN)
162 gtk_window_unfullscreen(GTK_WINDOW(mainwindow));
163 else
164 gtk_window_fullscreen(GTK_WINDOW(mainwindow));
165 }
167 /* TazWeb doc callback function */
168 static void
169 tazweb_doc_cb(GtkWidget* widget, gpointer data)
170 {
171 uri = ("file:///usr/share/doc/tazweb/tazweb.html");
172 g_assert(uri);
173 webkit_web_view_load_uri(webview, uri);
174 }
176 /* Download function */
177 static gboolean
178 download_requested_cb(WebKitWebView *webview, WebKitDownload *download,
179 gpointer user_data)
180 {
181 uri = webkit_download_get_uri(download);
182 const gchar* buffer;
183 asprintf(&buffer,
184 "xterm -T 'Download' -geom 72x10+0-24 -e \
185 'cd $HOME/Downloads && wget -c %s; sleep 2' &", uri);
186 system(buffer);
187 }
189 /* Zoom out and in callback function */
190 static void
191 zoom_out_cb(GtkWidget *mainwindow)
192 {
193 webkit_web_view_zoom_out(webview);
194 }
196 static void
197 zoom_in_cb(GtkWidget *mainwindow)
198 {
199 webkit_web_view_zoom_in(webview);
200 }
202 /* New webview clallbacks */
203 static WebKitWebView*
204 create_web_view_cb(WebKitWebView* webview, WebKitWebFrame* web_frame,
205 GtkWidget* window)
206 {
207 WebKitWebView *newview;
208 create_window(&newview);
209 return newview;
210 }
212 static gboolean
213 webview_ready_cb(WebKitWebView* webview, GtkWidget* window)
214 {
215 gtk_widget_grab_focus(GTK_WIDGET(webview));
216 gtk_widget_show_all(window);
217 return FALSE;
218 }
220 static gboolean
221 close_webview_cb(WebKitWebView* webview, GtkWidget* window)
222 {
223 gtk_widget_destroy(window);
224 return TRUE;
225 }
227 /* Add items to WebKit contextual menu */
228 static void
229 populate_menu_cb(WebKitWebView *webview, GtkMenu *menu, gpointer data)
230 {
231 GtkWidget* item;
233 /* Separator */
234 item = gtk_separator_menu_item_new();
235 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
237 /* Zoom in */
238 item = gtk_image_menu_item_new_with_label("Zoom in");
239 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
240 gtk_image_new_from_stock(GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_MENU));
241 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
242 g_signal_connect(item, "activate", G_CALLBACK(zoom_in_cb), NULL);
244 /* Zoom out */
245 item = gtk_image_menu_item_new_with_label("Zoom out");
246 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
247 gtk_image_new_from_stock(GTK_STOCK_ZOOM_OUT, GTK_ICON_SIZE_MENU));
248 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
249 g_signal_connect(item, "activate", G_CALLBACK(zoom_out_cb), NULL);
251 /* Separator */
252 item = gtk_separator_menu_item_new();
253 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
255 /* TazWeb documentation */
256 item = gtk_image_menu_item_new_with_label("TazWeb manual");
257 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
258 gtk_image_new_from_stock(GTK_STOCK_INFO, GTK_ICON_SIZE_MENU));
259 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
260 g_signal_connect(item, "activate", G_CALLBACK(tazweb_doc_cb), NULL);
262 /* View source mode */
263 item = gtk_image_menu_item_new_with_label("View source mode");
264 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
265 gtk_image_new_from_stock(GTK_STOCK_PROPERTIES, GTK_ICON_SIZE_MENU));
266 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
267 g_signal_connect(item, "activate", G_CALLBACK(view_source_cb), NULL);
269 gtk_widget_show_all(GTK_WIDGET(menu));
270 }
272 /* Scrolled window for the webview */
273 static GtkWidget*
274 create_browser(GtkWidget* window)
275 {
276 WebKitWebSettings *settings;
278 browser = gtk_scrolled_window_new(NULL, NULL);
279 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(browser),
280 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
282 gtk_container_add(GTK_CONTAINER(browser), GTK_WIDGET(webview));
284 /* User agent */
285 settings = webkit_web_view_get_settings (webview);
286 g_object_set (G_OBJECT (settings), "user-agent", useragent, NULL);
288 /* Connect WebKit events */
289 g_signal_connect(webview, "notify::title",
290 G_CALLBACK(notify_title_cb), window);
291 g_signal_connect(webview, "notify::progress",
292 G_CALLBACK(notify_progress_cb), window);
293 g_signal_connect(webview, "notify::load-status",
294 G_CALLBACK(notify_load_status_cb), window);
295 g_signal_connect(webview, "download-requested",
296 G_CALLBACK(download_requested_cb), NULL);
297 g_signal_connect(webview, "create-web-view",
298 G_CALLBACK(create_web_view_cb), window);
299 g_signal_connect(webview, "web-view-ready",
300 G_CALLBACK(webview_ready_cb), window);
301 g_signal_connect(webview, "close-web-view",
302 G_CALLBACK(close_webview_cb), window);
304 /* Connect WebKit contextual menu items */
305 g_object_connect(G_OBJECT(webview), "signal::populate-popup",
306 G_CALLBACK(populate_menu_cb), webview, NULL);
308 return browser;
309 }
311 static GtkWidget*
312 create_toolbar(GtkWidget* urientry, GtkWidget* search, WebKitWebView* webview)
313 {
314 GtkToolItem* item;
316 toolbar = gtk_toolbar_new();
317 gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar),
318 GTK_ORIENTATION_HORIZONTAL);
319 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar),
320 GTK_TOOLBAR_BOTH_HORIZ);
322 /* The back button */
323 item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
324 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_back_cb), NULL);
325 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
327 /* The forward button */
328 item = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
329 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(go_forward_cb), NULL);
330 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
332 /* Home button */
333 item = gtk_tool_button_new_from_stock(GTK_STOCK_HOME);
334 g_signal_connect(G_OBJECT(item), "clicked",
335 G_CALLBACK(go_home_cb), NULL);
336 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
338 /* URL entry */
339 item = gtk_tool_item_new();
340 gtk_tool_item_set_expand(item, TRUE);
341 gtk_widget_set_size_request(urientry, 0, 20);
342 gtk_container_add(GTK_CONTAINER(item), urientry);
343 g_signal_connect(G_OBJECT(urientry), "activate",
344 G_CALLBACK(uri_entry_cb), NULL);
345 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
347 /* Separator */
348 item = gtk_separator_tool_item_new();
349 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
351 /* Search entry */
352 item = gtk_tool_item_new();
353 gtk_widget_set_size_request(search, 150, 20);
354 gtk_container_add(GTK_CONTAINER(item), search);
355 g_signal_connect(G_OBJECT(search), "activate",
356 G_CALLBACK(search_entry_cb), NULL);
357 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
359 /* The Fullscreen button */
360 item = gtk_tool_button_new_from_stock(GTK_STOCK_FULLSCREEN);
361 g_signal_connect(G_OBJECT(item), "clicked",
362 G_CALLBACK(fullscreen_cb), NULL);
363 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
365 return toolbar;
366 }
368 /* Main window */
369 static GtkWidget*
370 create_window(WebKitWebView** newwebview)
371 {
372 GtkWidget* window;
373 g_atomic_int_inc(&count);
375 /* Default TazWeb window */
376 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
377 gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
378 gtk_window_set_icon(GTK_WINDOW(window),
379 create_pixbuf("/usr/share/pixmaps/tazweb.png"));
380 gtk_widget_set_name(window, "TazWeb");
381 g_signal_connect(window, "destroy", G_CALLBACK(destroy_cb), NULL);
383 /* Webview and widgets */
384 webview = WEBKIT_WEB_VIEW(webkit_web_view_new());
385 urientry = gtk_entry_new();
386 search = gtk_entry_new();
387 vbox = gtk_vbox_new(FALSE, 0);
389 /* Pack box and container */
390 gtk_box_pack_start(GTK_BOX(vbox),
391 create_browser(window), TRUE, TRUE, 0);
392 gtk_box_pack_start(GTK_BOX(vbox),
393 create_toolbar(urientry, search, webview), FALSE, FALSE, 0);
394 gtk_container_add(GTK_CONTAINER(window), vbox);
396 if (newwebview)
397 *newwebview = webview;
399 return window;
400 }
402 int
403 main(int argc, char* argv[])
404 {
405 gtk_init(NULL, NULL);
406 if (!g_thread_supported())
407 g_thread_init(NULL);
409 /* Get a default home.html if missing */
410 if (! g_file_test(CONFIG, G_FILE_TEST_EXISTS))
411 system("cp -r /usr/share/tazweb $HOME/.config/tazweb");
413 /* Load the start page file or the url in argument */
414 uri =(char*)(argc > 1 ? argv[1] : START);
415 if (argv[1])
416 check_requested_uri();
418 mainwindow = create_window(&webview);
420 gtk_widget_show_all(mainwindow);
421 webkit_web_view_load_uri(webview, uri);
422 gtk_widget_grab_focus(GTK_WIDGET(webview));
423 gtk_main();
425 return 0;
426 }