バージョン: 1.2.0-build2
最終更新: 2026-07-30
言語: 日本語 |
BlinkWebView が発する GObject シグナル 7
本のリファレンスです。ページの
ロード状態・URL・タイトルの変化、新規ウィンドウ要求、JS
からのメッセージ、
権限要求を受け取れます。
本ページはエンジン実装を実測して書かれています。ハンドラやシグナルの状況は
1.2.0-build2 時点で再確認しました。
旧版 (2026-07-29 以前) からの重大な訂正: 旧版は
title-changed/
uri-changedのコールバックに文字列引数があるかのように記載していましたが、
両シグナルに引数はありません。旧版のシグネチャどおりに書くと
user_dataが文字列引数の位置に入り、クラッシュやメモリ破壊の原因に
なります。本ページのシグネチャが実装どおりの正です。
| シグナル名 | 追加引数 | 発火タイミング | 用途 |
|---|---|---|---|
load-changed |
BlinkLoadEvent | ロード状態変化 (下記の表に注意) | プログレス表示、UI更新 |
load-failed |
error_code (int), failing_uri (この順) | コミットされない失敗のみ (下記) | エラーハンドリング |
title-changed |
なし — 値は get_title() で取る |
タイトル変化 | ウィンドウタイトル更新 |
uri-changed |
なし — 値は get_uri() で取る |
URL 変化 | アドレスバー更新 |
new-window-requested |
url | window.open() / target="_blank" |
新規ウィンドウ要求の通知 (制御は不可、下記) |
message-received |
name, data (2 引数) | ページ JS からの postMessage |
JS→C 連携 (アプリ連携 API) |
permission-request |
BlinkPermissionRequest* | ページが権限を要求 | 位置情報・通知等の許可判断 (既定は拒否・同期応答必須) |
GtkWidget 由来のプロパティ通知 notify::uri
/ notify::title /
notify::is-loading も使えます (WebKitGTK からの移行では
notify::uri /
notify::title をそのまま流用するのが最も簡単です)。
load_uri() が同期発火するシグナル (下記) は「API
を呼んだtitle-changed / uri-changed
に引数はありません。 値はハンドラ内でblink_web_view_get_title() /
blink_web_view_get_uri() から取ります。g_strdup() してください。static void on_title_changed(BlinkWebView *view, gpointer user_data) {
GtkWindow *win = GTK_WINDOW(user_data);
const char *title = blink_web_view_get_title(view); /* 引数でなく getter */
gtk_window_set_title(win, title ? title : "BlinkGTK");
}
static void on_uri_changed(BlinkWebView *view, gpointer user_data) {
GtkEditable *entry = GTK_EDITABLE(user_data);
const char *uri = blink_web_view_get_uri(view);
gtk_editable_set_text(entry, uri ? uri : "");
}
g_signal_connect(view, "title-changed", G_CALLBACK(on_title_changed), win);
g_signal_connect(view, "uri-changed", G_CALLBACK(on_uri_changed), entry);void user_function(BlinkWebView* web_view,
BlinkLoadEvent load_event,
gpointer user_data);typedef enum {
BLINK_LOAD_STARTED = 0,
BLINK_LOAD_COMMITTED = 1,
BLINK_LOAD_FINISHED = 2,
BLINK_LOAD_REDIRECTED = 3 /* 予約 — 現在のランタイムは発火しません */
} BlinkLoadEvent;BLINK_LOAD_REDIRECTED
は現在発火しません (将来のための予約値)。if (ev == 3) などは壊れます)| 値 | 実際の発火条件 |
|---|---|
STARTED |
blink_web_view_load_uri() /
load_html()
を呼んだときに同期発火。それ以外では来ません —
リンククリック・location.href・go_back()/go_forward()/reload()・ページ側起点の遷移では発火しない
(WebKitGTK との最大の非互換点) |
COMMITTED |
ナビゲーションのコミット時。ただしフレームの区別なし — iframe のロードや、pushState / fragment 移動 (same-document) でも毎回発火します。「新しいページに入った」の判定には使えません |
FINISHED |
メインフレームの onload 完了。iframe では来ない。pushState / fragment では来ない。履歴の戻る/進むがキャッシュ復元 (BFCache) だった場合も来ない |
| 操作 | STARTED | COMMITTED | FINISHED | uri-changed |
|---|---|---|---|---|
load_uri() (通常遷移) |
○ | ○ | ○ | ○ (2 回のことあり、下記) |
load_html() |
○ | ○ | ○ | — |
リンククリック / location.href |
— | ○ | ○ | ○ |
pushState / fragment (#foo) |
— | ○ | — | ○ |
go_back() / go_forward() (通常) |
— | ○ | ○ | ○ |
| 同 (BFCache 復元時) | — | ○ | — | ○ |
reload() |
— | ○ | ○ | — (URL 不変) |
| iframe のロード・遷移 | — | ○ (iframe ごと) | — | — |
FINISHED の直前に、エンジンは注入 CSS (アプリ連携 API)
と JS メッセージブリッジ (window.blinkgtk)
のセットアップを済ませています。
FINISHED ハンドラの中から execute_javascript()
を呼べばブリッジは使えます。
ただし FINISHED は onload
であり、ページが動的に組み立てるコンテンツの完成
までは意味しません (描画完成の通知は現在未提供です)。
FINISHED
だけで止めると永久スピナーになるケースがあります:
load-failed
で止めるblink_web_view_is_loading()
を保険にした/* FINISHED または load-failed で止め、無音ケースはタイムアウトで拾う */void user_function(BlinkWebView* web_view,
int error_code,
const char* failing_uri,
gpointer user_data);引数は (error_code, failing_uri) の順です。
逆順で書いたコールバックは
ポインタを整数として読み、クラッシュや文字化けの原因になります。
発火条件は「コミットされずに終わったナビゲーション + net
エラーあり」
だけです。帰結:
| ケース | load-failed | 実際に起きること |
|---|---|---|
| ユーザー操作・新しい遷移によるキャンセル | ○ (最頻) | error_code = -3
(ERR_ABORTED)。正常な操作でも頻繁に飛ぶため、無条件にエラーダイアログを出すと乱発します |
| DNS 失敗・接続不能 (例: -105, -102) | — (原則) | Chromium がエラーページをコミットするため、COMMITTED + FINISHED が来て既定のエラーページが表示されます |
| HTTP 404 / 500 | — | 正常コミット (net エラーではない)。COMMITTED + FINISHED |
| 画像・CSS・fetch などサブリソースの失敗 | — | ナビゲーションではないため対象外 |
| iframe のナビゲーション中断 | ○ | failing_uri は iframe の URL —
メインページの URL と比較するガードを推奨 |
| ダウンロード化 / 204・205 | — | どのシグナルも来ません |
値は Chromium の net エラーコードの生の負値です (-3,
-105, …)。
ヘッダの BlinkLoadError enum
(BLINK_LOAD_ERROR_NETWORK 等) は現在の
ランタイムでは使われません — C では int
として扱ってください。
| 値 | 定数名 (参考) | 意味 |
|---|---|---|
| -3 | net::ERR_ABORTED |
中断 (最頻・正常操作でも発生) |
| -7 | net::ERR_TIMED_OUT |
タイムアウト |
| -105 | net::ERR_NAME_NOT_RESOLVED |
DNS 解決失敗 (通常はエラーページがコミットされ load-failed は来ない) |
完全なリストは Chromium net_error_list.h を参照してください。
static void on_load_failed(BlinkWebView *view, int error_code,
const char *failing_uri, gpointer user_data) {
if (error_code == -3) /* ERR_ABORTED: 正常操作の副産物。無視が基本 */
return;
const char *current = blink_web_view_get_uri(view);
if (current && failing_uri && strcmp(current, failing_uri) != 0)
return; /* iframe など、表示中ページ以外の失敗 */
g_message("load failed: %d %s", error_code, failing_uri);
}void user_function(BlinkWebView* web_view, gpointer user_data);値はハンドラ内で blink_web_view_get_uri() /
blink_web_view_get_title()
で取得します。
| 観点 | 動作 |
|---|---|
| 発火点 | ①load_uri() 呼び出し時 (同期)
②ナビゲーションのコミット時。redirect の途中経過では来ません |
| 同一遷移で 2 回来ることがある | ①は渡された文字列、②は正規化済み URL
で重複判定するため、"http://example.com" →
"http://example.com/" のような差で 2
回発火します。履歴スタックを自作する場合はアプリ側でも重複排除してください |
①の時点の get_uri() |
まだコミットされていない URL を返します。遷移が失敗するとこの値は「実際には表示されなかった URL」になります |
| 中断時の巻き戻し | ありません。失敗した遷移の URL
がアドレスバーに残る形になるため、load-failed で
get_uri() を読み直して戻すのが確実です |
load_html() |
発火しません |
| 観点 | 動作 |
|---|---|
| 発火条件 | ページの <title>
設定時・document.title の動的変更時
(メインフレームのみ) |
<title> の無いページ |
発火しません (空文字で来るのではなく無音) |
| 履歴の戻る/進む | 履歴側に同じタイトルが記録済みだと発火しないことがあります。タブ
UI は notify::title の併用が確実です |
| 値の整形 | 前後の空白・改行は除去済みで届きます |
get_title() の返り値 |
空になりません — タイトル未設定ページでは URL を整形した文字列が返ります。「タイトル無し」を空文字で判定するコードは動きません |
void user_function(BlinkWebView* web_view,
const char* url,
gpointer user_data);window.open() や <a target="_blank">
が起きたことを知らせるシグナルで、
開かせない・別の場所に開く、という制御はできません
(戻り値なし)。
現在のエンジンはシングルウィンドウ動作で、シグナル発火の時点で既に同じ
WebView を対象 URL へナビゲートし始めています。
load_uri(url)
を呼ばないでください — エンジンが既にg_idle_add()
で遅延させてtarget="_blank"
系ではエンジンの遷移が同期呼び出しに勝つため)window.open() の戻り値:
通常は「直後に閉じられたclosed === true)、noopener
指定時は null です。ページ JS の window.blinkgtk.postMessage()
を受けるシグナルです。
引数は (name, data) の 2 つ (チャネル名と Base64
データ)。詳細な
セマンティクス (エンコーディング・多重購読・C API 版ハンドラとの関係)
は
アプリ連携 API
にまとめてあります。
位置情報・通知などの権限要求を受けるシグナルです。
static gboolean on_permission(BlinkWebView *view,
BlinkPermissionRequest *req,
gpointer user_data) {
const char *kind = blink_permission_request_get_type_name(req);
if (g_strcmp0(kind, "notifications") == 0)
blink_permission_request_allow(req); /* 通知だけ許可 */
else
blink_permission_request_deny(req);
return TRUE; /* 処理した */
}
g_signal_connect(view, "permission-request", G_CALLBACK(on_permission), NULL);blink_permission_request_allow() かblink_permission_request_deny()
のどちらか一方を一度だけ、BlinkPermissionRequest
はTRUE
を返して未応答のまま戻ると拒否扱い。無効になったハンドルにblink_permission_request_get_type_name()
が要求種別を返します:"geolocation" / "notifications" /
"audio-capture" /"video-capture" / "midi" /
"clipboard" / "unknown"TRUE を返さなければ要求は拒否されます
(deny-by-default)const char* blink_permission_request_get_type_name(BlinkPermissionRequest* request);
void blink_permission_request_allow(BlinkPermissionRequest* request);
void blink_permission_request_deny(BlinkPermissionRequest* request);実装で保証される順序:
load_uri() 内: uri-changed →
load-changed(STARTED) (この順・同期)notify::is-loading保証されない順序:
load_uri()
等がblink_gtk_shutdown()
の進行中にもシグナルが届くことがあります。そのget_uri() / get_title() が
NULL を返すため、ハンドラはg_strdup() してくださいBlinkWebViewEgl
ウィジェットは現在このページのBlinkWebView のみ)#include <blink_gtk/blink_gtk.h>
#include <gtk/gtk.h>
#include <string.h>
typedef struct {
GtkWidget *window;
GtkWidget *url_entry;
GtkWidget *spinner;
guint spinner_timeout;
} BrowserUI;
static gboolean stop_spinner_fallback(gpointer data) {
BrowserUI *ui = data;
gtk_widget_set_visible(ui->spinner, FALSE);
ui->spinner_timeout = 0;
return G_SOURCE_REMOVE;
}
static void on_load_changed(BlinkWebView *view, BlinkLoadEvent ev,
gpointer user_data) {
BrowserUI *ui = user_data;
if (ev == BLINK_LOAD_STARTED) {
gtk_widget_set_visible(ui->spinner, TRUE);
/* 無音ケース (ダウンロード化・204) の保険 */
if (ui->spinner_timeout)
g_source_remove(ui->spinner_timeout);
ui->spinner_timeout =
g_timeout_add_seconds(30, stop_spinner_fallback, ui);
} else if (ev == BLINK_LOAD_FINISHED) {
gtk_widget_set_visible(ui->spinner, FALSE);
if (ui->spinner_timeout) {
g_source_remove(ui->spinner_timeout);
ui->spinner_timeout = 0;
}
}
}
static void on_load_failed(BlinkWebView *view, int error_code,
const char *failing_uri, gpointer user_data) {
BrowserUI *ui = user_data;
gtk_widget_set_visible(ui->spinner, FALSE);
if (error_code == -3)
return; /* ERR_ABORTED は正常操作の副産物 */
g_message("load failed: %d %s", error_code,
failing_uri ? failing_uri : "");
}
static void on_uri_changed(BlinkWebView *view, gpointer user_data) {
BrowserUI *ui = user_data;
const char *uri = blink_web_view_get_uri(view);
gtk_editable_set_text(GTK_EDITABLE(ui->url_entry), uri ? uri : "");
}
static void on_title_changed(BlinkWebView *view, gpointer user_data) {
BrowserUI *ui = user_data;
const char *title = blink_web_view_get_title(view);
char *t = g_strdup_printf("%s - MyBrowser",
(title && *title) ? title : "(untitled)");
gtk_window_set_title(GTK_WINDOW(ui->window), t);
g_free(t);
}
static void setup_signals(BlinkWebView *view, BrowserUI *ui) {
g_signal_connect(view, "load-changed", G_CALLBACK(on_load_changed), ui);
g_signal_connect(view, "load-failed", G_CALLBACK(on_load_failed), ui);
g_signal_connect(view, "uri-changed", G_CALLBACK(on_uri_changed), ui);
g_signal_connect(view, "title-changed", G_CALLBACK(on_title_changed), ui);
}| WebKitGTK | BlinkGTK | 注意 |
|---|---|---|
load-changed (STARTED) |
load-changed (STARTED) |
非互換: BlinkGTK の STARTED は
load_uri()/load_html()
を呼んだときだけ。リンククリック等では来ません — スピナー開始は STARTED
に依存しない設計に |
load-changed (REDIRECTED) |
— | BlinkGTK では発火しません |
load-changed (COMMITTED / FINISHED) |
同名 | COMMITTED は iframe / same-document でも多重発火する点が異なります |
load-failed |
load-failed |
引数形式が違う (GError ではなく int + uri、順序は error_code が先)。発火条件も狭い (本ページの表を参照) |
notify::title / notify::uri |
そのまま使えます | 移行はこれが最も簡単。専用シグナル (title-changed / uri-changed) は引数なしの点だけ注意 |
create (新規ウィンドウ) |
new-window-requested |
非互換: BlinkGTK は通知のみで、ブロック・別 WebView での open はできません |
permission-request |
permission-request |
同期応答必須 (WebKitGTK のような遅延応答は不可) |
| 項目 | 現状 |
|---|---|
| リダイレクトの検知 | 不可 (BLINK_LOAD_REDIRECTED は予約値) |
| ページ側起点ナビの開始検知 | 不可 (STARTED は API 呼び出し時のみ) |
| 新規ウィンドウ要求の制御 | 不可 (通知のみ・常に同一 view で開く) |
| コミットされる失敗 (DNS 等) の load-failed | 来ない (既定エラーページが表示される) |
| 描画完成の通知 | 未提供 (FINISHED は onload まで) |
| 言語バインディングからの permission-request | 不可 (生ポインタ引数) |
go_back 等): Navigation API| バージョン | 変更 |
|---|---|
| v1.1.0 (2026-07-30) | エンジン実装の実測に基づき全面改訂。title-changed / uri-changed のシグネチャを訂正 (引数なし — 旧版はクラッシュを招く誤記)。BLINK_LOAD_REDIRECTED が発火しない事実、STARTED が API 呼び出し時のみの事実、load-failed の実発火条件 (コミットされない失敗のみ / -3 が最頻)、操作別発火パターン表、発火順序、無音ケース (ダウンロード・204) とスピナー対策、new-window-requested が通知専用である事実を明記 |
| v1.1.0 (2026-07-29 以前) | 旧版 |