mirror of
https://github.com/wailsapp/wails.git
synced 2025-05-10 22:19:46 +08:00
Merge branch 'master' into v3-alpha
# Conflicts: # v2/internal/frontend/desktop/windows/go-webview2/webviewloader/env_create.go
This commit is contained in:
commit
ee8eb001c2
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -7,7 +7,7 @@ body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
***Please note: No new bug reports are being accepted for Wails v1***
|
||||
***Please note: No bug reports are currently being accepted for Wails v3***
|
||||
Before submitting this issue, please do the following:
|
||||
- Do a web search for your error. This usually leads to a much better understanding of the issue.
|
||||
- Prove that the error is indeed a Wails bug and not an application bug, with a specific set of steps to reproduce.
|
||||
|
37
.github/workflows/format-markdown-files.yml
vendored
37
.github/workflows/format-markdown-files.yml
vendored
@ -1,37 +0,0 @@
|
||||
name: Format Markdown Files
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
format_markdown_files:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'wailsapp/wails'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Nodejs
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.x
|
||||
|
||||
- name: Install Task
|
||||
uses: arduino/setup-task@v1
|
||||
with:
|
||||
version: 3.x
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Format All Markdown Files
|
||||
run: task format-all-md
|
||||
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: "docs: format document"
|
||||
title: "docs: format document"
|
||||
body: "- [x] Format all Markdown(x) documents"
|
||||
branch: chore/format-markdown-files
|
||||
delete-branch: true
|
||||
draft: false
|
167
README.es.md
Normal file
167
README.es.md
Normal file
@ -0,0 +1,167 @@
|
||||
<p align="center" style="text-align: center">
|
||||
<img src="./assets/images/logo-universal.png" width="55%"><br/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Construye aplicaciones de escritorio usando Go y tecnologías web.
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="https://github.com/wailsapp/wails/blob/master/LICENSE">
|
||||
<img alt="GitHub" src="https://img.shields.io/github/license/wailsapp/wails"/>
|
||||
</a>
|
||||
<a href="https://goreportcard.com/report/github.com/wailsapp/wails">
|
||||
<img src="https://goreportcard.com/badge/github.com/wailsapp/wails" />
|
||||
</a>
|
||||
<a href="https://pkg.go.dev/github.com/wailsapp/wails">
|
||||
<img src="https://pkg.go.dev/badge/github.com/wailsapp/wails.svg" alt="Go Reference"/>
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/issues">
|
||||
<img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" />
|
||||
</a>
|
||||
<a href="https://app.fossa.com/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_shield" alt="FOSSA Status">
|
||||
<img src="https://app.fossa.com/api/projects/git%2Bgithub.com%2Fwailsapp%2Fwails.svg?type=shield" />
|
||||
</a>
|
||||
<a href="https://github.com/avelino/awesome-go" rel="nofollow">
|
||||
<img src="https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg" alt="Awesome" />
|
||||
</a>
|
||||
<a href="https://discord.gg/BrRSWTaxVK">
|
||||
<img alt="Discord" src="https://dcbadge.vercel.app/api/server/BrRSWTaxVK?style=flat"/>
|
||||
</a>
|
||||
<br/>
|
||||
<a href="https://github.com/wailsapp/wails/actions/workflows/build-and-test.yml" rel="nofollow">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/wailsapp/wails/build-and-test.yml?branch=master&logo=Github" alt="Build" />
|
||||
</a>
|
||||
<a href="https://github.com/wailsapp/wails/tags" rel="nofollow">
|
||||
<img alt="GitHub tag (latest SemVer pre-release)" src="https://img.shields.io/github/v/tag/wailsapp/wails?include_prereleases&label=version"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
<strong>
|
||||
<samp>
|
||||
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) ·
|
||||
[한국어](README.ko.md) · [Español](README.es.md)
|
||||
|
||||
</samp>
|
||||
</strong>
|
||||
</div>
|
||||
|
||||
## Tabla de Contenidos
|
||||
|
||||
- [Tabla de Contenidos](#tabla-de-contenidos)
|
||||
- [Introducción](#introducción)
|
||||
- [Funcionalidades](#funcionalidades)
|
||||
- [Plan de Trabajo](#plan-de-trabajo)
|
||||
- [Empezando](#empezando)
|
||||
- [Patrocinadores](#patrocinadores)
|
||||
- [Preguntas Frecuentes](#preguntas-frecuentes)
|
||||
- [Estrellas a lo Largo del Tiempo](#estrellas-a-lo-largo-del-tiempo)
|
||||
- [Colaboradores](#colaboradores)
|
||||
- [Licencia](#licencia)
|
||||
- [Inspiración](#inspiración)
|
||||
|
||||
## Introducción
|
||||
|
||||
El método tradicional para proveer una interfaz web en programas hechos con Go
|
||||
es a través del servidor web incorporado. Wails ofrece un enfoque diferente al
|
||||
permitir combinar el código hecho en Go con un frontend web en un solo archivo
|
||||
binario. Las herramientas que proporcionamos facilitan este trabajo para ti, al
|
||||
crear, compilar y empaquetar tu proyecto. ¡Lo único que debes hacer es ponerte
|
||||
creativo!
|
||||
|
||||
## Funcionalidades
|
||||
|
||||
- Utiliza Go estándar para el backend
|
||||
- Utiliza cualquier tecnología frontend con la que ya estés familiarizado para
|
||||
construir tu interfaz de usuario
|
||||
- Crea rápidamente interfaces de usuario enriquecidas para tus programas en Go
|
||||
utilizando plantillas predefinidas
|
||||
- Invoca fácilmente métodos de Go desde Javascript
|
||||
- Definiciones de Typescript generadas automáticamente para tus structs y
|
||||
métodos de Go
|
||||
- Diálogos y menús nativos
|
||||
- Soporte nativo de modo oscuro / claro
|
||||
- Soporte de translucidez y efectos de ventana esmerilada
|
||||
- Sistema de eventos unificado entre Go y Javascript
|
||||
- Herramienta CLI potente para generar y construir tus proyectos rápidamente
|
||||
- Multiplataforma
|
||||
- Usa motores de renderizado nativos - ¡_sin navegador integrado_!
|
||||
|
||||
### Plan de Trabajo
|
||||
|
||||
El plan de trabajo se puede encontrar
|
||||
[aqui](https://github.com/wailsapp/wails/discussions/1484). Por favor,
|
||||
consúltalo antes de abrir una solicitud de mejora.
|
||||
|
||||
## Empezando
|
||||
|
||||
Las instrucciones de instalacion se encuentran en nuestra
|
||||
[pagina web oficial](https://wails.io/docs/gettingstarted/installation).
|
||||
|
||||
## Patrocinadores
|
||||
|
||||
Este Proyecto cuenta con el apoyo de estas amables personas/ compañías:
|
||||
<img src="website/static/img/sponsors.svg" style="width:100%;max-width:800px;"/>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://wails.io/img/sponsor/jetbrains-grayscale.webp" style="width: 100px"/>
|
||||
</p>
|
||||
|
||||
## Preguntas Frecuentes
|
||||
|
||||
- ¿Es esta una alternativa a Electron?
|
||||
|
||||
Depende de tus requisitos. Está diseñado para facilitar a los programadores de
|
||||
Go la creación de aplicaciones de escritorio livianas o agregar una interfaz
|
||||
gráfica a sus aplicaciones existentes. Wails ofrece elementos nativos como
|
||||
menús y diálogos, por lo que podría considerarse una alternativa liviana a
|
||||
Electron.
|
||||
|
||||
- ¿A quien esta dirigido este proyecto?
|
||||
|
||||
El proyecto esta dirigido a programadores de Go que desean integrar una
|
||||
interfaz HMTL/JS/CSS en sus aplicaciones, sin tener que recurrir a la creación
|
||||
de un servidor y abrir el navegador para visualizarla.
|
||||
|
||||
- ¿Cual es el significado del nombre?
|
||||
|
||||
Cuando vi WebView, pensé: "Lo que realmente quiero es una herramienta para
|
||||
construir una aplicación WebView, algo similar a lo que Rails es para Ruby".
|
||||
Así que inicialmente fue un juego de palabras (WebView en Rails). Además, por
|
||||
casualidad, también es homófono del nombre en inglés del
|
||||
[país](https://en.wikipedia.org/wiki/Wales) del que provengo. Así que se quedó
|
||||
con ese nombre.
|
||||
|
||||
## Estrellas a lo Largo del Tiempo
|
||||
|
||||
[](https://star-history.com/#wailsapp/wails&Date)
|
||||
|
||||
## Colaboradores
|
||||
|
||||
¡La lista de colaboradores se está volviendo demasiado grande para el archivo
|
||||
readme! Todas las personas increíbles que han contribuido a este proyecto tienen
|
||||
su propia página [aqui](https://wails.io/credits#contributors).
|
||||
|
||||
## Licencia
|
||||
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Fwailsapp%2Fwails?ref=badge_large)
|
||||
|
||||
## Inspiración
|
||||
|
||||
Este proyecto fue construido mientras se escuchaban estos álbumes:
|
||||
|
||||
- [Manic Street Preachers - Resistance Is Futile](https://open.spotify.com/album/1R2rsEUqXjIvAbzM0yHrxA)
|
||||
- [Manic Street Preachers - This Is My Truth, Tell Me Yours](https://open.spotify.com/album/4VzCL9kjhgGQeKCiojK1YN)
|
||||
- [The Midnight - Endless Summer](https://open.spotify.com/album/4Krg8zvprquh7TVn9OxZn8)
|
||||
- [Gary Newman - Savage (Songs from a Broken World)](https://open.spotify.com/album/3kMfsD07Q32HRWKRrpcexr)
|
||||
- [Steve Vai - Passion & Warfare](https://open.spotify.com/album/0oL0OhrE2rYVns4IGj8h2m)
|
||||
- [Ben Howard - Every Kingdom](https://open.spotify.com/album/1nJsbWm3Yy2DW1KIc1OKle)
|
||||
- [Ben Howard - Noonday Dream](https://open.spotify.com/album/6astw05cTiXEc2OvyByaPs)
|
||||
- [Adwaith - Melyn](https://open.spotify.com/album/2vBE40Rp60tl7rNqIZjaXM)
|
||||
- [Gwidaith Hen Fran - Cedors Hen Wrach](https://open.spotify.com/album/3v2hrfNGINPLuDP0YDTOjm)
|
||||
- [Metallica - Metallica](https://open.spotify.com/album/2Kh43m04B1UkVcpcRa1Zug)
|
||||
- [Bloc Party - Silent Alarm](https://open.spotify.com/album/6SsIdN05HQg2GwYLfXuzLB)
|
||||
- [Maxthor - Another World](https://open.spotify.com/album/3tklE2Fgw1hCIUstIwPBJF)
|
||||
- [Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v)
|
||||
[Alun Tan Lan - Y Distawrwydd](https://open.spotify.com/album/0c32OywcLpdJCWWMC6vB8v)
|
@ -42,7 +42,8 @@
|
||||
<strong>
|
||||
<samp>
|
||||
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) ·
|
||||
[한국어](README.ko.md) · [Español](README.es.md)
|
||||
|
||||
</samp>
|
||||
</strong>
|
||||
|
@ -42,7 +42,8 @@
|
||||
<strong>
|
||||
<samp>
|
||||
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) ·
|
||||
[한국어](README.ko.md) · [Español](README.es.md)
|
||||
|
||||
</samp>
|
||||
</strong>
|
||||
|
@ -40,7 +40,8 @@
|
||||
<strong>
|
||||
<samp>
|
||||
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) ·
|
||||
[한국어](README.ko.md) · [Español](README.es.md)
|
||||
|
||||
</samp>
|
||||
</strong>
|
||||
|
@ -42,7 +42,8 @@
|
||||
<strong>
|
||||
<samp>
|
||||
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) · [한국어](README.ko.md)
|
||||
[English](README.md) · [简体中文](README.zh-Hans.md) · [日本語](README.ja.md) ·
|
||||
[한국어](README.ko.md) · [Español](README.es.md)
|
||||
|
||||
</samp>
|
||||
</strong>
|
||||
@ -87,7 +88,7 @@
|
||||
|
||||
## 快速入门
|
||||
|
||||
使用说明在 [官网](https://wails.io/docs/gettingstarted/installation)。
|
||||
使用说明在 [官网](https://wails.io/zh-Hans/docs/gettingstarted/installation/)。
|
||||
|
||||
## 赞助商
|
||||
|
||||
|
42
scripts/sponsors/package-lock.json
generated
42
scripts/sponsors/package-lock.json
generated
@ -13,9 +13,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/utils": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.5.2.tgz",
|
||||
"integrity": "sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA=="
|
||||
"version": "0.7.4",
|
||||
"resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.4.tgz",
|
||||
"integrity": "sha512-qe8Nmh9rYI/HIspLSTwtbMFPj6dISG6+dJnOguTlPNXtCvS2uezdxscVBb7/3DrmNbQK49TDqpkSQ1chbRGdpQ==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
@ -419,9 +422,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/defu": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.1.tgz",
|
||||
"integrity": "sha512-aA964RUCsBt0FGoNIlA3uFgo2hO+WWC0fiC6DBps/0SFzkKcYoM/3CzVLIa5xSsrFjdioMdYgAIbwo80qp2MoA=="
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.2.tgz",
|
||||
"integrity": "sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ=="
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
@ -951,9 +954,9 @@
|
||||
"integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.16.0.tgz",
|
||||
"integrity": "sha512-L3BJStEf5NAqNuzrpfbN71dp43mYIcBUlCRea/vdyv5dW/AYa1d4bpelko4SHdY3I6eN9Wzyasxirj1/vv5kmg==",
|
||||
"version": "1.18.2",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz",
|
||||
"integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==",
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
@ -1443,9 +1446,9 @@
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.3.8",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
@ -1765,13 +1768,16 @@
|
||||
"integrity": "sha512-fk6CmUgwKCfX79EzcDQQpSCMxrHstvbLswFChHS0Vump+kFkw7nJBfTZoC1j0bOGoY9I7R3n2DGek5ajbcYnOw=="
|
||||
},
|
||||
"node_modules/unconfig": {
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmmirror.com/unconfig/-/unconfig-0.3.7.tgz",
|
||||
"integrity": "sha512-1589b7oGa8ILBYpta7TndM5mLHLzHUqBfhszeZxuUBrjO/RoQ52VGVWsS3w0C0GLNxO9RPmqkf6BmIvBApaRdA==",
|
||||
"version": "0.3.9",
|
||||
"resolved": "https://registry.npmjs.org/unconfig/-/unconfig-0.3.9.tgz",
|
||||
"integrity": "sha512-8yhetFd48M641mxrkWA+C/lZU4N0rCOdlo3dFsyFPnBHBjMJfjT/3eAZBRT2RxCRqeBMAKBVgikejdS6yeBjMw==",
|
||||
"dependencies": {
|
||||
"@antfu/utils": "^0.5.2",
|
||||
"defu": "^6.1.0",
|
||||
"jiti": "^1.16.0"
|
||||
"@antfu/utils": "^0.7.2",
|
||||
"defu": "^6.1.2",
|
||||
"jiti": "^1.18.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/undici": {
|
||||
|
@ -57,6 +57,7 @@ func buildApplication(f *flags.Build) error {
|
||||
OutputFile: f.OutputFilename,
|
||||
CleanBinDirectory: f.Clean,
|
||||
Mode: f.GetBuildMode(),
|
||||
Devtools: f.Debug || f.Devtools,
|
||||
Pack: !f.NoPackage,
|
||||
LDFlags: f.LdFlags,
|
||||
Compiler: f.Compiler,
|
||||
@ -82,6 +83,7 @@ func buildApplication(f *flags.Build) error {
|
||||
{"Compiler", f.GetCompilerPath()},
|
||||
{"Skip Bindings", bool2Str(f.SkipBindings)},
|
||||
{"Build Mode", f.GetBuildModeAsString()},
|
||||
{"Devtools", bool2Str(buildOptions.Devtools)},
|
||||
{"Frontend Directory", projectOptions.GetFrontendDir()},
|
||||
{"Obfuscated", bool2Str(f.Obfuscated)},
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ type Build struct {
|
||||
ForceBuild bool `name:"f" description:"Force build of application"`
|
||||
UpdateWailsVersionGoMod bool `name:"u" description:"Updates go.mod to use the same Wails version as the CLI"`
|
||||
Debug bool `description:"Builds the application in debug mode"`
|
||||
Devtools bool `description:"Enable Devtools in productions, Already enabled in debug mode (-debug)"`
|
||||
NSIS bool `description:"Generate NSIS installer for Windows"`
|
||||
TrimPath bool `description:"Remove all file system paths from the resulting executable"`
|
||||
WindowsConsole bool `description:"Keep the console when building for Windows"`
|
||||
|
@ -120,6 +120,7 @@ func (d *Dev) GenerateBuildOptions() *build.Options {
|
||||
result := &build.Options{
|
||||
OutputType: "dev",
|
||||
Mode: build.Dev,
|
||||
Devtools: true,
|
||||
Arch: runtime.GOARCH,
|
||||
Pack: true,
|
||||
Platform: runtime.GOOS,
|
||||
|
@ -45,6 +45,9 @@ VIAddVersionKey "FileVersion" "${INFO_PRODUCTVERSION}"
|
||||
VIAddVersionKey "LegalCopyright" "${INFO_COPYRIGHT}"
|
||||
VIAddVersionKey "ProductName" "${INFO_PRODUCTNAME}"
|
||||
|
||||
# Enable HiDPI support. https://nsis.sourceforge.io/Reference/ManifestDPIAware
|
||||
ManifestDPIAware true
|
||||
|
||||
!include "MUI.nsh"
|
||||
|
||||
!define MUI_ICON "..\icon.ico"
|
||||
|
45
v2/go.mod
45
v2/go.mod
@ -13,33 +13,33 @@ require (
|
||||
github.com/go-git/go-git/v5 v5.3.0
|
||||
github.com/go-ole/go-ole v1.2.6
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/google/uuid v1.1.2
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/jackmordaunt/icns v1.0.0
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e
|
||||
github.com/labstack/echo/v4 v4.9.0
|
||||
github.com/labstack/gommon v0.3.1
|
||||
github.com/labstack/echo/v4 v4.10.2
|
||||
github.com/labstack/gommon v0.4.0
|
||||
github.com/leaanthony/clir v1.3.0
|
||||
github.com/leaanthony/debme v1.2.1
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1
|
||||
github.com/leaanthony/go-ansi-parser v1.6.0
|
||||
github.com/leaanthony/gosod v1.0.3
|
||||
github.com/leaanthony/slicer v1.5.0
|
||||
github.com/leaanthony/slicer v1.6.0
|
||||
github.com/leaanthony/winicon v1.0.0
|
||||
github.com/matryer/is v1.4.0
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pterm/pterm v0.12.49
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
|
||||
github.com/samber/lo v1.27.1
|
||||
github.com/stretchr/testify v1.8.0
|
||||
github.com/samber/lo v1.38.1
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/tc-hib/winres v0.1.5
|
||||
github.com/tidwall/sjson v1.1.7
|
||||
github.com/tkrajina/go-reflector v0.5.5
|
||||
github.com/tkrajina/go-reflector v0.5.6
|
||||
github.com/wailsapp/go-webview2 v1.0.1
|
||||
github.com/wailsapp/mimetype v1.4.1
|
||||
github.com/wzshiming/ctc v1.2.3
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
|
||||
golang.org/x/net v0.7.0
|
||||
golang.org/x/sys v0.5.0
|
||||
golang.org/x/tools v0.1.12
|
||||
golang.org/x/mod v0.8.0
|
||||
golang.org/x/net v0.10.0
|
||||
golang.org/x/sys v0.8.0
|
||||
golang.org/x/tools v0.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
@ -59,12 +59,13 @@ require (
|
||||
github.com/gorilla/css v1.0.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
|
||||
github.com/kr/pretty v0.3.0 // indirect
|
||||
github.com/lithammer/fuzzysearch v1.1.5 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.17 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
@ -73,23 +74,23 @@ require (
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/tidwall/gjson v1.9.3 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/wzshiming/winseq v0.0.0-20200112104235-db357dc107ae // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
|
||||
github.com/yuin/goldmark v1.4.13 // indirect
|
||||
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
||||
golang.org/x/crypto v0.1.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
||||
golang.org/x/image v0.5.0 // indirect
|
||||
golang.org/x/term v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/term v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
85
v2/go.sum
85
v2/go.sum
@ -67,12 +67,12 @@ github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
|
||||
github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo=
|
||||
github.com/gookit/color v1.5.2 h1:uLnfXcaFjlrDnQDT+NCBcfhrXqYTx/rcCa6xn01Y8yI=
|
||||
@ -103,21 +103,22 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.9.0 h1:wPOF1CE6gvt/kmbMR4dGzWvHMPT+sAEUJOwOTtvITVY=
|
||||
github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
||||
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/leaanthony/clir v1.0.4/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/clir v1.3.0 h1:L9nPDWrmc/qU9UWZZvRaFajWYuO0np9V5p+5gxyYno0=
|
||||
github.com/leaanthony/clir v1.3.0/go.mod h1:k/RBkdkFl18xkkACMCLt09bhiZnrGORoxmomeMvDpE0=
|
||||
github.com/leaanthony/debme v1.2.1 h1:9Tgwf+kjcrbMQ4WnPcEIUcQuIZYqdWftzZkBr+i/oOc=
|
||||
github.com/leaanthony/debme v1.2.1/go.mod h1:3V+sCm5tYAgQymvSOfYQ5Xx2JCr+OXiD9Jkw3otUjiA=
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1 h1:97v6c5kYppVsbScf4r/VZdXyQ21KQIfeQOk2DgKxGG4=
|
||||
github.com/leaanthony/go-ansi-parser v1.0.1/go.mod h1:7arTzgVI47srICYhvgUV4CGd063sGEeoSlych5yeSPM=
|
||||
github.com/leaanthony/go-ansi-parser v1.6.0 h1:T8TuMhFB6TUMIUm0oRrSbgJudTFw9csT3ZK09w0t4Pg=
|
||||
github.com/leaanthony/go-ansi-parser v1.6.0/go.mod h1:+vva/2y4alzVmmIEpk9QDhA7vLC5zKDTRwfZGOp3IWU=
|
||||
github.com/leaanthony/gosod v1.0.3 h1:Fnt+/B6NjQOVuCWOKYRREZnjGyvg+mEhd1nkkA04aTQ=
|
||||
github.com/leaanthony/gosod v1.0.3/go.mod h1:BJ2J+oHsQIyIQpnLPjnqFGTMnOZXDbvWtRCSG7jGxs4=
|
||||
github.com/leaanthony/slicer v1.5.0 h1:aHYTN8xbCCLxJmkNKiLB6tgcMARl4eWmH9/F+S/0HtY=
|
||||
github.com/leaanthony/slicer v1.5.0/go.mod h1:FwrApmf8gOrpzEWM2J/9Lh79tyq8KTX5AzRtwV7m4AY=
|
||||
github.com/leaanthony/slicer v1.6.0 h1:1RFP5uiPJvT93TAHi+ipd3NACobkW53yUiBqZheE/Js=
|
||||
github.com/leaanthony/slicer v1.6.0/go.mod h1:o/Iz29g7LN0GqH3aMjWAe90381nyZlDNquK+mtH2Fj8=
|
||||
github.com/leaanthony/winicon v1.0.0 h1:ZNt5U5dY71oEoKZ97UVwJRT4e+5xo5o/ieKuHuk8NqQ=
|
||||
github.com/leaanthony/winicon v1.0.0/go.mod h1:en5xhijl92aphrJdmRPlh4NI1L6wq3gEm0LpXAPghjU=
|
||||
github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c=
|
||||
@ -126,11 +127,14 @@ github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
@ -148,8 +152,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -165,14 +169,15 @@ github.com/pterm/pterm v0.12.40/go.mod h1:ffwPLwlbXxP+rxT0GsgDTzS3y3rmpAO1NMjUkG
|
||||
github.com/pterm/pterm v0.12.49 h1:qeNm0wTWawy6WhKoY8ZKq6qTXFr0s2UtUyRW0yVztEg=
|
||||
github.com/pterm/pterm v0.12.49/go.mod h1:D4OBoWNqAfXkm5QLTjIgjNiMXPHemLJHnIreGUsWzWg=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI=
|
||||
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs=
|
||||
github.com/samber/lo v1.27.1 h1:sTXwkRiIFIQG+G0HeAvOEnGjqWeWtI9cg5/n51KrxPg=
|
||||
github.com/samber/lo v1.27.1/go.mod h1:it33p9UtPMS7z72fP4gw/EIfQB2eI8ke7GR2wc6+Rhg=
|
||||
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
|
||||
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
@ -180,16 +185,17 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/tc-hib/winres v0.1.5 h1:2dA5yfjdoEA3UyRaOC92HNMt3jap66pLzoW4MjpC/0M=
|
||||
github.com/tc-hib/winres v0.1.5/go.mod h1:pe6dOR40VOrGz8PkzreVKNvEKnlE8t4yR8A8naL+t7A=
|
||||
github.com/thoas/go-funk v0.9.1 h1:O549iLZqPpTUQ10ykd26sZhzD+rmR5pWhuElrhbC20M=
|
||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||
github.com/tidwall/gjson v1.9.3 h1:hqzS9wAHMO+KVBBkLxYdkEeeFHuqr95GfClRLKlgK0E=
|
||||
github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
@ -201,12 +207,15 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.1.7 h1:sgVPwu/yygHJ2m1pJDLgGM/h+1F5odx5Q9ljG3imRm8=
|
||||
github.com/tidwall/sjson v1.1.7/go.mod h1:w/yG+ezBeTdUxiKs5NcPicO9diP38nk96QBAbIIGeFs=
|
||||
github.com/tkrajina/go-reflector v0.5.5 h1:gwoQFNye30Kk7NrExj8zm3zFtrGPqOkzFMLuQZg1DtQ=
|
||||
github.com/tkrajina/go-reflector v0.5.5/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
|
||||
github.com/tkrajina/go-reflector v0.5.6 h1:hKQ0gyocG7vgMD2M3dRlYN6WBBOmdoOzJ6njQSepKdE=
|
||||
github.com/tkrajina/go-reflector v0.5.6/go.mod h1:ECbqLgccecY5kPmPmXg1MrHW585yMcDkVl6IvJe64T4=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/wailsapp/go-webview2 v1.0.1 h1:dEJIeEApW/MhO2tTMISZBFZPuW7kwrFA1NtgFB1z1II=
|
||||
github.com/wailsapp/go-webview2 v1.0.1/go.mod h1:Uk2BePfCRzttBBjFrBmqKGJd41P6QIHeV9kTgIeOZNo=
|
||||
github.com/wailsapp/mimetype v1.4.1 h1:pQN9ycO7uo4vsUUuPeHEYoUkLVkaRntMnHJxVwYhwHs=
|
||||
github.com/wailsapp/mimetype v1.4.1/go.mod h1:9aV5k31bBOv5z6u+QP8TltzvNGJPmNJD4XlAL3U+j3o=
|
||||
github.com/wzshiming/ctc v1.2.3 h1:q+hW3IQNsjIlOFBTGZZZeIXTElFM4grF4spW/errh/c=
|
||||
@ -227,26 +236,28 @@ golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnf
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
|
||||
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
||||
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -271,24 +282,28 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
@ -2,6 +2,7 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/internal/menumanager"
|
||||
@ -20,6 +21,9 @@ type App struct {
|
||||
// Indicates if the app is in debug mode
|
||||
debug bool
|
||||
|
||||
// Indicates if the devtools is enabled
|
||||
devtools bool
|
||||
|
||||
// OnStartup/OnShutdown
|
||||
startupCallback func(ctx context.Context)
|
||||
shutdownCallback func(ctx context.Context)
|
||||
|
@ -42,7 +42,9 @@ func (a *App) Run() error {
|
||||
func CreateApp(appoptions *options.App) (*App, error) {
|
||||
var err error
|
||||
|
||||
ctx := context.WithValue(context.Background(), "debug", true)
|
||||
ctx := context.Background()
|
||||
ctx = context.WithValue(ctx, "debug", true)
|
||||
ctx = context.WithValue(ctx, "devtools", true)
|
||||
|
||||
// Set up logger
|
||||
myLogger := logger.New(appoptions.Logger)
|
||||
@ -211,7 +213,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
|
||||
eventHandler := runtime.NewEvents(myLogger)
|
||||
ctx = context.WithValue(ctx, "events", eventHandler)
|
||||
messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler)
|
||||
messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter)
|
||||
|
||||
// Create the frontends and register to event handler
|
||||
desktopFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
|
||||
@ -228,6 +230,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
debug: true,
|
||||
devtools: true,
|
||||
}
|
||||
|
||||
result.options = appoptions
|
||||
|
7
v2/internal/app/app_devtools.go
Normal file
7
v2/internal/app/app_devtools.go
Normal file
@ -0,0 +1,7 @@
|
||||
//go:build devtools
|
||||
|
||||
package app
|
||||
|
||||
func IsDevtoolsEnabled() bool {
|
||||
return true
|
||||
}
|
7
v2/internal/app/app_devtools_not.go
Normal file
7
v2/internal/app/app_devtools_not.go
Normal file
@ -0,0 +1,7 @@
|
||||
//go:build !devtools
|
||||
|
||||
package app
|
||||
|
||||
func IsDevtoolsEnabled() bool {
|
||||
return false
|
||||
}
|
@ -34,7 +34,9 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
options.MergeDefaults(appoptions)
|
||||
|
||||
debug := IsDebug()
|
||||
devtools := IsDevtoolsEnabled()
|
||||
ctx = context.WithValue(ctx, "debug", debug)
|
||||
ctx = context.WithValue(ctx, "devtools", devtools)
|
||||
|
||||
// Set up logger
|
||||
myLogger := logger.New(appoptions.Logger)
|
||||
@ -80,7 +82,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
ctx = context.WithValue(ctx, "buildtype", "production")
|
||||
}
|
||||
|
||||
messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler)
|
||||
messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler, appoptions.ErrorFormatter)
|
||||
appFrontend := desktop.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
|
||||
eventHandler.AddFrontend(appFrontend)
|
||||
|
||||
@ -93,6 +95,7 @@ func CreateApp(appoptions *options.App) (*App, error) {
|
||||
startupCallback: appoptions.OnStartup,
|
||||
shutdownCallback: appoptions.OnShutdown,
|
||||
debug: debug,
|
||||
devtools: devtools,
|
||||
options: appoptions,
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define WindowStartsMinimised 2
|
||||
#define WindowStartsFullscreen 3
|
||||
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled);
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int defaultContextMenu, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled);
|
||||
void Run(void*, const char* url);
|
||||
|
||||
void SetTitle(void* ctx, const char *title);
|
||||
|
@ -13,13 +13,14 @@
|
||||
#import "WailsMenu.h"
|
||||
#import "WailsMenuItem.h"
|
||||
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int debug, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) {
|
||||
WailsContext* Create(const char* title, int width, int height, int frameless, int resizable, int fullscreen, int fullSizeContent, int hideTitleBar, int titlebarAppearsTransparent, int hideTitle, int useToolbar, int hideToolbarSeparator, int webviewIsTransparent, int alwaysOnTop, int hideWindowOnClose, const char *appearance, int windowIsTranslucent, int devtools, int defaultContextMenu, int windowStartState, int startsHidden, int minWidth, int minHeight, int maxWidth, int maxHeight, bool fraudulentWebsiteWarningEnabled) {
|
||||
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
WailsContext *result = [WailsContext new];
|
||||
|
||||
result.debug = debug;
|
||||
result.devtools = devtools;
|
||||
result.defaultContextMenu = defaultContextMenu;
|
||||
|
||||
if ( windowStartState == WindowStartsFullscreen ) {
|
||||
fullscreen = 1;
|
||||
|
@ -44,7 +44,8 @@
|
||||
|
||||
@property bool alwaysOnTop;
|
||||
|
||||
@property bool debug;
|
||||
@property bool devtools;
|
||||
@property bool defaultContextMenu;
|
||||
|
||||
@property (retain) WKUserContentController* userContentController;
|
||||
|
||||
|
@ -225,12 +225,12 @@ typedef void (^schemeTaskCaller)(id<WKURLSchemeTask>);
|
||||
[userContentController addScriptMessageHandler:self name:@"external"];
|
||||
config.userContentController = userContentController;
|
||||
self.userContentController = userContentController;
|
||||
if (self.debug) {
|
||||
if (self.devtools) {
|
||||
[config.preferences setValue:@YES forKey:@"developerExtrasEnabled"];
|
||||
} else {
|
||||
} else if (!self.defaultContextMenu) {
|
||||
// Disable default context menus
|
||||
WKUserScript *initScript = [WKUserScript new];
|
||||
[initScript initWithSource:@"window.wails.flags.disableWailsDefaultContextMenu = true;"
|
||||
[initScript initWithSource:@"window.wails.flags.disableDefaultContextMenu = true;"
|
||||
injectionTime:WKUserScriptInjectionTimeAtDocumentEnd
|
||||
forMainFrameOnly:false];
|
||||
[userContentController addUserScript:initScript];
|
||||
|
@ -47,6 +47,7 @@ type Frontend struct {
|
||||
frontendOptions *options.App
|
||||
logger *logger.Logger
|
||||
debug bool
|
||||
devtools bool
|
||||
|
||||
// Assets
|
||||
assets *assetserver.AssetServer
|
||||
@ -151,12 +152,18 @@ func (f *Frontend) WindowSetDarkTheme() {
|
||||
|
||||
func (f *Frontend) Run(ctx context.Context) error {
|
||||
f.ctx = ctx
|
||||
|
||||
var _debug = ctx.Value("debug")
|
||||
var _devtools = ctx.Value("devtools")
|
||||
|
||||
if _debug != nil {
|
||||
f.debug = _debug.(bool)
|
||||
}
|
||||
if _devtools != nil {
|
||||
f.devtools = _devtools.(bool)
|
||||
}
|
||||
|
||||
mainWindow := NewWindow(f.frontendOptions, f.debug)
|
||||
mainWindow := NewWindow(f.frontendOptions, f.debug, f.devtools)
|
||||
f.mainWindow = mainWindow
|
||||
f.mainWindow.Center()
|
||||
|
||||
|
@ -215,10 +215,11 @@ int main(int argc, const char * argv[]) {
|
||||
int hideWindowOnClose = 0;
|
||||
const char* appearance = "NSAppearanceNameDarkAqua";
|
||||
int windowIsTranslucent = 1;
|
||||
int debug = 1;
|
||||
int devtools = 1;
|
||||
int defaultContextMenu = 1;
|
||||
int windowStartState = 0;
|
||||
int startsHidden = 0;
|
||||
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState,
|
||||
WailsContext *result = Create("OI OI!",400,400, frameless, resizable, fullscreen, fullSizeContent, hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent, alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtools, defaultContextMenu, windowStartState,
|
||||
startsHidden, 400, 400, 600, 600, false);
|
||||
SetBackgroundColour(result, 255, 0, 0, 255);
|
||||
void *m = NewMenu("");
|
||||
|
@ -40,7 +40,7 @@ func bool2Cint(value bool) C.int {
|
||||
return C.int(0)
|
||||
}
|
||||
|
||||
func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
||||
func NewWindow(frontendOptions *options.App, debug bool, devtools bool) *Window {
|
||||
|
||||
c := NewCalloc()
|
||||
defer c.Free()
|
||||
@ -51,7 +51,8 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
||||
alwaysOnTop := bool2Cint(frontendOptions.AlwaysOnTop)
|
||||
hideWindowOnClose := bool2Cint(frontendOptions.HideWindowOnClose)
|
||||
startsHidden := bool2Cint(frontendOptions.StartHidden)
|
||||
debug := bool2Cint(debugMode)
|
||||
devtoolsEnabled := bool2Cint(devtools)
|
||||
defaultContextMenu := bool2Cint(frontendOptions.EnableDefaultContextMenu)
|
||||
|
||||
var fullSizeContent, hideTitleBar, hideTitle, useToolbar, webviewIsTransparent C.int
|
||||
var titlebarAppearsTransparent, hideToolbarSeparator, windowIsTranslucent C.int
|
||||
@ -86,8 +87,8 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
||||
}
|
||||
var context *C.WailsContext = C.Create(title, width, height, frameless, resizable, fullscreen, fullSizeContent,
|
||||
hideTitleBar, titlebarAppearsTransparent, hideTitle, useToolbar, hideToolbarSeparator, webviewIsTransparent,
|
||||
alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, debug, windowStartState, startsHidden,
|
||||
minWidth, minHeight, maxWidth, maxHeight, enableFraudulentWebsiteWarnings)
|
||||
alwaysOnTop, hideWindowOnClose, appearance, windowIsTranslucent, devtoolsEnabled, defaultContextMenu,
|
||||
windowStartState, startsHidden, minWidth, minHeight, maxWidth, maxHeight, enableFraudulentWebsiteWarnings)
|
||||
|
||||
// Create menu
|
||||
result := &Window{
|
||||
@ -114,7 +115,7 @@ func NewWindow(frontendOptions *options.App, debugMode bool) *Window {
|
||||
result.SetApplicationMenu(frontendOptions.Menu)
|
||||
}
|
||||
|
||||
if debugMode && frontendOptions.Debug.OpenInspectorOnStartup {
|
||||
if debug && frontendOptions.Debug.OpenInspectorOnStartup {
|
||||
showInspector(result.context)
|
||||
}
|
||||
return result
|
||||
|
@ -106,6 +106,7 @@ type Frontend struct {
|
||||
frontendOptions *options.App
|
||||
logger *logger.Logger
|
||||
debug bool
|
||||
devtools bool
|
||||
|
||||
// Assets
|
||||
assets *assetserver.AssetServer
|
||||
@ -176,13 +177,25 @@ func NewFrontend(ctx context.Context, appoptions *options.App, myLogger *logger.
|
||||
go result.startMessageProcessor()
|
||||
|
||||
var _debug = ctx.Value("debug")
|
||||
var _devtools = ctx.Value("devtools")
|
||||
|
||||
if _debug != nil {
|
||||
result.debug = _debug.(bool)
|
||||
}
|
||||
result.mainWindow = NewWindow(appoptions, result.debug)
|
||||
if _devtools != nil {
|
||||
result.devtools = _devtools.(bool)
|
||||
}
|
||||
|
||||
result.mainWindow = NewWindow(appoptions, result.debug, result.devtools)
|
||||
|
||||
C.install_signal_handlers()
|
||||
|
||||
if appoptions.Linux != nil && appoptions.Linux.ProgramName != "" {
|
||||
prgname := C.CString(appoptions.Linux.ProgramName)
|
||||
C.g_set_prgname(prgname)
|
||||
C.free(unsafe.Pointer(prgname))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ func gtkBool(input bool) C.gboolean {
|
||||
type Window struct {
|
||||
appoptions *options.App
|
||||
debug bool
|
||||
devtools bool
|
||||
gtkWindow unsafe.Pointer
|
||||
contentManager unsafe.Pointer
|
||||
webview unsafe.Pointer
|
||||
@ -54,12 +55,13 @@ func bool2Cint(value bool) C.int {
|
||||
return C.int(0)
|
||||
}
|
||||
|
||||
func NewWindow(appoptions *options.App, debug bool) *Window {
|
||||
func NewWindow(appoptions *options.App, debug bool, devtools bool) *Window {
|
||||
validateWebKit2Version(appoptions)
|
||||
|
||||
result := &Window{
|
||||
appoptions: appoptions,
|
||||
debug: debug,
|
||||
devtools: devtools,
|
||||
minHeight: appoptions.MinHeight,
|
||||
minWidth: appoptions.MinWidth,
|
||||
maxHeight: appoptions.MaxHeight,
|
||||
@ -95,9 +97,9 @@ func NewWindow(appoptions *options.App, debug bool) *Window {
|
||||
defer C.free(unsafe.Pointer(buttonPressedName))
|
||||
C.ConnectButtons(unsafe.Pointer(webview))
|
||||
|
||||
if debug {
|
||||
C.DevtoolsEnabled(unsafe.Pointer(webview), C.int(1), C.bool(appoptions.Debug.OpenInspectorOnStartup))
|
||||
} else {
|
||||
if devtools {
|
||||
C.DevtoolsEnabled(unsafe.Pointer(webview), C.int(1), C.bool(debug && appoptions.Debug.OpenInspectorOnStartup))
|
||||
} else if !appoptions.EnableDefaultContextMenu {
|
||||
C.DisableContextMenu(unsafe.Pointer(webview))
|
||||
}
|
||||
|
||||
|
@ -21,9 +21,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/bep/debounce"
|
||||
"github.com/wailsapp/go-webview2/pkg/edge"
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/winc/w32"
|
||||
@ -48,6 +48,7 @@ type Frontend struct {
|
||||
logger *logger.Logger
|
||||
chromium *edge.Chromium
|
||||
debug bool
|
||||
devtools bool
|
||||
|
||||
// Assets
|
||||
assets *assetserver.AssetServer
|
||||
@ -142,9 +143,14 @@ func (f *Frontend) Run(ctx context.Context) error {
|
||||
f.mainWindow = mainWindow
|
||||
|
||||
var _debug = ctx.Value("debug")
|
||||
var _devtools = ctx.Value("devtools")
|
||||
|
||||
if _debug != nil {
|
||||
f.debug = _debug.(bool)
|
||||
}
|
||||
if _devtools != nil {
|
||||
f.devtools = _devtools.(bool)
|
||||
}
|
||||
|
||||
f.WindowCenter()
|
||||
f.setupChromium()
|
||||
@ -489,11 +495,11 @@ func (f *Frontend) setupChromium() {
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = settings.PutAreDefaultContextMenusEnabled(f.debug)
|
||||
err = settings.PutAreDefaultContextMenusEnabled(f.devtools || f.frontendOptions.EnableDefaultContextMenu)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = settings.PutAreDevToolsEnabled(f.debug)
|
||||
err = settings.PutAreDevToolsEnabled(f.devtools)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 John Chadwick
|
||||
Some portions Copyright (c) 2017 Serge Zaitsev
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,27 +0,0 @@
|
||||
# go-webview2
|
||||
|
||||
This is a proof of concept for embedding Webview2 into Go without CGo. It is based
|
||||
on [webview/webview](https://github.com/webview/webview) and provides a compatible API.
|
||||
|
||||
## Notice
|
||||
|
||||
Because this version doesn't currently have an EdgeHTML fallback, it will not work unless you have a Webview2 runtime
|
||||
installed. In addition, it requires the Webview2Loader DLL in order to function. Adding an EdgeHTML fallback should be
|
||||
technically possible but will likely require much worse hacks since the API is not strictly COM to my knowledge.
|
||||
|
||||
## Demo
|
||||
|
||||
For now, you'll need to install the Webview2 runtime, as it does not ship with Windows.
|
||||
|
||||
[WebView2 runtime](https://developer.microsoft.com/en-us/microsoft-edge/webview2/)
|
||||
|
||||
After that, you should be able to run go-webview2 directly:
|
||||
|
||||
```
|
||||
go run go-webview2/cmd/demo
|
||||
```
|
||||
|
||||
This will use go-winloader to load an embedded copy of WebView2Loader.dll.
|
||||
|
||||
If this does not work, please try running from a directory that has an appropriate copy of `WebView2Loader.dll` for your
|
||||
GOARCH. If _that_ worked, *please* file a bug so we can figure out what's wrong with go-winloader :)
|
@ -1,157 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package w32
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
ole32 = windows.NewLazySystemDLL("ole32")
|
||||
Ole32CoInitializeEx = ole32.NewProc("CoInitializeEx")
|
||||
|
||||
kernel32 = windows.NewLazySystemDLL("kernel32")
|
||||
Kernel32GetCurrentThreadID = kernel32.NewProc("GetCurrentThreadId")
|
||||
|
||||
shlwapi = windows.NewLazySystemDLL("shlwapi")
|
||||
shlwapiSHCreateMemStream = shlwapi.NewProc("SHCreateMemStream")
|
||||
|
||||
user32 = windows.NewLazySystemDLL("user32")
|
||||
User32LoadImageW = user32.NewProc("LoadImageW")
|
||||
User32GetSystemMetrics = user32.NewProc("GetSystemMetrics")
|
||||
User32RegisterClassExW = user32.NewProc("RegisterClassExW")
|
||||
User32CreateWindowExW = user32.NewProc("CreateWindowExW")
|
||||
User32DestroyWindow = user32.NewProc("DestroyWindow")
|
||||
User32ShowWindow = user32.NewProc("ShowWindow")
|
||||
User32UpdateWindow = user32.NewProc("UpdateWindow")
|
||||
User32SetFocus = user32.NewProc("SetFocus")
|
||||
User32GetMessageW = user32.NewProc("GetMessageW")
|
||||
User32TranslateMessage = user32.NewProc("TranslateMessage")
|
||||
User32DispatchMessageW = user32.NewProc("DispatchMessageW")
|
||||
User32DefWindowProcW = user32.NewProc("DefWindowProcW")
|
||||
User32GetClientRect = user32.NewProc("GetClientRect")
|
||||
User32PostQuitMessage = user32.NewProc("PostQuitMessage")
|
||||
User32SetWindowTextW = user32.NewProc("SetWindowTextW")
|
||||
User32PostThreadMessageW = user32.NewProc("PostThreadMessageW")
|
||||
User32GetWindowLongPtrW = user32.NewProc("GetWindowLongPtrW")
|
||||
User32SetWindowLongPtrW = user32.NewProc("SetWindowLongPtrW")
|
||||
User32AdjustWindowRect = user32.NewProc("AdjustWindowRect")
|
||||
User32SetWindowPos = user32.NewProc("SetWindowPos")
|
||||
)
|
||||
|
||||
const (
|
||||
SystemMetricsCxIcon = 11
|
||||
SystemMetricsCyIcon = 12
|
||||
)
|
||||
|
||||
const (
|
||||
SWShow = 5
|
||||
)
|
||||
|
||||
const (
|
||||
SWPNoZOrder = 0x0004
|
||||
SWPNoActivate = 0x0010
|
||||
SWPNoMove = 0x0002
|
||||
SWPFrameChanged = 0x0020
|
||||
)
|
||||
|
||||
const (
|
||||
WMDestroy = 0x0002
|
||||
WMMove = 0x0003
|
||||
WMSize = 0x0005
|
||||
WMClose = 0x0010
|
||||
WMQuit = 0x0012
|
||||
WMGetMinMaxInfo = 0x0024
|
||||
WMNCLButtonDown = 0x00A1
|
||||
WMMoving = 0x0216
|
||||
WMApp = 0x8000
|
||||
)
|
||||
|
||||
const (
|
||||
GWLStyle = -16
|
||||
)
|
||||
|
||||
const (
|
||||
WSOverlapped = 0x00000000
|
||||
WSMaximizeBox = 0x00020000
|
||||
WSThickFrame = 0x00040000
|
||||
WSCaption = 0x00C00000
|
||||
WSSysMenu = 0x00080000
|
||||
WSMinimizeBox = 0x00020000
|
||||
WSOverlappedWindow = (WSOverlapped | WSCaption | WSSysMenu | WSThickFrame | WSMinimizeBox | WSMaximizeBox)
|
||||
)
|
||||
|
||||
type WndClassExW struct {
|
||||
CbSize uint32
|
||||
Style uint32
|
||||
LpfnWndProc uintptr
|
||||
CnClsExtra int32
|
||||
CbWndExtra int32
|
||||
HInstance windows.Handle
|
||||
HIcon windows.Handle
|
||||
HCursor windows.Handle
|
||||
HbrBackground windows.Handle
|
||||
LpszMenuName *uint16
|
||||
LpszClassName *uint16
|
||||
HIconSm windows.Handle
|
||||
}
|
||||
|
||||
type Rect struct {
|
||||
Left int32
|
||||
Top int32
|
||||
Right int32
|
||||
Bottom int32
|
||||
}
|
||||
|
||||
type MinMaxInfo struct {
|
||||
PtReserved Point
|
||||
PtMaxSize Point
|
||||
PtMaxPosition Point
|
||||
PtMinTrackSize Point
|
||||
PtMaxTrackSize Point
|
||||
}
|
||||
|
||||
type Point struct {
|
||||
X, Y int32
|
||||
}
|
||||
|
||||
type Msg struct {
|
||||
Hwnd syscall.Handle
|
||||
Message uint32
|
||||
WParam uintptr
|
||||
LParam uintptr
|
||||
Time uint32
|
||||
Pt Point
|
||||
LPrivate uint32
|
||||
}
|
||||
|
||||
func Utf16PtrToString(p *uint16) string {
|
||||
if p == nil {
|
||||
return ""
|
||||
}
|
||||
// Find NUL terminator.
|
||||
end := unsafe.Pointer(p)
|
||||
n := 0
|
||||
for *(*uint16)(end) != 0 {
|
||||
end = unsafe.Pointer(uintptr(end) + unsafe.Sizeof(*p))
|
||||
n++
|
||||
}
|
||||
s := (*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:n:n]
|
||||
return string(utf16.Decode(s))
|
||||
}
|
||||
|
||||
func SHCreateMemStream(data []byte) (uintptr, error) {
|
||||
ret, _, err := shlwapiSHCreateMemStream.Call(
|
||||
uintptr(unsafe.Pointer(&data[0])),
|
||||
uintptr(len(data)),
|
||||
)
|
||||
if ret == 0 {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
@ -1,239 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package combridge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var (
|
||||
comIfcePointersL sync.RWMutex
|
||||
comIfcePointers = map[uintptr]*comObject{} // Map from ComInterfacePointer to the Go ComObject
|
||||
)
|
||||
|
||||
// Resolve the GoInterface of the specified ComInterfacePointer
|
||||
func Resolve[T IUnknown](ifceP uintptr) T {
|
||||
comIfcePointersL.RLock()
|
||||
comObj := comIfcePointers[ifceP]
|
||||
comIfcePointersL.RUnlock()
|
||||
|
||||
var n T
|
||||
if comObj != nil {
|
||||
t := comObj.resolve(ifceP)
|
||||
if t != nil {
|
||||
n = t.(T)
|
||||
}
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
// New returns a new ComObject which implements the specified Com Interface, com calls will be redirected
|
||||
// to the specified go interface.
|
||||
func New[T IUnknown](obj T) *ComObject[T] {
|
||||
cObj := new(
|
||||
ifceDef[T]{obj},
|
||||
)
|
||||
return newComObject[T](cObj)
|
||||
}
|
||||
|
||||
// New2 returns a new ComObject which implements the two specified Com Interfaces, com calls will be redirected
|
||||
// to those interfaces accordingly.
|
||||
// This is needed if a ComObject should implement two interfaces that are not descendants of each other,
|
||||
// then you get multiple inheritance.
|
||||
func New2[T IUnknown, T2 IUnknown](obj T, obj2 T2) *ComObject[T] {
|
||||
cObj := new(
|
||||
ifceDef[T]{obj},
|
||||
ifceDef[T2]{obj2},
|
||||
)
|
||||
return newComObject[T](cObj)
|
||||
}
|
||||
|
||||
// new returns a new ComObject which implements multiple specified Com Interfaces, com calls will be redirected
|
||||
// to the specified go interfaces accordingly.
|
||||
// This is needed if a ComObject should implement multiple interfaces that are not descendants of each other,
|
||||
// then you get multiple inheritance.
|
||||
func new(impls ...ifceImpl) *comObject {
|
||||
impls = append([]ifceImpl{ifceDef[IUnknown]{}}, impls...)
|
||||
|
||||
cObj := &comObject{
|
||||
refCount: 1,
|
||||
ifces: map[string]int{},
|
||||
ifcesImpl: make([]comInterfaceDesc, len(impls)),
|
||||
}
|
||||
|
||||
for i, ifceDef := range impls {
|
||||
vtable, err := ifceDef.ifce()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
needsImplement := false
|
||||
for table := vtable; table != nil; table = table.Parent {
|
||||
guid := table.ComGUID
|
||||
if i, found := cObj.ifces[guid]; found {
|
||||
// This Interface is already implemented
|
||||
if guid == iUnknownGUID {
|
||||
// IUnknown is a special interface and never has an user specific implementation
|
||||
} else if cObj.ifcesImpl[i].impl != ifceDef.impl() {
|
||||
panic(fmt.Sprintf("Interface '%s' is already implemented by another object", table.Name))
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
needsImplement = true
|
||||
cObj.ifces[guid] = i
|
||||
}
|
||||
|
||||
if !needsImplement {
|
||||
continue
|
||||
}
|
||||
|
||||
ifceP, ifcePSlice := allocUintptrObject(1)
|
||||
ifcePSlice[0] = vtable.ComVTable
|
||||
cObj.ifcesImpl[i] = comInterfaceDesc{ifceP, ifceDef.impl()}
|
||||
}
|
||||
|
||||
comIfcePointersL.Lock()
|
||||
for _, ifceImpl := range cObj.ifcesImpl {
|
||||
comIfcePointers[ifceImpl.ref] = cObj
|
||||
}
|
||||
comIfcePointersL.Unlock()
|
||||
|
||||
return cObj
|
||||
}
|
||||
|
||||
func newComObject[T IUnknown](comObj *comObject) *ComObject[T] {
|
||||
c := &ComObject[T]{obj: comObj}
|
||||
// Make sure to async release since release needs locks and might block the finalizer goroutine for a longer period
|
||||
runtime.SetFinalizer(c, func(obj *ComObject[T]) { obj.close(true) })
|
||||
return c
|
||||
}
|
||||
|
||||
// ComObject describes an exported go instance to be used as a ComObject which implements
|
||||
// the specified Interface.
|
||||
type ComObject[T IUnknown] struct {
|
||||
obj *comObject
|
||||
closed int32
|
||||
}
|
||||
|
||||
// Ref returns the native uintptr that points to the ComObject that is an interface pointer to T.
|
||||
// This can be used in native calls. If the object has been closed this function will panic.
|
||||
func (o *ComObject[T]) Ref() uintptr {
|
||||
if atomic.LoadInt32(&o.closed) != 0 {
|
||||
panic("ComObject has been released")
|
||||
}
|
||||
return o.obj.queryInterface(guidOf[T](), false)
|
||||
}
|
||||
|
||||
// Close releases the native com object from the go side. It will only be destroyed if the ref counter
|
||||
// reaches zero.
|
||||
// After closing `Ref()` will panic.
|
||||
func (o *ComObject[T]) Close() error {
|
||||
o.close(false)
|
||||
return nil
|
||||
}
|
||||
|
||||
// close releases the native com object from the go side. It will only be destroyed if the ref counter
|
||||
// reaches zero.
|
||||
// After closing `Ref()` will panic.
|
||||
func (o *ComObject[T]) close(asyncRelease bool) {
|
||||
if atomic.CompareAndSwapInt32(&o.closed, 0, 1) {
|
||||
runtime.SetFinalizer(o, nil)
|
||||
if asyncRelease {
|
||||
go o.obj.release()
|
||||
} else {
|
||||
o.obj.release()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type comInterfaceDesc struct {
|
||||
ref uintptr // The native Com InterfacePointer
|
||||
impl any // The golang target object
|
||||
}
|
||||
|
||||
type comObject struct {
|
||||
l sync.Mutex
|
||||
|
||||
refCount int32
|
||||
ifces map[string]int // Map of ComInterfaceGUID to Interface Slots
|
||||
ifcesImpl []comInterfaceDesc // Slots with InterfaceDescriptors
|
||||
}
|
||||
|
||||
func (c *comObject) queryInterface(ifceGUID string, withAddRef bool) uintptr {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
if c.refCount <= 0 {
|
||||
panic("call on released com object")
|
||||
}
|
||||
|
||||
i, found := c.ifces[ifceGUID]
|
||||
if !found {
|
||||
return 0
|
||||
}
|
||||
|
||||
if withAddRef {
|
||||
c.refCount++
|
||||
}
|
||||
return c.ifcesImpl[i].ref
|
||||
}
|
||||
|
||||
func (c *comObject) resolve(ifceP uintptr) any {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
if c.refCount <= 0 {
|
||||
panic("call on destroyed com object")
|
||||
}
|
||||
|
||||
for _, ifce := range c.ifcesImpl {
|
||||
if ifce.ref != ifceP {
|
||||
continue
|
||||
}
|
||||
|
||||
return ifce.impl
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *comObject) addRef() int32 {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
if c.refCount <= 0 {
|
||||
panic("call on destroyed com object")
|
||||
}
|
||||
|
||||
c.refCount++
|
||||
return c.refCount
|
||||
}
|
||||
|
||||
func (c *comObject) release() int32 {
|
||||
c.l.Lock()
|
||||
defer c.l.Unlock()
|
||||
if c.refCount <= 0 {
|
||||
panic("call on destroyed com object")
|
||||
}
|
||||
|
||||
if c.refCount--; c.refCount == 0 {
|
||||
comIfcePointersL.Lock()
|
||||
for _, ref := range c.ifcesImpl {
|
||||
delete(comIfcePointers, ref.ref)
|
||||
}
|
||||
comIfcePointersL.Unlock()
|
||||
|
||||
for _, impl := range c.ifcesImpl {
|
||||
ref := impl.ref
|
||||
if ref == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
globalFree(ref)
|
||||
}
|
||||
}
|
||||
|
||||
return c.refCount
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package combridge
|
||||
|
||||
import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const iUnknownGUID = "{00000000-0000-0000-C000-000000000046}"
|
||||
|
||||
func init() {
|
||||
registerVTableInternal[IUnknown, IUnknown](
|
||||
iUnknownGUID,
|
||||
true,
|
||||
iUnknownQueryInterface,
|
||||
iUnknownAddRef,
|
||||
iUnknownRelease,
|
||||
)
|
||||
}
|
||||
|
||||
type IUnknown interface{}
|
||||
|
||||
func iUnknownQueryInterface(this uintptr, refiid *windows.GUID, ppvObject *uintptr) uintptr {
|
||||
if refiid == nil || ppvObject == nil {
|
||||
return uintptr(windows.E_INVALIDARG)
|
||||
}
|
||||
|
||||
comIfcePointersL.RLock()
|
||||
obj := comIfcePointers[this]
|
||||
comIfcePointersL.RUnlock()
|
||||
|
||||
ref := obj.queryInterface(refiid.String(), true)
|
||||
if ref != 0 {
|
||||
*ppvObject = ref
|
||||
return windows.NO_ERROR
|
||||
}
|
||||
|
||||
*ppvObject = 0
|
||||
return uintptr(windows.E_NOINTERFACE)
|
||||
}
|
||||
|
||||
func iUnknownAddRef(this uintptr) uintptr {
|
||||
comIfcePointersL.RLock()
|
||||
obj := comIfcePointers[this]
|
||||
comIfcePointersL.RUnlock()
|
||||
|
||||
return uintptr(obj.addRef())
|
||||
}
|
||||
|
||||
func iUnknownRelease(this uintptr) uintptr {
|
||||
comIfcePointersL.RLock()
|
||||
obj := comIfcePointers[this]
|
||||
comIfcePointersL.RUnlock()
|
||||
|
||||
return uintptr(obj.release())
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package combridge
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// IUnknownFromPointer cast a generic pointer into a IUnknownImpl pointer
|
||||
func IUnknownFromPointer(ref unsafe.Pointer) *IUnknownImpl {
|
||||
return (*IUnknownImpl)(ref)
|
||||
}
|
||||
|
||||
// IUnknownFromPointer cast native pointer into a IUnknownImpl pointer
|
||||
func IUnknownFromUintptr(ref uintptr) *IUnknownImpl {
|
||||
return IUnknownFromPointer(unsafe.Pointer(ref))
|
||||
}
|
||||
|
||||
type IUnknownVtbl struct {
|
||||
queryInterface uintptr
|
||||
addRef uintptr
|
||||
release uintptr
|
||||
}
|
||||
|
||||
func (i *IUnknownVtbl) QueryInterface(this unsafe.Pointer, refiid *windows.GUID, ppvObject **IUnknownImpl) error {
|
||||
r, _, _ := syscall.SyscallN(
|
||||
i.queryInterface,
|
||||
uintptr(this),
|
||||
uintptr(unsafe.Pointer(refiid)),
|
||||
uintptr(unsafe.Pointer(ppvObject)),
|
||||
)
|
||||
|
||||
if r != uintptr(windows.S_OK) {
|
||||
return syscall.Errno(r)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *IUnknownVtbl) AddRef(this unsafe.Pointer) uint32 {
|
||||
r, _, _ := syscall.SyscallN(
|
||||
i.addRef,
|
||||
uintptr(this),
|
||||
)
|
||||
return uint32(r)
|
||||
}
|
||||
|
||||
func (i *IUnknownVtbl) Release(this unsafe.Pointer) uint32 {
|
||||
r, _, _ := syscall.SyscallN(
|
||||
i.release,
|
||||
uintptr(this),
|
||||
)
|
||||
|
||||
return uint32(r)
|
||||
}
|
||||
|
||||
type IUnknownImpl struct {
|
||||
vtbl *IUnknownVtbl
|
||||
}
|
||||
|
||||
func (i *IUnknownImpl) QueryInterface(refiid *windows.GUID, ppvObject **IUnknownImpl) error {
|
||||
return i.vtbl.QueryInterface(unsafe.Pointer(i), refiid, ppvObject)
|
||||
}
|
||||
|
||||
func (i *IUnknownImpl) AddRef() uint32 {
|
||||
return i.vtbl.AddRef(unsafe.Pointer(i))
|
||||
}
|
||||
|
||||
func (i *IUnknownImpl) Release() uint32 {
|
||||
return i.vtbl.Release(unsafe.Pointer(i))
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package combridge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
procGlobalAlloc = modkernel32.NewProc("GlobalAlloc")
|
||||
procGlobalFree = modkernel32.NewProc("GlobalFree")
|
||||
|
||||
uintptrSize = unsafe.Sizeof(uintptr(0))
|
||||
)
|
||||
|
||||
func allocUintptrObject(size int) (uintptr, []uintptr) {
|
||||
v := globalAlloc(uintptr(size) * uintptrSize)
|
||||
slice := unsafe.Slice((*uintptr)(unsafe.Pointer(v)), size)
|
||||
return v, slice
|
||||
}
|
||||
|
||||
func globalAlloc(dwBytes uintptr) uintptr {
|
||||
ret, _, _ := procGlobalAlloc.Call(uintptr(0), dwBytes)
|
||||
if ret == 0 {
|
||||
panic("globalAlloc failed")
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func globalFree(data uintptr) {
|
||||
ret, _, _ := procGlobalFree.Call(data)
|
||||
if ret != 0 {
|
||||
panic("globalFree failed")
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package combridge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
vTablesL sync.Mutex
|
||||
vTables = make(map[string]*vTable)
|
||||
)
|
||||
|
||||
// RegisterVTable registers the vtable trampoline methods for the specified ComInterface
|
||||
// TBase is the base interface of T, and must be another ComInterface which roots in IUnknown or IUnknown itself.
|
||||
// The first paramter of the fn is always the uintptr of the ComObject and the GoObject can be resolved with Resolve().
|
||||
// After having resolved the GoObject the call must be redirected to the GoObject.
|
||||
// Typically a trampoline FN looks like this.
|
||||
//
|
||||
// func _ICoreWebView2NavigationCompletedEventHandlerInvoke(this uintptr, sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr {
|
||||
// return combridge.Resolve[_ICoreWebView2NavigationCompletedEventHandler](this).NavigationCompleted(sender, args)
|
||||
// }
|
||||
//
|
||||
// The order of registration must be in the correct order as specified in the IDL of the interface.
|
||||
func RegisterVTable[TParent, T IUnknown](guid string, fns ...interface{}) {
|
||||
registerVTableInternal[TParent, T](guid, false, fns...)
|
||||
}
|
||||
|
||||
type vTable struct {
|
||||
Parent *vTable
|
||||
|
||||
Name string
|
||||
ComGUID string
|
||||
ComVTable uintptr
|
||||
ComProcs []uintptr
|
||||
}
|
||||
|
||||
func registerVTableInternal[TParent, T IUnknown](guid string, isInternal bool, fns ...interface{}) {
|
||||
vTablesL.Lock()
|
||||
defer vTablesL.Unlock()
|
||||
|
||||
t, tName := typeInterfaceToString[T]()
|
||||
tParent, tParentName := typeInterfaceToString[TParent]()
|
||||
if !t.Implements(tParent) {
|
||||
panic(fmt.Errorf("RegisterVTable '%s': '%s' must implement '%s'", tName, tName, tParentName))
|
||||
}
|
||||
|
||||
if !isInternal {
|
||||
if t == reflect.TypeOf((*IUnknown)(nil)).Elem() {
|
||||
panic(fmt.Errorf("RegisterVTable '%s' IUnknown can't be registered", tName))
|
||||
}
|
||||
|
||||
if t == tParent {
|
||||
panic(fmt.Errorf("RegisterVTable '%s': T and TParent can't be the same type", tName))
|
||||
}
|
||||
}
|
||||
|
||||
var parent *vTable
|
||||
var parentProcs []uintptr
|
||||
var parentProcsCount int
|
||||
if t != tParent {
|
||||
parent = vTables[tParentName]
|
||||
if parent == nil {
|
||||
panic(fmt.Errorf("RegisterVTable '%s': Parent VTable '%s' not registered", tName, tParentName))
|
||||
}
|
||||
|
||||
parentProcs = parent.ComProcs
|
||||
parentProcsCount = len(parentProcs)
|
||||
}
|
||||
|
||||
comGuid, err := windows.GUIDFromString(guid)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("RegisterVTable '%s': invalid guid: %s", tName, err))
|
||||
}
|
||||
|
||||
vTable := &vTable{
|
||||
Parent: parent,
|
||||
Name: tName,
|
||||
ComGUID: comGuid.String(),
|
||||
}
|
||||
vTable.ComVTable, vTable.ComProcs = allocUintptrObject(parentProcsCount + len(fns))
|
||||
|
||||
for i, proc := range parentProcs {
|
||||
vTable.ComProcs[i] = proc
|
||||
}
|
||||
|
||||
for i, fn := range fns {
|
||||
vTable.ComProcs[parentProcsCount+i] = windows.NewCallback(fn)
|
||||
}
|
||||
|
||||
vTables[tName] = vTable
|
||||
}
|
||||
|
||||
func typeInterfaceToString[T any]() (reflect.Type, string) {
|
||||
t := reflect.TypeOf((*T)(nil))
|
||||
if t.Kind() != reflect.Pointer {
|
||||
panic("must be a (*yourInterfaceType)(nil)")
|
||||
}
|
||||
t = t.Elem()
|
||||
return t, t.PkgPath() + "/" + t.Name()
|
||||
}
|
||||
|
||||
func typeInterfaceToStringOnly[T any]() string {
|
||||
_, nane := typeInterfaceToString[T]()
|
||||
return nane
|
||||
}
|
||||
|
||||
func guidOf[T any]() string {
|
||||
vtable := vTableOf[T]()
|
||||
if vtable == nil {
|
||||
return ""
|
||||
}
|
||||
return vtable.ComGUID
|
||||
}
|
||||
|
||||
func vTableOf[T any]() *vTable {
|
||||
name := typeInterfaceToStringOnly[T]()
|
||||
vTablesL.Lock()
|
||||
defer vTablesL.Unlock()
|
||||
|
||||
return vTables[name]
|
||||
}
|
||||
|
||||
type ifceImpl interface {
|
||||
impl() any
|
||||
ifce() (*vTable, error)
|
||||
}
|
||||
|
||||
type ifceDef[T any] struct {
|
||||
objImpl any
|
||||
}
|
||||
|
||||
func (i ifceDef[T]) impl() any {
|
||||
return i.objImpl
|
||||
}
|
||||
|
||||
func (i ifceDef[T]) ifce() (*vTable, error) {
|
||||
vtable := vTableOf[T]()
|
||||
if vtable == nil {
|
||||
return nil, fmt.Errorf("Unable to find vTable for %s", typeInterfaceToStringOnly[T]())
|
||||
}
|
||||
return vtable, nil
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_COLOR struct {
|
||||
A uint8
|
||||
R uint8
|
||||
G uint8
|
||||
B uint8
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND uint32
|
||||
|
||||
const (
|
||||
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY = iota
|
||||
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW
|
||||
COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_DENY_CORS
|
||||
)
|
@ -1,12 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_KEY_EVENT_KIND uint32
|
||||
|
||||
const (
|
||||
COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN = 0
|
||||
COREWEBVIEW2_KEY_EVENT_KIND_KEY_UP = 1
|
||||
COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN = 2
|
||||
COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_UP = 3
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_MOVE_FOCUS_REASON uint32
|
||||
|
||||
const (
|
||||
COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC = 0
|
||||
COREWEBVIEW2_MOVE_FOCUS_REASON_NEXT = 1
|
||||
COREWEBVIEW2_MOVE_FOCUS_REASON_PREVIOUS = 2
|
||||
)
|
@ -1,12 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_PHYSICAL_KEY_STATUS struct {
|
||||
RepeatCount uint32
|
||||
ScanCode uint32
|
||||
IsExtendedKey bool
|
||||
IsMenuKeyDown bool
|
||||
WasKeyDown bool
|
||||
IsKeyReleased bool
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_PROCESS_FAILED_KIND uint32
|
||||
|
||||
const (
|
||||
// Indicates that the browser process ended unexpectedly. The WebView
|
||||
// automatically moves to the Closed state. The app has to recreate a new
|
||||
// WebView to recover from this failure.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_BROWSER_PROCESS_EXITED = 0
|
||||
|
||||
// Indicates that the main frame's render process ended unexpectedly. A new
|
||||
// render process is created automatically and navigated to an error page.
|
||||
// You can use the `Reload` method to try to reload the page that failed.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_EXITED = 1
|
||||
|
||||
// Indicates that the main frame's render process is unresponsive.
|
||||
//
|
||||
// Note that this does not seem to work right now.
|
||||
// Does not fire for simple long running script case, the only related test
|
||||
// SitePerProcessBrowserTest::NoCommitTimeoutForInvisibleWebContents is
|
||||
// disabled.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_RENDER_PROCESS_UNRESPONSIVE = 2
|
||||
|
||||
// Indicates that a frame-only render process ended unexpectedly. The process
|
||||
// exit does not affect the top-level document, only a subset of the
|
||||
// subframes within it. The content in these frames is replaced with an error
|
||||
// page in the frame.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_FRAME_RENDER_PROCESS_EXITED = 3
|
||||
|
||||
// Indicates that a utility process ended unexpectedly.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_UTILITY_PROCESS_EXITED = 4
|
||||
|
||||
// Indicates that a sandbox helper process ended unexpectedly.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_SANDBOX_HELPER_PROCESS_EXITED = 5
|
||||
|
||||
// Indicates that the GPU process ended unexpectedly.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_GPU_PROCESS_EXITED = 6
|
||||
|
||||
// Indicates that a PPAPI plugin process ended unexpectedly.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_PLUGIN_PROCESS_EXITED = 7
|
||||
|
||||
// Indicates that a PPAPI plugin broker process ended unexpectedly.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_PPAPI_BROKER_PROCESS_EXITED = 8
|
||||
|
||||
// Indicates that a process of unspecified kind ended unexpectedly.
|
||||
COREWEBVIEW2_PROCESS_FAILED_KIND_UNKNOWN_PROCESS_EXITED = 9
|
||||
)
|
@ -1,25 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type COREWEBVIEW2_WEB_RESOURCE_CONTEXT uint32
|
||||
|
||||
const (
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_ALL = 0
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_DOCUMENT = 1
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_STYLESHEET = 2
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_IMAGE = 3
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MEDIA = 4
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FONT = 5
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SCRIPT = 6
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_XML_HTTP_REQUEST = 7
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_FETCH = 8
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_TEXT_TRACK = 9
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_EVENT_SOURCE = 10
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_WEBSOCKET = 11
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_MANIFEST = 12
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_SIGNED_EXCHANGE = 13
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_PING = 14
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_CSP_VIOLATION_REPORT = 15
|
||||
COREWEBVIEW2_WEB_RESOURCE_CONTEXT_OTHER = 16
|
||||
)
|
@ -1,79 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2AcceleratorKeyPressedEventArgsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetKeyEventKind ComProc
|
||||
GetVirtualKey ComProc
|
||||
GetKeyEventLParam ComProc
|
||||
GetPhysicalKeyStatus ComProc
|
||||
GetHandled ComProc
|
||||
PutHandled ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2AcceleratorKeyPressedEventArgs struct {
|
||||
vtbl *_ICoreWebView2AcceleratorKeyPressedEventArgsVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetKeyEventKind() (COREWEBVIEW2_KEY_EVENT_KIND, error) {
|
||||
var err error
|
||||
var keyEventKind COREWEBVIEW2_KEY_EVENT_KIND
|
||||
_, _, err = i.vtbl.GetKeyEventKind.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&keyEventKind)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return 0, err
|
||||
}
|
||||
return keyEventKind, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetVirtualKey() (uint, error) {
|
||||
var err error
|
||||
var virtualKey uint
|
||||
_, _, err = i.vtbl.GetVirtualKey.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&virtualKey)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return 0, err
|
||||
}
|
||||
return virtualKey, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) GetPhysicalKeyStatus() (COREWEBVIEW2_PHYSICAL_KEY_STATUS, error) {
|
||||
var err error
|
||||
var physicalKeyStatus COREWEBVIEW2_PHYSICAL_KEY_STATUS
|
||||
_, _, err = i.vtbl.GetPhysicalKeyStatus.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&physicalKeyStatus)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return COREWEBVIEW2_PHYSICAL_KEY_STATUS{}, err
|
||||
}
|
||||
return physicalKeyStatus, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2AcceleratorKeyPressedEventArgs) PutHandled(handled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutHandled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(handled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type _ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2AcceleratorKeyPressedEventHandler struct {
|
||||
vtbl *_ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl
|
||||
impl _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2AcceleratorKeyPressedEventHandler) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownQueryInterface(this *ICoreWebView2AcceleratorKeyPressedEventHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownAddRef(this *ICoreWebView2AcceleratorKeyPressedEventHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownRelease(this *ICoreWebView2AcceleratorKeyPressedEventHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2AcceleratorKeyPressedEventHandlerInvoke(this *ICoreWebView2AcceleratorKeyPressedEventHandler, sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr {
|
||||
return this.impl.AcceleratorKeyPressed(sender, args)
|
||||
}
|
||||
|
||||
type _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
AcceleratorKeyPressed(sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr
|
||||
}
|
||||
|
||||
var _ICoreWebView2AcceleratorKeyPressedEventHandlerFn = _ICoreWebView2AcceleratorKeyPressedEventHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2AcceleratorKeyPressedEventHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2AcceleratorKeyPressedEventHandler(impl _ICoreWebView2AcceleratorKeyPressedEventHandlerImpl) *ICoreWebView2AcceleratorKeyPressedEventHandler {
|
||||
return &ICoreWebView2AcceleratorKeyPressedEventHandler{
|
||||
vtbl: &_ICoreWebView2AcceleratorKeyPressedEventHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
@ -1,160 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"math"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2ControllerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetIsVisible ComProc
|
||||
PutIsVisible ComProc
|
||||
GetBounds ComProc
|
||||
PutBounds ComProc
|
||||
GetZoomFactor ComProc
|
||||
PutZoomFactor ComProc
|
||||
AddZoomFactorChanged ComProc
|
||||
RemoveZoomFactorChanged ComProc
|
||||
SetBoundsAndZoomFactor ComProc
|
||||
MoveFocus ComProc
|
||||
AddMoveFocusRequested ComProc
|
||||
RemoveMoveFocusRequested ComProc
|
||||
AddGotFocus ComProc
|
||||
RemoveGotFocus ComProc
|
||||
AddLostFocus ComProc
|
||||
RemoveLostFocus ComProc
|
||||
AddAcceleratorKeyPressed ComProc
|
||||
RemoveAcceleratorKeyPressed ComProc
|
||||
GetParentWindow ComProc
|
||||
PutParentWindow ComProc
|
||||
NotifyParentWindowPositionChanged ComProc
|
||||
Close ComProc
|
||||
GetCoreWebView2 ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2Controller struct {
|
||||
vtbl *_ICoreWebView2ControllerVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) GetBounds() (*w32.Rect, error) {
|
||||
var err error
|
||||
var bounds w32.Rect
|
||||
_, _, err = i.vtbl.GetBounds.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&bounds)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
return &bounds, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) PutBounds(bounds w32.Rect) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutBounds.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&bounds)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) MoveFocus(reason COREWEBVIEW2_MOVE_FOCUS_REASON) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.MoveFocus.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(reason),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) AddAcceleratorKeyPressed(eventHandler *ICoreWebView2AcceleratorKeyPressedEventHandler, token *_EventRegistrationToken) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.AddAcceleratorKeyPressed.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(eventHandler)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) PutIsVisible(isVisible bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsVisible.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isVisible)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) GetICoreWebView2Controller2() *ICoreWebView2Controller2 {
|
||||
|
||||
var result *ICoreWebView2Controller2
|
||||
|
||||
iidICoreWebView2Controller2 := NewGUID("{c979903e-d4ca-4228-92eb-47ee3fa96eab}")
|
||||
i.vtbl.QueryInterface.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(iidICoreWebView2Controller2)),
|
||||
uintptr(unsafe.Pointer(&result)))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) NotifyParentWindowPositionChanged() error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.NotifyParentWindowPositionChanged.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) PutZoomFactor(zoomFactor float64) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.PutZoomFactor.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(math.Float64bits(zoomFactor)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller) GetZoomFactor() (float64, error) {
|
||||
var err error
|
||||
var zoomFactorUint64 uint64
|
||||
_, _, err = i.vtbl.GetZoomFactor.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&zoomFactorUint64)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return 0.0, err
|
||||
}
|
||||
return math.Float64frombits(zoomFactorUint64), nil
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2Controller2Vtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetIsVisible ComProc
|
||||
PutIsVisible ComProc
|
||||
GetBounds ComProc
|
||||
PutBounds ComProc
|
||||
GetZoomFactor ComProc
|
||||
PutZoomFactor ComProc
|
||||
AddZoomFactorChanged ComProc
|
||||
RemoveZoomFactorChanged ComProc
|
||||
SetBoundsAndZoomFactor ComProc
|
||||
MoveFocus ComProc
|
||||
AddMoveFocusRequested ComProc
|
||||
RemoveMoveFocusRequested ComProc
|
||||
AddGotFocus ComProc
|
||||
RemoveGotFocus ComProc
|
||||
AddLostFocus ComProc
|
||||
RemoveLostFocus ComProc
|
||||
AddAcceleratorKeyPressed ComProc
|
||||
RemoveAcceleratorKeyPressed ComProc
|
||||
GetParentWindow ComProc
|
||||
PutParentWindow ComProc
|
||||
NotifyParentWindowPositionChanged ComProc
|
||||
Close ComProc
|
||||
GetCoreWebView2 ComProc
|
||||
GetDefaultBackgroundColor ComProc
|
||||
PutDefaultBackgroundColor ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2Controller2 struct {
|
||||
vtbl *_ICoreWebView2Controller2Vtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller2) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller2) GetDefaultBackgroundColor() (*COREWEBVIEW2_COLOR, error) {
|
||||
var err error
|
||||
var backgroundColor *COREWEBVIEW2_COLOR
|
||||
_, _, err = i.vtbl.GetDefaultBackgroundColor.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&backgroundColor)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
return backgroundColor, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Controller2) PutDefaultBackgroundColor(backgroundColor COREWEBVIEW2_COLOR) error {
|
||||
var err error
|
||||
|
||||
// Cast to a uint32 as that's what the call is expecting
|
||||
col := *(*uint32)(unsafe.Pointer(&backgroundColor))
|
||||
|
||||
_, _, err = i.vtbl.PutDefaultBackgroundColor.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(col),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2CreateCoreWebView2ControllerCompletedHandler struct {
|
||||
vtbl *_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl
|
||||
impl _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl
|
||||
}
|
||||
|
||||
func (i *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownQueryInterface(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownAddRef(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownRelease(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerInvoke(this *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler, errorCode uintptr, createdController *ICoreWebView2Controller) uintptr {
|
||||
return this.impl.CreateCoreWebView2ControllerCompleted(errorCode, createdController)
|
||||
}
|
||||
|
||||
type _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
CreateCoreWebView2ControllerCompleted(errorCode uintptr, createdController *ICoreWebView2Controller) uintptr
|
||||
}
|
||||
|
||||
var _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerFn = _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2CreateCoreWebView2ControllerCompletedHandler(impl _ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerImpl) *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler {
|
||||
return &iCoreWebView2CreateCoreWebView2ControllerCompletedHandler{
|
||||
vtbl: &_ICoreWebView2CreateCoreWebView2ControllerCompletedHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2HttpHeadersCollectionIteratorVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetCurrentHeader ComProc
|
||||
GetHasCurrentHeader ComProc
|
||||
MoveNext ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2HttpHeadersCollectionIterator struct {
|
||||
vtbl *_ICoreWebView2HttpHeadersCollectionIteratorVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2HttpHeadersCollectionIterator) Release() error {
|
||||
return i.vtbl.CallRelease(unsafe.Pointer(i))
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2HttpHeadersCollectionIterator) HasCurrentHeader() (bool, error) {
|
||||
var hasHeader int32
|
||||
res, _, err := i.vtbl.GetHasCurrentHeader.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&hasHeader)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return false, syscall.Errno(res)
|
||||
}
|
||||
return hasHeader != 0, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2HttpHeadersCollectionIterator) GetCurrentHeader() (string, string, error) {
|
||||
// Create *uint16 to hold result
|
||||
var _name *uint16
|
||||
var _value *uint16
|
||||
res, _, err := i.vtbl.GetCurrentHeader.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&_name)),
|
||||
uintptr(unsafe.Pointer(&_value)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return "", "", err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return "", "", syscall.Errno(res)
|
||||
}
|
||||
// Get result and cleanup
|
||||
name := windows.UTF16PtrToString(_name)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(_name))
|
||||
value := windows.UTF16PtrToString(_value)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(_value))
|
||||
return name, value, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2HttpHeadersCollectionIterator) MoveNext() (bool, error) {
|
||||
var next int32
|
||||
res, _, err := i.vtbl.MoveNext.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&next)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return false, syscall.Errno(res)
|
||||
}
|
||||
return next != 0, nil
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
const (
|
||||
ERROR_ELEMENT_NOT_FOUND syscall.Errno = 0x80070490
|
||||
)
|
||||
|
||||
type _ICoreWebView2HttpRequestHeadersVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetHeader ComProc
|
||||
GetHeaders ComProc
|
||||
Contains ComProc
|
||||
SetHeader ComProc
|
||||
RemoveHeader ComProc
|
||||
GetIterator ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2HttpRequestHeaders struct {
|
||||
vtbl *_ICoreWebView2HttpRequestHeadersVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2HttpRequestHeaders) Release() error {
|
||||
return i.vtbl.CallRelease(unsafe.Pointer(i))
|
||||
}
|
||||
|
||||
// GetHeader returns the value of the specified header. If the header is not found
|
||||
// ERROR_ELEMENT_NOT_FOUND is returned as error.
|
||||
func (i *ICoreWebView2HttpRequestHeaders) GetHeader(name string) (string, error) {
|
||||
_name, err := windows.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
var _value *uint16
|
||||
res, _, err := i.vtbl.GetHeader.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(_name)),
|
||||
uintptr(unsafe.Pointer(&_value)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return "", err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return "", syscall.Errno(res)
|
||||
}
|
||||
|
||||
value := windows.UTF16PtrToString(_value)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(_value))
|
||||
return value, nil
|
||||
}
|
||||
|
||||
// SetHeader sets the specified header to the value.
|
||||
func (i *ICoreWebView2HttpRequestHeaders) SetHeader(name, value string) error {
|
||||
_name, err := windows.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
_value, err := windows.UTF16PtrFromString(value)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
res, _, err := i.vtbl.SetHeader.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(_name)),
|
||||
uintptr(unsafe.Pointer(_value)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return syscall.Errno(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetIterator returns an iterator over the collection of request headers. Make sure to call
|
||||
// Release on the returned Object after finished using it.
|
||||
func (i *ICoreWebView2HttpRequestHeaders) GetIterator() (*ICoreWebView2HttpHeadersCollectionIterator, error) {
|
||||
var headers *ICoreWebView2HttpHeadersCollectionIterator
|
||||
res, _, err := i.vtbl.GetIterator.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&headers)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return nil, syscall.Errno(res)
|
||||
}
|
||||
return headers, nil
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type _ICoreWebView2NavigationCompletedEventArgsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetIsSuccess ComProc
|
||||
GetWebErrorStatus ComProc
|
||||
GetNavigationId ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2NavigationCompletedEventArgs struct {
|
||||
vtbl *_ICoreWebView2NavigationCompletedEventArgsVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2NavigationCompletedEventArgs) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type _ICoreWebView2NavigationCompletedEventHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2NavigationCompletedEventHandler struct {
|
||||
vtbl *_ICoreWebView2NavigationCompletedEventHandlerVtbl
|
||||
impl _ICoreWebView2NavigationCompletedEventHandlerImpl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2NavigationCompletedEventHandler) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
func _ICoreWebView2NavigationCompletedEventHandlerIUnknownQueryInterface(this *ICoreWebView2NavigationCompletedEventHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2NavigationCompletedEventHandlerIUnknownAddRef(this *ICoreWebView2NavigationCompletedEventHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2NavigationCompletedEventHandlerIUnknownRelease(this *ICoreWebView2NavigationCompletedEventHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2NavigationCompletedEventHandlerInvoke(this *ICoreWebView2NavigationCompletedEventHandler, sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr {
|
||||
return this.impl.NavigationCompleted(sender, args)
|
||||
}
|
||||
|
||||
type _ICoreWebView2NavigationCompletedEventHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
NavigationCompleted(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr
|
||||
}
|
||||
|
||||
var _ICoreWebView2NavigationCompletedEventHandlerFn = _ICoreWebView2NavigationCompletedEventHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2NavigationCompletedEventHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2NavigationCompletedEventHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2NavigationCompletedEventHandler(impl _ICoreWebView2NavigationCompletedEventHandlerImpl) *ICoreWebView2NavigationCompletedEventHandler {
|
||||
return &ICoreWebView2NavigationCompletedEventHandler{
|
||||
vtbl: &_ICoreWebView2NavigationCompletedEventHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2ProcessFailedEventArgsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetProcessFailedKind ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2ProcessFailedEventArgs struct {
|
||||
vtbl *_ICoreWebView2ProcessFailedEventArgsVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2ProcessFailedEventArgs) GetProcessFailedKind() (COREWEBVIEW2_PROCESS_FAILED_KIND, error) {
|
||||
kind := COREWEBVIEW2_PROCESS_FAILED_KIND(0xffffffff)
|
||||
hr, _, err := i.vtbl.GetProcessFailedKind.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&kind)),
|
||||
)
|
||||
|
||||
if windows.Handle(hr) != windows.S_OK {
|
||||
return 0, syscall.Errno(hr)
|
||||
}
|
||||
|
||||
if kind == 0xffffffff {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("unknown error")
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return kind, nil
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type _ICoreWebView2ProcessFailedEventHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2ProcessFailedEventHandler struct {
|
||||
vtbl *_ICoreWebView2ProcessFailedEventHandlerVtbl
|
||||
impl _ICoreWebView2ProcessFailedEventHandlerImpl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2ProcessFailedEventHandler) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
func _ICoreWebView2ProcessFailedEventHandlerIUnknownQueryInterface(this *ICoreWebView2ProcessFailedEventHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2ProcessFailedEventHandlerIUnknownAddRef(this *ICoreWebView2ProcessFailedEventHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2ProcessFailedEventHandlerIUnknownRelease(this *ICoreWebView2ProcessFailedEventHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2ProcessFailedEventHandlerInvoke(this *ICoreWebView2ProcessFailedEventHandler, sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr {
|
||||
return this.impl.ProcessFailed(sender, args)
|
||||
}
|
||||
|
||||
type _ICoreWebView2ProcessFailedEventHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
ProcessFailed(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr
|
||||
}
|
||||
|
||||
var _ICoreWebView2ProcessFailedEventHandlerFn = _ICoreWebView2ProcessFailedEventHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2ProcessFailedEventHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2ProcessFailedEventHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2ProcessFailedEventHandler(impl _ICoreWebView2ProcessFailedEventHandlerImpl) *ICoreWebView2ProcessFailedEventHandler {
|
||||
return &ICoreWebView2ProcessFailedEventHandler{
|
||||
vtbl: &_ICoreWebView2ProcessFailedEventHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
@ -1,271 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2SettingsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetIsScriptEnabled ComProc
|
||||
PutIsScriptEnabled ComProc
|
||||
GetIsWebMessageEnabled ComProc
|
||||
PutIsWebMessageEnabled ComProc
|
||||
GetAreDefaultScriptDialogsEnabled ComProc
|
||||
PutAreDefaultScriptDialogsEnabled ComProc
|
||||
GetIsStatusBarEnabled ComProc
|
||||
PutIsStatusBarEnabled ComProc
|
||||
GetAreDevToolsEnabled ComProc
|
||||
PutAreDevToolsEnabled ComProc
|
||||
GetAreDefaultContextMenusEnabled ComProc
|
||||
PutAreDefaultContextMenusEnabled ComProc
|
||||
GetAreHostObjectsAllowed ComProc
|
||||
PutAreHostObjectsAllowed ComProc
|
||||
GetIsZoomControlEnabled ComProc
|
||||
PutIsZoomControlEnabled ComProc
|
||||
GetIsBuiltInErrorPageEnabled ComProc
|
||||
PutIsBuiltInErrorPageEnabled ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2Settings struct {
|
||||
vtbl *_ICoreWebView2SettingsVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetIsScriptEnabled() (bool, error) {
|
||||
var err error
|
||||
var isScriptEnabled bool
|
||||
_, _, err = i.vtbl.GetIsScriptEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&isScriptEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return isScriptEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutIsScriptEnabled(isScriptEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsScriptEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isScriptEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetIsWebMessageEnabled() (bool, error) {
|
||||
var err error
|
||||
var isWebMessageEnabled bool
|
||||
_, _, err = i.vtbl.GetIsWebMessageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&isWebMessageEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return isWebMessageEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutIsWebMessageEnabled(isWebMessageEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsWebMessageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isWebMessageEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetAreDefaultScriptDialogsEnabled() (bool, error) {
|
||||
var err error
|
||||
var areDefaultScriptDialogsEnabled bool
|
||||
_, _, err = i.vtbl.GetAreDefaultScriptDialogsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return areDefaultScriptDialogsEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutAreDefaultScriptDialogsEnabled(areDefaultScriptDialogsEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutAreDefaultScriptDialogsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(areDefaultScriptDialogsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetIsStatusBarEnabled() (bool, error) {
|
||||
var err error
|
||||
var isStatusBarEnabled bool
|
||||
_, _, err = i.vtbl.GetIsStatusBarEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&isStatusBarEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return isStatusBarEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutIsStatusBarEnabled(isStatusBarEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsStatusBarEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isStatusBarEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetAreDevToolsEnabled() (bool, error) {
|
||||
var err error
|
||||
var areDevToolsEnabled bool
|
||||
_, _, err = i.vtbl.GetAreDevToolsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&areDevToolsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return areDevToolsEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutAreDevToolsEnabled(areDevToolsEnabled bool) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.PutAreDevToolsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(areDevToolsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetAreDefaultContextMenusEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetAreDefaultContextMenusEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutAreDefaultContextMenusEnabled(enabled bool) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.PutAreDefaultContextMenusEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetAreHostObjectsAllowed() (bool, error) {
|
||||
var err error
|
||||
var allowed bool
|
||||
_, _, err = i.vtbl.GetAreHostObjectsAllowed.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&allowed)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return allowed, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutAreHostObjectsAllowed(allowed bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutAreHostObjectsAllowed.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(allowed)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetIsZoomControlEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetIsZoomControlEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutIsZoomControlEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsZoomControlEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) GetIsBuiltInErrorPageEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetIsBuiltInErrorPageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2Settings) PutIsBuiltInErrorPageEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsBuiltInErrorPageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2WebResourceRequestVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetUri ComProc
|
||||
PutUri ComProc
|
||||
GetMethod ComProc
|
||||
PutMethod ComProc
|
||||
GetContent ComProc
|
||||
PutContent ComProc
|
||||
GetHeaders ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2WebResourceRequest struct {
|
||||
vtbl *_ICoreWebView2WebResourceRequestVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequest) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequest) GetMethod() (string, error) {
|
||||
// Create *uint16 to hold result
|
||||
var _method *uint16
|
||||
res, _, err := i.vtbl.GetMethod.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&_method)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return "", err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return "", syscall.Errno(res)
|
||||
}
|
||||
// Get result and cleanup
|
||||
uri := windows.UTF16PtrToString(_method)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(_method))
|
||||
return uri, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequest) GetUri() (string, error) {
|
||||
var err error
|
||||
// Create *uint16 to hold result
|
||||
var _uri *uint16
|
||||
_, _, err = i.vtbl.GetUri.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&_uri)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return "", err
|
||||
} // Get result and cleanup
|
||||
uri := windows.UTF16PtrToString(_uri)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(_uri))
|
||||
return uri, nil
|
||||
}
|
||||
|
||||
// GetContent returns the body of the request. Returns nil if there's no body. Make sure to call
|
||||
// Release on the returned IStream after finished using it.
|
||||
func (i *ICoreWebView2WebResourceRequest) GetContent() (*IStream, error) {
|
||||
var stream *IStream
|
||||
res, _, err := i.vtbl.GetContent.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&stream)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return nil, syscall.Errno(res)
|
||||
}
|
||||
return stream, nil
|
||||
}
|
||||
|
||||
// GetHeaders returns the mutable HTTP request headers. Make sure to call
|
||||
// Release on the returned Object after finished using it.
|
||||
func (i *ICoreWebView2WebResourceRequest) GetHeaders() (*ICoreWebView2HttpRequestHeaders, error) {
|
||||
var headers *ICoreWebView2HttpRequestHeaders
|
||||
res, _, err := i.vtbl.GetHeaders.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&headers)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
if windows.Handle(res) != windows.S_OK {
|
||||
return nil, syscall.Errno(res)
|
||||
}
|
||||
return headers, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequest) Release() error {
|
||||
return i.vtbl.CallRelease(unsafe.Pointer(i))
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _ICoreWebView2WebResourceRequestedEventArgsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetRequest ComProc
|
||||
GetResponse ComProc
|
||||
PutResponse ComProc
|
||||
GetDeferral ComProc
|
||||
GetResourceContext ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2WebResourceRequestedEventArgs struct {
|
||||
vtbl *_ICoreWebView2WebResourceRequestedEventArgsVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequestedEventArgs) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequestedEventArgs) PutResponse(response *ICoreWebView2WebResourceResponse) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutResponse.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(response)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceRequestedEventArgs) GetRequest() (*ICoreWebView2WebResourceRequest, error) {
|
||||
var err error
|
||||
var request *ICoreWebView2WebResourceRequest
|
||||
_, _, err = i.vtbl.GetRequest.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&request)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
return request, nil
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type _ICoreWebView2WebResourceRequestedEventHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2WebResourceRequestedEventHandler struct {
|
||||
vtbl *_ICoreWebView2WebResourceRequestedEventHandlerVtbl
|
||||
impl _ICoreWebView2WebResourceRequestedEventHandlerImpl
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownQueryInterface(this *iCoreWebView2WebResourceRequestedEventHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownAddRef(this *iCoreWebView2WebResourceRequestedEventHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebResourceRequestedEventHandlerIUnknownRelease(this *iCoreWebView2WebResourceRequestedEventHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebResourceRequestedEventHandlerInvoke(this *iCoreWebView2WebResourceRequestedEventHandler, sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr {
|
||||
return this.impl.WebResourceRequested(sender, args)
|
||||
}
|
||||
|
||||
type _ICoreWebView2WebResourceRequestedEventHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
WebResourceRequested(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr
|
||||
}
|
||||
|
||||
var _ICoreWebView2WebResourceRequestedEventHandlerFn = _ICoreWebView2WebResourceRequestedEventHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2WebResourceRequestedEventHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2WebResourceRequestedEventHandler(impl _ICoreWebView2WebResourceRequestedEventHandlerImpl) *iCoreWebView2WebResourceRequestedEventHandler {
|
||||
return &iCoreWebView2WebResourceRequestedEventHandler{
|
||||
vtbl: &_ICoreWebView2WebResourceRequestedEventHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type _ICoreWebView2WebResourceResponseVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetContent ComProc
|
||||
PutContent ComProc
|
||||
GetHeaders ComProc
|
||||
GetStatusCode ComProc
|
||||
PutStatusCode ComProc
|
||||
GetReasonPhrase ComProc
|
||||
PutReasonPhrase ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2WebResourceResponse struct {
|
||||
vtbl *_ICoreWebView2WebResourceResponseVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceResponse) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2WebResourceResponse) Release() error {
|
||||
return i.vtbl.CallRelease(unsafe.Pointer(i))
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
type iCoreWebView2_2Vtbl struct {
|
||||
iCoreWebView2Vtbl
|
||||
AddWebResourceResponseReceived ComProc
|
||||
RemoveWebResourceResponseReceived ComProc
|
||||
NavigateWithWebResourceRequest ComProc
|
||||
AddDomContentLoaded ComProc
|
||||
RemoveDomContentLoaded ComProc
|
||||
GetCookieManager ComProc
|
||||
GetEnvironment ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2_2 struct {
|
||||
vtbl *iCoreWebView2_2Vtbl
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type iCoreWebView2_3Vtbl struct {
|
||||
iCoreWebView2_2Vtbl
|
||||
TrySuspend ComProc
|
||||
Resume ComProc
|
||||
GetIsSuspended ComProc
|
||||
SetVirtualHostNameToFolderMapping ComProc
|
||||
ClearVirtualHostNameToFolderMapping ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2_3 struct {
|
||||
vtbl *iCoreWebView2_3Vtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2_3) SetVirtualHostNameToFolderMapping(hostName, folderPath string, accessKind COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND) error {
|
||||
_hostName, err := windows.UTF16PtrFromString(hostName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_folderPath, err := windows.UTF16PtrFromString(folderPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _, err = i.vtbl.SetVirtualHostNameToFolderMapping.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(_hostName)),
|
||||
uintptr(unsafe.Pointer(_folderPath)),
|
||||
uintptr(accessKind),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2) GetICoreWebView2_3() *ICoreWebView2_3 {
|
||||
var result *ICoreWebView2_3
|
||||
|
||||
iidICoreWebView2_3 := NewGUID("{A0D6DF20-3B92-416D-AA0C-437A9C727857}")
|
||||
_, _, _ = i.vtbl.QueryInterface.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(iidICoreWebView2_3)),
|
||||
uintptr(unsafe.Pointer(&result)))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (e *Chromium) GetICoreWebView2_3() *ICoreWebView2_3 {
|
||||
return e.webview.GetICoreWebView2_3()
|
||||
}
|
@ -1,397 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// ICoreWebviewSettings is the merged settings class
|
||||
|
||||
type _ICoreWebViewSettingsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetIsScriptEnabled ComProc
|
||||
PutIsScriptEnabled ComProc
|
||||
GetIsWebMessageEnabled ComProc
|
||||
PutIsWebMessageEnabled ComProc
|
||||
GetAreDefaultScriptDialogsEnabled ComProc
|
||||
PutAreDefaultScriptDialogsEnabled ComProc
|
||||
GetIsStatusBarEnabled ComProc
|
||||
PutIsStatusBarEnabled ComProc
|
||||
GetAreDevToolsEnabled ComProc
|
||||
PutAreDevToolsEnabled ComProc
|
||||
GetAreDefaultContextMenusEnabled ComProc
|
||||
PutAreDefaultContextMenusEnabled ComProc
|
||||
GetAreHostObjectsAllowed ComProc
|
||||
PutAreHostObjectsAllowed ComProc
|
||||
GetIsZoomControlEnabled ComProc
|
||||
PutIsZoomControlEnabled ComProc
|
||||
GetIsBuiltInErrorPageEnabled ComProc
|
||||
PutIsBuiltInErrorPageEnabled ComProc
|
||||
GetUserAgent ComProc // ICoreWebView2Settings2: SDK 1.0.864.35
|
||||
PutUserAgent ComProc
|
||||
GetAreBrowserAcceleratorKeysEnabled ComProc // ICoreWebView2Settings3: SDK 1.0.864.35
|
||||
PutAreBrowserAcceleratorKeysEnabled ComProc
|
||||
GetIsPasswordAutosaveEnabled ComProc // ICoreWebView2Settings4: SDK 1.0.902.49
|
||||
PutIsPasswordAutosaveEnabled ComProc
|
||||
GetIsGeneralAutofillEnabled ComProc
|
||||
PutIsGeneralAutofillEnabled ComProc
|
||||
GetIsPinchZoomEnabled ComProc // ICoreWebView2Settings5: SDK 1.0.902.49
|
||||
PutIsPinchZoomEnabled ComProc
|
||||
GetIsSwipeNavigationEnabled ComProc // ICoreWebView2Settings6: SDK 1.0.992.28
|
||||
PutIsSwipeNavigationEnabled ComProc
|
||||
}
|
||||
|
||||
type ICoreWebViewSettings struct {
|
||||
vtbl *_ICoreWebViewSettingsVtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) AddRef() uintptr {
|
||||
return i.AddRef()
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsScriptEnabled() (bool, error) {
|
||||
var err error
|
||||
var isScriptEnabled bool
|
||||
_, _, err = i.vtbl.GetIsScriptEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&isScriptEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return isScriptEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsScriptEnabled(isScriptEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsScriptEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isScriptEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsWebMessageEnabled() (bool, error) {
|
||||
var err error
|
||||
var isWebMessageEnabled bool
|
||||
_, _, err = i.vtbl.GetIsWebMessageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&isWebMessageEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return isWebMessageEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsWebMessageEnabled(isWebMessageEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsWebMessageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isWebMessageEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetAreDefaultScriptDialogsEnabled() (bool, error) {
|
||||
var err error
|
||||
var areDefaultScriptDialogsEnabled bool
|
||||
_, _, err = i.vtbl.GetAreDefaultScriptDialogsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&areDefaultScriptDialogsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return areDefaultScriptDialogsEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutAreDefaultScriptDialogsEnabled(areDefaultScriptDialogsEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutAreDefaultScriptDialogsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(areDefaultScriptDialogsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsStatusBarEnabled() (bool, error) {
|
||||
var err error
|
||||
var isStatusBarEnabled bool
|
||||
_, _, err = i.vtbl.GetIsStatusBarEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&isStatusBarEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return isStatusBarEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsStatusBarEnabled(isStatusBarEnabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsStatusBarEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(isStatusBarEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetAreDevToolsEnabled() (bool, error) {
|
||||
var err error
|
||||
var areDevToolsEnabled bool
|
||||
_, _, err = i.vtbl.GetAreDevToolsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&areDevToolsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return areDevToolsEnabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutAreDevToolsEnabled(areDevToolsEnabled bool) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.PutAreDevToolsEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(areDevToolsEnabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetAreDefaultContextMenusEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetAreDefaultContextMenusEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutAreDefaultContextMenusEnabled(enabled bool) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.PutAreDefaultContextMenusEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetAreHostObjectsAllowed() (bool, error) {
|
||||
var err error
|
||||
var allowed bool
|
||||
_, _, err = i.vtbl.GetAreHostObjectsAllowed.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&allowed)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return allowed, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutAreHostObjectsAllowed(allowed bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutAreHostObjectsAllowed.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(allowed)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsZoomControlEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetIsZoomControlEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsZoomControlEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsZoomControlEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsBuiltInErrorPageEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetIsBuiltInErrorPageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsBuiltInErrorPageEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsBuiltInErrorPageEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetUserAgent() (string, error) {
|
||||
var err error
|
||||
// Create *uint16 to hold result
|
||||
var _userAgent *uint16
|
||||
_, _, err = i.vtbl.GetUserAgent.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(_userAgent)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return "", err
|
||||
} // Get result and cleanup
|
||||
userAgent := windows.UTF16PtrToString(_userAgent)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(_userAgent))
|
||||
return userAgent, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutUserAgent(userAgent string) error {
|
||||
var err error
|
||||
// Convert string 'userAgent' to *uint16
|
||||
_userAgent, err := windows.UTF16PtrFromString(userAgent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _, err = i.vtbl.PutUserAgent.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(_userAgent)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetAreBrowserAcceleratorKeysEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetAreBrowserAcceleratorKeysEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutAreBrowserAcceleratorKeysEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutAreBrowserAcceleratorKeysEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsPinchZoomEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetIsPinchZoomEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsPinchZoomEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsPinchZoomEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) GetIsSwipeNavigationEnabled() (bool, error) {
|
||||
var err error
|
||||
var enabled bool
|
||||
_, _, err = i.vtbl.GetIsSwipeNavigationEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return false, err
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebViewSettings) PutIsSwipeNavigationEnabled(enabled bool) error {
|
||||
var err error
|
||||
|
||||
_, _, err = i.vtbl.PutIsSwipeNavigationEnabled.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(boolToInt(enabled)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"io"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type _IStreamVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Read ComProc
|
||||
Write ComProc
|
||||
}
|
||||
|
||||
type IStream struct {
|
||||
vtbl *_IStreamVtbl
|
||||
}
|
||||
|
||||
func (i *IStream) Release() error {
|
||||
return i.vtbl.CallRelease(unsafe.Pointer(i))
|
||||
}
|
||||
|
||||
func (i *IStream) Read(p []byte) (int, error) {
|
||||
bufLen := len(p)
|
||||
if bufLen == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
var n int
|
||||
res, _, err := i.vtbl.Read.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&p[0])),
|
||||
uintptr(bufLen),
|
||||
uintptr(unsafe.Pointer(&n)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch windows.Handle(res) {
|
||||
case windows.S_OK:
|
||||
// The buffer has been completely filled
|
||||
return n, nil
|
||||
case windows.S_FALSE:
|
||||
// The buffer has been filled with less than len data and the stream is EOF
|
||||
return n, io.EOF
|
||||
default:
|
||||
return 0, syscall.Errno(res)
|
||||
}
|
||||
}
|
@ -1,419 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
type Rect = w32.Rect
|
||||
|
||||
type Chromium struct {
|
||||
hwnd uintptr
|
||||
controller *ICoreWebView2Controller
|
||||
webview *ICoreWebView2
|
||||
inited uintptr
|
||||
envCompleted *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
controllerCompleted *iCoreWebView2CreateCoreWebView2ControllerCompletedHandler
|
||||
webMessageReceived *iCoreWebView2WebMessageReceivedEventHandler
|
||||
permissionRequested *iCoreWebView2PermissionRequestedEventHandler
|
||||
webResourceRequested *iCoreWebView2WebResourceRequestedEventHandler
|
||||
acceleratorKeyPressed *ICoreWebView2AcceleratorKeyPressedEventHandler
|
||||
navigationCompleted *ICoreWebView2NavigationCompletedEventHandler
|
||||
processFailed *ICoreWebView2ProcessFailedEventHandler
|
||||
|
||||
environment *ICoreWebView2Environment
|
||||
|
||||
padding Rect
|
||||
|
||||
// Settings
|
||||
Debug bool
|
||||
DataPath string
|
||||
BrowserPath string
|
||||
AdditionalBrowserArgs []string
|
||||
|
||||
// permissions
|
||||
permissions map[CoreWebView2PermissionKind]CoreWebView2PermissionState
|
||||
globalPermission *CoreWebView2PermissionState
|
||||
|
||||
// Callbacks
|
||||
MessageCallback func(string)
|
||||
WebResourceRequestedCallback func(request *ICoreWebView2WebResourceRequest, args *ICoreWebView2WebResourceRequestedEventArgs)
|
||||
NavigationCompletedCallback func(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs)
|
||||
ProcessFailedCallback func(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs)
|
||||
AcceleratorKeyCallback func(uint) bool
|
||||
}
|
||||
|
||||
func NewChromium() *Chromium {
|
||||
e := &Chromium{}
|
||||
/*
|
||||
All these handlers are passed to native code through syscalls with 'uintptr(unsafe.Pointer(handler))' and we know
|
||||
that a pointer to those will be kept in the native code. Furthermore these handlers als contain pointer to other Go
|
||||
structs like the vtable.
|
||||
This violates the unsafe.Pointer rule '(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall.' because
|
||||
theres no guarantee that Go doesn't move these objects.
|
||||
AFAIK currently the Go runtime doesn't move HEAP objects, so we should be safe with these handlers. But they don't
|
||||
guarantee it, because in the future Go might use a compacting GC.
|
||||
There's a proposal to add a runtime.Pin function, to prevent moving pinned objects, which would allow to easily fix
|
||||
this issue by just pinning the handlers. The https://go-review.googlesource.com/c/go/+/367296/ should land in Go 1.19.
|
||||
*/
|
||||
e.envCompleted = newICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler(e)
|
||||
e.controllerCompleted = newICoreWebView2CreateCoreWebView2ControllerCompletedHandler(e)
|
||||
e.webMessageReceived = newICoreWebView2WebMessageReceivedEventHandler(e)
|
||||
e.permissionRequested = newICoreWebView2PermissionRequestedEventHandler(e)
|
||||
e.webResourceRequested = newICoreWebView2WebResourceRequestedEventHandler(e)
|
||||
e.acceleratorKeyPressed = newICoreWebView2AcceleratorKeyPressedEventHandler(e)
|
||||
e.navigationCompleted = newICoreWebView2NavigationCompletedEventHandler(e)
|
||||
e.processFailed = newICoreWebView2ProcessFailedEventHandler(e)
|
||||
e.permissions = make(map[CoreWebView2PermissionKind]CoreWebView2PermissionState)
|
||||
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Chromium) Embed(hwnd uintptr) bool {
|
||||
e.hwnd = hwnd
|
||||
|
||||
dataPath := e.DataPath
|
||||
if dataPath == "" {
|
||||
currentExePath := make([]uint16, windows.MAX_PATH)
|
||||
_, err := windows.GetModuleFileName(windows.Handle(0), ¤tExePath[0], windows.MAX_PATH)
|
||||
if err != nil {
|
||||
// What to do here?
|
||||
return false
|
||||
}
|
||||
currentExeName := filepath.Base(windows.UTF16ToString(currentExePath))
|
||||
dataPath = filepath.Join(os.Getenv("AppData"), currentExeName)
|
||||
}
|
||||
|
||||
if e.BrowserPath != "" {
|
||||
if _, err := os.Stat(e.BrowserPath); errors.Is(err, os.ErrNotExist) {
|
||||
log.Printf("Browser path %s does not exist", e.BrowserPath)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
browserArgs := strings.Join(e.AdditionalBrowserArgs, " ")
|
||||
if err := createCoreWebView2EnvironmentWithOptions(e.BrowserPath, dataPath, e.envCompleted, browserArgs); err != nil {
|
||||
log.Printf("Error calling Webview2Loader: %v", err)
|
||||
return false
|
||||
}
|
||||
|
||||
var msg w32.Msg
|
||||
for {
|
||||
if atomic.LoadUintptr(&e.inited) != 0 {
|
||||
break
|
||||
}
|
||||
r, _, _ := w32.User32GetMessageW.Call(
|
||||
uintptr(unsafe.Pointer(&msg)),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
if r == 0 {
|
||||
break
|
||||
}
|
||||
w32.User32TranslateMessage.Call(uintptr(unsafe.Pointer(&msg)))
|
||||
w32.User32DispatchMessageW.Call(uintptr(unsafe.Pointer(&msg)))
|
||||
}
|
||||
e.Init("window.external={invoke:s=>window.chrome.webview.postMessage(s)}")
|
||||
return true
|
||||
}
|
||||
|
||||
func (e *Chromium) SetPadding(padding Rect) {
|
||||
if e.padding.Top == padding.Top && e.padding.Bottom == padding.Bottom &&
|
||||
e.padding.Left == padding.Left && e.padding.Right == padding.Right {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
e.padding = padding
|
||||
e.Resize()
|
||||
}
|
||||
|
||||
func (e *Chromium) Resize() {
|
||||
if e.hwnd == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
var bounds w32.Rect
|
||||
w32.User32GetClientRect.Call(e.hwnd, uintptr(unsafe.Pointer(&bounds)))
|
||||
|
||||
bounds.Top += e.padding.Top
|
||||
bounds.Bottom -= e.padding.Bottom
|
||||
bounds.Left += e.padding.Left
|
||||
bounds.Right -= e.padding.Right
|
||||
|
||||
e.SetSize(bounds)
|
||||
}
|
||||
|
||||
func (e *Chromium) Navigate(url string) {
|
||||
e.webview.vtbl.Navigate.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(url))),
|
||||
)
|
||||
}
|
||||
|
||||
func (e *Chromium) Init(script string) {
|
||||
e.webview.vtbl.AddScriptToExecuteOnDocumentCreated.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(script))),
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
func (e *Chromium) Eval(script string) {
|
||||
|
||||
_script, err := windows.UTF16PtrFromString(script)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
e.webview.vtbl.ExecuteScript.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(_script)),
|
||||
0,
|
||||
)
|
||||
}
|
||||
|
||||
func (e *Chromium) Show() error {
|
||||
return e.controller.PutIsVisible(true)
|
||||
}
|
||||
|
||||
func (e *Chromium) Hide() error {
|
||||
return e.controller.PutIsVisible(false)
|
||||
}
|
||||
|
||||
func (e *Chromium) QueryInterface(_, _ uintptr) uintptr {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) AddRef() uintptr {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (e *Chromium) Release() uintptr {
|
||||
return 1
|
||||
}
|
||||
|
||||
func (e *Chromium) EnvironmentCompleted(res uintptr, env *ICoreWebView2Environment) uintptr {
|
||||
if int32(res) < 0 {
|
||||
log.Fatalf("Creating environment failed with %08x: %s", res, syscall.Errno(res))
|
||||
}
|
||||
env.vtbl.AddRef.Call(uintptr(unsafe.Pointer(env)))
|
||||
e.environment = env
|
||||
|
||||
env.vtbl.CreateCoreWebView2Controller.Call(
|
||||
uintptr(unsafe.Pointer(env)),
|
||||
e.hwnd,
|
||||
uintptr(unsafe.Pointer(e.controllerCompleted)),
|
||||
)
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) CreateCoreWebView2ControllerCompleted(res uintptr, controller *ICoreWebView2Controller) uintptr {
|
||||
if int32(res) < 0 {
|
||||
log.Fatalf("Creating controller failed with %08x: %s", res, syscall.Errno(res))
|
||||
}
|
||||
controller.vtbl.AddRef.Call(uintptr(unsafe.Pointer(controller)))
|
||||
e.controller = controller
|
||||
|
||||
var token _EventRegistrationToken
|
||||
controller.vtbl.GetCoreWebView2.Call(
|
||||
uintptr(unsafe.Pointer(controller)),
|
||||
uintptr(unsafe.Pointer(&e.webview)),
|
||||
)
|
||||
e.webview.vtbl.AddRef.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
)
|
||||
e.webview.vtbl.AddWebMessageReceived.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(e.webMessageReceived)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
e.webview.vtbl.AddPermissionRequested.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(e.permissionRequested)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
e.webview.vtbl.AddWebResourceRequested.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(e.webResourceRequested)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
e.webview.vtbl.AddNavigationCompleted.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(e.navigationCompleted)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
e.webview.vtbl.AddProcessFailed.Call(
|
||||
uintptr(unsafe.Pointer(e.webview)),
|
||||
uintptr(unsafe.Pointer(e.processFailed)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
|
||||
e.controller.AddAcceleratorKeyPressed(e.acceleratorKeyPressed, &token)
|
||||
|
||||
atomic.StoreUintptr(&e.inited, 1)
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) MessageReceived(sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr {
|
||||
var message *uint16
|
||||
args.vtbl.TryGetWebMessageAsString.Call(
|
||||
uintptr(unsafe.Pointer(args)),
|
||||
uintptr(unsafe.Pointer(&message)),
|
||||
)
|
||||
if e.MessageCallback != nil {
|
||||
e.MessageCallback(w32.Utf16PtrToString(message))
|
||||
}
|
||||
sender.vtbl.PostWebMessageAsString.Call(
|
||||
uintptr(unsafe.Pointer(sender)),
|
||||
uintptr(unsafe.Pointer(message)),
|
||||
)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(message))
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) SetPermission(kind CoreWebView2PermissionKind, state CoreWebView2PermissionState) {
|
||||
e.permissions[kind] = state
|
||||
}
|
||||
|
||||
func (e *Chromium) SetGlobalPermission(state CoreWebView2PermissionState) {
|
||||
e.globalPermission = &state
|
||||
}
|
||||
|
||||
func (e *Chromium) PermissionRequested(_ *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr {
|
||||
var kind CoreWebView2PermissionKind
|
||||
args.vtbl.GetPermissionKind.Call(
|
||||
uintptr(unsafe.Pointer(args)),
|
||||
uintptr(kind),
|
||||
)
|
||||
var result CoreWebView2PermissionState
|
||||
if e.globalPermission != nil {
|
||||
result = *e.globalPermission
|
||||
} else {
|
||||
var ok bool
|
||||
result, ok = e.permissions[kind]
|
||||
if !ok {
|
||||
result = CoreWebView2PermissionStateDefault
|
||||
}
|
||||
}
|
||||
args.vtbl.PutState.Call(
|
||||
uintptr(unsafe.Pointer(args)),
|
||||
uintptr(result),
|
||||
)
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) WebResourceRequested(sender *ICoreWebView2, args *ICoreWebView2WebResourceRequestedEventArgs) uintptr {
|
||||
req, err := args.GetRequest()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer req.Release()
|
||||
|
||||
if e.WebResourceRequestedCallback != nil {
|
||||
e.WebResourceRequestedCallback(req, args)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) AddWebResourceRequestedFilter(filter string, ctx COREWEBVIEW2_WEB_RESOURCE_CONTEXT) {
|
||||
err := e.webview.AddWebResourceRequestedFilter(filter, ctx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Chromium) Environment() *ICoreWebView2Environment {
|
||||
return e.environment
|
||||
}
|
||||
|
||||
// AcceleratorKeyPressed is called when an accelerator key is pressed.
|
||||
// If the AcceleratorKeyCallback method has been set, it will defer handling of the keypress
|
||||
// to the callback. That callback returns a bool indicating if the event was handled.
|
||||
func (e *Chromium) AcceleratorKeyPressed(sender *ICoreWebView2Controller, args *ICoreWebView2AcceleratorKeyPressedEventArgs) uintptr {
|
||||
if e.AcceleratorKeyCallback == nil {
|
||||
return 0
|
||||
}
|
||||
eventKind, _ := args.GetKeyEventKind()
|
||||
if eventKind == COREWEBVIEW2_KEY_EVENT_KIND_KEY_DOWN ||
|
||||
eventKind == COREWEBVIEW2_KEY_EVENT_KIND_SYSTEM_KEY_DOWN {
|
||||
virtualKey, _ := args.GetVirtualKey()
|
||||
status, _ := args.GetPhysicalKeyStatus()
|
||||
if !status.WasKeyDown {
|
||||
args.PutHandled(e.AcceleratorKeyCallback(virtualKey))
|
||||
return 0
|
||||
}
|
||||
}
|
||||
args.PutHandled(false)
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) GetSettings() (*ICoreWebViewSettings, error) {
|
||||
return e.webview.GetSettings()
|
||||
}
|
||||
|
||||
func (e *Chromium) GetController() *ICoreWebView2Controller {
|
||||
return e.controller
|
||||
}
|
||||
|
||||
func boolToInt(input bool) int {
|
||||
if input {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) NavigationCompleted(sender *ICoreWebView2, args *ICoreWebView2NavigationCompletedEventArgs) uintptr {
|
||||
if e.NavigationCompletedCallback != nil {
|
||||
e.NavigationCompletedCallback(sender, args)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) ProcessFailed(sender *ICoreWebView2, args *ICoreWebView2ProcessFailedEventArgs) uintptr {
|
||||
if e.ProcessFailedCallback != nil {
|
||||
e.ProcessFailedCallback(sender, args)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *Chromium) NotifyParentWindowPositionChanged() error {
|
||||
//It looks like the wndproc function is called before the controller initialization is complete.
|
||||
//Because of this the controller is nil
|
||||
if e.controller == nil {
|
||||
return nil
|
||||
}
|
||||
return e.controller.NotifyParentWindowPositionChanged()
|
||||
}
|
||||
|
||||
func (e *Chromium) Focus() {
|
||||
err := e.controller.MoveFocus(COREWEBVIEW2_MOVE_FOCUS_REASON_PROGRAMMATIC)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Chromium) PutZoomFactor(zoomFactor float64) {
|
||||
err := e.controller.PutZoomFactor(zoomFactor)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *Chromium) OpenDevToolsWindow() {
|
||||
e.webview.OpenDevToolsWindow()
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (e *Chromium) SetSize(bounds w32.Rect) {
|
||||
if e.controller == nil {
|
||||
return
|
||||
}
|
||||
|
||||
e.controller.vtbl.PutBounds.Call(
|
||||
uintptr(unsafe.Pointer(e.controller)),
|
||||
uintptr(bounds.Left),
|
||||
uintptr(bounds.Top),
|
||||
uintptr(bounds.Right),
|
||||
uintptr(bounds.Bottom),
|
||||
)
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (e *Chromium) SetSize(bounds w32.Rect) {
|
||||
if e.controller == nil {
|
||||
return
|
||||
}
|
||||
|
||||
e.controller.vtbl.PutBounds.Call(
|
||||
uintptr(unsafe.Pointer(e.controller)),
|
||||
uintptr(unsafe.Pointer(&bounds)),
|
||||
)
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32"
|
||||
)
|
||||
|
||||
func (e *Chromium) SetSize(bounds w32.Rect) {
|
||||
if e.controller == nil {
|
||||
return
|
||||
}
|
||||
|
||||
words := (*[2]uintptr)(unsafe.Pointer(&bounds))
|
||||
e.controller.vtbl.PutBounds.Call(
|
||||
uintptr(unsafe.Pointer(e.controller)),
|
||||
words[0],
|
||||
words[1],
|
||||
)
|
||||
}
|
@ -1,503 +0,0 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/internal/w32"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func init() {
|
||||
runtime.LockOSThread()
|
||||
|
||||
r, _, _ := w32.Ole32CoInitializeEx.Call(0, 2)
|
||||
if int(r) < 0 {
|
||||
log.Printf("Warning: CoInitializeEx call failed: E=%08x", r)
|
||||
}
|
||||
}
|
||||
|
||||
type _EventRegistrationToken struct {
|
||||
value int64
|
||||
}
|
||||
|
||||
type CoreWebView2PermissionKind uint32
|
||||
|
||||
const (
|
||||
CoreWebView2PermissionKindUnknownPermission CoreWebView2PermissionKind = iota
|
||||
CoreWebView2PermissionKindMicrophone
|
||||
CoreWebView2PermissionKindCamera
|
||||
CoreWebView2PermissionKindGeolocation
|
||||
CoreWebView2PermissionKindNotifications
|
||||
CoreWebView2PermissionKindOtherSensors
|
||||
CoreWebView2PermissionKindClipboardRead
|
||||
)
|
||||
|
||||
type CoreWebView2PermissionState uint32
|
||||
|
||||
const (
|
||||
CoreWebView2PermissionStateDefault CoreWebView2PermissionState = iota
|
||||
CoreWebView2PermissionStateAllow
|
||||
CoreWebView2PermissionStateDeny
|
||||
)
|
||||
|
||||
// ComProc stores a COM procedure.
|
||||
type ComProc uintptr
|
||||
|
||||
// NewComProc creates a new COM proc from a Go function.
|
||||
func NewComProc(fn interface{}) ComProc {
|
||||
return ComProc(windows.NewCallback(fn))
|
||||
}
|
||||
|
||||
// Call calls a COM procedure.
|
||||
//
|
||||
//go:uintptrescapes
|
||||
func (p ComProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) {
|
||||
// The magic uintptrescapes comment is needed to prevent moving uintptr(unsafe.Pointer(p)) so calls to .Call() also
|
||||
// satisfy the unsafe.Pointer rule "(4) Conversion of a Pointer to a uintptr when calling syscall.Syscall."
|
||||
// Otherwise it might be that pointers get moved, especially pointer onto the Go stack which might grow dynamically.
|
||||
// See https://pkg.go.dev/unsafe#Pointer and https://github.com/golang/go/issues/34474
|
||||
switch len(a) {
|
||||
case 0:
|
||||
return syscall.Syscall(uintptr(p), 0, 0, 0, 0)
|
||||
case 1:
|
||||
return syscall.Syscall(uintptr(p), 1, a[0], 0, 0)
|
||||
case 2:
|
||||
return syscall.Syscall(uintptr(p), 2, a[0], a[1], 0)
|
||||
case 3:
|
||||
return syscall.Syscall(uintptr(p), 3, a[0], a[1], a[2])
|
||||
case 4:
|
||||
return syscall.Syscall6(uintptr(p), 4, a[0], a[1], a[2], a[3], 0, 0)
|
||||
case 5:
|
||||
return syscall.Syscall6(uintptr(p), 5, a[0], a[1], a[2], a[3], a[4], 0)
|
||||
case 6:
|
||||
return syscall.Syscall6(uintptr(p), 6, a[0], a[1], a[2], a[3], a[4], a[5])
|
||||
case 7:
|
||||
return syscall.Syscall9(uintptr(p), 7, a[0], a[1], a[2], a[3], a[4], a[5], a[6], 0, 0)
|
||||
case 8:
|
||||
return syscall.Syscall9(uintptr(p), 8, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], 0)
|
||||
case 9:
|
||||
return syscall.Syscall9(uintptr(p), 9, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8])
|
||||
case 10:
|
||||
return syscall.Syscall12(uintptr(p), 10, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], 0, 0)
|
||||
case 11:
|
||||
return syscall.Syscall12(uintptr(p), 11, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], 0)
|
||||
case 12:
|
||||
return syscall.Syscall12(uintptr(p), 12, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11])
|
||||
case 13:
|
||||
return syscall.Syscall15(uintptr(p), 13, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], 0, 0)
|
||||
case 14:
|
||||
return syscall.Syscall15(uintptr(p), 14, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], 0)
|
||||
case 15:
|
||||
return syscall.Syscall15(uintptr(p), 15, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14])
|
||||
default:
|
||||
panic("too many arguments")
|
||||
}
|
||||
}
|
||||
|
||||
// IUnknown
|
||||
|
||||
type _IUnknownVtbl struct {
|
||||
QueryInterface ComProc
|
||||
AddRef ComProc
|
||||
Release ComProc
|
||||
}
|
||||
|
||||
func (i *_IUnknownVtbl) CallRelease(this unsafe.Pointer) error {
|
||||
_, _, err := i.Release.Call(
|
||||
uintptr(this),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type _IUnknownImpl interface {
|
||||
QueryInterface(refiid, object uintptr) uintptr
|
||||
AddRef() uintptr
|
||||
Release() uintptr
|
||||
}
|
||||
|
||||
// ICoreWebView2
|
||||
|
||||
type iCoreWebView2Vtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetSettings ComProc
|
||||
GetSource ComProc
|
||||
Navigate ComProc
|
||||
NavigateToString ComProc
|
||||
AddNavigationStarting ComProc
|
||||
RemoveNavigationStarting ComProc
|
||||
AddContentLoading ComProc
|
||||
RemoveContentLoading ComProc
|
||||
AddSourceChanged ComProc
|
||||
RemoveSourceChanged ComProc
|
||||
AddHistoryChanged ComProc
|
||||
RemoveHistoryChanged ComProc
|
||||
AddNavigationCompleted ComProc
|
||||
RemoveNavigationCompleted ComProc
|
||||
AddFrameNavigationStarting ComProc
|
||||
RemoveFrameNavigationStarting ComProc
|
||||
AddFrameNavigationCompleted ComProc
|
||||
RemoveFrameNavigationCompleted ComProc
|
||||
AddScriptDialogOpening ComProc
|
||||
RemoveScriptDialogOpening ComProc
|
||||
AddPermissionRequested ComProc
|
||||
RemovePermissionRequested ComProc
|
||||
AddProcessFailed ComProc
|
||||
RemoveProcessFailed ComProc
|
||||
AddScriptToExecuteOnDocumentCreated ComProc
|
||||
RemoveScriptToExecuteOnDocumentCreated ComProc
|
||||
ExecuteScript ComProc
|
||||
CapturePreview ComProc
|
||||
Reload ComProc
|
||||
PostWebMessageAsJSON ComProc
|
||||
PostWebMessageAsString ComProc
|
||||
AddWebMessageReceived ComProc
|
||||
RemoveWebMessageReceived ComProc
|
||||
CallDevToolsProtocolMethod ComProc
|
||||
GetBrowserProcessID ComProc
|
||||
GetCanGoBack ComProc
|
||||
GetCanGoForward ComProc
|
||||
GoBack ComProc
|
||||
GoForward ComProc
|
||||
GetDevToolsProtocolEventReceiver ComProc
|
||||
Stop ComProc
|
||||
AddNewWindowRequested ComProc
|
||||
RemoveNewWindowRequested ComProc
|
||||
AddDocumentTitleChanged ComProc
|
||||
RemoveDocumentTitleChanged ComProc
|
||||
GetDocumentTitle ComProc
|
||||
AddHostObjectToScript ComProc
|
||||
RemoveHostObjectFromScript ComProc
|
||||
OpenDevToolsWindow ComProc
|
||||
AddContainsFullScreenElementChanged ComProc
|
||||
RemoveContainsFullScreenElementChanged ComProc
|
||||
GetContainsFullScreenElement ComProc
|
||||
AddWebResourceRequested ComProc
|
||||
RemoveWebResourceRequested ComProc
|
||||
AddWebResourceRequestedFilter ComProc
|
||||
RemoveWebResourceRequestedFilter ComProc
|
||||
AddWindowCloseRequested ComProc
|
||||
RemoveWindowCloseRequested ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2 struct {
|
||||
vtbl *iCoreWebView2Vtbl
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2) GetSettings() (*ICoreWebViewSettings, error) {
|
||||
var err error
|
||||
var settings *ICoreWebViewSettings
|
||||
_, _, err = i.vtbl.GetSettings.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(&settings)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return nil, err
|
||||
}
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
// ICoreWebView2Environment
|
||||
|
||||
type iCoreWebView2EnvironmentVtbl struct {
|
||||
_IUnknownVtbl
|
||||
CreateCoreWebView2Controller ComProc
|
||||
CreateWebResourceResponse ComProc
|
||||
GetBrowserVersionString ComProc
|
||||
AddNewBrowserVersionAvailable ComProc
|
||||
RemoveNewBrowserVersionAvailable ComProc
|
||||
}
|
||||
|
||||
type ICoreWebView2Environment struct {
|
||||
vtbl *iCoreWebView2EnvironmentVtbl
|
||||
}
|
||||
|
||||
// CreateWebResourceResponse creates a new ICoreWebView2WebResourceResponse, it must be released after finishing using it.
|
||||
func (e *ICoreWebView2Environment) CreateWebResourceResponse(content []byte, statusCode int, reasonPhrase string, headers string) (*ICoreWebView2WebResourceResponse, error) {
|
||||
var err error
|
||||
var stream uintptr
|
||||
|
||||
if len(content) > 0 {
|
||||
// Create stream for response
|
||||
stream, err = w32.SHCreateMemStream(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Release the IStream after we are finished, CreateWebResourceResponse Call will increase the reference
|
||||
// count on IStream and therefore it won't be freed until the reference count of the response is 0.
|
||||
defer (*IStream)(unsafe.Pointer(stream)).Release()
|
||||
}
|
||||
|
||||
// Convert string 'uri' to *uint16
|
||||
_reason, err := windows.UTF16PtrFromString(reasonPhrase)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Convert string 'uri' to *uint16
|
||||
_headers, err := windows.UTF16PtrFromString(headers)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response *ICoreWebView2WebResourceResponse
|
||||
hr, _, err := e.vtbl.CreateWebResourceResponse.Call(
|
||||
uintptr(unsafe.Pointer(e)),
|
||||
stream,
|
||||
uintptr(statusCode),
|
||||
uintptr(unsafe.Pointer(_reason)),
|
||||
uintptr(unsafe.Pointer(_headers)),
|
||||
uintptr(unsafe.Pointer(&response)),
|
||||
)
|
||||
if windows.Handle(hr) != windows.S_OK {
|
||||
return nil, syscall.Errno(hr)
|
||||
}
|
||||
|
||||
if response == nil {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("unknown error")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
|
||||
}
|
||||
|
||||
// ICoreWebView2WebMessageReceivedEventArgs
|
||||
|
||||
type iCoreWebView2WebMessageReceivedEventArgsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetSource ComProc
|
||||
GetWebMessageAsJSON ComProc
|
||||
TryGetWebMessageAsString ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2WebMessageReceivedEventArgs struct {
|
||||
vtbl *iCoreWebView2WebMessageReceivedEventArgsVtbl
|
||||
}
|
||||
|
||||
// ICoreWebView2PermissionRequestedEventArgs
|
||||
|
||||
type iCoreWebView2PermissionRequestedEventArgsVtbl struct {
|
||||
_IUnknownVtbl
|
||||
GetURI ComProc
|
||||
GetPermissionKind ComProc
|
||||
GetIsUserInitiated ComProc
|
||||
GetState ComProc
|
||||
PutState ComProc
|
||||
GetDeferral ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2PermissionRequestedEventArgs struct {
|
||||
vtbl *iCoreWebView2PermissionRequestedEventArgsVtbl
|
||||
}
|
||||
|
||||
// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
|
||||
type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
EnvironmentCompleted(res uintptr, env *ICoreWebView2Environment) uintptr
|
||||
}
|
||||
|
||||
type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler struct {
|
||||
vtbl *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl
|
||||
impl iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownQueryInterface(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownAddRef(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownRelease(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, res uintptr, env *ICoreWebView2Environment) uintptr {
|
||||
return this.impl.EnvironmentCompleted(res, env)
|
||||
}
|
||||
|
||||
var iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerFn = iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler(impl iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerImpl) *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler {
|
||||
return &iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler{
|
||||
vtbl: &iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
||||
|
||||
// ICoreWebView2WebMessageReceivedEventHandler
|
||||
|
||||
type iCoreWebView2WebMessageReceivedEventHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
MessageReceived(sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr
|
||||
}
|
||||
|
||||
type iCoreWebView2WebMessageReceivedEventHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2WebMessageReceivedEventHandler struct {
|
||||
vtbl *iCoreWebView2WebMessageReceivedEventHandlerVtbl
|
||||
impl iCoreWebView2WebMessageReceivedEventHandlerImpl
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownQueryInterface(this *iCoreWebView2WebMessageReceivedEventHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownAddRef(this *iCoreWebView2WebMessageReceivedEventHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebMessageReceivedEventHandlerIUnknownRelease(this *iCoreWebView2WebMessageReceivedEventHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2WebMessageReceivedEventHandlerInvoke(this *iCoreWebView2WebMessageReceivedEventHandler, sender *ICoreWebView2, args *iCoreWebView2WebMessageReceivedEventArgs) uintptr {
|
||||
return this.impl.MessageReceived(sender, args)
|
||||
}
|
||||
|
||||
var iCoreWebView2WebMessageReceivedEventHandlerFn = iCoreWebView2WebMessageReceivedEventHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2WebMessageReceivedEventHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2WebMessageReceivedEventHandler(impl iCoreWebView2WebMessageReceivedEventHandlerImpl) *iCoreWebView2WebMessageReceivedEventHandler {
|
||||
return &iCoreWebView2WebMessageReceivedEventHandler{
|
||||
vtbl: &iCoreWebView2WebMessageReceivedEventHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
||||
|
||||
// ICoreWebView2PermissionRequestedEventHandler
|
||||
|
||||
type iCoreWebView2PermissionRequestedEventHandlerImpl interface {
|
||||
_IUnknownImpl
|
||||
PermissionRequested(sender *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr
|
||||
}
|
||||
|
||||
type iCoreWebView2PermissionRequestedEventHandlerVtbl struct {
|
||||
_IUnknownVtbl
|
||||
Invoke ComProc
|
||||
}
|
||||
|
||||
type iCoreWebView2PermissionRequestedEventHandler struct {
|
||||
vtbl *iCoreWebView2PermissionRequestedEventHandlerVtbl
|
||||
impl iCoreWebView2PermissionRequestedEventHandlerImpl
|
||||
}
|
||||
|
||||
func _ICoreWebView2PermissionRequestedEventHandlerIUnknownQueryInterface(this *iCoreWebView2PermissionRequestedEventHandler, refiid, object uintptr) uintptr {
|
||||
return this.impl.QueryInterface(refiid, object)
|
||||
}
|
||||
|
||||
func _ICoreWebView2PermissionRequestedEventHandlerIUnknownAddRef(this *iCoreWebView2PermissionRequestedEventHandler) uintptr {
|
||||
return this.impl.AddRef()
|
||||
}
|
||||
|
||||
func _ICoreWebView2PermissionRequestedEventHandlerIUnknownRelease(this *iCoreWebView2PermissionRequestedEventHandler) uintptr {
|
||||
return this.impl.Release()
|
||||
}
|
||||
|
||||
func _ICoreWebView2PermissionRequestedEventHandlerInvoke(this *iCoreWebView2PermissionRequestedEventHandler, sender *ICoreWebView2, args *iCoreWebView2PermissionRequestedEventArgs) uintptr {
|
||||
return this.impl.PermissionRequested(sender, args)
|
||||
}
|
||||
|
||||
var iCoreWebView2PermissionRequestedEventHandlerFn = iCoreWebView2PermissionRequestedEventHandlerVtbl{
|
||||
_IUnknownVtbl{
|
||||
NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownQueryInterface),
|
||||
NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownAddRef),
|
||||
NewComProc(_ICoreWebView2PermissionRequestedEventHandlerIUnknownRelease),
|
||||
},
|
||||
NewComProc(_ICoreWebView2PermissionRequestedEventHandlerInvoke),
|
||||
}
|
||||
|
||||
func newICoreWebView2PermissionRequestedEventHandler(impl iCoreWebView2PermissionRequestedEventHandlerImpl) *iCoreWebView2PermissionRequestedEventHandler {
|
||||
return &iCoreWebView2PermissionRequestedEventHandler{
|
||||
vtbl: &iCoreWebView2PermissionRequestedEventHandlerFn,
|
||||
impl: impl,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2) AddWebResourceRequestedFilter(uri string, resourceContext COREWEBVIEW2_WEB_RESOURCE_CONTEXT) error {
|
||||
var err error
|
||||
// Convert string 'uri' to *uint16
|
||||
_uri, err := windows.UTF16PtrFromString(uri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _, err = i.vtbl.AddWebResourceRequestedFilter.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(_uri)),
|
||||
uintptr(resourceContext),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (i *ICoreWebView2) AddNavigationCompleted(eventHandler *ICoreWebView2NavigationCompletedEventHandler, token *_EventRegistrationToken) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.AddNavigationCompleted.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(eventHandler)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2) AddProcessFailed(eventHandler *ICoreWebView2ProcessFailedEventHandler, token *_EventRegistrationToken) error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.AddProcessFailed.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
uintptr(unsafe.Pointer(eventHandler)),
|
||||
uintptr(unsafe.Pointer(&token)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *ICoreWebView2) OpenDevToolsWindow() error {
|
||||
var err error
|
||||
_, _, err = i.vtbl.OpenDevToolsWindow.Call(
|
||||
uintptr(unsafe.Pointer(i)),
|
||||
)
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader"
|
||||
)
|
||||
|
||||
func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error {
|
||||
e := &environmentCreatedHandler{environmentCompletedHandle}
|
||||
return webviewloader.CreateCoreWebView2EnvironmentWithOptions(
|
||||
e,
|
||||
webviewloader.WithBrowserExecutableFolder(browserExecutableFolder),
|
||||
webviewloader.WithUserDataFolder(userDataFolder),
|
||||
webviewloader.WithAdditionalBrowserArguments(additionalBrowserArgs),
|
||||
)
|
||||
}
|
||||
|
||||
type environmentCreatedHandler struct {
|
||||
originalHandler *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
}
|
||||
|
||||
func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode webviewloader.HRESULT, createdEnvironment *webviewloader.ICoreWebView2Environment) webviewloader.HRESULT {
|
||||
env := (*ICoreWebView2Environment)(unsafe.Pointer(createdEnvironment))
|
||||
res := r.originalHandler.impl.EnvironmentCompleted(uintptr(errorCode), env)
|
||||
return webviewloader.HRESULT(res)
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package edge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/webviewloader"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func createCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder string, environmentCompletedHandle *iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, additionalBrowserArgs string) error {
|
||||
browserPathPtr, err := windows.UTF16PtrFromString(browserExecutableFolder)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", browserExecutableFolder, err)
|
||||
}
|
||||
|
||||
userPathPtr, err := windows.UTF16PtrFromString(userDataFolder)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error calling UTF16PtrFromString for %s: %v", userDataFolder, err)
|
||||
}
|
||||
|
||||
hr, err := webviewloader.CreateCoreWebView2EnvironmentWithOptions(
|
||||
browserPathPtr,
|
||||
userPathPtr,
|
||||
uintptr(unsafe.Pointer(environmentCompletedHandle)),
|
||||
additionalBrowserArgs,
|
||||
)
|
||||
|
||||
if hr != 0 {
|
||||
if err == nil || err == windows.ERROR_SUCCESS {
|
||||
err = syscall.Errno(hr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package edge
|
||||
|
||||
// This code has been adapted from: https://github.com/go-ole/go-ole
|
||||
|
||||
/*
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright © 2013-2017 Yasuhiro Matsumoto, <mattn.jp@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the “Software”), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
const hextable = "0123456789ABCDEF"
|
||||
const emptyGUID = "{00000000-0000-0000-0000-000000000000}"
|
||||
|
||||
// GUID is Windows API specific GUID type.
|
||||
//
|
||||
// This exists to match Windows GUID type for direct passing for COM.
|
||||
// Format is in xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx.
|
||||
type GUID struct {
|
||||
Data1 uint32
|
||||
Data2 uint16
|
||||
Data3 uint16
|
||||
Data4 [8]byte
|
||||
}
|
||||
|
||||
// NewGUID converts the given string into a globally unique identifier that is
|
||||
// compliant with the Windows API.
|
||||
//
|
||||
// The supplied string may be in any of these formats:
|
||||
//
|
||||
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
|
||||
// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
|
||||
//
|
||||
// The conversion of the supplied string is not case-sensitive.
|
||||
func NewGUID(guid string) *GUID {
|
||||
d := []byte(guid)
|
||||
var d1, d2, d3, d4a, d4b []byte
|
||||
|
||||
switch len(d) {
|
||||
case 38:
|
||||
if d[0] != '{' || d[37] != '}' {
|
||||
return nil
|
||||
}
|
||||
d = d[1:37]
|
||||
fallthrough
|
||||
case 36:
|
||||
if d[8] != '-' || d[13] != '-' || d[18] != '-' || d[23] != '-' {
|
||||
return nil
|
||||
}
|
||||
d1 = d[0:8]
|
||||
d2 = d[9:13]
|
||||
d3 = d[14:18]
|
||||
d4a = d[19:23]
|
||||
d4b = d[24:36]
|
||||
case 32:
|
||||
d1 = d[0:8]
|
||||
d2 = d[8:12]
|
||||
d3 = d[12:16]
|
||||
d4a = d[16:20]
|
||||
d4b = d[20:32]
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
var g GUID
|
||||
var ok1, ok2, ok3, ok4 bool
|
||||
g.Data1, ok1 = decodeHexUint32(d1)
|
||||
g.Data2, ok2 = decodeHexUint16(d2)
|
||||
g.Data3, ok3 = decodeHexUint16(d3)
|
||||
g.Data4, ok4 = decodeHexByte64(d4a, d4b)
|
||||
if ok1 && ok2 && ok3 && ok4 {
|
||||
return &g
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeHexUint32(src []byte) (value uint32, ok bool) {
|
||||
var b1, b2, b3, b4 byte
|
||||
var ok1, ok2, ok3, ok4 bool
|
||||
b1, ok1 = decodeHexByte(src[0], src[1])
|
||||
b2, ok2 = decodeHexByte(src[2], src[3])
|
||||
b3, ok3 = decodeHexByte(src[4], src[5])
|
||||
b4, ok4 = decodeHexByte(src[6], src[7])
|
||||
value = (uint32(b1) << 24) | (uint32(b2) << 16) | (uint32(b3) << 8) | uint32(b4)
|
||||
ok = ok1 && ok2 && ok3 && ok4
|
||||
return
|
||||
}
|
||||
|
||||
func decodeHexUint16(src []byte) (value uint16, ok bool) {
|
||||
var b1, b2 byte
|
||||
var ok1, ok2 bool
|
||||
b1, ok1 = decodeHexByte(src[0], src[1])
|
||||
b2, ok2 = decodeHexByte(src[2], src[3])
|
||||
value = (uint16(b1) << 8) | uint16(b2)
|
||||
ok = ok1 && ok2
|
||||
return
|
||||
}
|
||||
|
||||
func decodeHexByte64(s1 []byte, s2 []byte) (value [8]byte, ok bool) {
|
||||
var ok1, ok2, ok3, ok4, ok5, ok6, ok7, ok8 bool
|
||||
value[0], ok1 = decodeHexByte(s1[0], s1[1])
|
||||
value[1], ok2 = decodeHexByte(s1[2], s1[3])
|
||||
value[2], ok3 = decodeHexByte(s2[0], s2[1])
|
||||
value[3], ok4 = decodeHexByte(s2[2], s2[3])
|
||||
value[4], ok5 = decodeHexByte(s2[4], s2[5])
|
||||
value[5], ok6 = decodeHexByte(s2[6], s2[7])
|
||||
value[6], ok7 = decodeHexByte(s2[8], s2[9])
|
||||
value[7], ok8 = decodeHexByte(s2[10], s2[11])
|
||||
ok = ok1 && ok2 && ok3 && ok4 && ok5 && ok6 && ok7 && ok8
|
||||
return
|
||||
}
|
||||
|
||||
func decodeHexByte(c1, c2 byte) (value byte, ok bool) {
|
||||
var n1, n2 byte
|
||||
var ok1, ok2 bool
|
||||
n1, ok1 = decodeHexChar(c1)
|
||||
n2, ok2 = decodeHexChar(c2)
|
||||
value = (n1 << 4) | n2
|
||||
ok = ok1 && ok2
|
||||
return
|
||||
}
|
||||
|
||||
func decodeHexChar(c byte) (byte, bool) {
|
||||
switch {
|
||||
case '0' <= c && c <= '9':
|
||||
return c - '0', true
|
||||
case 'a' <= c && c <= 'f':
|
||||
return c - 'a' + 10, true
|
||||
case 'A' <= c && c <= 'F':
|
||||
return c - 'A' + 10, true
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// String converts the GUID to string form. It will adhere to this pattern:
|
||||
//
|
||||
// {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
|
||||
//
|
||||
// If the GUID is nil, the string representation of an empty GUID is returned:
|
||||
//
|
||||
// {00000000-0000-0000-0000-000000000000}
|
||||
func (guid *GUID) String() string {
|
||||
if guid == nil {
|
||||
return emptyGUID
|
||||
}
|
||||
|
||||
var c [38]byte
|
||||
c[0] = '{'
|
||||
putUint32Hex(c[1:9], guid.Data1)
|
||||
c[9] = '-'
|
||||
putUint16Hex(c[10:14], guid.Data2)
|
||||
c[14] = '-'
|
||||
putUint16Hex(c[15:19], guid.Data3)
|
||||
c[19] = '-'
|
||||
putByteHex(c[20:24], guid.Data4[0:2])
|
||||
c[24] = '-'
|
||||
putByteHex(c[25:37], guid.Data4[2:8])
|
||||
c[37] = '}'
|
||||
return string(c[:])
|
||||
}
|
||||
|
||||
func putUint32Hex(b []byte, v uint32) {
|
||||
b[0] = hextable[byte(v>>24)>>4]
|
||||
b[1] = hextable[byte(v>>24)&0x0f]
|
||||
b[2] = hextable[byte(v>>16)>>4]
|
||||
b[3] = hextable[byte(v>>16)&0x0f]
|
||||
b[4] = hextable[byte(v>>8)>>4]
|
||||
b[5] = hextable[byte(v>>8)&0x0f]
|
||||
b[6] = hextable[byte(v)>>4]
|
||||
b[7] = hextable[byte(v)&0x0f]
|
||||
}
|
||||
|
||||
func putUint16Hex(b []byte, v uint16) {
|
||||
b[0] = hextable[byte(v>>8)>>4]
|
||||
b[1] = hextable[byte(v>>8)&0x0f]
|
||||
b[2] = hextable[byte(v)>>4]
|
||||
b[3] = hextable[byte(v)&0x0f]
|
||||
}
|
||||
|
||||
func putByteHex(dst, src []byte) {
|
||||
for i := 0; i < len(src); i++ {
|
||||
dst[i*2] = hextable[src[i]>>4]
|
||||
dst[i*2+1] = hextable[src[i]&0x0f]
|
||||
}
|
||||
}
|
||||
|
||||
// IsEqualGUID compares two GUID.
|
||||
//
|
||||
// Not constant time comparison.
|
||||
func IsEqualGUID(guid1 *GUID, guid2 *GUID) bool {
|
||||
return guid1.Data1 == guid2.Data1 &&
|
||||
guid1.Data2 == guid2.Data2 &&
|
||||
guid1.Data3 == guid2.Data3 &&
|
||||
guid1.Data4[0] == guid2.Data4[0] &&
|
||||
guid1.Data4[1] == guid2.Data4[1] &&
|
||||
guid1.Data4[2] == guid2.Data4[2] &&
|
||||
guid1.Data4[3] == guid2.Data4[3] &&
|
||||
guid1.Data4[4] == guid2.Data4[4] &&
|
||||
guid1.Data4[5] == guid2.Data4[5] &&
|
||||
guid1.Data4[6] == guid2.Data4[6] &&
|
||||
guid1.Data4[7] == guid2.Data4[7]
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
ISC License (ISC)
|
||||
|
||||
Copyright (c) 2020 John Chadwick
|
||||
Copyright (c) 2022 Wails Project Developers
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
@ -1,19 +0,0 @@
|
||||
# Webviewloader
|
||||
|
||||
Webviewloader is a port of [OpenWebView2Loader](https://github.com/jchv/OpenWebView2Loader) to Go.
|
||||
|
||||
It is intended to be feature-complete with the original WebView2Loader distributed with
|
||||
the WebView2 NuGet package, but some features are intentionally not implemented.
|
||||
|
||||
## Status
|
||||
|
||||
- [x] CompareBrowserVersions
|
||||
- [x] CreateCoreWebView2Environment
|
||||
- [x] CreateCoreWebView2EnvironmentWithOptions
|
||||
- [x] GetAvailableCoreWebView2BrowserVersionString
|
||||
|
||||
## Not implemented features
|
||||
|
||||
- Registry Overrides of Parameters
|
||||
- Env Variable Overrides of Parameters
|
||||
- Does not incorporate `GetCurrentPackageInfo` to search for an installed runtime
|
Binary file not shown.
@ -1,177 +0,0 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// TODO: Set a flag here and output this message only if the flag is set in the application startup
|
||||
fmt.Println("DEB | Using go webview2loader")
|
||||
preventEnvAndRegistryOverrides()
|
||||
}
|
||||
|
||||
type webView2RunTimeType int32
|
||||
|
||||
const (
|
||||
webView2RunTimeTypeInstalled webView2RunTimeType = 0x00
|
||||
webView2RunTimeTypeRedistributable webView2RunTimeType = 0x01
|
||||
)
|
||||
|
||||
// CreateCoreWebView2Environment creates an evergreen WebView2 Environment using the installed WebView2 Runtime version.
|
||||
//
|
||||
// This is equivalent to running CreateCoreWebView2EnvironmentWithOptions without any options.
|
||||
// For more information, see CreateCoreWebView2EnvironmentWithOptions.
|
||||
func CreateCoreWebView2Environment(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error {
|
||||
return CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler)
|
||||
}
|
||||
|
||||
// CreateCoreWebView2EnvironmentWithOptions creates an environment with a custom version of WebView2 Runtime,
|
||||
// user data folder, and with or without additional options.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/webview2-idl?#createcorewebview2environmentwithoptions
|
||||
func CreateCoreWebView2EnvironmentWithOptions(environmentCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler, opts ...option) error {
|
||||
var params environmentOptions
|
||||
for _, opt := range opts {
|
||||
opt(¶ms)
|
||||
}
|
||||
|
||||
var err error
|
||||
var dllPath string
|
||||
var runtimeType webView2RunTimeType
|
||||
if browserExecutableFolder := params.browserExecutableFolder; browserExecutableFolder != "" {
|
||||
runtimeType = webView2RunTimeTypeRedistributable
|
||||
dllPath, err = findEmbeddedClientDll(browserExecutableFolder)
|
||||
} else {
|
||||
runtimeType = webView2RunTimeTypeInstalled
|
||||
dllPath, _, err = findInstalledClientDll(params.preferCanary)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return createWebViewEnvironmentWithClientDll(dllPath, runtimeType, params.userDataFolder,
|
||||
¶ms, environmentCompletedHandler)
|
||||
}
|
||||
|
||||
func createWebViewEnvironmentWithClientDll(lpLibFileName string, runtimeType webView2RunTimeType, userDataFolder string,
|
||||
envOptions *environmentOptions, envCompletedHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler) error {
|
||||
|
||||
if !filepath.IsAbs(lpLibFileName) {
|
||||
return fmt.Errorf("lpLibFileName must be absolute")
|
||||
}
|
||||
|
||||
dll, err := windows.LoadDLL(lpLibFileName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Loading DLL failed: %w", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
canUnloadProc, err := dll.FindProc("DllCanUnloadNow")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if r1, _, _ := canUnloadProc.Call(); r1 != windows.NO_ERROR {
|
||||
return
|
||||
}
|
||||
|
||||
dll.Release()
|
||||
}()
|
||||
|
||||
createProc, err := dll.FindProc("CreateWebViewEnvironmentWithOptionsInternal")
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to find CreateWebViewEnvironmentWithOptionsInternal entrypoint: %w", err)
|
||||
}
|
||||
|
||||
userDataPtr, err := windows.UTF16PtrFromString(userDataFolder)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
envOptionsCom := combridge.New2[iCoreWebView2EnvironmentOptions, iCoreWebView2EnvironmentOptions2](
|
||||
envOptions, envOptions)
|
||||
|
||||
defer envOptionsCom.Close()
|
||||
|
||||
envCompletedHandler = &environmentCreatedHandler{envCompletedHandler}
|
||||
envCompletedCom := combridge.New[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](envCompletedHandler)
|
||||
defer envCompletedCom.Close()
|
||||
|
||||
preventEnvAndRegistryOverrides()
|
||||
|
||||
const unknown = 1
|
||||
hr, _, err := createProc.Call(
|
||||
uintptr(unknown),
|
||||
uintptr(runtimeType),
|
||||
uintptr(unsafe.Pointer(userDataPtr)),
|
||||
uintptr(envOptionsCom.Ref()),
|
||||
uintptr(envCompletedCom.Ref()))
|
||||
|
||||
if hr != 0 {
|
||||
if err == nil || err == windows.ERROR_SUCCESS {
|
||||
err = syscall.Errno(hr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type environmentCreatedHandler struct {
|
||||
originalHandler ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
}
|
||||
|
||||
func (r *environmentCreatedHandler) EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT {
|
||||
// The OpenWebview2Loader has some retry logic and retries once, didn't encounter any case when this would have been
|
||||
// needed during the development: https://github.com/jchv/OpenWebView2Loader/blob/master/Source/WebView2Loader.cpp#L202
|
||||
|
||||
if createdEnvironment != nil {
|
||||
// May or may not be necessary, but the official WebView2Loader seems to do it.
|
||||
iidICoreWebView2Environment := windows.GUID{
|
||||
Data1: 0xb96d755e,
|
||||
Data2: 0x0319,
|
||||
Data3: 0x4e92,
|
||||
Data4: [8]byte{0xa2, 0x96, 0x23, 0x43, 0x6f, 0x46, 0xa1, 0xfc},
|
||||
}
|
||||
|
||||
if err := createdEnvironment.QueryInterface(&iidICoreWebView2Environment, &createdEnvironment); err != nil {
|
||||
createdEnvironment = nil
|
||||
errNo, ok := err.(syscall.Errno)
|
||||
if !ok {
|
||||
errNo = syscall.Errno(windows.E_FAIL)
|
||||
}
|
||||
errorCode = HRESULT(errNo)
|
||||
}
|
||||
}
|
||||
|
||||
r.originalHandler.EnvironmentCompleted(errorCode, createdEnvironment)
|
||||
|
||||
if createdEnvironment != nil {
|
||||
createdEnvironment.Release()
|
||||
}
|
||||
|
||||
return HRESULT(windows.S_OK)
|
||||
}
|
||||
|
||||
func preventEnvAndRegistryOverrides() {
|
||||
// Setting these env variables to empty string also prevents registry overrides because webview2
|
||||
// checks for existence and not for empty value
|
||||
os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "")
|
||||
os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", "")
|
||||
os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0")
|
||||
|
||||
// The following seems not be be required because those are only used by the webview2loader which
|
||||
// in this case is implemented on our own. But nevertheless set them to empty to be consistent.
|
||||
os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", "")
|
||||
os.Setenv("WEBVIEW2_USER_DATA_FOLDER", "")
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge"
|
||||
)
|
||||
|
||||
// HRESULT
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values
|
||||
type HRESULT int32
|
||||
|
||||
// ICoreWebView2Environment Represents the WebView2 Environment
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environment
|
||||
type ICoreWebView2Environment = combridge.IUnknownImpl
|
||||
|
||||
// ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler receives the WebView2Environment created using CreateCoreWebView2Environment.
|
||||
type ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface {
|
||||
// EnvironmentCompleted is invoked to receive the created WebView2Environment
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2createcorewebview2environmentcompletedhandler?#invoke
|
||||
EnvironmentCompleted(errorCode HRESULT, createdEnvironment *ICoreWebView2Environment) HRESULT
|
||||
}
|
||||
|
||||
type iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler interface {
|
||||
combridge.IUnknown
|
||||
ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler
|
||||
}
|
||||
|
||||
func init() {
|
||||
combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](
|
||||
"{4e8a3389-c9d8-4bd2-b6b5-124fee6cc14d}",
|
||||
_iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke,
|
||||
)
|
||||
}
|
||||
|
||||
func _iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandlerInvoke(this uintptr, errorCode HRESULT, env *combridge.IUnknownImpl) uintptr {
|
||||
res := combridge.Resolve[iCoreWebView2CreateCoreWebView2EnvironmentCompletedHandler](this).EnvironmentCompleted(errorCode, env)
|
||||
return uintptr(res)
|
||||
}
|
@ -1,276 +0,0 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/combridge"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// WithBrowserExecutableFolder to specify whether WebView2 controls use a fixed or installed version
|
||||
// of the WebView2 Runtime that exists on a user machine.
|
||||
//
|
||||
// To use a fixed version of the WebView2 Runtime,
|
||||
// pass the folder path that contains the fixed version of the WebView2 Runtime.
|
||||
// BrowserExecutableFolder supports both relative (to the application's executable) and absolute files paths.
|
||||
// To create WebView2 controls that use the installed version of the WebView2 Runtime that exists on user
|
||||
// machines, pass a empty string to WithBrowserExecutableFolder. In this scenario, the API tries to find a
|
||||
// compatible version of the WebView2 Runtime that is installed on the user machine (first at the machine level,
|
||||
// and then per user) using the selected channel preference. The path of fixed version of the WebView2 Runtime
|
||||
// should not contain \Edge\Application\. When such a path is used, the API fails with HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED).
|
||||
func WithBrowserExecutableFolder(folder string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.browserExecutableFolder = folder
|
||||
}
|
||||
}
|
||||
|
||||
// WithUserDataFolder specifies to user data folder location for WebView2
|
||||
//
|
||||
// You may specify the userDataFolder to change the default user data folder location for WebView2.
|
||||
// The path is either an absolute file path or a relative file path that is interpreted as relative
|
||||
// to the compiled code for the current process.
|
||||
// Dhe default user data ({Executable File Name}.WebView2) folder is created in the same directory
|
||||
// next to the compiled code for the app. WebView2 creation fails if the compiled code is running
|
||||
// in a directory in which the process does not have permission to create a new directory.
|
||||
// The app is responsible to clean up the associated user data folder when it is done.
|
||||
func WithUserDataFolder(folder string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.userDataFolder = folder
|
||||
}
|
||||
}
|
||||
|
||||
// WithAdditionalBrowserArguments changes the behavior of the WebView.
|
||||
//
|
||||
// The arguments are passed to the
|
||||
// browser process as part of the command. For more information about
|
||||
// using command-line switches with Chromium browser processes, navigate to
|
||||
// [Run Chromium with Flags][ChromiumDevelopersHowTosRunWithFlags].
|
||||
// The value appended to a switch is appended to the browser process, for
|
||||
// example, in `--edge-webview-switches=xxx` the value is `xxx`. If you
|
||||
// specify a switch that is important to WebView functionality, it is
|
||||
// ignored, for example, `--user-data-dir`. Specific features are disabled
|
||||
// internally and blocked from being enabled. If a switch is specified
|
||||
// multiple times, only the last instance is used.
|
||||
//
|
||||
// \> [!NOTE]\n\> A merge of the different values of the same switch is not attempted,
|
||||
// except for disabled and enabled features. The features specified by
|
||||
// `--enable-features` and `--disable-features` are merged with simple
|
||||
// logic.\n\> * The features is the union of the specified features
|
||||
// and built-in features. If a feature is disabled, it is removed from the
|
||||
// enabled features list.
|
||||
//
|
||||
// If you specify command-line switches and use the
|
||||
// `additionalBrowserArguments` parameter, the `--edge-webview-switches`
|
||||
// value takes precedence and is processed last. If a switch fails to
|
||||
// parse, the switch is ignored. The default state for the operation is
|
||||
// to run the browser process with no extra flags.
|
||||
//
|
||||
// [ChromiumDevelopersHowTosRunWithFlags]: https://www.chromium.org/developers/how-tos/run-chromium-with-flags "Run Chromium with flags | The Chromium Projects"
|
||||
func WithAdditionalBrowserArguments(args string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.additionalBrowserArguments = args
|
||||
}
|
||||
}
|
||||
|
||||
// WithLanguage sets the default display language for WebView.
|
||||
//
|
||||
// It applies to browser UI such as
|
||||
// context menu and dialogs. It also applies to the `accept-languages` HTTP
|
||||
// header that WebView sends to websites. It is in the format of
|
||||
//
|
||||
// `language[-country]` where `language` is the 2-letter code from
|
||||
// [ISO 639][ISO639LanguageCodesHtml]
|
||||
// and `country` is the
|
||||
// 2-letter code from
|
||||
// [ISO 3166][ISOStandard72482Html].
|
||||
//
|
||||
// [ISO639LanguageCodesHtml]: https://www.iso.org/iso-639-language-codes.html "ISO 639 | ISO"
|
||||
// [ISOStandard72482Html]: https://www.iso.org/standard/72482.html "ISO 3166-1:2020 | ISO"
|
||||
func WithLanguage(lang string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.language = lang
|
||||
}
|
||||
}
|
||||
|
||||
// WithTargetCompatibleBrowserVersion secifies the version of the WebView2 Runtime binaries required to be
|
||||
// compatible with your app.
|
||||
//
|
||||
// This defaults to the WebView2 Runtime version
|
||||
// that corresponds with the version of the SDK the app is using. The
|
||||
// format of this value is the same as the format of the
|
||||
// `BrowserVersionString` property and other `BrowserVersion` values. Only
|
||||
// the version part of the `BrowserVersion` value is respected. The channel
|
||||
// suffix, if it exists, is ignored. The version of the WebView2 Runtime
|
||||
// binaries actually used may be different from the specified
|
||||
// `TargetCompatibleBrowserVersion`. The binaries are only guaranteed to be
|
||||
// compatible. Verify the actual version on the `BrowserVersionString`
|
||||
// property on the `ICoreWebView2Environment`.
|
||||
func WithTargetCompatibleBrowserVersion(version string) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.targetCompatibleBrowserVersion = version
|
||||
}
|
||||
}
|
||||
|
||||
// WithAllowSingleSignOnUsingOSPrimaryAccount is used to enable
|
||||
// single sign on with Azure Active Directory (AAD) and personal Microsoft
|
||||
// Account (MSA) resources inside WebView. All AAD accounts, connected to
|
||||
// Windows and shared for all apps, are supported. For MSA, SSO is only enabled
|
||||
// for the account associated for Windows account login, if any.
|
||||
// Default is disabled. Universal Windows Platform apps must also declare
|
||||
// `enterpriseCloudSSO`
|
||||
// [Restricted capabilities][WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]
|
||||
// for the single sign on (SSO) to work.
|
||||
//
|
||||
// [WindowsUwpPackagingAppCapabilityDeclarationsRestrictedCapabilities]: /windows/uwp/packaging/app-capability-declarations\#restricted-capabilities "Restricted capabilities - App capability declarations | Microsoft Docs"
|
||||
func WithAllowSingleSignOnUsingOSPrimaryAccount(allow bool) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.allowSingleSignOnUsingOSPrimaryAccount = allow
|
||||
}
|
||||
}
|
||||
|
||||
// WithExclusiveUserDataFolderAccess specifies that the WebView environment
|
||||
// obtains exclusive access to the user data folder.
|
||||
//
|
||||
// If the user data folder is already being used by another WebView environment with a
|
||||
// different value for `ExclusiveUserDataFolderAccess` property, the creation of a WebView2Controller
|
||||
// using the environment object will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
|
||||
// When set as TRUE, no other WebView can be created from other processes using WebView2Environment
|
||||
// objects with the same UserDataFolder. This prevents other processes from creating WebViews
|
||||
// which share the same browser process instance, since sharing is performed among
|
||||
// WebViews that have the same UserDataFolder. When another process tries to create a
|
||||
// WebView2Controller from an WebView2Environment object created with the same user data folder,
|
||||
// it will fail with `HRESULT_FROM_WIN32(ERROR_INVALID_STATE)`.
|
||||
func WithExclusiveUserDataFolderAccess(exclusive bool) option {
|
||||
return func(wvep *environmentOptions) {
|
||||
wvep.exclusiveUserDataFolderAccess = exclusive
|
||||
}
|
||||
}
|
||||
|
||||
type option func(*environmentOptions)
|
||||
|
||||
var _ iCoreWebView2EnvironmentOptions = &environmentOptions{}
|
||||
var _ iCoreWebView2EnvironmentOptions2 = &environmentOptions{}
|
||||
|
||||
type environmentOptions struct {
|
||||
browserExecutableFolder string
|
||||
userDataFolder string
|
||||
preferCanary bool
|
||||
|
||||
additionalBrowserArguments string
|
||||
language string
|
||||
targetCompatibleBrowserVersion string
|
||||
allowSingleSignOnUsingOSPrimaryAccount bool
|
||||
exclusiveUserDataFolderAccess bool
|
||||
}
|
||||
|
||||
func (o *environmentOptions) AdditionalBrowserArguments() string {
|
||||
return o.additionalBrowserArguments
|
||||
}
|
||||
|
||||
func (o *environmentOptions) Language() string {
|
||||
return o.language
|
||||
}
|
||||
|
||||
func (o *environmentOptions) TargetCompatibleBrowserVersion() string {
|
||||
v := o.targetCompatibleBrowserVersion
|
||||
if v == "" {
|
||||
v = kMinimumCompatibleVersion
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (o *environmentOptions) AllowSingleSignOnUsingOSPrimaryAccount() bool {
|
||||
return o.allowSingleSignOnUsingOSPrimaryAccount
|
||||
}
|
||||
|
||||
func (o *environmentOptions) ExclusiveUserDataFolderAccess() bool {
|
||||
return o.exclusiveUserDataFolderAccess
|
||||
}
|
||||
|
||||
type iCoreWebView2EnvironmentOptions interface {
|
||||
combridge.IUnknown
|
||||
|
||||
AdditionalBrowserArguments() string
|
||||
Language() string
|
||||
TargetCompatibleBrowserVersion() string
|
||||
AllowSingleSignOnUsingOSPrimaryAccount() bool
|
||||
}
|
||||
|
||||
type iCoreWebView2EnvironmentOptions2 interface {
|
||||
combridge.IUnknown
|
||||
|
||||
ExclusiveUserDataFolderAccess() bool
|
||||
}
|
||||
|
||||
func init() {
|
||||
combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions](
|
||||
"{2fde08a8-1e9a-4766-8c05-95a9ceb9d1c5}",
|
||||
_iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
_iCoreWebView2EnvironmentOptionsLanguage,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
_iCoreWebView2EnvironmentTargetCompatibleBrowserVersion,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
_iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
)
|
||||
|
||||
combridge.RegisterVTable[combridge.IUnknown, iCoreWebView2EnvironmentOptions2](
|
||||
"{ff85c98a-1ba7-4a6b-90c8-2b752c89e9e2}",
|
||||
_iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess,
|
||||
_iCoreWebView2EnvironmentOptionsNOP,
|
||||
)
|
||||
}
|
||||
func _iCoreWebView2EnvironmentOptionsNOP(this uintptr) uintptr {
|
||||
return uintptr(windows.S_FALSE)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptionsAdditionalBrowserArguments(this uintptr, value **uint16) uintptr {
|
||||
v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AdditionalBrowserArguments()
|
||||
*value = stringToOleString(v)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptionsLanguage(this uintptr, value **uint16) uintptr {
|
||||
args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).Language()
|
||||
*value = stringToOleString(args)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentTargetCompatibleBrowserVersion(this uintptr, value **uint16) uintptr {
|
||||
args := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).TargetCompatibleBrowserVersion()
|
||||
*value = stringToOleString(args)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptionsAllowSingleSignOnUsingOSPrimaryAccount(this uintptr, value *int32) uintptr {
|
||||
v := combridge.Resolve[iCoreWebView2EnvironmentOptions](this).AllowSingleSignOnUsingOSPrimaryAccount()
|
||||
*value = boolToInt(v)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func _iCoreWebView2EnvironmentOptions2ExclusiveUserDataFolderAccess(this uintptr, value *int32) uintptr {
|
||||
v := combridge.Resolve[iCoreWebView2EnvironmentOptions2](this).ExclusiveUserDataFolderAccess()
|
||||
*value = boolToInt(v)
|
||||
return uintptr(windows.S_OK)
|
||||
}
|
||||
|
||||
func stringToOleString(v string) *uint16 {
|
||||
wstr := utf16.Encode([]rune(v + "\x00"))
|
||||
lwstr := len(wstr)
|
||||
ptr := (*uint16)(coTaskMemAlloc(2 * lwstr))
|
||||
|
||||
copy(unsafe.Slice(ptr, lwstr), wstr)
|
||||
|
||||
return ptr
|
||||
}
|
||||
|
||||
func boolToInt(v bool) int32 {
|
||||
if v {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
var (
|
||||
errNoClientDLLFound = errors.New("no webview2 found")
|
||||
)
|
||||
|
||||
func findEmbeddedBrowserVersion(filename string) (string, error) {
|
||||
block, err := getFileVersionInfo(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
info, err := verQueryValueString(block, "\\StringFileInfo\\040904B0\\ProductVersion")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func findEmbeddedClientDll(embeddedEdgeSubFolder string) (outClientPath string, err error) {
|
||||
if !filepath.IsAbs(embeddedEdgeSubFolder) {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
embeddedEdgeSubFolder = filepath.Join(filepath.Dir(exe), embeddedEdgeSubFolder)
|
||||
}
|
||||
|
||||
return findClientDllInFolder(embeddedEdgeSubFolder)
|
||||
}
|
||||
|
||||
func findClientDllInFolder(folder string) (string, error) {
|
||||
arch := ""
|
||||
switch runtime.GOARCH {
|
||||
case "arm64":
|
||||
arch = "arm64"
|
||||
case "amd64":
|
||||
arch = "x64"
|
||||
case "386":
|
||||
arch = "x86"
|
||||
default:
|
||||
return "", fmt.Errorf("Unsupported architecture")
|
||||
}
|
||||
|
||||
dllPath := filepath.Join(folder, "EBWebView", arch, "EmbeddedBrowserWebView.dll")
|
||||
if _, err := os.Stat(dllPath); err != nil {
|
||||
return "", mapFindErr(err)
|
||||
}
|
||||
return dllPath, nil
|
||||
}
|
||||
|
||||
func mapFindErr(err error) error {
|
||||
if errors.Is(err, registry.ErrNotExist) {
|
||||
return errNoClientDLLFound
|
||||
}
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return errNoClientDLLFound
|
||||
}
|
||||
return err
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
const (
|
||||
kNumChannels = 4
|
||||
kInstallKeyPath = "Software\\Microsoft\\EdgeUpdate\\ClientState\\"
|
||||
kMinimumCompatibleVersion = "86.0.616.0"
|
||||
)
|
||||
|
||||
var (
|
||||
kChannelName = [kNumChannels]string{
|
||||
"", "beta", "dev", "canary", // "internal"
|
||||
}
|
||||
|
||||
kChannelUuid = [kNumChannels]string{
|
||||
"{F3017226-FE2A-4295-8BDF-00C3A9A7E4C5}",
|
||||
"{2CD8A007-E189-409D-A2C8-9AF4EF3C72AA}",
|
||||
"{0D50BFEC-CD6A-4F9A-964C-C7416E3ACB10}",
|
||||
"{65C35B14-6C1D-4122-AC46-7148CC9D6497}",
|
||||
//"{BE59E8FD-089A-411B-A3B0-051D9E417818}",
|
||||
}
|
||||
|
||||
minimumCompatibleVersion, _ = parseVersion(kMinimumCompatibleVersion)
|
||||
)
|
||||
|
||||
func findInstalledClientDll(preferCanary bool) (clientPath string, version *version, err error) {
|
||||
for i := 0; i < kNumChannels; i++ {
|
||||
channel := i
|
||||
if preferCanary {
|
||||
channel = (kNumChannels - 1) - i
|
||||
}
|
||||
|
||||
key := kInstallKeyPath + kChannelUuid[channel]
|
||||
for _, checkSystem := range []bool{true, false} {
|
||||
clientPath, version, err := findInstalledClientDllForChannel(key, checkSystem)
|
||||
if err == errNoClientDLLFound {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
version.channel = kChannelName[channel]
|
||||
return clientPath, version, nil
|
||||
}
|
||||
}
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
func findInstalledClientDllForChannel(subKey string, system bool) (clientPath string, clientVersion *version, err error) {
|
||||
key := registry.LOCAL_MACHINE
|
||||
if !system {
|
||||
key = registry.CURRENT_USER
|
||||
}
|
||||
|
||||
regKey, err := registry.OpenKey(key, subKey, registry.READ|registry.WOW64_32KEY)
|
||||
if err != nil {
|
||||
return "", nil, mapFindErr(err)
|
||||
}
|
||||
defer regKey.Close()
|
||||
|
||||
embeddedEdgeSubFolder, _, err := regKey.GetStringValue("EBWebView")
|
||||
if err != nil {
|
||||
return "", nil, mapFindErr(err)
|
||||
}
|
||||
|
||||
if embeddedEdgeSubFolder == "" {
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
versionString := filepath.Base(embeddedEdgeSubFolder)
|
||||
version, err := parseVersion(versionString)
|
||||
if err != nil {
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
if version.compare(minimumCompatibleVersion) < 0 {
|
||||
return "", nil, errNoClientDLLFound
|
||||
}
|
||||
|
||||
dllPath, err := findEmbeddedClientDll(embeddedEdgeSubFolder)
|
||||
if err != nil {
|
||||
return "", nil, mapFindErr(err)
|
||||
}
|
||||
|
||||
return dllPath, &version, nil
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/jchv/go-winloader"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func init() {
|
||||
preventEnvAndRegistryOverrides(nil, nil, "")
|
||||
}
|
||||
|
||||
var (
|
||||
memOnce sync.Once
|
||||
memModule winloader.Module
|
||||
memCreate winloader.Proc
|
||||
memCompareBrowserVersions winloader.Proc
|
||||
memGetAvailableCoreWebView2BrowserVersionString winloader.Proc
|
||||
memErr error
|
||||
)
|
||||
|
||||
const (
|
||||
// https://referencesource.microsoft.com/#system.web/Util/hresults.cs,20
|
||||
E_FILENOTFOUND = 0x80070002
|
||||
)
|
||||
|
||||
// CompareBrowserVersions will compare the 2 given versions and return:
|
||||
//
|
||||
// Less than zero: v1 < v2
|
||||
// zero: v1 == v2
|
||||
// Greater than zero: v1 > v2
|
||||
func CompareBrowserVersions(v1 string, v2 string) (int, error) {
|
||||
_v1, err := windows.UTF16PtrFromString(v1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
_v2, err := windows.UTF16PtrFromString(v2)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
err = loadFromMemory()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
var result int32
|
||||
_, _, err = memCompareBrowserVersions.Call(
|
||||
uint64(uintptr(unsafe.Pointer(_v1))),
|
||||
uint64(uintptr(unsafe.Pointer(_v2))),
|
||||
uint64(uintptr(unsafe.Pointer(&result))))
|
||||
|
||||
if err != windows.ERROR_SUCCESS {
|
||||
return 0, err
|
||||
}
|
||||
return int(result), nil
|
||||
}
|
||||
|
||||
// GetAvailableCoreWebView2BrowserVersionString returns version of the webview2 runtime.
|
||||
// If path is empty, it will try to find installed webview2 is the system.
|
||||
// If there is no version installed, a blank string is returned.
|
||||
func GetAvailableCoreWebView2BrowserVersionString(path string) (string, error) {
|
||||
if path != "" {
|
||||
// The default implementation fails if CGO and a fixed browser path is used. It's caused by the go-winloader
|
||||
// which loads the native DLL from memory.
|
||||
// Use the new GoWebView2Loader in this case, in the future we will make GoWebView2Loader
|
||||
// feature-complete and remove the use of the native DLL and go-winloader.
|
||||
version, err := goGetAvailableCoreWebView2BrowserVersionString(path)
|
||||
if errors.Is(err, errNoClientDLLFound) {
|
||||
// WebView2 is not found
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return version, nil
|
||||
}
|
||||
|
||||
err := loadFromMemory()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var browserPath *uint16 = nil
|
||||
if path != "" {
|
||||
browserPath, err = windows.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error calling UTF16PtrFromString for %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
preventEnvAndRegistryOverrides(browserPath, nil, "")
|
||||
var result *uint16
|
||||
res, _, err := memGetAvailableCoreWebView2BrowserVersionString.Call(
|
||||
uint64(uintptr(unsafe.Pointer(browserPath))),
|
||||
uint64(uintptr(unsafe.Pointer(&result))))
|
||||
|
||||
if res != 0 {
|
||||
if res == E_FILENOTFOUND {
|
||||
// WebView2 is not installed
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Unable to call GetAvailableCoreWebView2BrowserVersionString (%x): %w", res, err)
|
||||
}
|
||||
|
||||
version := windows.UTF16PtrToString(result)
|
||||
windows.CoTaskMemFree(unsafe.Pointer(result))
|
||||
return version, nil
|
||||
}
|
||||
|
||||
// CreateCoreWebView2EnvironmentWithOptions tries to load WebviewLoader2 and
|
||||
// call the CreateCoreWebView2EnvironmentWithOptions routine.
|
||||
func CreateCoreWebView2EnvironmentWithOptions(browserExecutableFolder, userDataFolder *uint16, environmentCompletedHandle uintptr, additionalBrowserArgs string) (uintptr, error) {
|
||||
err := loadFromMemory()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
preventEnvAndRegistryOverrides(browserExecutableFolder, userDataFolder, additionalBrowserArgs)
|
||||
res, _, _ := memCreate.Call(
|
||||
uint64(uintptr(unsafe.Pointer(browserExecutableFolder))),
|
||||
uint64(uintptr(unsafe.Pointer(userDataFolder))),
|
||||
0,
|
||||
uint64(environmentCompletedHandle),
|
||||
)
|
||||
return uintptr(res), nil
|
||||
}
|
||||
|
||||
func loadFromMemory() error {
|
||||
var err error
|
||||
// DLL is not available natively. Try loading embedded copy.
|
||||
memOnce.Do(func() {
|
||||
memModule, memErr = winloader.LoadFromMemory(WebView2Loader)
|
||||
if memErr != nil {
|
||||
err = fmt.Errorf("Unable to load WebView2Loader.dll from memory: %w", memErr)
|
||||
return
|
||||
}
|
||||
memCreate = memModule.Proc("CreateCoreWebView2EnvironmentWithOptions")
|
||||
memCompareBrowserVersions = memModule.Proc("CompareBrowserVersions")
|
||||
memGetAvailableCoreWebView2BrowserVersionString = memModule.Proc("GetAvailableCoreWebView2BrowserVersionString")
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func preventEnvAndRegistryOverrides(browserFolder, userDataFolder *uint16, additionalBrowserArgs string) {
|
||||
// Setting these env variables to empty string also prevents registry overrides because webview2loader
|
||||
// checks for existence and not for empty value
|
||||
os.Setenv("WEBVIEW2_PIPE_FOR_SCRIPT_DEBUGGER", "")
|
||||
|
||||
// Set these overrides to the values or empty to prevent registry and external env overrides
|
||||
os.Setenv("WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", additionalBrowserArgs)
|
||||
os.Setenv("WEBVIEW2_RELEASE_CHANNEL_PREFERENCE", "0")
|
||||
os.Setenv("WEBVIEW2_BROWSER_EXECUTABLE_FOLDER", windows.UTF16PtrToString(browserFolder))
|
||||
os.Setenv("WEBVIEW2_USER_DATA_FOLDER", windows.UTF16PtrToString(userDataFolder))
|
||||
}
|
||||
|
||||
func goGetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) {
|
||||
clientPath, err := findEmbeddedClientDll(browserExecutableFolder)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return findEmbeddedBrowserVersion(clientPath)
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed x86/WebView2Loader.dll
|
||||
var WebView2Loader []byte
|
@ -1,8 +0,0 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed x64/WebView2Loader.dll
|
||||
var WebView2Loader []byte
|
@ -1,8 +0,0 @@
|
||||
//go:build windows && native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed arm64/WebView2Loader.dll
|
||||
var WebView2Loader []byte
|
@ -1,143 +0,0 @@
|
||||
//go:build windows
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||
procGlobalAlloc = modkernel32.NewProc("GlobalAlloc")
|
||||
procGlobalFree = modkernel32.NewProc("GlobalFree")
|
||||
|
||||
modversion = windows.NewLazySystemDLL("version.dll")
|
||||
procGetFileVersionInfoSize = modversion.NewProc("GetFileVersionInfoSizeW")
|
||||
procGetFileVersionInfo = modversion.NewProc("GetFileVersionInfoW")
|
||||
procVerQueryValue = modversion.NewProc("VerQueryValueW")
|
||||
|
||||
modole32 = windows.NewLazySystemDLL("ole32.dll")
|
||||
procCoTaskMemAlloc = modole32.NewProc("CoTaskMemAlloc")
|
||||
)
|
||||
|
||||
func getFileVersionInfo(path string) ([]byte, error) {
|
||||
lptstrFilename, err := syscall.UTF16PtrFromString(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
size, _, err := procGetFileVersionInfoSize.Call(
|
||||
uintptr(unsafe.Pointer(lptstrFilename)),
|
||||
0,
|
||||
)
|
||||
|
||||
err = maskErrorSuccess(err)
|
||||
if size == 0 && err == nil {
|
||||
err = fmt.Errorf("GetFileVersionInfoSize failed")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data := make([]byte, size)
|
||||
ret, _, err := procGetFileVersionInfo.Call(
|
||||
uintptr(unsafe.Pointer(lptstrFilename)),
|
||||
0,
|
||||
uintptr(size),
|
||||
uintptr(unsafe.Pointer(&data[0])),
|
||||
)
|
||||
|
||||
err = maskErrorSuccess(err)
|
||||
if ret == 0 && err == nil {
|
||||
err = fmt.Errorf("GetFileVersionInfo failed")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func verQueryValueString(block []byte, subBlock string) (string, error) {
|
||||
// Allocate memory from native side to make sure the block doesn't get moved
|
||||
// because we get a pointer into that memory block from the native verQueryValue
|
||||
// call back.
|
||||
pBlock := globalAlloc(0, uint32(len(block)))
|
||||
defer globalFree(unsafe.Pointer(pBlock))
|
||||
|
||||
// Copy the memory region into native side memory
|
||||
copy(unsafe.Slice((*byte)(pBlock), len(block)), block)
|
||||
|
||||
lpSubBlock, err := syscall.UTF16PtrFromString(subBlock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var lplpBuffer unsafe.Pointer
|
||||
var puLen uint
|
||||
ret, _, err := procVerQueryValue.Call(
|
||||
uintptr(pBlock),
|
||||
uintptr(unsafe.Pointer(lpSubBlock)),
|
||||
uintptr(unsafe.Pointer(&lplpBuffer)),
|
||||
uintptr(unsafe.Pointer(&puLen)),
|
||||
)
|
||||
|
||||
err = maskErrorSuccess(err)
|
||||
if ret == 0 && err == nil {
|
||||
err = fmt.Errorf("VerQueryValue failed")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if puLen <= 1 {
|
||||
return "", nil
|
||||
}
|
||||
puLen -= 1 // Remove Null-Terminator
|
||||
|
||||
wchar := unsafe.Slice((*uint16)(lplpBuffer), puLen)
|
||||
return string(utf16.Decode(wchar)), nil
|
||||
}
|
||||
|
||||
func globalAlloc(uFlags uint, dwBytes uint32) unsafe.Pointer {
|
||||
ret, _, _ := procGlobalAlloc.Call(
|
||||
uintptr(uFlags),
|
||||
uintptr(dwBytes))
|
||||
|
||||
if ret == 0 {
|
||||
panic("globalAlloc failed")
|
||||
}
|
||||
|
||||
return unsafe.Pointer(ret)
|
||||
}
|
||||
|
||||
func globalFree(data unsafe.Pointer) {
|
||||
ret, _, _ := procGlobalFree.Call(uintptr(data))
|
||||
if ret != 0 {
|
||||
panic("globalFree failed")
|
||||
}
|
||||
}
|
||||
|
||||
func maskErrorSuccess(err error) error {
|
||||
if err == windows.ERROR_SUCCESS {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func coTaskMemAlloc(size int) unsafe.Pointer {
|
||||
ret, _, _ := procCoTaskMemAlloc.Call(
|
||||
uintptr(size))
|
||||
|
||||
if ret == 0 {
|
||||
panic("coTaskMemAlloc failed")
|
||||
}
|
||||
return unsafe.Pointer(ret)
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
//go:build windows && !native_webview2loader
|
||||
|
||||
package webviewloader
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CompareBrowserVersions will compare the 2 given versions and return:
|
||||
//
|
||||
// -1 = v1 < v2
|
||||
// 0 = v1 == v2
|
||||
// 1 = v1 > v2
|
||||
func CompareBrowserVersions(v1 string, v2 string) (int, error) {
|
||||
v, err := parseVersion(v1)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("v1 invalid: %w", err)
|
||||
}
|
||||
|
||||
w, err := parseVersion(v2)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("v2 invalid: %w", err)
|
||||
}
|
||||
|
||||
return v.compare(w), nil
|
||||
}
|
||||
|
||||
// GetAvailableCoreWebView2BrowserVersionString get the browser version info including channel name
|
||||
// if it is the WebView2 Runtime.
|
||||
// Channel names are Beta, Dev, and Canary.
|
||||
func GetAvailableCoreWebView2BrowserVersionString(browserExecutableFolder string) (string, error) {
|
||||
if browserExecutableFolder != "" {
|
||||
clientPath, err := findEmbeddedClientDll(browserExecutableFolder)
|
||||
if errors.Is(err, errNoClientDLLFound) {
|
||||
// WebView2 is not found
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return findEmbeddedBrowserVersion(clientPath)
|
||||
}
|
||||
|
||||
_, version, err := findInstalledClientDll(false)
|
||||
if errors.Is(err, errNoClientDLLFound) {
|
||||
return "", nil
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return version.String(), nil
|
||||
}
|
||||
|
||||
type version struct {
|
||||
major int
|
||||
minor int
|
||||
patch int
|
||||
build int
|
||||
|
||||
channel string
|
||||
}
|
||||
|
||||
func (v version) String() string {
|
||||
vv := fmt.Sprintf("%d.%d.%d.%d", v.major, v.minor, v.patch, v.build)
|
||||
if v.channel != "" {
|
||||
vv += " " + v.channel
|
||||
}
|
||||
|
||||
return vv
|
||||
}
|
||||
|
||||
func (v version) compare(o version) int {
|
||||
if c := compareInt(v.major, o.major); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := compareInt(v.minor, o.minor); c != 0 {
|
||||
return c
|
||||
}
|
||||
if c := compareInt(v.patch, o.patch); c != 0 {
|
||||
return c
|
||||
}
|
||||
return compareInt(v.build, o.build)
|
||||
}
|
||||
|
||||
func parseVersion(v string) (version, error) {
|
||||
var p version
|
||||
|
||||
// Split away channel information...
|
||||
if i := strings.Index(v, " "); i > 0 {
|
||||
p.channel = v[i+1:]
|
||||
v = v[:i]
|
||||
}
|
||||
|
||||
vv := strings.Split(v, ".")
|
||||
if len(vv) > 4 {
|
||||
return p, fmt.Errorf("too many version parts")
|
||||
}
|
||||
|
||||
var err error
|
||||
vv, p.major, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad major version: %w", err)
|
||||
}
|
||||
|
||||
vv, p.minor, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad minor version: %w", err)
|
||||
}
|
||||
|
||||
vv, p.patch, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad patch version: %w", err)
|
||||
}
|
||||
|
||||
_, p.build, err = parseInt(vv)
|
||||
if err != nil {
|
||||
return p, fmt.Errorf("bad build version: %w", err)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func parseInt(v []string) ([]string, int, error) {
|
||||
if len(v) == 0 {
|
||||
return nil, 0, nil
|
||||
}
|
||||
|
||||
p, err := strconv.ParseInt(v[0], 10, 32)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return v[1:], int(p), nil
|
||||
}
|
||||
|
||||
func compareInt(v1, v2 int) int {
|
||||
if v1 == v2 {
|
||||
return 0
|
||||
}
|
||||
if v1 < v2 {
|
||||
return -1
|
||||
} else {
|
||||
return +1
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
@ -3,11 +3,10 @@
|
||||
package windows
|
||||
|
||||
import (
|
||||
"github.com/wailsapp/go-webview2/pkg/edge"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/go-webview2/pkg/edge"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend/desktop/windows/win32"
|
||||
"github.com/wailsapp/wails/v2/internal/system/operatingsystem"
|
||||
|
||||
|
@ -3,8 +3,9 @@ package dispatcher
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"strings"
|
||||
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
)
|
||||
|
||||
type callMessage struct {
|
||||
@ -49,7 +50,12 @@ func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend
|
||||
CallbackID: payload.CallbackID,
|
||||
}
|
||||
if err != nil {
|
||||
callbackMessage.Err = err.Error()
|
||||
// Use the error formatter if one was provided
|
||||
if d.errfmt != nil {
|
||||
callbackMessage.Err = d.errfmt(err)
|
||||
} else {
|
||||
callbackMessage.Err = err.Error()
|
||||
}
|
||||
} else {
|
||||
callbackMessage.Result = result
|
||||
}
|
||||
@ -66,7 +72,7 @@ func (d *Dispatcher) processCallMessage(message string, sender frontend.Frontend
|
||||
// CallbackMessage defines a message that contains the result of a call
|
||||
type CallbackMessage struct {
|
||||
Result interface{} `json:"result"`
|
||||
Err string `json:"error"`
|
||||
Err any `json:"error"`
|
||||
CallbackID string `json:"callbackid"`
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/wailsapp/wails/v2/internal/binding"
|
||||
"github.com/wailsapp/wails/v2/internal/frontend"
|
||||
"github.com/wailsapp/wails/v2/internal/logger"
|
||||
"github.com/wailsapp/wails/v2/pkg/options"
|
||||
)
|
||||
|
||||
type Dispatcher struct {
|
||||
@ -15,15 +16,17 @@ type Dispatcher struct {
|
||||
events frontend.Events
|
||||
bindingsDB *binding.DB
|
||||
ctx context.Context
|
||||
errfmt options.ErrorFormatter
|
||||
}
|
||||
|
||||
func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events) *Dispatcher {
|
||||
func NewDispatcher(ctx context.Context, log *logger.Logger, bindings *binding.Bindings, events frontend.Events, errfmt options.ErrorFormatter) *Dispatcher {
|
||||
return &Dispatcher{
|
||||
log: log,
|
||||
bindings: bindings,
|
||||
events: events,
|
||||
bindingsDB: bindings.DB(),
|
||||
ctx: ctx,
|
||||
errfmt: errfmt,
|
||||
}
|
||||
}
|
||||
|
||||
|
50
v2/internal/frontend/runtime/desktop/contextmenu.js
Normal file
50
v2/internal/frontend/runtime/desktop/contextmenu.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
--default-contextmenu: auto; (default) will show the default context menu if contentEditable is true OR text has been selected OR element is input or textarea
|
||||
--default-contextmenu: show; will always show the default context menu
|
||||
--default-contextmenu: hide; will always hide the default context menu
|
||||
|
||||
This rule is inherited like normal CSS rules, so nesting works as expected
|
||||
*/
|
||||
export function processDefaultContextMenu(event) {
|
||||
// Process default context menu
|
||||
const element = event.target;
|
||||
const computedStyle = window.getComputedStyle(element);
|
||||
const defaultContextMenuAction = computedStyle.getPropertyValue("--default-contextmenu").trim();
|
||||
switch (defaultContextMenuAction) {
|
||||
case "show":
|
||||
return;
|
||||
case "hide":
|
||||
event.preventDefault();
|
||||
return;
|
||||
default:
|
||||
// Check if contentEditable is true
|
||||
if (element.isContentEditable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if text has been selected and action is on the selected elements
|
||||
const selection = window.getSelection();
|
||||
const hasSelection = (selection.toString().length > 0)
|
||||
if (hasSelection) {
|
||||
for (let i = 0; i < selection.rangeCount; i++) {
|
||||
const range = selection.getRangeAt(i);
|
||||
const rects = range.getClientRects();
|
||||
for (let j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
if (document.elementFromPoint(rect.left, rect.top) === element) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Check if tagname is input or textarea
|
||||
if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") {
|
||||
if (hasSelection || (!element.readOnly && !element.disabled)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// hide default context menu
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import * as Window from "./window";
|
||||
import * as Screen from "./screen";
|
||||
import * as Browser from "./browser";
|
||||
import * as Clipboard from "./clipboard";
|
||||
import * as ContextMenu from "./contextmenu";
|
||||
|
||||
|
||||
export function Quit() {
|
||||
@ -61,7 +62,7 @@ window.wails = {
|
||||
callbacks,
|
||||
flags: {
|
||||
disableScrollbarDrag: false,
|
||||
disableWailsDefaultContextMenu: false,
|
||||
disableDefaultContextMenu: false,
|
||||
enableResize: false,
|
||||
defaultCursor: null,
|
||||
borderThickness: 6,
|
||||
@ -78,10 +79,8 @@ if (window.wailsbindings) {
|
||||
delete window.wails.SetBindings;
|
||||
}
|
||||
|
||||
// This is evaluated at build time in package.json
|
||||
// const dev = 0;
|
||||
// const production = 1;
|
||||
if (ENV === 1) {
|
||||
// (bool) This is evaluated at build time in package.json
|
||||
if (!DEBUG) {
|
||||
delete window.wailsbindings;
|
||||
}
|
||||
|
||||
@ -189,8 +188,13 @@ window.addEventListener('mousemove', function (e) {
|
||||
|
||||
// Setup context menu hook
|
||||
window.addEventListener('contextmenu', function (e) {
|
||||
if (window.wails.flags.disableWailsDefaultContextMenu) {
|
||||
// always show the contextmenu in debug & dev
|
||||
if (DEBUG) return;
|
||||
|
||||
if (window.wails.flags.disableDefaultContextMenu) {
|
||||
e.preventDefault();
|
||||
} else {
|
||||
ContextMenu.processDefaultContextMenu(e);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
"build": "run-p build:*",
|
||||
"build:ipc-desktop": "npx esbuild desktop/ipc.js --bundle --minify --outfile=ipc.js",
|
||||
"build:ipc-dev": "cd dev && npm install && npm run build",
|
||||
"build:runtime-desktop-prod": "npx esbuild desktop/main.js --bundle --minify --outfile=runtime_prod_desktop.js --define:ENV=1",
|
||||
"build:runtime-desktop-dev": "npx esbuild desktop/main.js --bundle --sourcemap=inline --outfile=runtime_dev_desktop.js --define:ENV=0",
|
||||
"build:runtime-desktop-prod": "npx esbuild desktop/main.js --bundle --minify --outfile=runtime_prod_desktop.js --define:DEBUG=false",
|
||||
"build:runtime-desktop-debug": "npx esbuild desktop/main.js --bundle --sourcemap=inline --outfile=runtime_debug_desktop.js --define:DEBUG=true",
|
||||
"test": "vitest"
|
||||
},
|
||||
"author": "Lea Anthony <lea.anthony@gmail.com>",
|
||||
|
8
v2/internal/frontend/runtime/runtime_debug_desktop.go
Normal file
8
v2/internal/frontend/runtime/runtime_debug_desktop.go
Normal file
@ -0,0 +1,8 @@
|
||||
//go:build debug || !production
|
||||
|
||||
package runtime
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed runtime_debug_desktop.js
|
||||
var RuntimeDesktopJS []byte
|
621
v2/internal/frontend/runtime/runtime_debug_desktop.js
Normal file
621
v2/internal/frontend/runtime/runtime_debug_desktop.js
Normal file
File diff suppressed because one or more lines are too long
@ -1,8 +0,0 @@
|
||||
//go:build dev || bindings || (!dev && !production && !bindings)
|
||||
|
||||
package runtime
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed runtime_dev_desktop.js
|
||||
var RuntimeDesktopJS []byte
|
File diff suppressed because one or more lines are too long
@ -1,4 +1,4 @@
|
||||
//go:build production
|
||||
//go:build production && !debug
|
||||
|
||||
package runtime
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user