static void testWebViewDefaultContext(WebViewTest* test, gconstpointer) { g_assert(webkit_web_view_get_context(test->m_webView) == webkit_web_context_get_default()); // Check that a web view created with g_object_new has the default context. GRefPtr<WebKitWebView> webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, NULL)); g_assert(webkit_web_view_get_context(webView.get()) == webkit_web_context_get_default()); }
static void testWebViewWebContextLifetime(WebViewTest* test, gconstpointer) { WebKitWebContext* webContext = webkit_web_context_new(); test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webContext)); GtkWidget* webView = webkit_web_view_new_with_context(webContext); test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView)); g_object_ref_sink(webView); g_object_unref(webContext); // Check that the web view still has a valid context. WebKitWebContext* tmpContext = webkit_web_view_get_context(WEBKIT_WEB_VIEW(webView)); g_assert_true(WEBKIT_IS_WEB_CONTEXT(tmpContext)); g_object_unref(webView); WebKitWebContext* webContext2 = webkit_web_context_new(); test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webContext2)); GtkWidget* webView2 = webkit_web_view_new_with_context(webContext2); test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(webView2)); g_object_ref_sink(webView2); g_object_unref(webView2); // Check that the context is still valid. g_assert_true(WEBKIT_IS_WEB_CONTEXT(webContext2)); g_object_unref(webContext2); }
static void testLoadFailedWithTLSErrors(TLSErrorsTest* test, gconstpointer) { WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); // The load-failed-with-tls-errors signal should be emitted when there is a TLS failure. test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data()); test->waitUntilLoadFinished(); g_assert(G_IS_TLS_CERTIFICATE(test->certificate())); g_assert_cmpuint(test->tlsErrors(), ==, G_TLS_CERTIFICATE_UNKNOWN_CA); g_assert_cmpstr(test->host(), ==, soup_uri_get_host(kHttpsServer->baseURI())); g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadFailedWithTLSErrors); g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); // Test allowing an exception for this certificate on this host. webkit_web_context_allow_tls_certificate_for_host(context, test->certificate(), test->host()); // The page should now load without errors. test->loadURI(kHttpsServer->getURIForPath("/test-tls/").data()); test->waitUntilLoadFinished(); g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted); g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted); g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished); g_assert_cmpstr(webkit_web_view_get_title(test->m_webView), ==, TLSExpectedSuccessTitle); webkit_web_context_set_tls_errors_policy(context, originalPolicy); }
static void testWebViewWebContext(WebViewTest* test, gconstpointer) { g_assert(webkit_web_view_get_context(test->m_webView) == test->m_webContext.get()); g_assert(webkit_web_context_get_default() != test->m_webContext.get()); // Check that a web view created with g_object_new has the default context. GRefPtr<WebKitWebView> webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, nullptr)); g_assert(webkit_web_view_get_context(webView.get()) == webkit_web_context_get_default()); // Check that a web view created with a related view has the related view context. webView = WEBKIT_WEB_VIEW(webkit_web_view_new_with_related_view(test->m_webView)); g_assert(webkit_web_view_get_context(webView.get()) == test->m_webContext.get()); // Check that a web context given as construct parameter is ignored if a related view is also provided. webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, "web-context", webkit_web_context_get_default(), "related-view", test->m_webView, nullptr)); g_assert(webkit_web_view_get_context(webView.get()) == test->m_webContext.get()); }
static void testTLSErrorsRedirect(SSLTest* test, gconstpointer) { WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); test->loadURI(kHttpsServer->getURIForPath("/redirect").data()); test->waitUntilLoadFinished(); g_assert(test->m_loadFailed); g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted)); webkit_web_context_set_tls_errors_policy(context, originalPolicy); }
static void testInsecureContent(InsecureContentTest* test, gconstpointer) { WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE); test->loadURI(kHttpsServer->getURIForPath("/insecure-content/").data()); test->waitUntilLoadFinished(); g_assert(test->m_insecureContentRun); g_assert(test->m_insecureContentDisplayed); webkit_web_context_set_tls_errors_policy(context, originalPolicy); }
static int cookie_accept(Client *c, const char *name, DataType type, void *value, void *data) { WebKitWebContext *ctx; WebKitCookieManager *cm; char *policy = (char*)value; ctx = webkit_web_view_get_context(c->webview); cm = webkit_web_context_get_cookie_manager(ctx); if (strcmp("always", policy) == 0) { webkit_cookie_manager_set_accept_policy(cm, WEBKIT_COOKIE_POLICY_ACCEPT_ALWAYS); } else if (strcmp("origin", policy) == 0) { webkit_cookie_manager_set_accept_policy(cm, WEBKIT_COOKIE_POLICY_ACCEPT_NO_THIRD_PARTY); } else if (strcmp("never", policy) == 0) { webkit_cookie_manager_set_accept_policy(cm, WEBKIT_COOKIE_POLICY_ACCEPT_NEVER); } else { vb_echo(c, MSG_ERROR, TRUE, "%s must be in [always, origin, never]", name); return CMD_ERROR | CMD_KEEPINPUT; } return CMD_SUCCESS; }
static void testSSL(SSLTest* test, gconstpointer) { WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); WebKitTLSErrorsPolicy originalPolicy = webkit_web_context_get_tls_errors_policy(context); webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE); test->loadURI(kHttpsServer->getURIForPath("/").data()); test->waitUntilLoadFinished(); g_assert(test->m_certificate); // We always expect errors because we are using a self-signed certificate, // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present. g_assert(test->m_tlsErrors); g_assert_cmpuint(test->m_tlsErrors, ==, G_TLS_CERTIFICATE_UNKNOWN_CA); // Non HTTPS loads shouldn't have a certificate nor errors. test->loadHtml(indexHTML, 0); test->waitUntilLoadFinished(); g_assert(!test->m_certificate); g_assert(!test->m_tlsErrors); webkit_web_context_set_tls_errors_policy(context, originalPolicy); }
static void testTLSErrorsPolicy(SSLTest* test, gconstpointer) { WebKitWebContext* context = webkit_web_view_get_context(test->m_webView); // TLS errors are treated as transport failures by default. g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_FAIL); test->loadURI(kHttpsServer->getURIForPath("/").data()); test->waitUntilLoadFinished(); g_assert(test->m_loadFailed); g_assert(test->m_loadEvents.contains(LoadTrackingTest::ProvisionalLoadFailed)); g_assert(!test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted)); webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_IGNORE); g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_IGNORE); test->m_loadFailed = false; test->loadURI(kHttpsServer->getURIForPath("/").data()); test->waitUntilLoadFinished(); g_assert(!test->m_loadFailed); webkit_web_context_set_tls_errors_policy(context, WEBKIT_TLS_ERRORS_POLICY_FAIL); g_assert(webkit_web_context_get_tls_errors_policy(context) == WEBKIT_TLS_ERRORS_POLICY_FAIL); }
static gboolean webViewDecidePolicy(WebKitWebView *webView, WebKitPolicyDecision *decision, WebKitPolicyDecisionType decisionType, BrowserWindow *window) { switch (decisionType) { case WEBKIT_POLICY_DECISION_TYPE_NAVIGATION_ACTION: { WebKitNavigationAction *navigationAction = webkit_navigation_policy_decision_get_navigation_action(WEBKIT_NAVIGATION_POLICY_DECISION(decision)); if (webkit_navigation_action_get_navigation_type(navigationAction) != WEBKIT_NAVIGATION_TYPE_LINK_CLICKED || webkit_navigation_action_get_mouse_button(navigationAction) != GDK_BUTTON_MIDDLE) return FALSE; // 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: return FALSE; } }
gboolean key_web_view(GtkWidget *widget, GdkEvent *event, gpointer data) { struct Client *c = (struct Client *)data; gdouble dx, dy; gchar *f; gfloat z; WebKitWebContext *wc = webkit_web_view_get_context(WEBKIT_WEB_VIEW(c->web_view)); if (event->type == GDK_KEY_PRESS) { if (((GdkEventKey *)event)->state & GDK_MOD1_MASK) { switch (((GdkEventKey *)event)->keyval) { case GDK_KEY_q: /* close window (left hand) */ gtk_widget_destroy(c->win); return TRUE; case GDK_KEY_w: /* home (left hand) */ f = ensure_uri_scheme(home_uri); webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), f); g_free(f); return TRUE; case GDK_KEY_e: /* new tab (left hand) */ f = ensure_uri_scheme(home_uri); client_new(f); g_free(f); return TRUE; case GDK_KEY_r: /* reload (left hand) */ webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW( c->web_view)); return TRUE; case GDK_KEY_d: /* download manager (left hand) */ gtk_widget_show_all(dm.win); return TRUE; case GDK_KEY_2: /* search forward (left hand) */ case GDK_KEY_n: /* search forward (maybe both hands) */ search(c, 1); return TRUE; case GDK_KEY_3: /* search backward (left hand) */ search(c, -1); return TRUE; case GDK_KEY_l: /* location (BOTH hands) */ gtk_widget_grab_focus(c->location); return TRUE; case GDK_KEY_k: /* initiate search (BOTH hands) */ gtk_widget_grab_focus(c->location); gtk_entry_set_text(GTK_ENTRY(c->location), "/"); gtk_editable_set_position(GTK_EDITABLE(c->location), -1); return TRUE; case GDK_KEY_c: /* reload trusted certs (left hand) */ trust_user_certs(wc); return TRUE; } } /* navigate backward (left hand) */ else if (((GdkEventKey *)event)->keyval == GDK_KEY_F2) { webkit_web_view_go_back(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; } /* navigate forward (left hand) */ else if (((GdkEventKey *)event)->keyval == GDK_KEY_F3) { webkit_web_view_go_forward(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; } else if (((GdkEventKey *)event)->keyval == GDK_KEY_Escape) { webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(c->web_view)); gtk_level_bar_set_value(GTK_LEVEL_BAR(c->progress), 0); } } else if (event->type == GDK_BUTTON_PRESS) { switch (((GdkEventButton *)event)->button) { case 2: if (c->hover_uri != NULL) { client_new(c->hover_uri); return TRUE; } break; case 8: webkit_web_view_go_back(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; case 9: webkit_web_view_go_forward(WEBKIT_WEB_VIEW(c->web_view)); return TRUE; } } else if (event->type == GDK_SCROLL) { if (((GdkEventScroll *)event)->state & GDK_MOD1_MASK || ((GdkEventScroll *)event)->state & GDK_CONTROL_MASK) { gdk_event_get_scroll_deltas(event, &dx, &dy); z = webkit_web_view_get_zoom_level(WEBKIT_WEB_VIEW(c->web_view)); z += -dy * 0.1; z = dx != 0 ? global_zoom : z; webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), z); return TRUE; } } return FALSE; }
gboolean key_location(GtkWidget *widget, GdkEvent *event, gpointer data) { struct Client *c = (struct Client *)data; const gchar *t; gchar *f; WebKitWebContext *wc = webkit_web_view_get_context(WEBKIT_WEB_VIEW(c->web_view)); if (event->type == GDK_KEY_PRESS) { if (((GdkEventKey *)event)->state & GDK_MOD1_MASK) { switch (((GdkEventKey *)event)->keyval) { case GDK_KEY_q: /* close window (left hand) */ gtk_widget_destroy(c->win); return TRUE; case GDK_KEY_d: /* download manager (left hand) */ gtk_widget_show_all(dm.win); return TRUE; case GDK_KEY_r: /* reload (left hand) */ webkit_web_view_reload_bypass_cache(WEBKIT_WEB_VIEW( c->web_view)); return TRUE; case GDK_KEY_k: /* initiate search (BOTH hands) */ gtk_entry_set_text(GTK_ENTRY(c->location), "/"); gtk_editable_set_position(GTK_EDITABLE(c->location), -1); return TRUE; case GDK_KEY_c: /* reload trusted certs (left hand) */ trust_user_certs(wc); return TRUE; } } else { switch (((GdkEventKey *)event)->keyval) { case GDK_KEY_KP_Enter: case GDK_KEY_Return: gtk_widget_grab_focus(c->web_view); t = gtk_entry_get_text(GTK_ENTRY(c->location)); if (t != NULL && t[0] == '/') { if (search_text != NULL) g_free(search_text); search_text = g_strdup(t + 1); /* XXX whacky */ search(c, 0); } else if (!keywords_try_search(WEBKIT_WEB_VIEW(c->web_view), t)) { f = ensure_uri_scheme(t); webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), f); g_free(f); } return TRUE; case GDK_KEY_Escape: t = webkit_web_view_get_uri(WEBKIT_WEB_VIEW(c->web_view)); gtk_entry_set_text(GTK_ENTRY(c->location), (t == NULL ? __NAME__ : t)); return TRUE; } } } return FALSE; }
WebKitWebView * client_new(const gchar *uri) { struct Client *c; WebKitWebContext *wc; gchar *f; if (uri != NULL && cooperative_instances && !cooperative_alone) { write(cooperative_pipe_fp, uri, strlen(uri)); write(cooperative_pipe_fp, "\n", 1); return NULL; } c = malloc(sizeof(struct Client)); if (!c) { fprintf(stderr, __NAME__": fatal: malloc failed\n"); exit(EXIT_FAILURE); } c->hover_uri = NULL; c->win = NULL; if (embed != 0) { c->win = gtk_plug_new(embed); if (!gtk_plug_get_embedded(GTK_PLUG(c->win))) { fprintf(stderr, __NAME__": Can't plug-in to XID %ld.\n", embed); gtk_widget_destroy(c->win); c->win = NULL; embed = 0; } } if (c->win == NULL) { c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_wmclass(GTK_WINDOW(c->win), __NAME__, __NAME_CAPITALIZED__); } gtk_window_set_default_size(GTK_WINDOW(c->win), 800, 600); g_signal_connect(G_OBJECT(c->win), "destroy", G_CALLBACK(client_destroy), c); gtk_window_set_title(GTK_WINDOW(c->win), __NAME__); c->web_view = webkit_web_view_new(); wc = webkit_web_view_get_context(WEBKIT_WEB_VIEW(c->web_view)); webkit_web_view_set_zoom_level(WEBKIT_WEB_VIEW(c->web_view), global_zoom); g_signal_connect(G_OBJECT(c->web_view), "notify::title", G_CALLBACK(changed_title), c); g_signal_connect(G_OBJECT(c->web_view), "notify::uri", G_CALLBACK(changed_uri), c); g_signal_connect(G_OBJECT(c->web_view), "notify::estimated-load-progress", G_CALLBACK(changed_load_progress), c); g_signal_connect(G_OBJECT(c->web_view), "create", G_CALLBACK(client_new_request), NULL); g_signal_connect(G_OBJECT(c->web_view), "close", G_CALLBACK(client_destroy_request), c); g_signal_connect(G_OBJECT(c->web_view), "decide-policy", G_CALLBACK(decide_policy), NULL); g_signal_connect(G_OBJECT(c->web_view), "key-press-event", G_CALLBACK(key_web_view), c); g_signal_connect(G_OBJECT(c->web_view), "button-press-event", G_CALLBACK(key_web_view), c); g_signal_connect(G_OBJECT(c->web_view), "scroll-event", G_CALLBACK(key_web_view), c); g_signal_connect(G_OBJECT(c->web_view), "mouse-target-changed", G_CALLBACK(hover_web_view), c); g_signal_connect(G_OBJECT(c->web_view), "web-process-crashed", G_CALLBACK(crashed_web_view), c); if (!initial_wc_setup_done) { if (accepted_language[0] != NULL) webkit_web_context_set_preferred_languages(wc, accepted_language); g_signal_connect(G_OBJECT(wc), "download-started", G_CALLBACK(download_handle_start), NULL); trust_user_certs(wc); initial_wc_setup_done = TRUE; } if (user_agent != NULL) g_object_set(G_OBJECT(webkit_web_view_get_settings(WEBKIT_WEB_VIEW(c->web_view))), "user-agent", user_agent, NULL); c->location = gtk_entry_new(); g_signal_connect(G_OBJECT(c->location), "key-press-event", G_CALLBACK(key_location), c); /* XXX Progress bars don't work/look as intended anymore. Level bars * are a dirty workaround (kind of). */ c->progress = gtk_level_bar_new(); gtk_level_bar_set_value(GTK_LEVEL_BAR(c->progress), 0); gtk_widget_set_size_request(c->progress, 100, -1); c->top_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start(GTK_BOX(c->top_box), c->location, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(c->top_box), c->progress, FALSE, FALSE, 0); c->vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); gtk_box_pack_start(GTK_BOX(c->vbox), c->top_box, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(c->vbox), c->web_view, TRUE, TRUE, 0); gtk_container_add(GTK_CONTAINER(c->win), c->vbox); gtk_widget_grab_focus(c->web_view); gtk_widget_show_all(c->win); if (uri != NULL) { f = ensure_uri_scheme(uri); webkit_web_view_load_uri(WEBKIT_WEB_VIEW(c->web_view), f); g_free(f); } clients++; return WEBKIT_WEB_VIEW(c->web_view); }
static void browserWindowConstructed(GObject *gObject) { BrowserWindow *window = BROWSER_WINDOW(gObject); WebKitSettings *settings = webkit_web_view_get_settings(window->webView); /*init minimumZoomLevel, maximumZoomLevel sunhaiming add.*/ minimumZoomLevel = zoom_factor[0]; maximumZoomLevel = zoom_factor[settings->pageZoomNum - 1]; // browserWindowUpdateZoomActions(window); g_signal_connect(window->webView, "notify::uri", G_CALLBACK(webViewURIChanged), window); g_signal_connect(window->webView, "notify::estimated-load-progress", G_CALLBACK(webViewLoadProgressChanged), window); g_signal_connect(window->webView, "notify::title", G_CALLBACK(webViewTitleChanged), window); g_signal_connect(window->webView, "create", G_CALLBACK(webViewCreate), window); g_signal_connect(window->webView, "load-failed", G_CALLBACK(webViewLoadFailed), window); g_signal_connect(window->webView, "decide-policy", G_CALLBACK(webViewDecidePolicy), window); g_signal_connect(window->webView, "permission-request", G_CALLBACK(webViewDecidePermissionRequest), window); g_signal_connect(window->webView, "mouse-target-changed", G_CALLBACK(webViewMouseTargetChanged), window); // g_signal_connect(window->webView, "notify::zoom-level", G_CALLBACK(webViewZoomLevelChanged), window); g_signal_connect(window->webView, "notify::favicon", G_CALLBACK(faviconChanged), window); g_signal_connect(window->webView, "enter-fullscreen", G_CALLBACK(webViewEnterFullScreen), window); g_signal_connect(window->webView, "leave-fullscreen", G_CALLBACK(webViewLeaveFullScreen), window); g_signal_connect(window->webView, "notify::is-loading", G_CALLBACK(webViewIsLoadingChanged), window); g_signal_connect(webkit_web_view_get_context(window->webView), "download-started", G_CALLBACK(downloadStarted), window); window->searchBar = BROWSER_SEARCH_BAR(browser_search_bar_new(window->webView)); browser_search_bar_add_accelerators(window->searchBar, window->accelGroup); gtk_box_pack_start(GTK_BOX(window->mainBox), GTK_WIDGET(window->searchBar), FALSE, FALSE, 0); WebKitBackForwardList *backForwadlist = webkit_web_view_get_back_forward_list(window->webView); g_signal_connect(backForwadlist, "changed", G_CALLBACK(backForwadlistChanged), window); WebKitWebInspector *inspectorWindow = webkit_web_view_get_inspector(WEBKIT_WEB_VIEW(window->webView)); g_signal_connect(inspectorWindow, "open-window", G_CALLBACK(inspectorWasOpenedInAnotherWindow), window); g_signal_connect(inspectorWindow, "closed", G_CALLBACK(inspectorWasClosed), window); GtkWidget *overlay = gtk_overlay_new(); gtk_box_pack_start(GTK_BOX(window->mainBox), overlay, TRUE, TRUE, 0); gtk_widget_show(overlay); window->statusLabel = gtk_label_new(NULL); gtk_widget_set_halign(window->statusLabel, GTK_ALIGN_START); gtk_widget_set_valign(window->statusLabel, GTK_ALIGN_END); gtk_widget_set_margin_left(window->statusLabel, 1); gtk_widget_set_margin_right(window->statusLabel, 1); gtk_widget_set_margin_top(window->statusLabel, 1); gtk_widget_set_margin_bottom(window->statusLabel, 1); gtk_overlay_add_overlay(GTK_OVERLAY(overlay), window->statusLabel); gtk_container_add(GTK_CONTAINER(overlay), GTK_WIDGET(window->webView)); window->fullScreenMessageLabel = gtk_label_new(NULL); gtk_widget_set_halign(window->fullScreenMessageLabel, GTK_ALIGN_CENTER); gtk_widget_set_valign(window->fullScreenMessageLabel, GTK_ALIGN_CENTER); gtk_widget_set_no_show_all(window->fullScreenMessageLabel, TRUE); gtk_overlay_add_overlay(GTK_OVERLAY(overlay), window->fullScreenMessageLabel); gtk_widget_show(GTK_WIDGET(window->webView)); //<wangc attach webview to tab window->overlay=overlay; GtkWidget *btab = gtk_button_new_with_label ("Tab"); gtk_box_pack_start (GTK_BOX(window->boxtab), btab, FALSE, FALSE, 0); int tabid=window->tabmng->generateTabId(window->tabmng); TabInfo* ti=(TabInfo*)malloc(sizeof(TabInfo)); ti->window=window; ti->tabid=tabid; g_signal_connect (G_OBJECT (btab), "clicked", G_CALLBACK (cbShowTab), ti); gtk_widget_show (btab); window->tabmng->addTab(window->tabmng,tabid,window->overlay,window->webView); //> }