Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,12 @@ pub fn build(b: *std.Build) void {
.{ .path = "src/platform/windows/webview2_host.cpp", .pattern = "bridgeOriginForWebViewUrl(source_webview->second, source_url)" },
.{ .path = "src/platform/windows/webview2_host.cpp", .pattern = "webview.spa_fallback = spa_fallback != 0;" },
});
addFileContainsCheckStep(b, file_contains_checker, test_step, "test-devtools-inspector", "Verify DevTools inspector is enabled on Windows and Linux", &.{
.{ .path = "src/platform/windows/webview2_host.cpp", .pattern = "put_AreDevToolsEnabled(TRUE)" },
.{ .path = "src/platform/windows/webview2_host.cpp", .pattern = "OpenDevToolsWindow()" },
.{ .path = "src/platform/linux/gtk_host.c", .pattern = "webkit_settings_set_enable_developer_extras" },
.{ .path = "src/platform/linux/gtk_host.c", .pattern = "webkit_web_view_get_inspector" },
});
addFileContainsCheckStep(b, file_contains_checker, test_step, "test-macos-cef-packaged-assets-webviews", "Verify macOS CEF child WebViews resolve packaged asset URLs before loading", &.{
.{ .path = "src/platform/macos/cef_host.mm", .pattern = "self.assetRoots = [[NSMutableDictionary alloc] init];" },
.{ .path = "src/platform/macos/cef_host.mm", .pattern = "resolvedWebViewURLString:(NSString *)url windowId:(uint64_t)windowId" },
Expand Down
1 change: 1 addition & 0 deletions changelog.d/devtools-inspector.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
feature: **DevTools inspector on Windows & Linux**: press F12 or Ctrl+Shift+I to open the browser DevTools inspector. Right-click "Inspect Element" is also available. Matches the existing macOS Cmd+Option+I behavior.
34 changes: 34 additions & 0 deletions src/platform/linux/gtk_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ typedef struct native_sdk_gtk_window {
* UNDER the WebView (or the WebView over a canvas) set it through
* the same layer channel the child views use. */
int main_webview_layer;
int inspector_open;
/* Last pointer press on a gpu_surface view, in window coordinates —
* what an interactive window move begins from. The device/time pair
* comes from the originating event; a zero time means no press has
Expand Down Expand Up @@ -2277,11 +2278,37 @@ static int native_sdk_shortcut_modifiers_match(uint32_t shortcut_modifiers, GdkM
has_command == needs_command;
}

static gboolean on_inspector_open_window(WebKitWebInspector *inspector, gpointer data) {
(void)inspector;
native_sdk_gtk_window_t *win = data;
win->inspector_open = 1;
return FALSE;
}

static void on_inspector_closed(WebKitWebInspector *inspector, gpointer data) {
(void)inspector;
native_sdk_gtk_window_t *win = data;
win->inspector_open = 0;
}

static gboolean on_shortcut_key_pressed(GtkEventControllerKey *controller, guint keyval, guint keycode, GdkModifierType state, gpointer data) {
(void)controller;
(void)keycode;
native_sdk_gtk_window_t *win = data;
native_sdk_gtk_host_t *host = win ? win->host : NULL;
if (win && win->web_view &&
Comment thread
vercel[bot] marked this conversation as resolved.
(keyval == GDK_KEY_F12 ||
(keyval == GDK_KEY_I && (state & GDK_CONTROL_MASK) && (state & GDK_SHIFT_MASK)))) {
WebKitWebInspector *inspector = webkit_web_view_get_inspector(win->web_view);
if (win->inspector_open) {
webkit_web_inspector_close(inspector);
win->inspector_open = 0;
} else {
webkit_web_inspector_show(inspector);
win->inspector_open = 1;
}
return TRUE;
}
if (!host || host->shortcut_count == 0) return FALSE;
char key_buffer[32];
int uses_implicit_shift = 0;
Expand Down Expand Up @@ -2597,6 +2624,10 @@ static native_sdk_gtk_window_t *native_sdk_create_window_internal(native_sdk_gtk
"user-content-manager", win->content_manager,
NULL));
win->web_view = wv;
WebKitSettings *wk_settings = webkit_web_view_get_settings(wv);
webkit_settings_set_enable_developer_extras(wk_settings, TRUE);
g_signal_connect(webkit_web_view_get_inspector(wv), "open-window", G_CALLBACK(on_inspector_open_window), win);
g_signal_connect(webkit_web_view_get_inspector(wv), "closed", G_CALLBACK(on_inspector_closed), win);
if (!host->scheme_registered) {
webkit_web_context_register_uri_scheme(webkit_web_view_get_context(wv), "zero", native_sdk_asset_scheme_request, host, NULL);
host->scheme_registered = 1;
Expand Down Expand Up @@ -3608,6 +3639,9 @@ int native_sdk_gtk_create_webview(native_sdk_gtk_host_t *host, uint64_t window_i
return 0;
}

WebKitSettings *child_wk_settings = webkit_web_view_get_settings(web_view);
webkit_settings_set_enable_developer_extras(child_wk_settings, TRUE);

native_sdk_gtk_webview_t *webview = &win->webviews[win->webview_count++];
memset(webview, 0, sizeof(*webview));
webview->label = label_copy;
Expand Down
15 changes: 14 additions & 1 deletion src/platform/windows/webview2_host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4101,6 +4101,11 @@ static bool createChildWebView(Host *host, const std::string &key) {
controller->put_ZoomFactor(found->second.zoom);
controller->put_IsVisible(TRUE);
if (found->second.webview) {
ICoreWebView2Settings *settings = nullptr;
if (SUCCEEDED(found->second.webview->get_Settings(&settings)) && settings) {
settings->put_AreDevToolsEnabled(TRUE);
settings->Release();
}
if (found->second.bridge_enabled) {
found->second.webview->AddScriptToExecuteOnDocumentCreated(nativeSdkBridgeScript(), nullptr);
EventRegistrationToken bridge_token = {};
Expand Down Expand Up @@ -4146,7 +4151,7 @@ static bool createChildWebView(Host *host, const std::string &key) {
EventRegistrationToken accelerator_token = {};
uint64_t accelerator_window_id = found->second.window_id;
found->second.controller->add_AcceleratorKeyPressed(Callback<ICoreWebView2AcceleratorKeyPressedEventHandler>(
[host, accelerator_window_id, lifetime](ICoreWebView2Controller *, ICoreWebView2AcceleratorKeyPressedEventArgs *args) -> HRESULT {
[host, key, accelerator_window_id, lifetime](ICoreWebView2Controller *, ICoreWebView2AcceleratorKeyPressedEventArgs *args) -> HRESULT {
auto token = lifetime.lock();
if (!token) return S_OK;
std::lock_guard<std::recursive_mutex> guard(token->mutex);
Expand All @@ -4156,6 +4161,14 @@ static bool createChildWebView(Host *host, const std::string &key) {
if (kind != COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN && kind != COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN) return S_OK;
UINT virtual_key = 0;
if (FAILED(args->get_VirtualKey(&virtual_key))) return S_OK;
if (virtual_key == VK_F12 || (virtual_key == 'I' && keyDown(VK_CONTROL) && keyDown(VK_SHIFT))) {
auto it = host->webviews.find(key);
if (it != host->webviews.end() && it->second.webview) {
it->second.webview->OpenDevToolsWindow();
}
args->put_Handled(TRUE);
return S_OK;
}
if (emitShortcutForWindowId(host, accelerator_window_id, virtual_key)) {
args->put_Handled(TRUE);
}
Expand Down