<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[203271] trunk/Tools</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/203271">203271</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-07-15 02:25:15 -0700 (Fri, 15 Jul 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[GTK] Add basic tabs support to MiniBrowser
https://bugs.webkit.org/show_bug.cgi?id=159803

Reviewed by Sergio Villar Senin.

It's quite common to have issues with web views loaded in secondary tabs, and we need to use an external browser
like epiphany to debug those issues. It would be a lot easier to work on those bugs if we could use the MiniBrowser.

* MiniBrowser/gtk/BrowserTab.c: Added.
(titleChanged):
(isLoadingChanged):
(decidePolicy):
(removeChildIfInfoBar):
(loadChanged):
(createInfoBarQuestionMessage):
(tlsErrorsDialogResponse):
(loadFailedWithTLSerrors):
(permissionRequestDialogResponse):
(decidePermissionRequest):
(colorChooserRGBAChanged):
(popoverColorClosed):
(colorChooserRequestFinished):
(runColorChooserCallback):
(inspectorOpenedInWindow):
(inspectorClosed):
(browserTabSetProperty):
(browserTabFinalize):
(browser_tab_init):
(browserTabConstructed):
(browser_tab_class_init):
(getInternalURI):
(browser_tab_new):
(browser_tab_get_web_view):
(browser_tab_load_uri):
(browser_tab_get_title_widget):
(browser_tab_set_status_text):
(browser_tab_toggle_inspector):
(browser_tab_start_search):
(browser_tab_stop_search):
(browser_tab_add_accelerators):
(fullScreenMessageTimeoutCallback):
(browser_tab_enter_fullscreen):
(browser_tab_leave_fullscreen):
* MiniBrowser/gtk/BrowserTab.h: Added.
* MiniBrowser/gtk/BrowserWindow.c:
(getExternalURI):
(browserWindowSetStatusText):
(reloadOrStopCallback):
(goBackCallback):
(goForwardCallback):
(settingsCallback):
(webViewURIChanged):
(browserWindowHistoryItemActivated):
(browserWindowUpdateNavigationActions):
(webViewCreate):
(webViewEnterFullScreen):
(webViewLeaveFullScreen):
(webViewDecidePolicy):
(browserWindowCanZoomIn):
(browserWindowCanZoomOut):
(browserWindowZoomIn):
(browserWindowZoomOut):
(scrollEventCallback):
(faviconChanged):
(webViewIsLoadingChanged):
(defaultZoomCallback):
(searchCallback):
(newTabCallback):
(toggleWebInspector):
(reloadPage):
(reloadPageIgnoringCache):
(stopPageLoad):
(loadHomePage):
(editingCommandCallback):
(insertImageCommandCallback):
(insertLinkCommandCallback):
(browserWindowSetupEditorToolbar):
(browserWindowSwitchTab):
(browserWindowTabAddedOrRemoved):
(browser_window_init):
(browserWindowConstructed):
(browserWindowSaveSession):
(browserWindowDeleteEvent):
(browser_window_new):
(browser_window_append_view):
(browser_window_load_uri):
(browser_window_load_session):
(browser_window_set_background_color):
(resetStatusText): Deleted.
(activateUriEntryCallback): Deleted.
(webViewTitleChanged): Deleted.
(resetEntryProgress): Deleted.
(browserWindowCreateBackForwardMenu): Deleted.
(webViewReadyToShow): Deleted.
(webViewLoadFailed): Deleted.
(webViewMouseTargetChanged): Deleted.
(browserWindowUpdateZoomActions): Deleted.
(webViewZoomLevelChanged): Deleted.
(updateUriEntryIcon): Deleted.
(zoomInCallback): Deleted.
(zoomOutCallback): Deleted.
(toggleFullScreen): Deleted.
(browserWindowEditingCommandToggleButtonSetActive): Deleted.
(browserWindowFinalize): Deleted.
(browser_window_class_init): Deleted.
* MiniBrowser/gtk/BrowserWindow.h:
* MiniBrowser/gtk/CMakeLists.txt:
* MiniBrowser/gtk/main.c:
(createBrowserTab):
(aboutURISchemeRequestCallback):
(main):
(parseBackgroundColor): Deleted.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsMiniBrowsergtkBrowserWindowc">trunk/Tools/MiniBrowser/gtk/BrowserWindow.c</a></li>
<li><a href="#trunkToolsMiniBrowsergtkBrowserWindowh">trunk/Tools/MiniBrowser/gtk/BrowserWindow.h</a></li>
<li><a href="#trunkToolsMiniBrowsergtkCMakeListstxt">trunk/Tools/MiniBrowser/gtk/CMakeLists.txt</a></li>
<li><a href="#trunkToolsMiniBrowsergtkmainc">trunk/Tools/MiniBrowser/gtk/main.c</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkToolsMiniBrowsergtkBrowserTabc">trunk/Tools/MiniBrowser/gtk/BrowserTab.c</a></li>
<li><a href="#trunkToolsMiniBrowsergtkBrowserTabh">trunk/Tools/MiniBrowser/gtk/BrowserTab.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (203270 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-07-15 06:03:25 UTC (rev 203270)
+++ trunk/Tools/ChangeLog        2016-07-15 09:25:15 UTC (rev 203271)
</span><span class="lines">@@ -1,3 +1,118 @@
</span><ins>+2016-07-15  Carlos Garcia Campos  &lt;cgarcia@igalia.com&gt;
+
+        [GTK] Add basic tabs support to MiniBrowser
+        https://bugs.webkit.org/show_bug.cgi?id=159803
+
+        Reviewed by Sergio Villar Senin.
+
+        It's quite common to have issues with web views loaded in secondary tabs, and we need to use an external browser
+        like epiphany to debug those issues. It would be a lot easier to work on those bugs if we could use the MiniBrowser.
+
+        * MiniBrowser/gtk/BrowserTab.c: Added.
+        (titleChanged):
+        (isLoadingChanged):
+        (decidePolicy):
+        (removeChildIfInfoBar):
+        (loadChanged):
+        (createInfoBarQuestionMessage):
+        (tlsErrorsDialogResponse):
+        (loadFailedWithTLSerrors):
+        (permissionRequestDialogResponse):
+        (decidePermissionRequest):
+        (colorChooserRGBAChanged):
+        (popoverColorClosed):
+        (colorChooserRequestFinished):
+        (runColorChooserCallback):
+        (inspectorOpenedInWindow):
+        (inspectorClosed):
+        (browserTabSetProperty):
+        (browserTabFinalize):
+        (browser_tab_init):
+        (browserTabConstructed):
+        (browser_tab_class_init):
+        (getInternalURI):
+        (browser_tab_new):
+        (browser_tab_get_web_view):
+        (browser_tab_load_uri):
+        (browser_tab_get_title_widget):
+        (browser_tab_set_status_text):
+        (browser_tab_toggle_inspector):
+        (browser_tab_start_search):
+        (browser_tab_stop_search):
+        (browser_tab_add_accelerators):
+        (fullScreenMessageTimeoutCallback):
+        (browser_tab_enter_fullscreen):
+        (browser_tab_leave_fullscreen):
+        * MiniBrowser/gtk/BrowserTab.h: Added.
+        * MiniBrowser/gtk/BrowserWindow.c:
+        (getExternalURI):
+        (browserWindowSetStatusText):
+        (reloadOrStopCallback):
+        (goBackCallback):
+        (goForwardCallback):
+        (settingsCallback):
+        (webViewURIChanged):
+        (browserWindowHistoryItemActivated):
+        (browserWindowUpdateNavigationActions):
+        (webViewCreate):
+        (webViewEnterFullScreen):
+        (webViewLeaveFullScreen):
+        (webViewDecidePolicy):
+        (browserWindowCanZoomIn):
+        (browserWindowCanZoomOut):
+        (browserWindowZoomIn):
+        (browserWindowZoomOut):
+        (scrollEventCallback):
+        (faviconChanged):
+        (webViewIsLoadingChanged):
+        (defaultZoomCallback):
+        (searchCallback):
+        (newTabCallback):
+        (toggleWebInspector):
+        (reloadPage):
+        (reloadPageIgnoringCache):
+        (stopPageLoad):
+        (loadHomePage):
+        (editingCommandCallback):
+        (insertImageCommandCallback):
+        (insertLinkCommandCallback):
+        (browserWindowSetupEditorToolbar):
+        (browserWindowSwitchTab):
+        (browserWindowTabAddedOrRemoved):
+        (browser_window_init):
+        (browserWindowConstructed):
+        (browserWindowSaveSession):
+        (browserWindowDeleteEvent):
+        (browser_window_new):
+        (browser_window_append_view):
+        (browser_window_load_uri):
+        (browser_window_load_session):
+        (browser_window_set_background_color):
+        (resetStatusText): Deleted.
+        (activateUriEntryCallback): Deleted.
+        (webViewTitleChanged): Deleted.
+        (resetEntryProgress): Deleted.
+        (browserWindowCreateBackForwardMenu): Deleted.
+        (webViewReadyToShow): Deleted.
+        (webViewLoadFailed): Deleted.
+        (webViewMouseTargetChanged): Deleted.
+        (browserWindowUpdateZoomActions): Deleted.
+        (webViewZoomLevelChanged): Deleted.
+        (updateUriEntryIcon): Deleted.
+        (zoomInCallback): Deleted.
+        (zoomOutCallback): Deleted.
+        (toggleFullScreen): Deleted.
+        (browserWindowEditingCommandToggleButtonSetActive): Deleted.
+        (browserWindowFinalize): Deleted.
+        (browser_window_class_init): Deleted.
+        * MiniBrowser/gtk/BrowserWindow.h:
+        * MiniBrowser/gtk/CMakeLists.txt:
+        * MiniBrowser/gtk/main.c:
+        (createBrowserTab):
+        (aboutURISchemeRequestCallback):
+        (main):
+        (parseBackgroundColor): Deleted.
+
</ins><span class="cx"> 2016-07-14  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Allow RefPtrs of const RefCounted types
</span></span></pre></div>
<a id="trunkToolsMiniBrowsergtkBrowserTabc"></a>
<div class="addfile"><h4>Added: trunk/Tools/MiniBrowser/gtk/BrowserTab.c (0 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/gtk/BrowserTab.c                                (rev 0)
+++ trunk/Tools/MiniBrowser/gtk/BrowserTab.c        2016-07-15 09:25:15 UTC (rev 203271)
</span><span class="lines">@@ -0,0 +1,550 @@
</span><ins>+/*
+ * 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) &amp;&amp; HAVE_CONFIG_H &amp;&amp; defined(BUILDING_WITH_CMAKE)
+#include &quot;cmakeconfig.h&quot;
+#endif
+#include &quot;BrowserTab.h&quot;
+
+#include &quot;BrowserSearchBar.h&quot;
+#include &quot;BrowserWindow.h&quot;
+#include &lt;string.h&gt;
+
+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 &amp;&amp; *title)
+        gtk_label_set_text(GTK_LABEL(tab-&gt;titleLabel), title);
+}
+
+static void isLoadingChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserTab *tab)
+{
+    if (webkit_web_view_is_loading(webView)) {
+        gtk_spinner_start(GTK_SPINNER(tab-&gt;titleSpinner));
+        gtk_widget_show(tab-&gt;titleSpinner);
+    } else {
+        gtk_spinner_stop(GTK_SPINNER(tab-&gt;titleSpinner));
+        gtk_widget_hide(tab-&gt;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(&quot;No&quot;, GTK_RESPONSE_NO, &quot;Yes&quot;, 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(&quot;&lt;span size='xx-large' weight='bold'&gt;%s&lt;/span&gt;&quot;, 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), &quot;failingURI&quot;);
+        GTlsCertificate *certificate = (GTlsCertificate *)g_object_get_data(G_OBJECT(dialog), &quot;certificate&quot;);
+        SoupURI *uri = soup_uri_new(failingURI);
+        webkit_web_context_allow_tls_certificate_for_host(webkit_web_view_get_context(tab-&gt;webView), certificate, uri-&gt;host);
+        soup_uri_free(uri);
+        webkit_web_view_load_uri(tab-&gt;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(&quot;Failed to load %s: Do you want to continue ignoring the TLS errors?&quot;, failingURI);
+    GtkWidget *dialog = createInfoBarQuestionMessage(&quot;Invalid TLS Certificate&quot;, text);
+    g_free(text);
+    g_object_set_data_full(G_OBJECT(dialog), &quot;failingURI&quot;, g_strdup(failingURI), g_free);
+    g_object_set_data_full(G_OBJECT(dialog), &quot;certificate&quot;, g_object_ref(certificate), g_object_unref);
+
+    g_signal_connect(dialog, &quot;response&quot;, 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 = &quot;Geolocation request&quot;;
+        text = g_strdup(&quot;Allow geolocation request?&quot;);
+    } else if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)) {
+        title = &quot;Notification request&quot;;
+        text = g_strdup(&quot;Allow notifications request?&quot;);
+    } else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)) {
+        title = &quot;UserMedia request&quot;;
+        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 = &quot;audio/video&quot;;
+            else
+                mediaType = &quot;audio&quot;;
+        } else if (is_for_video_device)
+            mediaType = &quot;video&quot;;
+        text = g_strdup_printf(&quot;Allow access to %s device?&quot;, mediaType);
+    } else if (WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)) {
+        title = &quot;Media plugin missing request&quot;;
+        text = g_strdup_printf(&quot;The media backend was unable to find a plugin to play the requested media:\n%s.\nAllow to search and install the missing plugin?&quot;,
+            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, &quot;response&quot;, 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, &amp;rgba);
+    webkit_color_chooser_request_set_rgba(request, &amp;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, &amp;rectangle);
+    gtk_popover_set_pointing_to(GTK_POPOVER(popover), &amp;rectangle);
+
+    GtkWidget *colorChooser = gtk_color_chooser_widget_new();
+    GdkRGBA rgba;
+    webkit_color_chooser_request_get_rgba(request, &amp;rgba);
+    gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(colorChooser), &amp;rgba);
+    g_signal_connect(colorChooser, &quot;notify::rgba&quot;, G_CALLBACK(colorChooserRGBAChanged), request);
+    gtk_container_add(GTK_CONTAINER(popover), colorChooser);
+    gtk_widget_show(colorChooser);
+
+    g_object_ref(request);
+    g_signal_connect_object(popover, &quot;hide&quot;, G_CALLBACK(popoverColorClosed), request, 0);
+    g_signal_connect_object(request, &quot;finished&quot;, 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-&gt;inspectorIsVisible = TRUE;
+    return FALSE;
+}
+
+static gboolean inspectorClosed(WebKitWebInspector *inspector, BrowserTab *tab)
+{
+    tab-&gt;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-&gt;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-&gt;fullScreenMessageLabelId)
+        g_source_remove(tab-&gt;fullScreenMessageLabelId);
+
+    G_OBJECT_CLASS(browser_tab_parent_class)-&gt;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)-&gt;constructed(gObject);
+
+    tab-&gt;searchBar = BROWSER_SEARCH_BAR(browser_search_bar_new(tab-&gt;webView));
+    gtk_box_pack_start(GTK_BOX(tab), GTK_WIDGET(tab-&gt;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-&gt;statusLabel = gtk_label_new(NULL);
+    gtk_widget_set_halign(tab-&gt;statusLabel, GTK_ALIGN_START);
+    gtk_widget_set_valign(tab-&gt;statusLabel, GTK_ALIGN_END);
+    gtk_widget_set_margin_left(tab-&gt;statusLabel, 1);
+    gtk_widget_set_margin_right(tab-&gt;statusLabel, 1);
+    gtk_widget_set_margin_top(tab-&gt;statusLabel, 1);
+    gtk_widget_set_margin_bottom(tab-&gt;statusLabel, 1);
+    gtk_overlay_add_overlay(GTK_OVERLAY(overlay), tab-&gt;statusLabel);
+
+    tab-&gt;fullScreenMessageLabel = gtk_label_new(NULL);
+    gtk_widget_set_halign(tab-&gt;fullScreenMessageLabel, GTK_ALIGN_CENTER);
+    gtk_widget_set_valign(tab-&gt;fullScreenMessageLabel, GTK_ALIGN_CENTER);
+    gtk_widget_set_no_show_all(tab-&gt;fullScreenMessageLabel, TRUE);
+    gtk_overlay_add_overlay(GTK_OVERLAY(overlay), tab-&gt;fullScreenMessageLabel);
+
+    gtk_container_add(GTK_CONTAINER(overlay), GTK_WIDGET(tab-&gt;webView));
+    gtk_widget_show(GTK_WIDGET(tab-&gt;webView));
+
+    tab-&gt;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-&gt;titleSpinner = gtk_spinner_new();
+    gtk_box_pack_start(GTK_BOX(hbox), tab-&gt;titleSpinner, FALSE, FALSE, 0);
+
+    tab-&gt;titleLabel = gtk_label_new(NULL);
+    gtk_label_set_ellipsize(GTK_LABEL(tab-&gt;titleLabel), PANGO_ELLIPSIZE_END);
+    gtk_label_set_single_line_mode(GTK_LABEL(tab-&gt;titleLabel), TRUE);
+    gtk_misc_set_padding(GTK_MISC(tab-&gt;titleLabel), 0, 0);
+    gtk_box_pack_start(GTK_BOX(hbox), tab-&gt;titleLabel, FALSE, FALSE, 0);
+    gtk_widget_show(tab-&gt;titleLabel);
+
+    gtk_box_pack_start(GTK_BOX(tab-&gt;titleBox), hbox, TRUE, TRUE, 0);
+    gtk_widget_show(hbox);
+
+    tab-&gt;titleCloseButton = gtk_button_new();
+    g_signal_connect_swapped(tab-&gt;titleCloseButton, &quot;clicked&quot;, G_CALLBACK(gtk_widget_destroy), tab);
+    gtk_button_set_relief(GTK_BUTTON(tab-&gt;titleCloseButton), GTK_RELIEF_NONE);
+    gtk_button_set_focus_on_click(GTK_BUTTON(tab-&gt;titleCloseButton), FALSE);
+
+    GtkWidget *image = gtk_image_new_from_icon_name(&quot;window-close-symbolic&quot;, GTK_ICON_SIZE_MENU);
+    gtk_container_add(GTK_CONTAINER(tab-&gt;titleCloseButton), image);
+    gtk_widget_show(image);
+
+    gtk_box_pack_start(GTK_BOX(tab-&gt;titleBox), tab-&gt;titleCloseButton, FALSE, FALSE, 0);
+    gtk_widget_show(tab-&gt;titleCloseButton);
+
+    g_signal_connect(tab-&gt;webView, &quot;notify::title&quot;, G_CALLBACK(titleChanged), tab);
+    g_signal_connect(tab-&gt;webView, &quot;notify::is-loading&quot;, G_CALLBACK(isLoadingChanged), tab);
+    g_signal_connect(tab-&gt;webView, &quot;decide-policy&quot;, G_CALLBACK(decidePolicy), tab);
+    g_signal_connect(tab-&gt;webView, &quot;load-changed&quot;, G_CALLBACK(loadChanged), tab);
+    g_signal_connect(tab-&gt;webView, &quot;load-failed-with-tls-errors&quot;, G_CALLBACK(loadFailedWithTLSerrors), tab);
+    g_signal_connect(tab-&gt;webView, &quot;permission-request&quot;, G_CALLBACK(decidePermissionRequest), tab);
+#if GTK_CHECK_VERSION(3, 12, 0)
+    g_signal_connect(tab-&gt;webView, &quot;run-color-chooser&quot;, G_CALLBACK(runColorChooserCallback), tab);
+#endif
+
+    WebKitWebInspector *inspector = webkit_web_view_get_inspector(tab-&gt;webView);
+    g_signal_connect(inspector, &quot;open-window&quot;, G_CALLBACK(inspectorOpenedInWindow), tab);
+    g_signal_connect(inspector, &quot;closed&quot;, G_CALLBACK(inspectorClosed), tab);
+
+    if (webkit_web_view_is_editable(tab-&gt;webView))
+        webkit_web_view_load_html(tab-&gt;webView, &quot;&lt;html&gt;&lt;/html&gt;&quot;, &quot;file:///&quot;);
+}
+
+static void browser_tab_class_init(BrowserTabClass *klass)
+{
+    GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
+    gobjectClass-&gt;constructed = browserTabConstructed;
+    gobjectClass-&gt;set_property = browserTabSetProperty;
+    gobjectClass-&gt;finalize = browserTabFinalize;
+
+    g_object_class_install_property(
+        gobjectClass,
+        PROP_VIEW,
+        g_param_spec_object(
+            &quot;view&quot;,
+            &quot;View&quot;,
+            &quot;The web view of this tab&quot;,
+            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, &quot;about:&quot;) &amp;&amp; !g_str_equal(uri, &quot;about:blank&quot;))
+        return g_strconcat(BROWSER_ABOUT_SCHEME, uri + strlen (&quot;about&quot;), 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, &quot;view&quot;, view, NULL));
+}
+
+WebKitWebView *browser_tab_get_web_view(BrowserTab *tab)
+{
+    g_return_val_if_fail(BROWSER_IS_TAB(tab), NULL);
+
+    return tab-&gt;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, &quot;javascript:&quot;)) {
+        char *internalURI = getInternalURI(uri);
+        webkit_web_view_load_uri(tab-&gt;webView, internalURI);
+        g_free(internalURI);
+        return;
+    }
+
+    webkit_web_view_run_javascript(tab-&gt;webView, strstr(uri, &quot;javascript:&quot;), NULL, NULL, NULL);
+}
+
+GtkWidget *browser_tab_get_title_widget(BrowserTab *tab)
+{
+    g_return_val_if_fail(BROWSER_IS_TAB(tab), NULL);
+
+    return tab-&gt;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-&gt;statusLabel), text);
+    gtk_widget_set_visible(tab-&gt;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-&gt;webView);
+    if (!tab-&gt;inspectorIsVisible) {
+        webkit_web_inspector_show(inspector);
+        tab-&gt;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-&gt;searchBar)))
+        browser_search_bar_open(tab-&gt;searchBar);
+}
+
+void browser_tab_stop_search(BrowserTab *tab)
+{
+    g_return_if_fail(BROWSER_IS_TAB(tab));
+
+    if (gtk_widget_get_visible(GTK_WIDGET(tab-&gt;searchBar)))
+        browser_search_bar_close(tab-&gt;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-&gt;searchBar, accelGroup);
+}
+
+static gboolean fullScreenMessageTimeoutCallback(BrowserTab *tab)
+{
+    gtk_widget_hide(tab-&gt;fullScreenMessageLabel);
+    tab-&gt;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-&gt;webView);
+    if (!titleOrURI || !titleOrURI[0])
+        titleOrURI = webkit_web_view_get_uri(tab-&gt;webView);
+
+    gchar *message = g_strdup_printf(&quot;%s is now full screen. Press ESC or f to exit.&quot;, titleOrURI);
+    gtk_label_set_text(GTK_LABEL(tab-&gt;fullScreenMessageLabel), message);
+    g_free(message);
+
+    gtk_widget_show(tab-&gt;fullScreenMessageLabel);
+
+    tab-&gt;fullScreenMessageLabelId = g_timeout_add_seconds(2, (GSourceFunc)fullScreenMessageTimeoutCallback, tab);
+    g_source_set_name_by_id(tab-&gt;fullScreenMessageLabelId, &quot;[WebKit] fullScreenMessageTimeoutCallback&quot;);
+
+    tab-&gt;wasSearchingWhenEnteredFullscreen = gtk_widget_get_visible(GTK_WIDGET(tab-&gt;searchBar));
+    browser_tab_stop_search(tab);
+}
+
+void browser_tab_leave_fullscreen(BrowserTab *tab)
+{
+    g_return_if_fail(BROWSER_IS_TAB(tab));
+
+    if (tab-&gt;fullScreenMessageLabelId) {
+        g_source_remove(tab-&gt;fullScreenMessageLabelId);
+        tab-&gt;fullScreenMessageLabelId = 0;
+    }
+
+    gtk_widget_hide(tab-&gt;fullScreenMessageLabel);
+
+    if (tab-&gt;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);
+    }
+}
</ins></span></pre></div>
<a id="trunkToolsMiniBrowsergtkBrowserTabhfromrev203270trunkToolsMiniBrowsergtkBrowserWindowh"></a>
<div class="copfile"><h4>Copied: trunk/Tools/MiniBrowser/gtk/BrowserTab.h (from rev 203270, trunk/Tools/MiniBrowser/gtk/BrowserWindow.h) (0 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/gtk/BrowserTab.h                                (rev 0)
+++ trunk/Tools/MiniBrowser/gtk/BrowserTab.h        2016-07-15 09:25:15 UTC (rev 203271)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+/*
+ * 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.
+ */
+
+#ifndef BrowserTab_h
+#define BrowserTab_h
+
+#include &lt;gtk/gtk.h&gt;
+#include &lt;webkit2/webkit2.h&gt;
+
+G_BEGIN_DECLS
+
+#define BROWSER_TYPE_TAB            (browser_tab_get_type())
+#define BROWSER_TAB(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), BROWSER_TYPE_TAB, BrowserTab))
+#define BROWSER_TAB_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  BROWSER_TYPE_TAB, BrowserTabClass))
+#define BROWSER_IS_TAB(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), BROWSER_TYPE_TAB))
+#define BROWSER_IS_TAB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  BROWSER_TYPE_TAB))
+#define BROWSER_TAB_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  BROWSER_TYPE_TAB, BrowserTabClass))
+
+typedef struct _BrowserTab        BrowserTab;
+typedef struct _BrowserTabClass   BrowserTabClass;
+
+GType browser_tab_get_type(void);
+
+GtkWidget* browser_tab_new(WebKitWebView*);
+WebKitWebView* browser_tab_get_web_view(BrowserTab*);
+void browser_tab_load_uri(BrowserTab*, const char* uri);
+GtkWidget *browser_tab_get_title_widget(BrowserTab*);
+void browser_tab_set_status_text(BrowserTab*, const char* text);
+void browser_tab_toggle_inspector(BrowserTab*);
+void browser_tab_start_search(BrowserTab*);
+void browser_tab_stop_search(BrowserTab*);
+void browser_tab_add_accelerators(BrowserTab*, GtkAccelGroup*);
+void browser_tab_enter_fullscreen(BrowserTab*);
+void browser_tab_leave_fullscreen(BrowserTab*);
+
+G_END_DECLS
+
+#endif
</ins></span></pre></div>
<a id="trunkToolsMiniBrowsergtkBrowserWindowc"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/gtk/BrowserWindow.c (203270 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -33,15 +33,10 @@
</span><span class="cx"> #include &quot;BrowserDownloadsBar.h&quot;
</span><span class="cx"> #include &quot;BrowserSearchBar.h&quot;
</span><span class="cx"> #include &quot;BrowserSettingsDialog.h&quot;
</span><ins>+#include &quot;BrowserTab.h&quot;
</ins><span class="cx"> #include &lt;gdk/gdkkeysyms.h&gt;
</span><span class="cx"> #include &lt;string.h&gt;
</span><span class="cx"> 
</span><del>-enum {
-    PROP_0,
-
-    PROP_VIEW
-};
-
</del><span class="cx"> struct _BrowserWindow {
</span><span class="cx">     GtkWindow parent;
</span><span class="cx"> 
</span><span class="lines">@@ -57,19 +52,15 @@
</span><span class="cx">     GtkWidget *italicItem;
</span><span class="cx">     GtkWidget *underlineItem;
</span><span class="cx">     GtkWidget *strikethroughItem;
</span><del>-    GtkWidget *statusLabel;
</del><span class="cx">     GtkWidget *settingsDialog;
</span><del>-    WebKitWebView *webView;
</del><ins>+    GtkWidget *notebook;
+    BrowserTab *activeTab;
</ins><span class="cx">     GtkWidget *downloadsBar;
</span><del>-    BrowserSearchBar *searchBar;
</del><span class="cx">     gboolean searchBarVisible;
</span><del>-    gboolean inspectorWindowIsVisible;
</del><span class="cx">     gboolean fullScreenIsEnabled;
</span><span class="cx">     GdkPixbuf *favicon;
</span><span class="cx">     GtkWidget *reloadOrStopButton;
</span><del>-    GtkWidget *fullScreenMessageLabel;
</del><span class="cx">     GtkWindow *parentWindow;
</span><del>-    guint fullScreenMessageLabelId;
</del><span class="cx">     guint resetEntryProgressTimeoutId;
</span><span class="cx">     gchar *sessionFile;
</span><span class="cx"> };
</span><span class="lines">@@ -79,7 +70,6 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static const char *defaultWindowTitle = &quot;WebKitGTK+ MiniBrowser&quot;;
</span><del>-static const char *miniBrowserAboutScheme = &quot;minibrowser-about&quot;;
</del><span class="cx"> static const gdouble minimumZoomLevel = 0.5;
</span><span class="cx"> static const gdouble maximumZoomLevel = 3;
</span><span class="cx"> static const gdouble defaultZoomLevel = 1;
</span><span class="lines">@@ -88,20 +78,11 @@
</span><span class="cx"> 
</span><span class="cx"> G_DEFINE_TYPE(BrowserWindow, browser_window, GTK_TYPE_WINDOW)
</span><span class="cx"> 
</span><del>-static char *getInternalURI(const char *uri)
-{
-    // Internally we use minibrowser-about: as about: prefix is ignored by WebKit.
-    if (g_str_has_prefix(uri, &quot;about:&quot;) &amp;&amp; !g_str_equal(uri, &quot;about:blank&quot;))
-        return g_strconcat(miniBrowserAboutScheme, uri + strlen (&quot;about&quot;), NULL);
-
-    return g_strdup(uri);
-}
-
</del><span class="cx"> static char *getExternalURI(const char *uri)
</span><span class="cx"> {
</span><del>-    // From the user point of view we support about: prefix.
-    if (g_str_has_prefix(uri, miniBrowserAboutScheme))
-        return g_strconcat(&quot;about&quot;, uri + strlen(miniBrowserAboutScheme), NULL);
</del><ins>+    /* From the user point of view we support about: prefix. */
+    if (uri &amp;&amp; g_str_has_prefix(uri, BROWSER_ABOUT_SCHEME))
+        return g_strconcat(&quot;about&quot;, uri + strlen(BROWSER_ABOUT_SCHEME), NULL);
</ins><span class="cx"> 
</span><span class="cx">     return g_strdup(uri);
</span><span class="cx"> }
</span><span class="lines">@@ -108,8 +89,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void browserWindowSetStatusText(BrowserWindow *window, const char *text)
</span><span class="cx"> {
</span><del>-    gtk_label_set_text(GTK_LABEL(window-&gt;statusLabel), text);
-    gtk_widget_set_visible(window-&gt;statusLabel, !!text);
</del><ins>+    browser_tab_set_status_text(window-&gt;activeTab, text);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void resetStatusText(GtkWidget *widget, BrowserWindow *window)
</span><span class="lines">@@ -124,20 +104,23 @@
</span><span class="cx"> 
</span><span class="cx"> static void reloadOrStopCallback(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    if (webkit_web_view_is_loading(window-&gt;webView))
-        webkit_web_view_stop_loading(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    if (webkit_web_view_is_loading(webView))
+        webkit_web_view_stop_loading(webView);
</ins><span class="cx">     else
</span><del>-        webkit_web_view_reload(window-&gt;webView);
</del><ins>+        webkit_web_view_reload(webView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void goBackCallback(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    webkit_web_view_go_back(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_go_back(webView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void goForwardCallback(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    webkit_web_view_go_forward(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_go_forward(webView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void settingsCallback(BrowserWindow *window)
</span><span class="lines">@@ -147,7 +130,8 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    window-&gt;settingsDialog = browser_settings_dialog_new(webkit_web_view_get_settings(window-&gt;webView));
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    window-&gt;settingsDialog = browser_settings_dialog_new(webkit_web_view_get_settings(webView));
</ins><span class="cx">     gtk_window_set_transient_for(GTK_WINDOW(window-&gt;settingsDialog), GTK_WINDOW(window));
</span><span class="cx">     g_object_add_weak_pointer(G_OBJECT(window-&gt;settingsDialog), (gpointer *)&amp;window-&gt;settingsDialog);
</span><span class="cx">     gtk_widget_show(window-&gt;settingsDialog);
</span><span class="lines">@@ -156,8 +140,11 @@
</span><span class="cx"> static void webViewURIChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     char *externalURI = getExternalURI(webkit_web_view_get_uri(webView));
</span><del>-    gtk_entry_set_text(GTK_ENTRY(window-&gt;uriEntry), externalURI);
-    g_free(externalURI);
</del><ins>+    if (externalURI) {
+        gtk_entry_set_text(GTK_ENTRY(window-&gt;uriEntry), externalURI);
+        g_free(externalURI);
+    } else
+        gtk_entry_set_text(GTK_ENTRY(window-&gt;uriEntry), &quot;&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void webViewTitleChanged(WebKitWebView *webView, GParamSpec *pspec, BrowserWindow *window)
</span><span class="lines">@@ -207,7 +194,8 @@
</span><span class="cx">     if (!item)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    webkit_web_view_go_to_back_forward_list_item(window-&gt;webView, item);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_go_to_back_forward_list_item(webView, item);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static GtkWidget *browserWindowCreateBackForwardMenu(BrowserWindow *window, GList *list)
</span><span class="lines">@@ -241,8 +229,9 @@
</span><span class="cx"> 
</span><span class="cx"> static void browserWindowUpdateNavigationActions(BrowserWindow *window, WebKitBackForwardList *backForwadlist)
</span><span class="cx"> {
</span><del>-    gtk_widget_set_sensitive(window-&gt;backItem, webkit_web_view_can_go_back(window-&gt;webView));
-    gtk_widget_set_sensitive(window-&gt;forwardItem, webkit_web_view_can_go_forward(window-&gt;webView));
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    gtk_widget_set_sensitive(window-&gt;backItem, webkit_web_view_can_go_back(webView));
+    gtk_widget_set_sensitive(window-&gt;forwardItem, webkit_web_view_can_go_forward(webView));
</ins><span class="cx"> 
</span><span class="cx">     GList *list = g_list_reverse(webkit_back_forward_list_get_back_list_with_limit(backForwadlist, 10));
</span><span class="cx">     gtk_menu_tool_button_set_menu(GTK_MENU_TOOL_BUTTON(window-&gt;backItem),
</span><span class="lines">@@ -260,21 +249,6 @@
</span><span class="cx">     browserWindowUpdateNavigationActions(window, backForwadlist);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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);
-}
-
</del><span class="cx"> static void webViewClose(WebKitWebView *webView, BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     gtk_widget_destroy(GTK_WIDGET(window));
</span><span class="lines">@@ -308,65 +282,33 @@
</span><span class="cx">     gtk_widget_show(GTK_WIDGET(window));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static gboolean fullScreenMessageTimeoutCallback(BrowserWindow *window)
</del><ins>+static GtkWidget *webViewCreate(WebKitWebView *webView, WebKitNavigationAction *navigation, BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    gtk_widget_hide(window-&gt;fullScreenMessageLabel);
-    window-&gt;fullScreenMessageLabelId = 0;
-    return FALSE;
</del><ins>+    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, &quot;ready-to-show&quot;, G_CALLBACK(webViewReadyToShow), newWindow);
+    g_signal_connect(newWebView, &quot;run-as-modal&quot;, G_CALLBACK(webViewRunAsModal), newWindow);
+    g_signal_connect(newWebView, &quot;close&quot;, G_CALLBACK(webViewClose), newWindow);
+    return GTK_WIDGET(newWebView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static gboolean webViewEnterFullScreen(WebKitWebView *webView, BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    gchar *titleOrURI = g_strdup(webkit_web_view_get_title(window-&gt;webView));
-    if (!titleOrURI)
-        titleOrURI = getExternalURI(webkit_web_view_get_uri(window-&gt;webView));
-    gchar *message = g_strdup_printf(&quot;%s is now full screen. Press ESC or f to exit.&quot;, titleOrURI);
-    gtk_label_set_text(GTK_LABEL(window-&gt;fullScreenMessageLabel), message);
-    g_free(titleOrURI);
-    g_free(message);
-
-    gtk_widget_show(window-&gt;fullScreenMessageLabel);
-
-    window-&gt;fullScreenMessageLabelId = g_timeout_add_seconds(2, (GSourceFunc)fullScreenMessageTimeoutCallback, window);
-    g_source_set_name_by_id(window-&gt;fullScreenMessageLabelId, &quot;[WebKit] fullScreenMessageTimeoutCallback&quot;);
</del><span class="cx">     gtk_widget_hide(window-&gt;toolbar);
</span><del>-    window-&gt;searchBarVisible = gtk_widget_get_visible(GTK_WIDGET(window-&gt;searchBar));
-    browser_search_bar_close(window-&gt;searchBar);
-
</del><ins>+    browser_tab_enter_fullscreen(window-&gt;activeTab);
</ins><span class="cx">     return FALSE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static gboolean webViewLeaveFullScreen(WebKitWebView *webView, BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    if (window-&gt;fullScreenMessageLabelId) {
-        g_source_remove(window-&gt;fullScreenMessageLabelId);
-        window-&gt;fullScreenMessageLabelId = 0;
-    }
-    gtk_widget_hide(window-&gt;fullScreenMessageLabel);
</del><ins>+    browser_tab_leave_fullscreen(window-&gt;activeTab);
</ins><span class="cx">     gtk_widget_show(window-&gt;toolbar);
</span><del>-    if (window-&gt;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-&gt;searchBar);
-        gtk_window_set_focus(GTK_WINDOW(window), focusWidget);
-    }
-
</del><span class="cx">     return FALSE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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, &quot;ready-to-show&quot;, G_CALLBACK(webViewReadyToShow), newWindow);
-    g_signal_connect(newWebView, &quot;run-as-modal&quot;, G_CALLBACK(webViewRunAsModal), newWindow);
-    g_signal_connect(newWebView, &quot;close&quot;, G_CALLBACK(webViewClose), newWindow);
-    return GTK_WIDGET(newWebView);
-}
-
</del><span class="cx"> static gboolean webViewLoadFailed(WebKitWebView *webView, WebKitLoadEvent loadEvent, const char *failingURI, GError *error, BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     gtk_entry_set_progress_fraction(GTK_ENTRY(window-&gt;uriEntry), 0.);
</span><span class="lines">@@ -373,104 +315,26 @@
</span><span class="cx">     return FALSE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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, &quot;%s&quot;, &quot;Invalid TLS Certificate&quot;);
-    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), &quot;Failed to load %s: Do you want to continue ignoring the TLS errors?&quot;, 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-&gt;host);
-        soup_uri_free(uri);
-        webkit_web_view_load_uri(webView, failingURI);
-    }
-
-    return TRUE;
-}
-
</del><span class="cx"> static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    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;
</del><ins>+    if (decisionType != WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION)
+        return FALSE;
</ins><span class="cx"> 
</span><del>-        // 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:
</del><ins>+    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)
</ins><span class="cx">         return FALSE;
</span><del>-    }
-}
</del><span class="cx"> 
</span><del>-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 = &quot;Geolocation request&quot;;
-        dialog_message_format = &quot;%s&quot;;
-        dialog_message = &quot;Allow geolocation request?&quot;;
-    } else if (WEBKIT_IS_NOTIFICATION_PERMISSION_REQUEST(request)) {
-        dialog_title = &quot;Notification request&quot;;
-        dialog_message_format = &quot;%s&quot;;
-        dialog_message = &quot;Allow notifications request?&quot;;
-    } else if (WEBKIT_IS_USER_MEDIA_PERMISSION_REQUEST(request)) {
-        dialog_message_format = &quot;Allow access to %s device?&quot;;
-        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 = &quot;UserMedia request&quot;;
-        if (is_for_audio_device) {
-            if (is_for_video_device)
-                dialog_message = &quot;audio/video&quot;;
-            else
-                dialog_message = &quot;audio&quot;;
-        } else if (is_for_video_device)
-            dialog_message = &quot;video&quot;;
-    } else if (WEBKIT_IS_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request)) {
-        dialog_title = &quot;Media plugin missing request&quot;;
-        dialog_message_format = &quot;The media backend was unable to find a plugin to play the requested media:\n%s.\nAllow to search and install the missing plugin?&quot;;
-        dialog_message = webkit_install_missing_media_plugins_permission_request_get_description(WEBKIT_INSTALL_MISSING_MEDIA_PLUGINS_PERMISSION_REQUEST(request));
-    } else
</del><ins>+    /* Multiple tabs are not allowed in editor mode. */
+    if (webkit_web_view_is_editable(webView))
</ins><span class="cx">         return FALSE;
</span><span class="cx"> 
</span><del>-    GtkWidget *dialog = gtk_message_dialog_new(GTK_WINDOW(window),
-        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
-        GTK_MESSAGE_QUESTION,
-        GTK_BUTTONS_YES_NO,
-        &quot;%s&quot;, dialog_title);
</del><ins>+    /* 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));
</ins><span class="cx"> 
</span><del>-    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), dialog_message_format, dialog_message);
-    g_signal_connect(dialog, &quot;response&quot;, G_CALLBACK(permissionRequestDialogCallback), g_object_ref(request));
-    gtk_widget_show(dialog);
</del><ins>+    webkit_policy_decision_ignore(decision);
</ins><span class="cx">     return TRUE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -485,13 +349,15 @@
</span><span class="cx"> 
</span><span class="cx"> static gboolean browserWindowCanZoomIn(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    gdouble zoomLevel = webkit_web_view_get_zoom_level(window-&gt;webView) * zoomStep;
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) * zoomStep;
</ins><span class="cx">     return zoomLevel &lt; maximumZoomLevel;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static gboolean browserWindowCanZoomOut(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    gdouble zoomLevel = webkit_web_view_get_zoom_level(window-&gt;webView) / zoomStep;
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) / zoomStep;
</ins><span class="cx">     return zoomLevel &gt; minimumZoomLevel;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -498,8 +364,9 @@
</span><span class="cx"> static gboolean browserWindowZoomIn(BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     if (browserWindowCanZoomIn(window)) {
</span><del>-        gdouble zoomLevel = webkit_web_view_get_zoom_level(window-&gt;webView) * zoomStep;
-        webkit_web_view_set_zoom_level(window-&gt;webView, zoomLevel);
</del><ins>+        WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+        gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) * zoomStep;
+        webkit_web_view_set_zoom_level(webView, zoomLevel);
</ins><span class="cx">         return TRUE;
</span><span class="cx">     }
</span><span class="cx">     return FALSE;
</span><span class="lines">@@ -508,8 +375,9 @@
</span><span class="cx"> static gboolean browserWindowZoomOut(BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     if (browserWindowCanZoomOut(window)) {
</span><del>-        gdouble zoomLevel = webkit_web_view_get_zoom_level(window-&gt;webView) / zoomStep;
-        webkit_web_view_set_zoom_level(window-&gt;webView, zoomLevel);
</del><ins>+        WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+        gdouble zoomLevel = webkit_web_view_get_zoom_level(webView) / zoomStep;
+        webkit_web_view_set_zoom_level(webView, zoomLevel);
</ins><span class="cx">         return TRUE;
</span><span class="cx">     }
</span><span class="cx">     return FALSE;
</span><span class="lines">@@ -521,58 +389,13 @@
</span><span class="cx"> 
</span><span class="cx">     if ((event-&gt;state &amp; mod) != GDK_CONTROL_MASK)
</span><span class="cx">         return FALSE;
</span><del>-    
</del><ins>+
</ins><span class="cx">     if (event-&gt;delta_y &lt; 0)
</span><span class="cx">         return browserWindowZoomIn(window);
</span><del>-    
</del><ins>+
</ins><span class="cx">     return browserWindowZoomOut(window);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-#if GTK_CHECK_VERSION(3, 12, 0)
-static void colorChooserRGBAChanged(GtkColorChooser *colorChooser, GParamSpec *paramSpec, WebKitColorChooserRequest *request)
-{
-    GdkRGBA rgba;
-    gtk_color_chooser_get_rgba(colorChooser, &amp;rgba);
-    webkit_color_chooser_request_set_rgba(request, &amp;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, &amp;rectangle);
-    gtk_popover_set_pointing_to(GTK_POPOVER(popover), &amp;rectangle);
-
-    GtkWidget *colorChooser = gtk_color_chooser_widget_new();
-    GdkRGBA rgba;
-    webkit_color_chooser_request_get_rgba(request, &amp;rgba);
-    gtk_color_chooser_set_rgba(GTK_COLOR_CHOOSER(colorChooser), &amp;rgba);
-    g_signal_connect(colorChooser, &quot;notify::rgba&quot;, G_CALLBACK(colorChooserRGBAChanged), request);
-    gtk_container_add(GTK_CONTAINER(popover), colorChooser);
-    gtk_widget_show(colorChooser);
-
-    g_object_ref(request);
-    g_signal_connect_object(popover, &quot;hide&quot;, G_CALLBACK(popoverColorClosed), request, 0);
-    g_signal_connect_object(request, &quot;finished&quot;, G_CALLBACK(colorChooserRequestFinished), popover, 0);
-
-    gtk_widget_show(popover);
-
-    return TRUE;
-}
-#endif /* GTK_CHECK_VERSION(3, 12, 0) */
-
</del><span class="cx"> static void browserWindowUpdateZoomActions(BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     gtk_widget_set_sensitive(window-&gt;zoomInItem, browserWindowCanZoomIn(window));
</span><span class="lines">@@ -593,10 +416,10 @@
</span><span class="cx">         gtk_entry_set_icon_from_stock(entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_NEW);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void faviconChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window)
</del><ins>+static void faviconChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserWindow *window)
</ins><span class="cx"> {
</span><span class="cx">     GdkPixbuf *favicon = NULL;
</span><del>-    cairo_surface_t *surface = webkit_web_view_get_favicon(window-&gt;webView);
</del><ins>+    cairo_surface_t *surface = webkit_web_view_get_favicon(webView);
</ins><span class="cx"> 
</span><span class="cx">     if (surface) {
</span><span class="cx">         int width = cairo_image_surface_get_width(surface);
</span><span class="lines">@@ -611,24 +434,12 @@
</span><span class="cx">     updateUriEntryIcon(window);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void webViewIsLoadingChanged(GObject *object, GParamSpec *paramSpec, BrowserWindow *window)
</del><ins>+static void webViewIsLoadingChanged(WebKitWebView *webView, GParamSpec *paramSpec, BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    gboolean isLoading = webkit_web_view_is_loading(window-&gt;webView);
</del><ins>+    gboolean isLoading = webkit_web_view_is_loading(webView);
</ins><span class="cx">     gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(window-&gt;reloadOrStopButton), isLoading ? GTK_STOCK_STOP : GTK_STOCK_REFRESH);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static gboolean inspectorWasOpenedInAnotherWindow(WebKitWebInspector *inspectorWindow, BrowserWindow *window)
-{
-    window-&gt;inspectorWindowIsVisible = TRUE;
-    return FALSE;
-}
-
-static gboolean inspectorWasClosed(WebKitWebInspector *inspectorWindow, BrowserWindow *window)
-{
-    window-&gt;inspectorWindowIsVisible = FALSE;
-    return FALSE;
-}
-
</del><span class="cx"> static void zoomInCallback(BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     browserWindowZoomIn(window);
</span><span class="lines">@@ -641,49 +452,54 @@
</span><span class="cx"> 
</span><span class="cx"> static void defaultZoomCallback(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    webkit_web_view_set_zoom_level(window-&gt;webView, defaultZoomLevel);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_set_zoom_level(webView, defaultZoomLevel);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void searchCallback(BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    browser_search_bar_open(window-&gt;searchBar);
</del><ins>+    browser_tab_start_search(window-&gt;activeTab);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static gboolean toggleWebInspector(BrowserWindow *window, gpointer user_data)
</del><ins>+static void newTabCallback(BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    WebKitWebInspector *inspectorWindow;
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;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-&gt;notebook), -1);
+}
</ins><span class="cx"> 
</span><del>-    inspectorWindow = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(window-&gt;webView));
-    if (!window-&gt;inspectorWindowIsVisible) {
-        webkit_web_inspector_show(inspectorWindow);
-        window-&gt;inspectorWindowIsVisible = TRUE;
-    } else
-        webkit_web_inspector_close(inspectorWindow);
-
-    return TRUE;
</del><ins>+static void toggleWebInspector(BrowserWindow *window)
+{
+    browser_tab_toggle_inspector(window-&gt;activeTab);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void reloadPage(BrowserWindow *window, gpointer user_data)
</del><ins>+static void reloadPage(BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    webkit_web_view_reload(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_reload(webView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void reloadPageIgnoringCache(BrowserWindow *window, gpointer user_data)
</del><ins>+static void reloadPageIgnoringCache(BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    webkit_web_view_reload_bypass_cache(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_reload_bypass_cache(webView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void stopPageLoad(BrowserWindow *window, gpointer user_data)
</del><ins>+static void stopPageLoad(BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    if (gtk_widget_get_visible(GTK_WIDGET(window-&gt;searchBar))) 
-        browser_search_bar_close(window-&gt;searchBar);
-    else if (webkit_web_view_is_loading(window-&gt;webView))
-        webkit_web_view_stop_loading(window-&gt;webView);
</del><ins>+    browser_tab_stop_search(window-&gt;activeTab);
+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    if (webkit_web_view_is_loading(webView))
+        webkit_web_view_stop_loading(webView);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void loadHomePage(BrowserWindow *window, gpointer user_data)
</del><ins>+static void loadHomePage(BrowserWindow *window)
</ins><span class="cx"> {
</span><del>-    webkit_web_view_load_uri(window-&gt;webView, BROWSER_DEFAULT_URL);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static gboolean toggleFullScreen(BrowserWindow *window, gpointer user_data)
</span><span class="lines">@@ -702,7 +518,8 @@
</span><span class="cx"> 
</span><span class="cx"> static void editingCommandCallback(GtkWidget*widget, BrowserWindow *window)
</span><span class="cx"> {
</span><del>-    webkit_web_view_execute_editing_command(window-&gt;webView, gtk_widget_get_name(widget));
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_execute_editing_command(webView, gtk_widget_get_name(widget));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void insertImageCommandCallback(GtkWidget*widget, BrowserWindow *window)
</span><span class="lines">@@ -718,7 +535,8 @@
</span><span class="cx">     if (gtk_dialog_run(GTK_DIALOG(fileChooser)) == GTK_RESPONSE_ACCEPT) {
</span><span class="cx">         char *uri = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(fileChooser));
</span><span class="cx">         if (uri) {
</span><del>-            webkit_web_view_execute_editing_command_with_argument(window-&gt;webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, uri);
</del><ins>+            WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+            webkit_web_view_execute_editing_command_with_argument(webView, WEBKIT_EDITING_COMMAND_INSERT_IMAGE, uri);
</ins><span class="cx">             g_free(uri);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -738,8 +556,10 @@
</span><span class="cx"> 
</span><span class="cx">     if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
</span><span class="cx">         const char *url = gtk_entry_get_text(GTK_ENTRY(entry));
</span><del>-        if (url &amp;&amp; *url)
-            webkit_web_view_execute_editing_command_with_argument(window-&gt;webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, url);
</del><ins>+        if (url &amp;&amp; *url) {
+            WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+            webkit_web_view_execute_editing_command_with_argument(webView, WEBKIT_EDITING_COMMAND_CREATE_LINK, url);
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     gtk_widget_destroy(dialog);
</span><span class="lines">@@ -774,9 +594,6 @@
</span><span class="cx">         window-&gt;accelGroup = NULL;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (window-&gt;fullScreenMessageLabelId)
-        g_source_remove(window-&gt;fullScreenMessageLabelId);
-
</del><span class="cx">     if (window-&gt;resetEntryProgressTimeoutId)
</span><span class="cx">         g_source_remove(window-&gt;resetEntryProgressTimeoutId);
</span><span class="cx"> 
</span><span class="lines">@@ -788,32 +605,6 @@
</span><span class="cx">         gtk_main_quit();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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-&gt;webView = g_value_get_object(value);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
-    }
-}
-
</del><span class="cx"> static void browserWindowSetupEditorToolbar(BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     GtkWidget *toolbar = gtk_toolbar_new();
</span><span class="lines">@@ -943,9 +734,66 @@
</span><span class="cx">     gtk_widget_show(GTK_WIDGET(item));
</span><span class="cx"> 
</span><span class="cx">     gtk_box_pack_start(GTK_BOX(window-&gt;mainBox), toolbar, FALSE, FALSE, 0);
</span><ins>+    gtk_box_reorder_child(GTK_BOX(window-&gt;mainBox), toolbar, 1);
</ins><span class="cx">     gtk_widget_show(toolbar);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static void browserWindowSwitchTab(GtkNotebook *notebook, BrowserTab *tab, guint tabIndex, BrowserWindow *window)
+{
+    if (window-&gt;activeTab == tab)
+        return;
+
+    if (window-&gt;activeTab) {
+        browser_tab_set_status_text(window-&gt;activeTab, NULL);
+        g_clear_object(&amp;window-&gt;favicon);
+
+        WebKitWebView *webView = browser_tab_get_web_view(window-&gt;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-&gt;activeTab = tab;
+
+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    if (webkit_web_view_is_editable(webView)) {
+        browserWindowSetupEditorToolbar(window);
+        g_signal_connect(webkit_web_view_get_editor_state(webView), &quot;notify::typing-attributes&quot;, 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, &quot;notify::uri&quot;, G_CALLBACK(webViewURIChanged), window);
+    g_signal_connect(webView, &quot;notify::estimated-load-progress&quot;, G_CALLBACK(webViewLoadProgressChanged), window);
+    g_signal_connect(webView, &quot;notify::title&quot;, G_CALLBACK(webViewTitleChanged), window);
+    g_signal_connect(webView, &quot;notify::is-loading&quot;, G_CALLBACK(webViewIsLoadingChanged), window);
+    g_signal_connect(webView, &quot;create&quot;, G_CALLBACK(webViewCreate), window);
+    g_signal_connect(webView, &quot;close&quot;, G_CALLBACK(webViewClose), window);
+    g_signal_connect(webView, &quot;load-failed&quot;, G_CALLBACK(webViewLoadFailed), window);
+    g_signal_connect(webView, &quot;decide-policy&quot;, G_CALLBACK(webViewDecidePolicy), window);
+    g_signal_connect(webView, &quot;mouse-target-changed&quot;, G_CALLBACK(webViewMouseTargetChanged), window);
+    g_signal_connect(webView, &quot;notify::zoom-level&quot;, G_CALLBACK(webViewZoomLevelChanged), window);
+    g_signal_connect(webView, &quot;notify::favicon&quot;, G_CALLBACK(faviconChanged), window);
+    g_signal_connect(webView, &quot;enter-fullscreen&quot;, G_CALLBACK(webViewEnterFullScreen), window);
+    g_signal_connect(webView, &quot;leave-fullscreen&quot;, G_CALLBACK(webViewLeaveFullScreen), window);
+    g_signal_connect(webView, &quot;scroll-event&quot;, G_CALLBACK(scrollEventCallback), window);
+
+    WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(webView);
+    browserWindowUpdateNavigationActions(window, backForwadlist);
+    g_signal_connect(backForwadlist, &quot;changed&quot;, G_CALLBACK(backForwadlistChanged), window);
+}
+
+static void browserWindowTabAddedOrRemoved(GtkNotebook *notebook, BrowserTab *tab, guint tabIndex, BrowserWindow *window)
+{
+    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window-&gt;notebook), gtk_notebook_get_n_pages(notebook) &gt; 1);
+}
+
</ins><span class="cx"> static void browser_window_init(BrowserWindow *window)
</span><span class="cx"> {
</span><span class="cx">     g_atomic_int_inc(&amp;windowCount);
</span><span class="lines">@@ -968,7 +816,7 @@
</span><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_F12, 0, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(toggleWebInspector), window, NULL));
</span><span class="cx"> 
</span><del>-    /* Reload page */ 
</del><ins>+    /* Reload page */
</ins><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_F5, 0, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(reloadPage), window, NULL));
</span><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_R, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
</span><span class="lines">@@ -980,13 +828,13 @@
</span><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_R, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(reloadPageIgnoringCache), window, NULL));
</span><span class="cx"> 
</span><del>-    /* Stop page load */ 
</del><ins>+    /* Stop page load */
</ins><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_F6, 0, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(stopPageLoad), window, NULL));
</span><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_Escape, 0, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(stopPageLoad), window, NULL));
</span><span class="cx"> 
</span><del>-    /* Load home page */ 
</del><ins>+    /* Load home page */
</ins><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_Home, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(loadHomePage), window, NULL));
</span><span class="cx"> 
</span><span class="lines">@@ -1004,7 +852,7 @@
</span><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_KP_0, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(defaultZoomCallback), window, NULL));
</span><span class="cx"> 
</span><del>-    /* Toggle fullscreen */ 
</del><ins>+    /* Toggle fullscreen */
</ins><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_F11, 0, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(toggleFullScreen), window, NULL));
</span><span class="cx"> 
</span><span class="lines">@@ -1014,6 +862,8 @@
</span><span class="cx">     gtk_accel_group_connect(window-&gt;accelGroup, GDK_KEY_W, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE,
</span><span class="cx">         g_cclosure_new_swap(G_CALLBACK(gtk_widget_destroy), window, NULL));
</span><span class="cx"> 
</span><ins>+    g_signal_connect(webkit_web_context_get_default(), &quot;download-started&quot;, G_CALLBACK(downloadStarted), window);
+
</ins><span class="cx">     GtkWidget *toolbar = gtk_toolbar_new();
</span><span class="cx">     window-&gt;toolbar = toolbar;
</span><span class="cx">     gtk_orientable_set_orientation(GTK_ORIENTABLE(toolbar), GTK_ORIENTATION_HORIZONTAL);
</span><span class="lines">@@ -1062,6 +912,12 @@
</span><span class="cx">     gtk_widget_add_accelerator(GTK_WIDGET(item), &quot;clicked&quot;, window-&gt;accelGroup, GDK_KEY_Home, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE);
</span><span class="cx">     gtk_widget_show(GTK_WIDGET(item));
</span><span class="cx"> 
</span><ins>+    item = gtk_tool_button_new(gtk_image_new_from_icon_name(&quot;tab-new&quot;, GTK_ICON_SIZE_SMALL_TOOLBAR), NULL);
+    g_signal_connect_swapped(item, &quot;clicked&quot;, G_CALLBACK(newTabCallback), window);
+    gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, -1);
+    gtk_widget_add_accelerator(GTK_WIDGET(item), &quot;clicked&quot;, window-&gt;accelGroup, GDK_KEY_T, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
+    gtk_widget_show_all(GTK_WIDGET(item));
+
</ins><span class="cx">     item = gtk_tool_item_new();
</span><span class="cx">     gtk_tool_item_set_expand(item, TRUE);
</span><span class="cx">     gtk_container_add(GTK_CONTAINER(item), window-&gt;uriEntry);
</span><span class="lines">@@ -1081,6 +937,15 @@
</span><span class="cx">     gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
</span><span class="cx">     gtk_widget_show(toolbar);
</span><span class="cx"> 
</span><ins>+    window-&gt;notebook = gtk_notebook_new();
+    g_signal_connect(window-&gt;notebook, &quot;switch-page&quot;, G_CALLBACK(browserWindowSwitchTab), window);
+    g_signal_connect(window-&gt;notebook, &quot;page-added&quot;, G_CALLBACK(browserWindowTabAddedOrRemoved), window);
+    g_signal_connect(window-&gt;notebook, &quot;page-removed&quot;, G_CALLBACK(browserWindowTabAddedOrRemoved), window);
+    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(window-&gt;notebook), FALSE);
+    gtk_notebook_set_show_border(GTK_NOTEBOOK(window-&gt;notebook), FALSE);
+    gtk_box_pack_start(GTK_BOX(window-&gt;mainBox), window-&gt;notebook, TRUE, TRUE, 0);
+    gtk_widget_show(window-&gt;notebook);
+
</ins><span class="cx">     gtk_container_add(GTK_CONTAINER(window), vbox);
</span><span class="cx">     gtk_widget_show(vbox);
</span><span class="cx"> }
</span><span class="lines">@@ -1089,69 +954,7 @@
</span><span class="cx"> {
</span><span class="cx">     BrowserWindow *window = BROWSER_WINDOW(gObject);
</span><span class="cx"> 
</span><del>-    browserWindowUpdateZoomActions(window);
-    if (webkit_web_view_is_editable(window-&gt;webView)) {
-        browserWindowSetupEditorToolbar(window);
-        g_signal_connect(webkit_web_view_get_editor_state(window-&gt;webView), &quot;notify::typing-attributes&quot;, G_CALLBACK(typingAttributesChanged), window);
-    }
-
-    g_signal_connect(window-&gt;webView, &quot;notify::uri&quot;, G_CALLBACK(webViewURIChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;notify::estimated-load-progress&quot;, G_CALLBACK(webViewLoadProgressChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;notify::title&quot;, G_CALLBACK(webViewTitleChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;create&quot;, G_CALLBACK(webViewCreate), window);
-    g_signal_connect(window-&gt;webView, &quot;close&quot;, G_CALLBACK(webViewClose), window);
-    g_signal_connect(window-&gt;webView, &quot;load-failed&quot;, G_CALLBACK(webViewLoadFailed), window);
-    g_signal_connect(window-&gt;webView, &quot;load-failed-with-tls-errors&quot;, G_CALLBACK(webViewLoadFailedWithTLSerrors), window);
-    g_signal_connect(window-&gt;webView, &quot;decide-policy&quot;, G_CALLBACK(webViewDecidePolicy), window);
-    g_signal_connect(window-&gt;webView, &quot;permission-request&quot;, G_CALLBACK(webViewDecidePermissionRequest), window);
-    g_signal_connect(window-&gt;webView, &quot;mouse-target-changed&quot;, G_CALLBACK(webViewMouseTargetChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;notify::zoom-level&quot;, G_CALLBACK(webViewZoomLevelChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;notify::favicon&quot;, G_CALLBACK(faviconChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;enter-fullscreen&quot;, G_CALLBACK(webViewEnterFullScreen), window);
-    g_signal_connect(window-&gt;webView, &quot;leave-fullscreen&quot;, G_CALLBACK(webViewLeaveFullScreen), window);
-    g_signal_connect(window-&gt;webView, &quot;notify::is-loading&quot;, G_CALLBACK(webViewIsLoadingChanged), window);
-    g_signal_connect(window-&gt;webView, &quot;scroll-event&quot;, G_CALLBACK(scrollEventCallback), window);
-#if GTK_CHECK_VERSION(3, 12, 0)
-    g_signal_connect(window-&gt;webView, &quot;run-color-chooser&quot;, G_CALLBACK(runColorChooserCallback), window);
-#endif
-
-    g_signal_connect(webkit_web_view_get_context(window-&gt;webView), &quot;download-started&quot;, G_CALLBACK(downloadStarted), window);
-
-    window-&gt;searchBar = BROWSER_SEARCH_BAR(browser_search_bar_new(window-&gt;webView));
-    browser_search_bar_add_accelerators(window-&gt;searchBar, window-&gt;accelGroup);
-    gtk_box_pack_start(GTK_BOX(window-&gt;mainBox), GTK_WIDGET(window-&gt;searchBar), FALSE, FALSE, 0);
-
-    WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(window-&gt;webView);
-    g_signal_connect(backForwadlist, &quot;changed&quot;, G_CALLBACK(backForwadlistChanged), window);
-
-    WebKitWebInspector *inspectorWindow = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(window-&gt;webView));
-    g_signal_connect(inspectorWindow, &quot;open-window&quot;, G_CALLBACK(inspectorWasOpenedInAnotherWindow), window);
-    g_signal_connect(inspectorWindow, &quot;closed&quot;, G_CALLBACK(inspectorWasClosed), window);
-
-    GtkWidget *overlay = gtk_overlay_new();
-    gtk_box_pack_start(GTK_BOX(window-&gt;mainBox), overlay, TRUE, TRUE, 0);
-    gtk_widget_show(overlay);
-
-    window-&gt;statusLabel = gtk_label_new(NULL);
-    gtk_widget_set_halign(window-&gt;statusLabel, GTK_ALIGN_START);
-    gtk_widget_set_valign(window-&gt;statusLabel, GTK_ALIGN_END);
-    gtk_widget_set_margin_left(window-&gt;statusLabel, 1);
-    gtk_widget_set_margin_right(window-&gt;statusLabel, 1);
-    gtk_widget_set_margin_top(window-&gt;statusLabel, 1);
-    gtk_widget_set_margin_bottom(window-&gt;statusLabel, 1);
-    gtk_overlay_add_overlay(GTK_OVERLAY(overlay), window-&gt;statusLabel);
-
-    gtk_container_add(GTK_CONTAINER(overlay), GTK_WIDGET(window-&gt;webView));
-
-    window-&gt;fullScreenMessageLabel = gtk_label_new(NULL);
-    gtk_widget_set_halign(window-&gt;fullScreenMessageLabel, GTK_ALIGN_CENTER);
-    gtk_widget_set_valign(window-&gt;fullScreenMessageLabel, GTK_ALIGN_CENTER);
-    gtk_widget_set_no_show_all(window-&gt;fullScreenMessageLabel, TRUE);
-    gtk_overlay_add_overlay(GTK_OVERLAY(overlay), window-&gt;fullScreenMessageLabel);
-    gtk_widget_show(GTK_WIDGET(window-&gt;webView));
-
-    if (webkit_web_view_is_editable(window-&gt;webView))
-        webkit_web_view_load_html(window-&gt;webView, &quot;&lt;html&gt;&lt;/html&gt;&quot;, &quot;file:///&quot;);
</del><ins>+    G_OBJECT_CLASS(browser_window_parent_class)-&gt;constructed(gObject);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void browserWindowSaveSession(BrowserWindow *window)
</span><span class="lines">@@ -1159,7 +962,8 @@
</span><span class="cx">     if (!window-&gt;sessionFile)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    WebKitWebViewSessionState *state = webkit_web_view_get_session_state(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    WebKitWebViewSessionState *state = webkit_web_view_get_session_state(webView);
</ins><span class="cx">     GBytes *bytes = webkit_web_view_session_state_serialize(state);
</span><span class="cx">     webkit_web_view_session_state_unref(state);
</span><span class="cx">     g_file_set_contents(window-&gt;sessionFile, g_bytes_get_data(bytes, NULL), g_bytes_get_size(bytes), NULL);
</span><span class="lines">@@ -1170,7 +974,8 @@
</span><span class="cx"> {
</span><span class="cx">     BrowserWindow *window = BROWSER_WINDOW(widget);
</span><span class="cx">     browserWindowSaveSession(window);
</span><del>-    webkit_web_view_try_close(window-&gt;webView);
</del><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
+    webkit_web_view_try_close(webView);
</ins><span class="cx">     return TRUE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1179,29 +984,17 @@
</span><span class="cx">     GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
</span><span class="cx"> 
</span><span class="cx">     gobjectClass-&gt;constructed = browserWindowConstructed;
</span><del>-    gobjectClass-&gt;get_property = browserWindowGetProperty;
-    gobjectClass-&gt;set_property = browserWindowSetProperty;
</del><span class="cx">     gobjectClass-&gt;finalize = browserWindowFinalize;
</span><span class="cx"> 
</span><span class="cx">     GtkWidgetClass *widgetClass = GTK_WIDGET_CLASS(klass);
</span><span class="cx">     widgetClass-&gt;delete_event = browserWindowDeleteEvent;
</span><del>-
-    g_object_class_install_property(gobjectClass,
-                                    PROP_VIEW,
-                                    g_param_spec_object(&quot;view&quot;,
-                                                        &quot;View&quot;,
-                                                        &quot;The web view of this window&quot;,
-                                                        WEBKIT_TYPE_WEB_VIEW,
-                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-// Public API.
-GtkWidget *browser_window_new(WebKitWebView *view, GtkWindow *parent)
</del><ins>+/* Public API. */
+GtkWidget *browser_window_new(GtkWindow *parent)
</ins><span class="cx"> {
</span><del>-    g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(view), 0);
-
</del><span class="cx">     BrowserWindow *window = BROWSER_WINDOW(g_object_new(BROWSER_TYPE_WINDOW,
</span><del>-        &quot;type&quot;, GTK_WINDOW_TOPLEVEL, &quot;view&quot;, view, NULL));
</del><ins>+        &quot;type&quot;, GTK_WINDOW_TOPLEVEL, NULL));
</ins><span class="cx"> 
</span><span class="cx">     if (parent) {
</span><span class="cx">         window-&gt;parentWindow = parent;
</span><span class="lines">@@ -1211,11 +1004,21 @@
</span><span class="cx">     return GTK_WIDGET(window);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebKitWebView *browser_window_get_view(BrowserWindow *window)
</del><ins>+void browser_window_append_view(BrowserWindow *window, WebKitWebView *webView)
</ins><span class="cx"> {
</span><del>-    g_return_val_if_fail(BROWSER_IS_WINDOW(window), 0);
</del><ins>+    g_return_if_fail(BROWSER_IS_WINDOW(window));
+    g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
</ins><span class="cx"> 
</span><del>-    return window-&gt;webView;
</del><ins>+    if (window-&gt;activeTab &amp;&amp; webkit_web_view_is_editable(browser_tab_get_web_view(window-&gt;activeTab))) {
+        g_warning(&quot;Only one tab is allowed in editable mode&quot;);
+        return;
+    }
+
+    GtkWidget *tab = browser_tab_new(webView);
+    browser_tab_add_accelerators(BROWSER_TAB(tab), window-&gt;accelGroup);
+    gtk_notebook_append_page(GTK_NOTEBOOK(window-&gt;notebook), tab, browser_tab_get_title_widget(BROWSER_TAB(tab)));
+    gtk_container_child_set(GTK_CONTAINER(window-&gt;notebook), tab, &quot;tab-expand&quot;, TRUE, NULL);
+    gtk_widget_show(tab);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void browser_window_load_uri(BrowserWindow *window, const char *uri)
</span><span class="lines">@@ -1223,14 +1026,7 @@
</span><span class="cx">     g_return_if_fail(BROWSER_IS_WINDOW(window));
</span><span class="cx">     g_return_if_fail(uri);
</span><span class="cx"> 
</span><del>-    if (!g_str_has_prefix(uri, &quot;javascript:&quot;)) {
-        char *internalURI = getInternalURI(uri);
-        webkit_web_view_load_uri(window-&gt;webView, internalURI);
-        g_free(internalURI);
-        return;
-    }
-
-    webkit_web_view_run_javascript(window-&gt;webView, strstr(uri, &quot;javascript:&quot;), NULL, NULL, NULL);
</del><ins>+    browser_tab_load_uri(window-&gt;activeTab, uri);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void browser_window_load_session(BrowserWindow *window, const char *sessionFile)
</span><span class="lines">@@ -1238,6 +1034,7 @@
</span><span class="cx">     g_return_if_fail(BROWSER_IS_WINDOW(window));
</span><span class="cx">     g_return_if_fail(sessionFile);
</span><span class="cx"> 
</span><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
</ins><span class="cx">     window-&gt;sessionFile = g_strdup(sessionFile);
</span><span class="cx">     gchar *data = NULL;
</span><span class="cx">     gsize dataLength;
</span><span class="lines">@@ -1247,17 +1044,17 @@
</span><span class="cx">         g_bytes_unref(bytes);
</span><span class="cx"> 
</span><span class="cx">         if (state) {
</span><del>-            webkit_web_view_restore_session_state(window-&gt;webView, state);
</del><ins>+            webkit_web_view_restore_session_state(webView, state);
</ins><span class="cx">             webkit_web_view_session_state_unref(state);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WebKitBackForwardList *bfList = webkit_web_view_get_back_forward_list(window-&gt;webView);
</del><ins>+    WebKitBackForwardList *bfList = webkit_web_view_get_back_forward_list(webView);
</ins><span class="cx">     WebKitBackForwardListItem *item = webkit_back_forward_list_get_current_item(bfList);
</span><span class="cx">     if (item)
</span><del>-        webkit_web_view_go_to_back_forward_list_item(window-&gt;webView, item);
</del><ins>+        webkit_web_view_go_to_back_forward_list_item(webView, item);
</ins><span class="cx">     else
</span><del>-        webkit_web_view_load_uri(window-&gt;webView, BROWSER_DEFAULT_URL);
</del><ins>+        webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL);
</ins><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1266,8 +1063,9 @@
</span><span class="cx">     g_return_if_fail(BROWSER_IS_WINDOW(window));
</span><span class="cx">     g_return_if_fail(rgba);
</span><span class="cx"> 
</span><ins>+    WebKitWebView *webView = browser_tab_get_web_view(window-&gt;activeTab);
</ins><span class="cx">     GdkRGBA viewRGBA;
</span><del>-    webkit_web_view_get_background_color(window-&gt;webView, &amp;viewRGBA);
</del><ins>+    webkit_web_view_get_background_color(webView, &amp;viewRGBA);
</ins><span class="cx">     if (gdk_rgba_equal(rgba, &amp;viewRGBA))
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="lines">@@ -1280,5 +1078,5 @@
</span><span class="cx">         gtk_widget_set_app_paintable(GTK_WIDGET(window), TRUE);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    webkit_web_view_set_background_color(window-&gt;webView, rgba);
</del><ins>+    webkit_web_view_set_background_color(webView, rgba);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkToolsMiniBrowsergtkBrowserWindowh"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/gtk/BrowserWindow.h (203270 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/gtk/BrowserWindow.h        2016-07-15 06:03:25 UTC (rev 203270)
+++ trunk/Tools/MiniBrowser/gtk/BrowserWindow.h        2016-07-15 09:25:15 UTC (rev 203271)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx"> #define BROWSER_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  BROWSER_TYPE_WINDOW))
</span><span class="cx"> #define BROWSER_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  BROWSER_TYPE_WINDOW, BrowserWindowClass))
</span><span class="cx"> #define BROWSER_DEFAULT_URL            &quot;http://www.webkitgtk.org/&quot;
</span><ins>+#define BROWSER_ABOUT_SCHEME           &quot;minibrowser-about&quot;
</ins><span class="cx"> 
</span><span class="cx"> typedef struct _BrowserWindow        BrowserWindow;
</span><span class="cx"> typedef struct _BrowserWindowClass   BrowserWindowClass;
</span><span class="lines">@@ -44,9 +45,9 @@
</span><span class="cx"> 
</span><span class="cx"> GType browser_window_get_type(void);
</span><span class="cx"> 
</span><del>-GtkWidget* browser_window_new(WebKitWebView*, GtkWindow*);
-WebKitWebView* browser_window_get_view(BrowserWindow*);
-void browser_window_load_uri(BrowserWindow *, const char *uri);
</del><ins>+GtkWidget* browser_window_new(GtkWindow*);
+void browser_window_append_view(BrowserWindow*, WebKitWebView*);
+void browser_window_load_uri(BrowserWindow*, const char *uri);
</ins><span class="cx"> void browser_window_load_session(BrowserWindow *, const char *sessionFile);
</span><span class="cx"> void browser_window_set_background_color(BrowserWindow*, GdkRGBA*);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsMiniBrowsergtkCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/gtk/CMakeLists.txt (203270 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/gtk/CMakeLists.txt        2016-07-15 06:03:25 UTC (rev 203270)
+++ trunk/Tools/MiniBrowser/gtk/CMakeLists.txt        2016-07-15 09:25:15 UTC (rev 203271)
</span><span class="lines">@@ -13,6 +13,8 @@
</span><span class="cx">     ${MINIBROWSER_DIR}/BrowserSearchBar.h
</span><span class="cx">     ${MINIBROWSER_DIR}/BrowserSettingsDialog.c
</span><span class="cx">     ${MINIBROWSER_DIR}/BrowserSettingsDialog.h
</span><ins>+    ${MINIBROWSER_DIR}/BrowserTab.c
+    ${MINIBROWSER_DIR}/BrowserTab.h
</ins><span class="cx">     ${MINIBROWSER_DIR}/BrowserWindow.c
</span><span class="cx">     ${MINIBROWSER_DIR}/BrowserWindow.h
</span><span class="cx">     ${MINIBROWSER_DIR}/main.c
</span></span></pre></div>
<a id="trunkToolsMiniBrowsergtkmainc"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/gtk/main.c (203270 => 203271)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/gtk/main.c        2016-07-15 06:03:25 UTC (rev 203270)
+++ trunk/Tools/MiniBrowser/gtk/main.c        2016-07-15 09:25:15 UTC (rev 203271)
</span><span class="lines">@@ -36,7 +36,6 @@
</span><span class="cx"> #define MINI_BROWSER_ERROR (miniBrowserErrorQuark())
</span><span class="cx"> 
</span><span class="cx"> static const gchar **uriArguments = NULL;
</span><del>-static const char *miniBrowserAboutScheme = &quot;minibrowser-about&quot;;
</del><span class="cx"> static GdkRGBA *backgroundColor;
</span><span class="cx"> static gboolean editorMode;
</span><span class="cx"> static const char *sessionFile;
</span><span class="lines">@@ -60,32 +59,16 @@
</span><span class="cx">     return fileURL;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void createBrowserWindow(const gchar *uri, WebKitSettings *webkitSettings, gboolean shouldLoadSession)
</del><ins>+static WebKitWebView *createBrowserTab(BrowserWindow *window, WebKitSettings *webkitSettings)
</ins><span class="cx"> {
</span><del>-    GtkWidget *webView = webkit_web_view_new();
</del><ins>+    WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+    if (webkitSettings)
+        webkit_web_view_set_settings(webView, webkitSettings);
</ins><span class="cx">     if (editorMode)
</span><del>-        webkit_web_view_set_editable(WEBKIT_WEB_VIEW(webView), TRUE);
-    GtkWidget *mainWindow = browser_window_new(WEBKIT_WEB_VIEW(webView), NULL);
-    if (backgroundColor)
-        browser_window_set_background_color(BROWSER_WINDOW(mainWindow), backgroundColor);
-    if (geometry)
-        gtk_window_parse_geometry(GTK_WINDOW(mainWindow), geometry);
</del><ins>+        webkit_web_view_set_editable(webView, TRUE);
</ins><span class="cx"> 
</span><del>-    if (webkitSettings)
-        webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webView), webkitSettings);
-
-    if (!editorMode) {
-        if (shouldLoadSession &amp;&amp; sessionFile)
-            browser_window_load_session(BROWSER_WINDOW(mainWindow), sessionFile);
-        else {
-            gchar *url = argumentToURL(uri);
-            browser_window_load_uri(BROWSER_WINDOW(mainWindow), url);
-            g_free(url);
-        }
-    }
-
-    gtk_widget_grab_focus(webView);
-    gtk_widget_show(mainWindow);
</del><ins>+    browser_window_append_view(window, webView);
+    return webView;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static gboolean parseBackgroundColor(const char *optionName, const char *value, gpointer data, GError **error)
</span><span class="lines">@@ -242,8 +225,7 @@
</span><span class="cx">     return TRUE;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void
-aboutURISchemeRequestCallback(WebKitURISchemeRequest *request, gpointer userData)
</del><ins>+static void aboutURISchemeRequestCallback(WebKitURISchemeRequest *request, gpointer userData)
</ins><span class="cx"> {
</span><span class="cx">     GInputStream *stream;
</span><span class="cx">     gsize streamLength;
</span><span class="lines">@@ -303,16 +285,42 @@
</span><span class="cx">     // Enable the favicon database, by specifying the default directory.
</span><span class="cx">     webkit_web_context_set_favicon_database_directory(webkit_web_context_get_default(), NULL);
</span><span class="cx"> 
</span><del>-    webkit_web_context_register_uri_scheme(webkit_web_context_get_default(), miniBrowserAboutScheme, aboutURISchemeRequestCallback, NULL, NULL);
</del><ins>+    webkit_web_context_register_uri_scheme(webkit_web_context_get_default(), BROWSER_ABOUT_SCHEME, aboutURISchemeRequestCallback, NULL, NULL);
</ins><span class="cx"> 
</span><ins>+    BrowserWindow *mainWindow = BROWSER_WINDOW(browser_window_new(NULL));
+    if (geometry)
+        gtk_window_parse_geometry(GTK_WINDOW(mainWindow), geometry);
+
+    GtkWidget *firstTab = NULL;
</ins><span class="cx">     if (uriArguments) {
</span><span class="cx">         int i;
</span><span class="cx"> 
</span><del>-        for (i = 0; uriArguments[i]; i++)
-            createBrowserWindow(uriArguments[i], webkitSettings, FALSE);
-    } else
-        createBrowserWindow(BROWSER_DEFAULT_URL, webkitSettings, TRUE);
</del><ins>+        for (i = 0; uriArguments[i]; i++) {
+            WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings);
+            if (!i)
+                firstTab = GTK_WIDGET(webView);
+            gchar *url = argumentToURL(uriArguments[i]);
+            webkit_web_view_load_uri(webView, url);
+            g_free(url);
+        }
+    } else {
+        WebKitWebView *webView = createBrowserTab(mainWindow, webkitSettings);
+        firstTab = GTK_WIDGET(webView);
</ins><span class="cx"> 
</span><ins>+        if (backgroundColor)
+            browser_window_set_background_color(mainWindow, backgroundColor);
+
+        if (!editorMode) {
+            if (sessionFile)
+                browser_window_load_session(mainWindow, sessionFile);
+            else
+                webkit_web_view_load_uri(webView, BROWSER_DEFAULT_URL);
+        }
+    }
+
+    gtk_widget_grab_focus(firstTab);
+    gtk_widget_show(GTK_WIDGET(mainWindow));
+
</ins><span class="cx">     g_clear_object(&amp;webkitSettings);
</span><span class="cx"> 
</span><span class="cx">     gtk_main();
</span></span></pre>
</div>
</div>

</body>
</html>