blob: 86b04461d8d2bdc5fe2834d200590f808c458b49 [file] [log] [blame]
/*
* Copyright (C) 2006, 2007 Apple Inc.
* Copyright (C) 2007 Alp Toker <alp@atoker.com>
* Copyright (C) 2011 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "BrowserWindow.h"
#include "BrowserDownloadsBar.h"
#include "BrowserSettingsDialog.h"
#include <string.h>
enum {
PROP_0,
PROP_VIEW
};
struct _BrowserWindow {
GtkWindow parent;
GtkWidget *mainBox;
GtkWidget *toolbar;
GtkWidget *uriEntry;
GtkWidget *backItem;
GtkWidget *forwardItem;
GtkWidget *zoomInItem;
GtkWidget *zoomOutItem;
GtkWidget *statusLabel;
GtkWidget *settingsDialog;
WebKitWebView *webView;
GtkWidget *downloadsBar;
GdkPixbuf *favicon;
};
struct _BrowserWindowClass {
GtkWindowClass parent;
};
static const char *defaultWindowTitle = "WebKitGTK+ MiniBrowser";
static const gdouble minimumZoomLevel = 0.5;
static const gdouble maximumZoomLevel = 3;
static const gdouble zoomStep = 1.2;
static gint windowCount = 0;
G_DEFINE_TYPE(BrowserWindow, browser_window, GTK_TYPE_WINDOW)
static void browserWindowSetStatusText(BrowserWindow *window, const char *text)
{
#if GTK_CHECK_VERSION(3, 2, 0)
gtk_label_set_text(GTK_LABEL(window->statusLabel), text);
gtk_widget_set_visible(window->statusLabel, !!text);
#endif
}
static void resetStatusText(GtkWidget *widget, BrowserWindow *window)
{
browserWindowSetStatusText(window, NULL);
}
static void activateUriEntryCallback(BrowserWindow *window)
{
browser_window_load_uri(window, gtk_entry_get_text(GTK_ENTRY(window->uriEntry)));
}
static void reloadCallback(BrowserWindow *window)
{
webkit_web_view_reload(window->webView);
}
static void goBackCallback(BrowserWindow *window)
{
webkit_web_view_go_back(window->webView);
}
static void goForwardCallback(BrowserWindow *window)
{
webkit_web_view_go_forward(window->webView);
}
static void settingsCallback(BrowserWindow *window)
{
if (window->settingsDialog) {
gtk_window_present(GTK_WINDOW(window->settingsDialog));
return;
}
window->settingsDialog = browser_settings_dialog_new(webkit_web_view_get_settings(window->webView));
gtk_window_set_transient_for(GTK_WINDOW(window->settingsDialog), GTK_WINDOW(window));
g_object_add_weak_pointer(G_OBJECT(window->settingsDialog), (gpointer *)&window->settingsDialog);
gtk_widget_show(window->settingsDialog);
}
static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
{
gtk_entry_set_text(GTK_ENTRY(window->uriEntry), webkit_web_view_get_uri(webView));
}
static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
{
const char *title = webkit_web_view_get_title(webView);
gtk_window_set_title(GTK_WINDOW(window), title ? title : defaultWindowTitle);
}
static gboolean resetEntryProgress(GtkEntry *entry)
{
gtk_entry_set_progress_fraction(entry, 0);
return FALSE;
}
static void webViewLoadProgressChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
{
gdouble progress = webkit_web_view_get_estimated_load_progress(webView);
gtk_entry_set_progress_fraction(GTK_ENTRY(window->uriEntry), progress);
if (progress == 1.0)
g_timeout_add(500, (GSourceFunc)resetEntryProgress, window->uriEntry);
}
static void downloadStarted(WebKitWebContext *webContext, WebKitDownload *download, BrowserWindow *window)
{
if (!window->downloadsBar) {
window->downloadsBar = browser_downloads_bar_new();
gtk_box_pack_start(GTK_BOX(window->mainBox), window->downloadsBar, FALSE, FALSE, 0);
gtk_box_reorder_child(GTK_BOX(window->mainBox), window->downloadsBar, 0);
g_object_add_weak_pointer(G_OBJECT(window->downloadsBar), (gpointer *)&(window->downloadsBar));
gtk_widget_show(window->downloadsBar);
}
browser_downloads_bar_add_download(BROWSER_DOWNLOADS_BAR(window->downloadsBar), download);
}
static void browserWindowHistoryItemSelected(BrowserWindow *window, GtkMenuItem *item)
{
GtkAction *action = gtk_activatable_get_related_action(GTK_ACTIVATABLE(item));
browserWindowSetStatusText(window, action ? gtk_action_get_name(action) : NULL);
}
static void browserWindowHistoryItemActivated(BrowserWindow *window, GtkAction *action)
{
WebKitBackForwardListItem *item = g_object_get_data(G_OBJECT(action), "back-forward-list-item");
if (!item)
return;
webkit_web_view_go_to_back_forward_list_item(window->webView, item);
}
static GtkWidget *browserWindowCreateBackForwardMenu(BrowserWindow *window, GList *list)
{
if (!list)
return NULL;
GtkWidget *menu = gtk_menu_new();
GList *listItem;
for (listItem = list; listItem; listItem = g_list_next(listItem)) {
WebKitBackForwardListItem *item = (WebKitBackForwardListItem *)listItem->data;
const char *uri = webkit_back_forward_list_item_get_uri(item);
const char *title = webkit_back_forward_list_item_get_title(item);
GtkAction *action = gtk_action_new(uri, title, NULL, NULL);
g_object_set_data_full(G_OBJECT(action), "back-forward-list-item", g_object_ref(item), g_object_unref);
g_signal_connect_swapped(action, "activate", G_CALLBACK(browserWindowHistoryItemActivated), window);
GtkWidget *menuItem = gtk_action_create_menu_item(action);
g_signal_connect_swapped(menuItem, "select", G_CALLBACK(browserWindowHistoryItemSelected), window);
g_object_unref(action);
gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuItem);
gtk_widget_show(menuItem);
}
g_signal_connect(menu, "hide", G_CALLBACK(resetStatusText), window);
return menu;
}
static void browserWindowUpdateNavigationActions(BrowserWindow *window, WebKitBackForwardList *backForwadlist)
{
gtk_widget_set_sensitive(window->backItem, webkit_web_view_can_go_back(window->webView));
gtk_widget_set_sensitive(window->forwardItem, webkit_web_view_can_go_forward(window->webView));
GList *list = webkit_back_forward_list_get_back_list_with_limit(backForwadlist, 10);
gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window->backItem),
browserWindowCreateBackForwardMenu(window, list));
g_list_free(list);
list = webkit_back_forward_list_get_forward_list_with_limit(backForwadlist, 10);
gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window->forwardItem),
browserWindowCreateBackForwardMenu(window, list));
g_list_free(list);
}
static void backForwadlistChanged(WebKitBackForwardList *backForwadlist, WebKitBackForwardListItem *itemAdded, GList *itemsRemoved, BrowserWindow *window)
{
browserWindowUpdateNavigationActions(window, backForwadlist);
}
static void geolocationRequestDialogCallback(GtkDialog *dialog, gint response, WebKitPermissionRequest *request)
{
switch (response) {
case GTK_RESPONSE_YES:
webkit_permission_request_allow(request);
break;
default:
webkit_permission_request_deny(request);
break;
}
gtk_widget_destroy(GTK_WIDGET(dialog));
g_object_unref(request);
}
static void webViewClose(WebKitWebView *webView, BrowserWindow *window)
{
gtk_widget_destroy(GTK_WIDGET(window));
}
static void webViewRunAsModal(WebKitWebView *webView, BrowserWindow *window)
{
gtk_window_set_modal(GTK_WINDOW(window), TRUE);
}
static void webViewReadyToShow(WebKitWebView *webView, BrowserWindow *window)
{
WebKitWindowProperties *windowProperties = webkit_web_view_get_window_properties(webView);
GdkRectangle geometry;
webkit_window_properties_get_geometry(windowProperties, &geometry);
if (geometry.x >= 0 && geometry.y >= 0)
gtk_window_move(GTK_WINDOW(window), geometry.x, geometry.y);
if (geometry.width > 0 && geometry.height > 0)
gtk_window_resize(GTK_WINDOW(window), geometry.width, geometry.height);
if (!webkit_window_properties_get_toolbar_visible(windowProperties))
gtk_widget_hide(window->toolbar);
else if (!webkit_window_properties_get_locationbar_visible(windowProperties))
gtk_widget_hide(window->uriEntry);
if (!webkit_window_properties_get_resizable(windowProperties))
gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
gtk_widget_show(GTK_WIDGET(window));
}
static GtkWidget *webViewCreate(WebKitWebView *webView, BrowserWindow *window)
{
WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(webkit_web_view_get_context(webView)));
webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
GtkWidget *newWindow = browser_window_new(newWebView, GTK_WINDOW(window));
g_signal_connect(newWebView, "ready-to-show", G_CALLBACK(webViewReadyToShow), newWindow);
g_signal_connect(newWebView, "run-as-modal", G_CALLBACK(webViewRunAsModal), newWindow);
g_signal_connect(newWebView, "close", G_CALLBACK(webViewClose), newWindow);
return GTK_WIDGET(newWebView);
}
static gboolean webViewLoadFailed(WebKitWebView *webView, WebKitLoadEvent loadEvent, const char *failingURI, GError *error, BrowserWindow *window)
{
gtk_entry_set_progress_fraction(GTK_ENTRY(window->uriEntry), 0.);
return FALSE;
}
static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserWindow *window)
{
if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
return FALSE;
WebKitNavigationPolicyDecision *navigationDecision = WEBKIT_NAVIGATION_POLICY_DECISION(decision);
if (webkit_navigation_policy_decision_get_navigation_type(navigationDecision) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
|| webkit_navigation_policy_decision_get_mouse_button(navigationDecision) != 2)
return FALSE;
WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(webkit_web_view_get_context(webView)));
webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
GtkWidget *newWindow = browser_window_new(newWebView, GTK_WINDOW(window));
webkit_web_view_load_request(newWebView, webkit_navigation_policy_decision_get_request(navigationDecision));
gtk_widget_show(newWindow);
webkit_policy_decision_ignore(decision);
return TRUE;
}
static gboolean webViewDecidePermissionRequest(WebKitWebView *webView, WebKitPermissionRequest *request, BrowserWindow *window)
{
if (!WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(request))
return FALSE;
GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
"Geolocation request");
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "Allow geolocation request?");
g_signal_connect(dialog, "response", G_CALLBACK(geolocationRequestDialogCallback), g_object_ref(request));
gtk_widget_show(dialog);
return TRUE;
}
static void webViewMouseTargetChanged(WebKitWebView *webView, WebKitHitTestResult *hitTestResult, guint mouseModifiers, BrowserWindow *window)
{
if (!webkit_hit_test_result_context_is_link(hitTestResult)) {
browserWindowSetStatusText(window, NULL);
return;
}
browserWindowSetStatusText(window, webkit_hit_test_result_get_link_uri(hitTestResult));
}
static gboolean browserWindowCanZoomIn(BrowserWindow *window)
{
gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) * zoomStep;
return zoomLevel < maximumZoomLevel;
}
static gboolean browserWindowCanZoomOut(BrowserWindow *window)
{
gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) / zoomStep;
return zoomLevel > minimumZoomLevel;
}
static void browserWindowUpdateZoomActions(BrowserWindow *window)
{
gtk_widget_set_sensitive(window->zoomInItem, browserWindowCanZoomIn(window));
gtk_widget_set_sensitive(window->zoomOutItem, browserWindowCanZoomOut(window));
}
static void webViewZoomLevelChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window)
{
browserWindowUpdateZoomActions(window);
}
static void updateUriEntryIcon(BrowserWindow *window)
{
GtkEntry *entry = GTK_ENTRY(window->uriEntry);
if (window->favicon)
gtk_entry_set_icon_from_pixbuf(entry, GTK_ENTRY_ICON_PRIMARY, window->favicon);
else
gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_NEW);
}
static void faviconChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window)
{
GdkPixbuf *favicon = NULL;
cairo_surface_t *surface = webkit_web_view_get_favicon(window->webView);
if (surface) {
int width = cairo_image_surface_get_width(surface);
int height = cairo_image_surface_get_height(surface);
favicon = gdk_pixbuf_get_from_surface(surface, 0, 0, width, height);
}
if (window->favicon)
g_object_unref(window->favicon);
window->favicon = favicon;
updateUriEntryIcon(window);
}
static void zoomInCallback(BrowserWindow *window)
{
gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) * zoomStep;
webkit_web_view_set_zoom_level(window->webView, zoomLevel);
}
static void zoomOutCallback(BrowserWindow *window)
{
gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) / zoomStep;
webkit_web_view_set_zoom_level(window->webView, zoomLevel);
}
static void browserWindowFinalize(GObject *gObject)
{
BrowserWindow *window = BROWSER_WINDOW(gObject);
if (window->favicon) {
g_object_unref(window->favicon);
window->favicon = NULL;
}
G_OBJECT_CLASS(browser_window_parent_class)->finalize(gObject);
if (g_atomic_int_dec_and_test(&windowCount))
gtk_main_quit();
}
static void browserWindowGetProperty(GObject *object, guint propId, GValue *value, GParamSpec *pspec)
{
BrowserWindow *window = BROWSER_WINDOW(object);
switch (propId) {
case PROP_VIEW:
g_value_set_object(value, browser_window_get_view(window));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
}
}
static void browserWindowSetProperty(GObject *object, guint propId, const GValue *value, GParamSpec *pspec)
{
BrowserWindow* window = BROWSER_WINDOW(object);
switch (propId) {
case PROP_VIEW:
window->webView = g_value_get_object(value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
}
}
static void browser_window_init(BrowserWindow *window)
{
g_atomic_int_inc(&windowCount);
gtk_window_set_title(GTK_WINDOW(window), defaultWindowTitle);
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
window->uriEntry = gtk_entry_new();
g_signal_connect_swapped(window->uriEntry, "activate", G_CALLBACK(activateUriEntryCallback), (gpointer)window);
gtk_entry_set_icon_activatable(GTK_ENTRY(window->uriEntry), GTK_ENTRY_ICON_PRIMARY, FALSE);
updateUriEntryIcon(window);
GtkWidget *toolbar = gtk_toolbar_new();
window->toolbar = toolbar;
gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH_HORIZ);
GtkToolItem *item = gtk_menu_tool_button_new_from_stock(GTK_STOCK_GO_BACK);
window->backItem = GTK_WIDGET(item);
gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), 0);
g_signal_connect_swapped(item, "clicked", G_CALLBACK(goBackCallback), (gpointer)window);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
item = gtk_menu_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD);
window->forwardItem = GTK_WIDGET(item);
gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(item), 0);
g_signal_connect_swapped(G_OBJECT(item), "clicked", G_CALLBACK(goForwardCallback), (gpointer)window);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
item = gtk_tool_button_new_from_stock(GTK_STOCK_PREFERENCES);
g_signal_connect_swapped(G_OBJECT(item), "clicked", G_CALLBACK(settingsCallback), window);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
item = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_OUT);
window->zoomOutItem = GTK_WIDGET(item);
g_signal_connect_swapped(item, "clicked", G_CALLBACK(zoomOutCallback), window);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
item = gtk_tool_button_new_from_stock(GTK_STOCK_ZOOM_IN);
window->zoomInItem = GTK_WIDGET(item);
g_signal_connect_swapped(item, "clicked", G_CALLBACK(zoomInCallback), window);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
item = gtk_tool_item_new();
gtk_tool_item_set_expand(item, TRUE);
gtk_container_add(GTK_CONTAINER(item), window->uriEntry);
gtk_widget_show(window->uriEntry);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
item = gtk_tool_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect_swapped(item, "clicked", G_CALLBACK(reloadCallback), window);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
gtk_widget_show(GTK_WIDGET(item));
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
window->mainBox = vbox;
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
gtk_widget_show(toolbar);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
}
static void browserWindowConstructed(GObject *gObject)
{
BrowserWindow *window = BROWSER_WINDOW(gObject);
browserWindowUpdateZoomActions(window);
g_signal_connect(window->webView, "notify::uri", G_CALLBACK(webViewURIChanged), window);
g_signal_connect(window->webView, "notify::estimated-load-progress", G_CALLBACK(webViewLoadProgressChanged), window);
g_signal_connect(window->webView, "notify::title", G_CALLBACK(webViewTitleChanged), window);
g_signal_connect(window->webView, "create", G_CALLBACK(webViewCreate), window);
g_signal_connect(window->webView, "load-failed", G_CALLBACK(webViewLoadFailed), window);
g_signal_connect(window->webView, "decide-policy", G_CALLBACK(webViewDecidePolicy), window);
g_signal_connect(window->webView, "permission-request", G_CALLBACK(webViewDecidePermissionRequest), window);
g_signal_connect(window->webView, "mouse-target-changed", G_CALLBACK(webViewMouseTargetChanged), window);
g_signal_connect(window->webView, "notify::zoom-level", G_CALLBACK(webViewZoomLevelChanged), window);
g_signal_connect(window->webView, "notify::favicon", G_CALLBACK(faviconChanged), window);
g_signal_connect(webkit_web_view_get_context(window->webView), "download-started", G_CALLBACK(downloadStarted), window);
WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(window->webView);
g_signal_connect(backForwadlist, "changed", G_CALLBACK(backForwadlistChanged), window);
#if GTK_CHECK_VERSION(3, 2, 0)
GtkWidget *overlay = gtk_overlay_new();
gtk_box_pack_start(GTK_BOX(window->mainBox), overlay, TRUE, TRUE, 0);
gtk_widget_show(overlay);
window->statusLabel = gtk_label_new(NULL);
gtk_widget_set_halign(window->statusLabel, GTK_ALIGN_START);
gtk_widget_set_valign(window->statusLabel, GTK_ALIGN_END);
gtk_widget_set_margin_left(window->statusLabel, 1);
gtk_widget_set_margin_right(window->statusLabel, 1);
gtk_widget_set_margin_top(window->statusLabel, 1);
gtk_widget_set_margin_bottom(window->statusLabel, 1);
gtk_overlay_add_overlay(GTK_OVERLAY(overlay), window->statusLabel);
gtk_container_add(GTK_CONTAINER(overlay), GTK_WIDGET(window->webView));
#else
gtk_box_pack_start(GTK_BOX(window->mainBox), GTK_WIDGET(window->webView), TRUE, TRUE, 0);
#endif
gtk_widget_show(GTK_WIDGET(window->webView));
}
static void browser_window_class_init(BrowserWindowClass *klass)
{
GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
gobjectClass->constructed = browserWindowConstructed;
gobjectClass->get_property = browserWindowGetProperty;
gobjectClass->set_property = browserWindowSetProperty;
gobjectClass->finalize = browserWindowFinalize;
g_object_class_install_property(gobjectClass,
PROP_VIEW,
g_param_spec_object("view",
"View",
"The web view of this window",
WEBKIT_TYPE_WEB_VIEW,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
// Public API.
GtkWidget *browser_window_new(WebKitWebView *view, GtkWindow *parent)
{
g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(view), 0);
return GTK_WIDGET(g_object_new(BROWSER_TYPE_WINDOW,
"transient-for", parent,
"type", GTK_WINDOW_TOPLEVEL,
"view", view, NULL));
}
WebKitWebView *browser_window_get_view(BrowserWindow *window)
{
g_return_val_if_fail(BROWSER_IS_WINDOW(window), 0);
return window->webView;
}
void browser_window_load_uri(BrowserWindow *window, const char *uri)
{
g_return_if_fail(BROWSER_IS_WINDOW(window));
g_return_if_fail(uri);
if (!g_str_has_prefix(uri, "javascript:")) {
webkit_web_view_load_uri(window->webView, uri);
return;
}
webkit_web_view_run_javascript(window->webView, strstr(uri, "javascript:"), NULL, NULL, NULL);
}