Added: trunk/Tools/MiniBrowser/gtk/BrowserTab.c (0 => 203271)
--- trunk/Tools/MiniBrowser/gtk/BrowserTab.c (rev 0)
+++ trunk/Tools/MiniBrowser/gtk/BrowserTab.c 2016-07-15 09:25:15 UTC (rev 203271)
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H && defined(BUILDING_WITH_CMAKE)
+#include "cmakeconfig.h"
+#endif
+#include "BrowserTab.h"
+
+#include "BrowserSearchBar.h"
+#include "BrowserWindow.h"
+#include <string.h>
+
+enum {
+ PROP_0,
+
+ PROP_VIEW
+};
+
+struct _BrowserTab {
+ GtkBox parent;
+
+ WebKitWebView *webView;
+ BrowserSearchBar *searchBar;
+ GtkWidget *statusLabel;
+ gboolean wasSearchingWhenEnteredFullscreen;
+ gboolean inspectorIsVisible;
+ GtkWidget *fullScreenMessageLabel;
+ guint fullScreenMessageLabelId;
+
+ /* Tab Title */
+ GtkWidget *titleBox;
+ GtkWidget *titleLabel;
+ GtkWidget *titleSpinner;
+ GtkWidget *titleCloseButton;
+};
+
+struct _BrowserTabClass {
+ GtkBoxClass parent;
+};
+
+G_DEFINE_TYPE(BrowserTab, browser_tab, GTK_TYPE_BOX)
+
+static void titleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserTab *tab)
+{
+ const char *title = webkit_web_view_get_title(webView);
+ if (title && *title)
+ gtk_label_set_text(GTK_LABEL(tab->titleLabel), title);
+}
+
+static void isLoadingChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserTab *tab)
+{
+ if (webkit_web_view_is_loading(webView)) {
+ gtk_spinner_start(GTK_SPINNER(tab->titleSpinner));
+ gtk_widget_show(tab->titleSpinner);
+ } else {
+ gtk_spinner_stop(GTK_SPINNER(tab->titleSpinner));
+ gtk_widget_hide(tab->titleSpinner);
+ }
+}
+
+static gboolean decidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserTab *tab)
+{
+ if (decisionType != WEBKIT_POLICY_DECISION_TYPE_RESPONSE)
+ return FALSE;
+
+ WebKitResponsePolicyDecision *responseDecision = WEBKIT_RESPONSE_POLICY_DECISION(decision);
+ if (webkit_response_policy_decision_is_mime_type_supported(responseDecision))
+ return FALSE;
+
+ WebKitWebResource *mainResource = webkit_web_view_get_main_resource(webView);
+ WebKitURIRequest *request = webkit_response_policy_decision_get_request(responseDecision);
+ const char *requestURI = webkit_uri_request_get_uri(request);
+ if (g_strcmp0(webkit_web_resource_get_uri(mainResource), requestURI))
+ return FALSE;
+
+ webkit_policy_decision_download(decision);
+ return TRUE;
+}
+
+static void removeChildIfInfoBar(GtkWidget *child, GtkContainer *tab)
+{
+ if (GTK_IS_INFO_BAR(child))
+ gtk_container_remove(tab, child);
+}
+
+static void loadChanged(WebKitWebView *webView, WebKitLoadEvent loadEvent, BrowserTab *tab)
+{
+ if (loadEvent != WEBKIT_LOAD_STARTED)
+ return;
+
+ gtk_container_foreach(GTK_CONTAINER(tab), (GtkCallback)removeChildIfInfoBar, tab);
+}
+
+static GtkWidget *createInfoBarQuestionMessage(const char *title, const char *text)
+{
+ GtkWidget *dialog = gtk_info_bar_new_with_buttons("No", GTK_RESPONSE_NO, "Yes", GTK_RESPONSE_YES, NULL);
+ gtk_info_bar_set_message_type(GTK_INFO_BAR(dialog), GTK_MESSAGE_QUESTION);
+
+ GtkWidget *contentBox = gtk_info_bar_get_content_area(GTK_INFO_BAR(dialog));
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(contentBox), GTK_ORIENTATION_VERTICAL);
+ gtk_box_set_spacing(GTK_BOX(contentBox), 0);
+
+ GtkWidget *label = gtk_label_new(NULL);
+ gchar *markup = g_strdup_printf("<span size='xx-large' weight='bold'>%s</span>", title);
+ gtk_label_set_markup(GTK_LABEL(label), markup);
+ g_free(markup);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_label_set_selectable(GTK_LABEL(label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5);
+ gtk_box_pack_start(GTK_BOX(contentBox), label, FALSE, FALSE, 2);
+ gtk_widget_show(label);
+
+ label = gtk_label_new(text);
+ gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
+ gtk_label_set_selectable(GTK_LABEL(label), TRUE);
+ gtk_misc_set_alignment(GTK_MISC(label), 0., 0.5);
+ gtk_box_pack_start(GTK_BOX(contentBox), label, FALSE, FALSE, 0);
+ gtk_widget_show(label);
+
+ return dialog;
+}
+
+static void tlsErrorsDialogResponse(GtkWidget *dialog, gint response, BrowserTab *tab)
+{
+ if (response == GTK_RESPONSE_YES) {
+ const char *failingURI = (const char *)g_object_get_data(G_OBJECT(dialog), "failingURI");
+ GTlsCertificate *certificate = (GTlsCertificate *)g_object_get_data(G_OBJECT(dialog), "certificate");
+ SoupURI *uri = soup_uri_new(failingURI);
+ webkit_web_context_allow_tls_certificate_for_host(webkit_web_view_get_context(tab->webView), certificate, uri->host);
+ soup_uri_free(uri);
+ webkit_web_view_load_uri(tab->webView, failingURI);
+ }
+ gtk_widget_destroy(dialog);
+}
+
+static gboolean loadFailedWithTLSerrors(WebKitWebView *webView, const char *failingURI, GTlsCertificate *certificate, GTlsCertificateFlags errors, BrowserTab *tab)
+{
+ gchar *text = g_strdup_printf("Failed to load %s: Do you want to continue ignoring the TLS errors?", failingURI);
+ GtkWidget *dialog = createInfoBarQuestionMessage("Invalid TLS Certificate", text);
+ g_free(text);
+ g_object_set_data_full(G_OBJECT(dialog), "failingURI", g_strdup(failingURI), g_free);
+ g_object_set_data_full(G_OBJECT(dialog), "certificate", g_object_ref(certificate), g_object_unref);
+
+ g_signal_connect(dialog, "response", G_CALLBACK(tlsErrorsDialogResponse), tab);
+
+ gtk_box_pack_start(GTK_BOX(tab), dialog, FALSE, FALSE, 0);
+ gtk_box_reorder_child(GTK_BOX(tab), dialog, 0);
+ gtk_widget_show(dialog);
+
+ return TRUE;
+}
+
+static void permissionRequestDialogResponse(GtkWidget *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(dialog);
+ g_object_unref(request);
+}
+
+static gboolean decidePermissionRequest(WebKitWebView *webView, WebKitPermissionRequest *request, BrowserTab *tab)
+{
+ const gchar *title = NULL;
+ gchar *text = NULL;
+
+ if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(request)) {
+ title = "Geolocation request";
+ text = g_strdup("Allow geolocation request?");
+ } else if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)) {
+ title = "Notification request";
+ text = g_strdup("Allow notifications request?");
+ } else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)) {
+ title = "UserMedia request";
+ gboolean is_for_audio_device = webkit_user_media_permission_is_for_audio_device(WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request));
+ gboolean is_for_video_device = webkit_user_media_permission_is_for_video_device(WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request));
+ const char *mediaType = NULL;
+ if (is_for_audio_device) {
+ if (is_for_video_device)
+ mediaType = "audio/video";
+ else
+ mediaType = "audio";
+ } else if (is_for_video_device)
+ mediaType = "video";
+ text = g_strdup_printf("Allow access to %s device?", mediaType);
+ } else if (WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)) {
+ title = "Media plugin missing request";
+ text = g_strdup_printf("The media backend was unable to find a plugin to play the requested media:\n%s.\nAllow to search and install the missing plugin?",
+ webkit_install_missing_media_plugins_permission_request_get_description(WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)));
+ } else
+ return FALSE;
+
+ GtkWidget *dialog = createInfoBarQuestionMessage(title, text);
+ g_free(text);
+ g_signal_connect(dialog, "response", G_CALLBACK(permissionRequestDialogResponse), g_object_ref(request));
+
+ gtk_box_pack_start(GTK_BOX(tab), dialog, FALSE, FALSE, 0);
+ gtk_box_reorder_child(GTK_BOX(tab), dialog, 0);
+ gtk_widget_show(dialog);
+}
+
+#if GTK_CHECK_VERSION(3, 12, 0)
+static void colorChooserRGBAChanged(GtkColorChooser *colorChooser, GParamSpec *paramSpec, WebKitColorChooserRequest *request)
+{
+ GdkRGBA rgba;
+ gtk_color_chooser_get_rgba(colorChooser, &rgba);
+ webkit_color_chooser_request_set_rgba(request, &rgba);
+}
+
+static void popoverColorClosed(GtkWidget *popover, WebKitColorChooserRequest *request)
+{
+ webkit_color_chooser_request_finish(request);
+}
+
+static void colorChooserRequestFinished(WebKitColorChooserRequest *request, GtkWidget *popover)
+{
+ g_object_unref(request);
+ gtk_widget_destroy(popover);
+}
+
+static gboolean runColorChooserCallback(WebKitWebView *webView, WebKitColorChooserRequest *request, BrowserTab *tab)
+{
+ GtkWidget *popover = gtk_popover_new(GTK_WIDGET(webView));
+
+ GdkRectangle rectangle;
+ webkit_color_chooser_request_get_element_rectangle(request, &rectangle);
+ gtk_popover_set_pointing_to(GTK_POPOVER(popover), &rectangle);
+
+ GtkWidget *colorChooser = gtk_color_chooser_widget_new();
+ GdkRGBA rgba;
+ webkit_color_chooser_request_get_rgba(request, &rgba);
+ gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(colorChooser), &rgba);
+ g_signal_connect(colorChooser, "notify::rgba", G_CALLBACK(colorChooserRGBAChanged), request);
+ gtk_container_add(GTK_CONTAINER(popover), colorChooser);
+ gtk_widget_show(colorChooser);
+
+ g_object_ref(request);
+ g_signal_connect_object(popover, "hide", G_CALLBACK(popoverColorClosed), request, 0);
+ g_signal_connect_object(request, "finished", G_CALLBACK(colorChooserRequestFinished), popover, 0);
+
+ gtk_widget_show(popover);
+
+ return TRUE;
+}
+#endif /* GTK_CHECK_VERSION(3, 12, 0) */
+
+static gboolean inspectorOpenedInWindow(WebKitWebInspector *inspector, BrowserTab *tab)
+{
+ tab->inspectorIsVisible = TRUE;
+ return FALSE;
+}
+
+static gboolean inspectorClosed(WebKitWebInspector *inspector, BrowserTab *tab)
+{
+ tab->inspectorIsVisible = FALSE;
+ return FALSE;
+}
+
+static void browserTabSetProperty(GObject *object, guint propId, const GValue *value, GParamSpec *pspec)
+{
+ BrowserTab *tab = BROWSER_TAB(object);
+
+ switch (propId) {
+ case PROP_VIEW:
+ tab->webView = g_value_get_object(value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
+ }
+}
+
+static void browserTabFinalize(GObject *gObject)
+{
+ BrowserTab *tab = BROWSER_TAB(gObject);
+
+ if (tab->fullScreenMessageLabelId)
+ g_source_remove(tab->fullScreenMessageLabelId);
+
+ G_OBJECT_CLASS(browser_tab_parent_class)->finalize(gObject);
+}
+
+static void browser_tab_init(BrowserTab *tab)
+{
+ gtk_orientable_set_orientation(GTK_ORIENTABLE(tab), GTK_ORIENTATION_VERTICAL);
+}
+
+static void browserTabConstructed(GObject *gObject)
+{
+ BrowserTab *tab = BROWSER_TAB(gObject);
+
+ G_OBJECT_CLASS(browser_tab_parent_class)->constructed(gObject);
+
+ tab->searchBar = BROWSER_SEARCH_BAR(browser_search_bar_new(tab->webView));
+ gtk_box_pack_start(GTK_BOX(tab), GTK_WIDGET(tab->searchBar), FALSE, FALSE, 0);
+
+ GtkWidget *overlay = gtk_overlay_new();
+ gtk_box_pack_start(GTK_BOX(tab), overlay, TRUE, TRUE, 0);
+ gtk_widget_show(overlay);
+
+ tab->statusLabel = gtk_label_new(NULL);
+ gtk_widget_set_halign(tab->statusLabel, GTK_ALIGN_START);
+ gtk_widget_set_valign(tab->statusLabel, GTK_ALIGN_END);
+ gtk_widget_set_margin_left(tab->statusLabel, 1);
+ gtk_widget_set_margin_right(tab->statusLabel, 1);
+ gtk_widget_set_margin_top(tab->statusLabel, 1);
+ gtk_widget_set_margin_bottom(tab->statusLabel, 1);
+ gtk_overlay_add_overlay(GTK_OVERLAY(overlay), tab->statusLabel);
+
+ tab->fullScreenMessageLabel = gtk_label_new(NULL);
+ gtk_widget_set_halign(tab->fullScreenMessageLabel, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign(tab->fullScreenMessageLabel, GTK_ALIGN_CENTER);
+ gtk_widget_set_no_show_all(tab->fullScreenMessageLabel, TRUE);
+ gtk_overlay_add_overlay(GTK_OVERLAY(overlay), tab->fullScreenMessageLabel);
+
+ gtk_container_add(GTK_CONTAINER(overlay), GTK_WIDGET(tab->webView));
+ gtk_widget_show(GTK_WIDGET(tab->webView));
+
+ tab->titleBox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 4);
+
+ GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
+ gtk_widget_set_halign(hbox, GTK_ALIGN_CENTER);
+
+ tab->titleSpinner = gtk_spinner_new();
+ gtk_box_pack_start(GTK_BOX(hbox), tab->titleSpinner, FALSE, FALSE, 0);
+
+ tab->titleLabel = gtk_label_new(NULL);
+ gtk_label_set_ellipsize(GTK_LABEL(tab->titleLabel), PANGO_ELLIPSIZE_END);
+ gtk_label_set_single_line_mode(GTK_LABEL(tab->titleLabel), TRUE);
+ gtk_misc_set_padding(GTK_MISC(tab->titleLabel), 0, 0);
+ gtk_box_pack_start(GTK_BOX(hbox), tab->titleLabel, FALSE, FALSE, 0);
+ gtk_widget_show(tab->titleLabel);
+
+ gtk_box_pack_start(GTK_BOX(tab->titleBox), hbox, TRUE, TRUE, 0);
+ gtk_widget_show(hbox);
+
+ tab->titleCloseButton = gtk_button_new();
+ g_signal_connect_swapped(tab->titleCloseButton, "clicked", G_CALLBACK(gtk_widget_destroy), tab);
+ gtk_button_set_relief(GTK_BUTTON(tab->titleCloseButton), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click(GTK_BUTTON(tab->titleCloseButton), FALSE);
+
+ GtkWidget *image = gtk_image_new_from_icon_name("window-close-symbolic", GTK_ICON_SIZE_MENU);
+ gtk_container_add(GTK_CONTAINER(tab->titleCloseButton), image);
+ gtk_widget_show(image);
+
+ gtk_box_pack_start(GTK_BOX(tab->titleBox), tab->titleCloseButton, FALSE, FALSE, 0);
+ gtk_widget_show(tab->titleCloseButton);
+
+ g_signal_connect(tab->webView, "notify::title", G_CALLBACK(titleChanged), tab);
+ g_signal_connect(tab->webView, "notify::is-loading", G_CALLBACK(isLoadingChanged), tab);
+ g_signal_connect(tab->webView, "decide-policy", G_CALLBACK(decidePolicy), tab);
+ g_signal_connect(tab->webView, "load-changed", G_CALLBACK(loadChanged), tab);
+ g_signal_connect(tab->webView, "load-failed-with-tls-errors", G_CALLBACK(loadFailedWithTLSerrors), tab);
+ g_signal_connect(tab->webView, "permission-request", G_CALLBACK(decidePermissionRequest), tab);
+#if GTK_CHECK_VERSION(3, 12, 0)
+ g_signal_connect(tab->webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), tab);
+#endif
+
+ WebKitWebInspector *inspector = webkit_web_view_get_inspector(tab->webView);
+ g_signal_connect(inspector, "open-window", G_CALLBACK(inspectorOpenedInWindow), tab);
+ g_signal_connect(inspector, "closed", G_CALLBACK(inspectorClosed), tab);
+
+ if (webkit_web_view_is_editable(tab->webView))
+ webkit_web_view_load_html(tab->webView, "<html></html>", "file:///");
+}
+
+static void browser_tab_class_init(BrowserTabClass *klass)
+{
+ GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
+ gobjectClass->constructed = browserTabConstructed;
+ gobjectClass->set_property = browserTabSetProperty;
+ gobjectClass->finalize = browserTabFinalize;
+
+ g_object_class_install_property(
+ gobjectClass,
+ PROP_VIEW,
+ g_param_spec_object(
+ "view",
+ "View",
+ "The web view of this tab",
+ WEBKIT_TYPE_WEB_VIEW,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static char *getInternalURI(const char *uri)
+{
+ /* Internally we use minibrowser-about: as about: prefix is ignored by WebKit. */
+ if (g_str_has_prefix(uri, "about:") && !g_str_equal(uri, "about:blank"))
+ return g_strconcat(BROWSER_ABOUT_SCHEME, uri + strlen ("about"), NULL);
+
+ return g_strdup(uri);
+}
+
+/* Public API. */
+GtkWidget *browser_tab_new(WebKitWebView *view)
+{
+ g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(view), NULL);
+
+ return GTK_WIDGET(g_object_new(BROWSER_TYPE_TAB, "view", view, NULL));
+}
+
+WebKitWebView *browser_tab_get_web_view(BrowserTab *tab)
+{
+ g_return_val_if_fail(BROWSER_IS_TAB(tab), NULL);
+
+ return tab->webView;
+}
+
+void browser_tab_load_uri(BrowserTab *tab, const char *uri)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+ g_return_if_fail(uri);
+
+ if (!g_str_has_prefix(uri, "_javascript_:")) {
+ char *internalURI = getInternalURI(uri);
+ webkit_web_view_load_uri(tab->webView, internalURI);
+ g_free(internalURI);
+ return;
+ }
+
+ webkit_web_view_run_javascript(tab->webView, strstr(uri, "_javascript_:"), NULL, NULL, NULL);
+}
+
+GtkWidget *browser_tab_get_title_widget(BrowserTab *tab)
+{
+ g_return_val_if_fail(BROWSER_IS_TAB(tab), NULL);
+
+ return tab->titleBox;
+}
+
+void browser_tab_set_status_text(BrowserTab *tab, const char *text)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+
+ gtk_label_set_text(GTK_LABEL(tab->statusLabel), text);
+ gtk_widget_set_visible(tab->statusLabel, !!text);
+}
+
+void browser_tab_toggle_inspector(BrowserTab *tab)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+
+ WebKitWebInspector *inspector = webkit_web_view_get_inspector(tab->webView);
+ if (!tab->inspectorIsVisible) {
+ webkit_web_inspector_show(inspector);
+ tab->inspectorIsVisible = TRUE;
+ } else
+ webkit_web_inspector_close(inspector);
+}
+
+void browser_tab_start_search(BrowserTab *tab)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+
+ if (!gtk_widget_get_visible(GTK_WIDGET(tab->searchBar)))
+ browser_search_bar_open(tab->searchBar);
+}
+
+void browser_tab_stop_search(BrowserTab *tab)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+
+ if (gtk_widget_get_visible(GTK_WIDGET(tab->searchBar)))
+ browser_search_bar_close(tab->searchBar);
+}
+
+void browser_tab_add_accelerators(BrowserTab *tab, GtkAccelGroup *accelGroup)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+ g_return_if_fail(GTK_IS_ACCEL_GROUP(accelGroup));
+
+ browser_search_bar_add_accelerators(tab->searchBar, accelGroup);
+}
+
+static gboolean fullScreenMessageTimeoutCallback(BrowserTab *tab)
+{
+ gtk_widget_hide(tab->fullScreenMessageLabel);
+ tab->fullScreenMessageLabelId = 0;
+ return FALSE;
+}
+
+void browser_tab_enter_fullscreen(BrowserTab *tab)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+
+ const gchar *titleOrURI = webkit_web_view_get_title(tab->webView);
+ if (!titleOrURI || !titleOrURI[0])
+ titleOrURI = webkit_web_view_get_uri(tab->webView);
+
+ gchar *message = g_strdup_printf("%s is now full screen. Press ESC or f to exit.", titleOrURI);
+ gtk_label_set_text(GTK_LABEL(tab->fullScreenMessageLabel), message);
+ g_free(message);
+
+ gtk_widget_show(tab->fullScreenMessageLabel);
+
+ tab->fullScreenMessageLabelId = g_timeout_add_seconds(2, (GSourceFunc)fullScreenMessageTimeoutCallback, tab);
+ g_source_set_name_by_id(tab->fullScreenMessageLabelId, "[WebKit] fullScreenMessageTimeoutCallback");
+
+ tab->wasSearchingWhenEnteredFullscreen = gtk_widget_get_visible(GTK_WIDGET(tab->searchBar));
+ browser_tab_stop_search(tab);
+}
+
+void browser_tab_leave_fullscreen(BrowserTab *tab)
+{
+ g_return_if_fail(BROWSER_IS_TAB(tab));
+
+ if (tab->fullScreenMessageLabelId) {
+ g_source_remove(tab->fullScreenMessageLabelId);
+ tab->fullScreenMessageLabelId = 0;
+ }
+
+ gtk_widget_hide(tab->fullScreenMessageLabel);
+
+ if (tab->wasSearchingWhenEnteredFullscreen) {
+ /* Opening the search bar steals the focus. Usually, we want
+ * this but not when coming back from fullscreen.
+ */
+ GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(tab)));
+ GtkWidget *focusWidget = gtk_window_get_focus(window);
+ browser_tab_start_search(tab);
+ gtk_window_set_focus(window, focusWidget);
+ }
+}
Modified: trunk/Tools/MiniBrowser/gtk/BrowserWindow.c (203270 => 203271)
--- trunk/Tools/MiniBrowser/gtk/BrowserWindow.c 2016-07-15 06:03:25 UTC (rev 203270)
+++ trunk/Tools/MiniBrowser/gtk/BrowserWindow.c 2016-07-15 09:25:15 UTC (rev 203271)
@@ -33,15 +33,10 @@
#include "BrowserDownloadsBar.h"
#include "BrowserSearchBar.h"
#include "BrowserSettingsDialog.h"
+#include "BrowserTab.h"
#include <gdk/gdkkeysyms.h>
#include <string.h>
-enum {
- PROP_0,
-
- PROP_VIEW
-};
-
struct _BrowserWindow {
GtkWindow parent;
@@ -57,19 +52,15 @@
GtkWidget *italicItem;
GtkWidget *underlineItem;
GtkWidget *strikethroughItem;
- GtkWidget *statusLabel;
GtkWidget *settingsDialog;
- WebKitWebView *webView;
+ GtkWidget *notebook;
+ BrowserTab *activeTab;
GtkWidget *downloadsBar;
- BrowserSearchBar *searchBar;
gboolean searchBarVisible;
- gboolean inspectorWindowIsVisible;
gboolean fullScreenIsEnabled;
GdkPixbuf *favicon;
GtkWidget *reloadOrStopButton;
- GtkWidget *fullScreenMessageLabel;
GtkWindow *parentWindow;
- guint fullScreenMessageLabelId;
guint resetEntryProgressTimeoutId;
gchar *sessionFile;
};
@@ -79,7 +70,6 @@
};
static const char *defaultWindowTitle = "WebKitGTK+ MiniBrowser";
-static const char *miniBrowserAboutScheme = "minibrowser-about";
static const gdouble minimumZoomLevel = 0.5;
static const gdouble maximumZoomLevel = 3;
static const gdouble defaultZoomLevel = 1;
@@ -88,20 +78,11 @@
G_DEFINE_TYPE(BrowserWindow, browser_window, GTK_TYPE_WINDOW)
-static char *getInternalURI(const char *uri)
-{
- // Internally we use minibrowser-about: as about: prefix is ignored by WebKit.
- if (g_str_has_prefix(uri, "about:") && !g_str_equal(uri, "about:blank"))
- return g_strconcat(miniBrowserAboutScheme, uri + strlen ("about"), NULL);
-
- return g_strdup(uri);
-}
-
static char *getExternalURI(const char *uri)
{
- // From the user point of view we support about: prefix.
- if (g_str_has_prefix(uri, miniBrowserAboutScheme))
- return g_strconcat("about", uri + strlen(miniBrowserAboutScheme), NULL);
+ /* From the user point of view we support about: prefix. */
+ if (uri && g_str_has_prefix(uri, BROWSER_ABOUT_SCHEME))
+ return g_strconcat("about", uri + strlen(BROWSER_ABOUT_SCHEME), NULL);
return g_strdup(uri);
}
@@ -108,8 +89,7 @@
static void browserWindowSetStatusText(BrowserWindow *window, const char *text)
{
- gtk_label_set_text(GTK_LABEL(window->statusLabel), text);
- gtk_widget_set_visible(window->statusLabel, !!text);
+ browser_tab_set_status_text(window->activeTab, text);
}
static void resetStatusText(GtkWidget *widget, BrowserWindow *window)
@@ -124,20 +104,23 @@
static void reloadOrStopCallback(BrowserWindow *window)
{
- if (webkit_web_view_is_loading(window->webView))
- webkit_web_view_stop_loading(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ if (webkit_web_view_is_loading(webView))
+ webkit_web_view_stop_loading(webView);
else
- webkit_web_view_reload(window->webView);
+ webkit_web_view_reload(webView);
}
static void goBackCallback(BrowserWindow *window)
{
- webkit_web_view_go_back(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_go_back(webView);
}
static void goForwardCallback(BrowserWindow *window)
{
- webkit_web_view_go_forward(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_go_forward(webView);
}
static void settingsCallback(BrowserWindow *window)
@@ -147,7 +130,8 @@
return;
}
- window->settingsDialog = browser_settings_dialog_new(webkit_web_view_get_settings(window->webView));
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ window->settingsDialog = browser_settings_dialog_new(webkit_web_view_get_settings(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);
@@ -156,8 +140,11 @@
static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
{
char *externalURI = getExternalURI(webkit_web_view_get_uri(webView));
- gtk_entry_set_text(GTK_ENTRY(window->uriEntry), externalURI);
- g_free(externalURI);
+ if (externalURI) {
+ gtk_entry_set_text(GTK_ENTRY(window->uriEntry), externalURI);
+ g_free(externalURI);
+ } else
+ gtk_entry_set_text(GTK_ENTRY(window->uriEntry), "");
}
static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
@@ -207,7 +194,8 @@
if (!item)
return;
- webkit_web_view_go_to_back_forward_list_item(window->webView, item);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_go_to_back_forward_list_item(webView, item);
}
static GtkWidget *browserWindowCreateBackForwardMenu(BrowserWindow *window, GList *list)
@@ -241,8 +229,9 @@
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));
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ gtk_widget_set_sensitive(window->backItem, webkit_web_view_can_go_back(webView));
+ gtk_widget_set_sensitive(window->forwardItem, webkit_web_view_can_go_forward(webView));
GList *list = g_list_reverse(webkit_back_forward_list_get_back_list_with_limit(backForwadlist, 10));
gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window->backItem),
@@ -260,21 +249,6 @@
browserWindowUpdateNavigationActions(window, backForwadlist);
}
-static void permissionRequestDialogCallback(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));
@@ -308,65 +282,33 @@
gtk_widget_show(GTK_WIDGET(window));
}
-static gboolean fullScreenMessageTimeoutCallback(BrowserWindow *window)
+static GtkWidget *webViewCreate(WebKitWebView *webView, WebKitNavigationAction *navigation, BrowserWindow *window)
{
- gtk_widget_hide(window->fullScreenMessageLabel);
- window->fullScreenMessageLabelId = 0;
- return FALSE;
+ WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_related_view(webView));
+ webkit_web_view_set_settings(newWebView, webkit_web_view_get_settings(webView));
+
+ GtkWidget *newWindow = browser_window_new(GTK_WINDOW(window));
+ browser_window_append_view(BROWSER_WINDOW(newWindow), newWebView);
+ 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 webViewEnterFullScreen(WebKitWebView *webView, BrowserWindow *window)
{
- gchar *titleOrURI = g_strdup(webkit_web_view_get_title(window->webView));
- if (!titleOrURI)
- titleOrURI = getExternalURI(webkit_web_view_get_uri(window->webView));
- gchar *message = g_strdup_printf("%s is now full screen. Press ESC or f to exit.", titleOrURI);
- gtk_label_set_text(GTK_LABEL(window->fullScreenMessageLabel), message);
- g_free(titleOrURI);
- g_free(message);
-
- gtk_widget_show(window->fullScreenMessageLabel);
-
- window->fullScreenMessageLabelId = g_timeout_add_seconds(2, (GSourceFunc)fullScreenMessageTimeoutCallback, window);
- g_source_set_name_by_id(window->fullScreenMessageLabelId, "[WebKit] fullScreenMessageTimeoutCallback");
gtk_widget_hide(window->toolbar);
- window->searchBarVisible = gtk_widget_get_visible(GTK_WIDGET(window->searchBar));
- browser_search_bar_close(window->searchBar);
-
+ browser_tab_enter_fullscreen(window->activeTab);
return FALSE;
}
static gboolean webViewLeaveFullScreen(WebKitWebView *webView, BrowserWindow *window)
{
- if (window->fullScreenMessageLabelId) {
- g_source_remove(window->fullScreenMessageLabelId);
- window->fullScreenMessageLabelId = 0;
- }
- gtk_widget_hide(window->fullScreenMessageLabel);
+ browser_tab_leave_fullscreen(window->activeTab);
gtk_widget_show(window->toolbar);
- if (window->searchBarVisible) {
- // Opening the search bar steals the focus. Usually, we want
- // this but not when coming back from fullscreen.
- GtkWidget *focusWidget = gtk_window_get_focus(GTK_WINDOW(window));
- browser_search_bar_open(window->searchBar);
- gtk_window_set_focus(GTK_WINDOW(window), focusWidget);
- }
-
return FALSE;
}
-static GtkWidget *webViewCreate(WebKitWebView *webView, WebKitNavigationAction *navigation, BrowserWindow *window)
-{
- WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_related_view(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.);
@@ -373,104 +315,26 @@
return FALSE;
}
-static gboolean webViewLoadFailedWithTLSerrors(WebKitWebView *webView, const char *failingURI, GTlsCertificate *certificate, GTlsCertificateFlags errors, BrowserWindow *window)
-{
- GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, "%s", "Invalid TLS Certificate");
- gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "Failed to load %s: Do you want to continue ignoring the TLS errors?", failingURI);
- int response = gtk_dialog_run(GTK_DIALOG(dialog));
- gtk_widget_destroy(dialog);
-
- if (response == GTK_RESPONSE_YES) {
- SoupURI *uri = soup_uri_new(failingURI);
- webkit_web_context_allow_tls_certificate_for_host(webkit_web_view_get_context(webView), certificate, uri->host);
- soup_uri_free(uri);
- webkit_web_view_load_uri(webView, failingURI);
- }
-
- return TRUE;
-}
-
static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserWindow *window)
{
- switch (decisionType) {
- case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: {
- WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
- if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
- || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE)
- return FALSE;
+ if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
+ return FALSE;
- // Opening a new window if link clicked with the middle button.
- WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(webkit_web_view_get_context(webView)));
- GtkWidget *newWindow = browser_window_new(newWebView, GTK_WINDOW(window));
- webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction));
- gtk_widget_show(newWindow);
-
- webkit_policy_decision_ignore(decision);
- return TRUE;
- }
- case WEBKIT_POLICY_DECISION_TYPE_RESPONSE: {
- WebKitResponsePolicyDecision *responseDecision = WEBKIT_RESPONSE_POLICY_DECISION(decision);
- if (webkit_response_policy_decision_is_mime_type_supported(responseDecision))
- return FALSE;
-
- WebKitWebResource *mainResource = webkit_web_view_get_main_resource(webView);
- WebKitURIRequest *request = webkit_response_policy_decision_get_request(responseDecision);
- const char *requestURI = webkit_uri_request_get_uri(request);
- if (g_strcmp0(webkit_web_resource_get_uri(mainResource), requestURI))
- return FALSE;
-
- webkit_policy_decision_download(decision);
- return TRUE;
- }
- case WEBKIT_POLICY_DECISION_TYPE_NEW_WINDOW_ACTION:
- default:
+ WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision));
+ if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED
+ || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE)
return FALSE;
- }
-}
-static gboolean webViewDecidePermissionRequest(WebKitWebView *webView, WebKitPermissionRequest *request, BrowserWindow *window)
-{
- const gchar *dialog_title = NULL;
- const gchar *dialog_message = NULL;
- const gchar *dialog_message_format = NULL;
-
- if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(request)) {
- dialog_title = "Geolocation request";
- dialog_message_format = "%s";
- dialog_message = "Allow geolocation request?";
- } else if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)) {
- dialog_title = "Notification request";
- dialog_message_format = "%s";
- dialog_message = "Allow notifications request?";
- } else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)) {
- dialog_message_format = "Allow access to %s device?";
- gboolean is_for_audio_device = webkit_user_media_permission_is_for_audio_device(WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request));
- gboolean is_for_video_device = webkit_user_media_permission_is_for_video_device(WEBKIT_USER_MEDIA_PERMISSION_REQUEST(request));
- dialog_title = "UserMedia request";
- if (is_for_audio_device) {
- if (is_for_video_device)
- dialog_message = "audio/video";
- else
- dialog_message = "audio";
- } else if (is_for_video_device)
- dialog_message = "video";
- } else if (WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)) {
- dialog_title = "Media plugin missing request";
- dialog_message_format = "The media backend was unable to find a plugin to play the requested media:\n%s.\nAllow to search and install the missing plugin?";
- dialog_message = webkit_install_missing_media_plugins_permission_request_get_description(WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request));
- } else
+ /* Multiple tabs are not allowed in editor mode. */
+ if (webkit_web_view_is_editable(webView))
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,
- "%s", dialog_title);
+ /* Opening a new tab if link clicked with the middle button. */
+ WebKitWebView *newWebView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_context(webkit_web_view_get_context(webView)));
+ browser_window_append_view(window, newWebView);
+ webkit_web_view_load_request(newWebView, webkit_navigation_action_get_request(navigationAction));
- gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), dialog_message_format, dialog_message);
- g_signal_connect(dialog, "response", G_CALLBACK(permissionRequestDialogCallback), g_object_ref(request));
- gtk_widget_show(dialog);
+ webkit_policy_decision_ignore(decision);
return TRUE;
}
@@ -485,13 +349,15 @@
static gboolean browserWindowCanZoomIn(BrowserWindow *window)
{
- gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) * zoomStep;
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) * zoomStep;
return zoomLevel < maximumZoomLevel;
}
static gboolean browserWindowCanZoomOut(BrowserWindow *window)
{
- gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) / zoomStep;
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) / zoomStep;
return zoomLevel > minimumZoomLevel;
}
@@ -498,8 +364,9 @@
static gboolean browserWindowZoomIn(BrowserWindow *window)
{
if (browserWindowCanZoomIn(window)) {
- gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) * zoomStep;
- webkit_web_view_set_zoom_level(window->webView, zoomLevel);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) * zoomStep;
+ webkit_web_view_set_zoom_level(webView, zoomLevel);
return TRUE;
}
return FALSE;
@@ -508,8 +375,9 @@
static gboolean browserWindowZoomOut(BrowserWindow *window)
{
if (browserWindowCanZoomOut(window)) {
- gdouble zoomLevel = webkit_web_view_get_zoom_level(window->webView) / zoomStep;
- webkit_web_view_set_zoom_level(window->webView, zoomLevel);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) / zoomStep;
+ webkit_web_view_set_zoom_level(webView, zoomLevel);
return TRUE;
}
return FALSE;
@@ -521,58 +389,13 @@
if ((event->state & mod) != GDK_CONTROL_MASK)
return FALSE;
-
+
if (event->delta_y < 0)
return browserWindowZoomIn(window);
-
+
return browserWindowZoomOut(window);
}
-#if GTK_CHECK_VERSION(3, 12, 0)
-static void colorChooserRGBAChanged(GtkColorChooser *colorChooser, GParamSpec *paramSpec, WebKitColorChooserRequest *request)
-{
- GdkRGBA rgba;
- gtk_color_chooser_get_rgba(colorChooser, &rgba);
- webkit_color_chooser_request_set_rgba(request, &rgba);
-}
-
-static void popoverColorClosed(GtkWidget *popover, WebKitColorChooserRequest *request)
-{
- webkit_color_chooser_request_finish(request);
-}
-
-static void colorChooserRequestFinished(WebKitColorChooserRequest *request, GtkWidget *popover)
-{
- g_object_unref(request);
- gtk_widget_destroy(popover);
-}
-
-static gboolean runColorChooserCallback(WebKitWebView *webView, WebKitColorChooserRequest *request, BrowserWindow *window)
-{
- GtkWidget *popover = gtk_popover_new(GTK_WIDGET(webView));
-
- GdkRectangle rectangle;
- webkit_color_chooser_request_get_element_rectangle(request, &rectangle);
- gtk_popover_set_pointing_to(GTK_POPOVER(popover), &rectangle);
-
- GtkWidget *colorChooser = gtk_color_chooser_widget_new();
- GdkRGBA rgba;
- webkit_color_chooser_request_get_rgba(request, &rgba);
- gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(colorChooser), &rgba);
- g_signal_connect(colorChooser, "notify::rgba", G_CALLBACK(colorChooserRGBAChanged), request);
- gtk_container_add(GTK_CONTAINER(popover), colorChooser);
- gtk_widget_show(colorChooser);
-
- g_object_ref(request);
- g_signal_connect_object(popover, "hide", G_CALLBACK(popoverColorClosed), request, 0);
- g_signal_connect_object(request, "finished", G_CALLBACK(colorChooserRequestFinished), popover, 0);
-
- gtk_widget_show(popover);
-
- return TRUE;
-}
-#endif /* GTK_CHECK_VERSION(3, 12, 0) */
-
static void browserWindowUpdateZoomActions(BrowserWindow *window)
{
gtk_widget_set_sensitive(window->zoomInItem, browserWindowCanZoomIn(window));
@@ -593,10 +416,10 @@
gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_NEW);
}
-static void faviconChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window)
+static void faviconChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserWindow *window)
{
GdkPixbuf *favicon = NULL;
- cairo_surface_t *surface = webkit_web_view_get_favicon(window->webView);
+ cairo_surface_t *surface = webkit_web_view_get_favicon(webView);
if (surface) {
int width = cairo_image_surface_get_width(surface);
@@ -611,24 +434,12 @@
updateUriEntryIcon(window);
}
-static void webViewIsLoadingChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window)
+static void webViewIsLoadingChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserWindow *window)
{
- gboolean isLoading = webkit_web_view_is_loading(window->webView);
+ gboolean isLoading = webkit_web_view_is_loading(webView);
gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(window->reloadOrStopButton), isLoading ? GTK_STOCK_STOP : GTK_STOCK_REFRESH);
}
-static gboolean inspectorWasOpenedInAnotherWindow(WebKitWebInspector *inspectorWindow, BrowserWindow *window)
-{
- window->inspectorWindowIsVisible = TRUE;
- return FALSE;
-}
-
-static gboolean inspectorWasClosed(WebKitWebInspector *inspectorWindow, BrowserWindow *window)
-{
- window->inspectorWindowIsVisible = FALSE;
- return FALSE;
-}
-
static void zoomInCallback(BrowserWindow *window)
{
browserWindowZoomIn(window);
@@ -641,49 +452,54 @@
static void defaultZoomCallback(BrowserWindow *window)
{
- webkit_web_view_set_zoom_level(window->webView, defaultZoomLevel);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_set_zoom_level(webView, defaultZoomLevel);
}
static void searchCallback(BrowserWindow *window)
{
- browser_search_bar_open(window->searchBar);
+ browser_tab_start_search(window->activeTab);
}
-static gboolean toggleWebInspector(BrowserWindow *window, gpointer user_data)
+static void newTabCallback(BrowserWindow *window)
{
- WebKitWebInspector *inspectorWindow;
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ if (webkit_web_view_is_editable(webView))
+ return;
+ WebKitSettings *settings = webkit_web_view_get_settings(webView);
+ browser_window_append_view(window, WEBKIT_WEB_VIEW(webkit_web_view_new_with_settings(settings)));
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(window->notebook), -1);
+}
- inspectorWindow = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(window->webView));
- if (!window->inspectorWindowIsVisible) {
- webkit_web_inspector_show(inspectorWindow);
- window->inspectorWindowIsVisible = TRUE;
- } else
- webkit_web_inspector_close(inspectorWindow);
-
- return TRUE;
+static void toggleWebInspector(BrowserWindow *window)
+{
+ browser_tab_toggle_inspector(window->activeTab);
}
-static void reloadPage(BrowserWindow *window, gpointer user_data)
+static void reloadPage(BrowserWindow *window)
{
- webkit_web_view_reload(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_reload(webView);
}
-static void reloadPageIgnoringCache(BrowserWindow *window, gpointer user_data)
+static void reloadPageIgnoringCache(BrowserWindow *window)
{
- webkit_web_view_reload_bypass_cache(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_reload_bypass_cache(webView);
}
-static void stopPageLoad(BrowserWindow *window, gpointer user_data)
+static void stopPageLoad(BrowserWindow *window)
{
- if (gtk_widget_get_visible(GTK_WIDGET(window->searchBar)))
- browser_search_bar_close(window->searchBar);
- else if (webkit_web_view_is_loading(window->webView))
- webkit_web_view_stop_loading(window->webView);
+ browser_tab_stop_search(window->activeTab);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ if (webkit_web_view_is_loading(webView))
+ webkit_web_view_stop_loading(webView);
}
-static void loadHomePage(BrowserWindow *window, gpointer user_data)
+static void loadHomePage(BrowserWindow *window)
{
- webkit_web_view_load_uri(window->webView, BROWSER_DEFAULT_URL);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL);
}
static gboolean toggleFullScreen(BrowserWindow *window, gpointer user_data)
@@ -702,7 +518,8 @@
static void editingCommandCallback(GtkWidget*widget, BrowserWindow *window)
{
- webkit_web_view_execute_editing_command(window->webView, gtk_widget_get_name(widget));
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_execute_editing_command(webView, gtk_widget_get_name(widget));
}
static void insertImageCommandCallback(GtkWidget*widget, BrowserWindow *window)
@@ -718,7 +535,8 @@
if (gtk_dialog_run(GTK_DIALOG(fileChooser)) == GTK_RESPONSE_ACCEPT) {
char *uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(fileChooser));
if (uri) {
- webkit_web_view_execute_editing_command_with_argument(window->webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, uri);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_execute_editing_command_with_argument(webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, uri);
g_free(uri);
}
}
@@ -738,8 +556,10 @@
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
const char *url = ""
- if (url && *url)
- webkit_web_view_execute_editing_command_with_argument(window->webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, url);
+ if (url && *url) {
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_execute_editing_command_with_argument(webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, url);
+ }
}
gtk_widget_destroy(dialog);
@@ -774,9 +594,6 @@
window->accelGroup = NULL;
}
- if (window->fullScreenMessageLabelId)
- g_source_remove(window->fullScreenMessageLabelId);
-
if (window->resetEntryProgressTimeoutId)
g_source_remove(window->resetEntryProgressTimeoutId);
@@ -788,32 +605,6 @@
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 browserWindowSetupEditorToolbar(BrowserWindow *window)
{
GtkWidget *toolbar = gtk_toolbar_new();
@@ -943,9 +734,66 @@
gtk_widget_show(GTK_WIDGET(item));
gtk_box_pack_start(GTK_BOX(window->mainBox), toolbar, FALSE, FALSE, 0);
+ gtk_box_reorder_child(GTK_BOX(window->mainBox), toolbar, 1);
gtk_widget_show(toolbar);
}
+static void browserWindowSwitchTab(GtkNotebook *notebook, BrowserTab *tab, guint tabIndex, BrowserWindow *window)
+{
+ if (window->activeTab == tab)
+ return;
+
+ if (window->activeTab) {
+ browser_tab_set_status_text(window->activeTab, NULL);
+ g_clear_object(&window->favicon);
+
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ g_signal_handlers_disconnect_by_data(webView, window);
+
+ WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(webView);
+ g_signal_handlers_disconnect_by_data(backForwadlist, window);
+ }
+
+ window->activeTab = tab;
+
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ if (webkit_web_view_is_editable(webView)) {
+ browserWindowSetupEditorToolbar(window);
+ g_signal_connect(webkit_web_view_get_editor_state(webView), "notify::typing-attributes", G_CALLBACK(typingAttributesChanged), window);
+ }
+ webViewURIChanged(webView, NULL, window);
+ webViewTitleChanged(webView, NULL, window);
+ webViewIsLoadingChanged(webView, NULL, window);
+ faviconChanged(webView, NULL, window);
+ browserWindowUpdateZoomActions(window);
+ if (webkit_web_view_is_loading(webView))
+ webViewLoadProgressChanged(webView, NULL, window);
+
+ g_signal_connect(webView, "notify::uri", G_CALLBACK(webViewURIChanged), window);
+ g_signal_connect(webView, "notify::estimated-load-progress", G_CALLBACK(webViewLoadProgressChanged), window);
+ g_signal_connect(webView, "notify::title", G_CALLBACK(webViewTitleChanged), window);
+ g_signal_connect(webView, "notify::is-loading", G_CALLBACK(webViewIsLoadingChanged), window);
+ g_signal_connect(webView, "create", G_CALLBACK(webViewCreate), window);
+ g_signal_connect(webView, "close", G_CALLBACK(webViewClose), window);
+ g_signal_connect(webView, "load-failed", G_CALLBACK(webViewLoadFailed), window);
+ g_signal_connect(webView, "decide-policy", G_CALLBACK(webViewDecidePolicy), window);
+ g_signal_connect(webView, "mouse-target-changed", G_CALLBACK(webViewMouseTargetChanged), window);
+ g_signal_connect(webView, "notify::zoom-level", G_CALLBACK(webViewZoomLevelChanged), window);
+ g_signal_connect(webView, "notify::favicon", G_CALLBACK(faviconChanged), window);
+ g_signal_connect(webView, "enter-fullscreen", G_CALLBACK(webViewEnterFullScreen), window);
+ g_signal_connect(webView, "leave-fullscreen", G_CALLBACK(webViewLeaveFullScreen), window);
+ g_signal_connect(webView, "scroll-event", G_CALLBACK(scrollEventCallback), window);
+
+ WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(webView);
+ browserWindowUpdateNavigationActions(window, backForwadlist);
+ g_signal_connect(backForwadlist, "changed", G_CALLBACK(backForwadlistChanged), window);
+}
+
+static void browserWindowTabAddedOrRemoved(GtkNotebook *notebook, BrowserTab *tab, guint tabIndex, BrowserWindow *window)
+{
+ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window->notebook), gtk_notebook_get_n_pages(notebook) > 1);
+}
+
static void browser_window_init(BrowserWindow *window)
{
g_atomic_int_inc(&windowCount);
@@ -968,7 +816,7 @@
gtk_accel_group_connect(window->accelGroup, GDK_KEY_F12, 0, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(toggleWebInspector), window, NULL));
- /* Reload page */
+ /* Reload page */
gtk_accel_group_connect(window->accelGroup, GDK_KEY_F5, 0, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(reloadPage), window, NULL));
gtk_accel_group_connect(window->accelGroup, GDK_KEY_R, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
@@ -980,13 +828,13 @@
gtk_accel_group_connect(window->accelGroup, GDK_KEY_R, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(reloadPageIgnoringCache), window, NULL));
- /* Stop page load */
+ /* Stop page load */
gtk_accel_group_connect(window->accelGroup, GDK_KEY_F6, 0, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(stopPageLoad), window, NULL));
gtk_accel_group_connect(window->accelGroup, GDK_KEY_Escape, 0, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(stopPageLoad), window, NULL));
- /* Load home page */
+ /* Load home page */
gtk_accel_group_connect(window->accelGroup, GDK_KEY_Home, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(loadHomePage), window, NULL));
@@ -1004,7 +852,7 @@
gtk_accel_group_connect(window->accelGroup, GDK_KEY_KP_0, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(defaultZoomCallback), window, NULL));
- /* Toggle fullscreen */
+ /* Toggle fullscreen */
gtk_accel_group_connect(window->accelGroup, GDK_KEY_F11, 0, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(toggleFullScreen), window, NULL));
@@ -1014,6 +862,8 @@
gtk_accel_group_connect(window->accelGroup, GDK_KEY_W, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
g_cclosure_new_swap(G_CALLBACK(gtk_widget_destroy), window, NULL));
+ g_signal_connect(webkit_web_context_get_default(), "download-started", G_CALLBACK(downloadStarted), window);
+
GtkWidget *toolbar = gtk_toolbar_new();
window->toolbar = toolbar;
gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
@@ -1062,6 +912,12 @@
gtk_widget_add_accelerator(GTK_WIDGET(item), "clicked", window->accelGroup, GDK_KEY_Home, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
gtk_widget_show(GTK_WIDGET(item));
+ item = gtk_tool_button_new(gtk_image_new_from_icon_name("tab-new", GTK_ICON_SIZE_SMALL_TOOLBAR), NULL);
+ g_signal_connect_swapped(item, "clicked", G_CALLBACK(newTabCallback), window);
+ gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
+ gtk_widget_add_accelerator(GTK_WIDGET(item), "clicked", window->accelGroup, GDK_KEY_T, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+ gtk_widget_show_all(GTK_WIDGET(item));
+
item = gtk_tool_item_new();
gtk_tool_item_set_expand(item, TRUE);
gtk_container_add(GTK_CONTAINER(item), window->uriEntry);
@@ -1081,6 +937,15 @@
gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
gtk_widget_show(toolbar);
+ window->notebook = gtk_notebook_new();
+ g_signal_connect(window->notebook, "switch-page", G_CALLBACK(browserWindowSwitchTab), window);
+ g_signal_connect(window->notebook, "page-added", G_CALLBACK(browserWindowTabAddedOrRemoved), window);
+ g_signal_connect(window->notebook, "page-removed", G_CALLBACK(browserWindowTabAddedOrRemoved), window);
+ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window->notebook), FALSE);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(window->notebook), FALSE);
+ gtk_box_pack_start(GTK_BOX(window->mainBox), window->notebook, TRUE, TRUE, 0);
+ gtk_widget_show(window->notebook);
+
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
}
@@ -1089,69 +954,7 @@
{
BrowserWindow *window = BROWSER_WINDOW(gObject);
- browserWindowUpdateZoomActions(window);
- if (webkit_web_view_is_editable(window->webView)) {
- browserWindowSetupEditorToolbar(window);
- g_signal_connect(webkit_web_view_get_editor_state(window->webView), "notify::typing-attributes", G_CALLBACK(typingAttributesChanged), 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, "close", G_CALLBACK(webViewClose), window);
- g_signal_connect(window->webView, "load-failed", G_CALLBACK(webViewLoadFailed), window);
- g_signal_connect(window->webView, "load-failed-with-tls-errors", G_CALLBACK(webViewLoadFailedWithTLSerrors), 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(window->webView, "enter-fullscreen", G_CALLBACK(webViewEnterFullScreen), window);
- g_signal_connect(window->webView, "leave-fullscreen", G_CALLBACK(webViewLeaveFullScreen), window);
- g_signal_connect(window->webView, "notify::is-loading", G_CALLBACK(webViewIsLoadingChanged), window);
- g_signal_connect(window->webView, "scroll-event", G_CALLBACK(scrollEventCallback), window);
-#if GTK_CHECK_VERSION(3, 12, 0)
- g_signal_connect(window->webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), window);
-#endif
-
- g_signal_connect(webkit_web_view_get_context(window->webView), "download-started", G_CALLBACK(downloadStarted), window);
-
- window->searchBar = BROWSER_SEARCH_BAR(browser_search_bar_new(window->webView));
- browser_search_bar_add_accelerators(window->searchBar, window->accelGroup);
- gtk_box_pack_start(GTK_BOX(window->mainBox), GTK_WIDGET(window->searchBar), FALSE, FALSE, 0);
-
- WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(window->webView);
- g_signal_connect(backForwadlist, "changed", G_CALLBACK(backForwadlistChanged), window);
-
- WebKitWebInspector *inspectorWindow = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(window->webView));
- g_signal_connect(inspectorWindow, "open-window", G_CALLBACK(inspectorWasOpenedInAnotherWindow), window);
- g_signal_connect(inspectorWindow, "closed", G_CALLBACK(inspectorWasClosed), window);
-
- 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));
-
- window->fullScreenMessageLabel = gtk_label_new(NULL);
- gtk_widget_set_halign(window->fullScreenMessageLabel, GTK_ALIGN_CENTER);
- gtk_widget_set_valign(window->fullScreenMessageLabel, GTK_ALIGN_CENTER);
- gtk_widget_set_no_show_all(window->fullScreenMessageLabel, TRUE);
- gtk_overlay_add_overlay(GTK_OVERLAY(overlay), window->fullScreenMessageLabel);
- gtk_widget_show(GTK_WIDGET(window->webView));
-
- if (webkit_web_view_is_editable(window->webView))
- webkit_web_view_load_html(window->webView, "<html></html>", "file:///");
+ G_OBJECT_CLASS(browser_window_parent_class)->constructed(gObject);
}
static void browserWindowSaveSession(BrowserWindow *window)
@@ -1159,7 +962,8 @@
if (!window->sessionFile)
return;
- WebKitWebViewSessionState *state = webkit_web_view_get_session_state(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ WebKitWebViewSessionState *state = webkit_web_view_get_session_state(webView);
GBytes *bytes = webkit_web_view_session_state_serialize(state);
webkit_web_view_session_state_unref(state);
g_file_set_contents(window->sessionFile, g_bytes_get_data(bytes, NULL), g_bytes_get_size(bytes), NULL);
@@ -1170,7 +974,8 @@
{
BrowserWindow *window = BROWSER_WINDOW(widget);
browserWindowSaveSession(window);
- webkit_web_view_try_close(window->webView);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
+ webkit_web_view_try_close(webView);
return TRUE;
}
@@ -1179,29 +984,17 @@
GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
gobjectClass->constructed = browserWindowConstructed;
- gobjectClass->get_property = browserWindowGetProperty;
- gobjectClass->set_property = browserWindowSetProperty;
gobjectClass->finalize = browserWindowFinalize;
GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS(klass);
widgetClass->delete_event = browserWindowDeleteEvent;
-
- 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)
+/* Public API. */
+GtkWidget *browser_window_new(GtkWindow *parent)
{
- g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(view), 0);
-
BrowserWindow *window = BROWSER_WINDOW(g_object_new(BROWSER_TYPE_WINDOW,
- "type", GTK_WINDOW_TOPLEVEL, "view", view, NULL));
+ "type", GTK_WINDOW_TOPLEVEL, NULL));
if (parent) {
window->parentWindow = parent;
@@ -1211,11 +1004,21 @@
return GTK_WIDGET(window);
}
-WebKitWebView *browser_window_get_view(BrowserWindow *window)
+void browser_window_append_view(BrowserWindow *window, WebKitWebView *webView)
{
- g_return_val_if_fail(BROWSER_IS_WINDOW(window), 0);
+ g_return_if_fail(BROWSER_IS_WINDOW(window));
+ g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
- return window->webView;
+ if (window->activeTab && webkit_web_view_is_editable(browser_tab_get_web_view(window->activeTab))) {
+ g_warning("Only one tab is allowed in editable mode");
+ return;
+ }
+
+ GtkWidget *tab = browser_tab_new(webView);
+ browser_tab_add_accelerators(BROWSER_TAB(tab), window->accelGroup);
+ gtk_notebook_append_page(GTK_NOTEBOOK(window->notebook), tab, browser_tab_get_title_widget(BROWSER_TAB(tab)));
+ gtk_container_child_set(GTK_CONTAINER(window->notebook), tab, "tab-expand", TRUE, NULL);
+ gtk_widget_show(tab);
}
void browser_window_load_uri(BrowserWindow *window, const char *uri)
@@ -1223,14 +1026,7 @@
g_return_if_fail(BROWSER_IS_WINDOW(window));
g_return_if_fail(uri);
- if (!g_str_has_prefix(uri, "_javascript_:")) {
- char *internalURI = getInternalURI(uri);
- webkit_web_view_load_uri(window->webView, internalURI);
- g_free(internalURI);
- return;
- }
-
- webkit_web_view_run_javascript(window->webView, strstr(uri, "_javascript_:"), NULL, NULL, NULL);
+ browser_tab_load_uri(window->activeTab, uri);
}
void browser_window_load_session(BrowserWindow *window, const char *sessionFile)
@@ -1238,6 +1034,7 @@
g_return_if_fail(BROWSER_IS_WINDOW(window));
g_return_if_fail(sessionFile);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
window->sessionFile = g_strdup(sessionFile);
gchar *data = ""
gsize dataLength;
@@ -1247,17 +1044,17 @@
g_bytes_unref(bytes);
if (state) {
- webkit_web_view_restore_session_state(window->webView, state);
+ webkit_web_view_restore_session_state(webView, state);
webkit_web_view_session_state_unref(state);
}
}
- WebKitBackForwardList *bfList = webkit_web_view_get_back_forward_list(window->webView);
+ WebKitBackForwardList *bfList = webkit_web_view_get_back_forward_list(webView);
WebKitBackForwardListItem *item = webkit_back_forward_list_get_current_item(bfList);
if (item)
- webkit_web_view_go_to_back_forward_list_item(window->webView, item);
+ webkit_web_view_go_to_back_forward_list_item(webView, item);
else
- webkit_web_view_load_uri(window->webView, BROWSER_DEFAULT_URL);
+ webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL);
}
@@ -1266,8 +1063,9 @@
g_return_if_fail(BROWSER_IS_WINDOW(window));
g_return_if_fail(rgba);
+ WebKitWebView *webView = browser_tab_get_web_view(window->activeTab);
GdkRGBA viewRGBA;
- webkit_web_view_get_background_color(window->webView, &viewRGBA);
+ webkit_web_view_get_background_color(webView, &viewRGBA);
if (gdk_rgba_equal(rgba, &viewRGBA))
return;
@@ -1280,5 +1078,5 @@
gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
}
- webkit_web_view_set_background_color(window->webView, rgba);
+ webkit_web_view_set_background_color(webView, rgba);
}