mirror of
https://github.com/wavetermdev/wails.git
synced 2026-04-22 15:26:15 -07:00
Compare commits
56 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0394bcaea7 | |||
| 793191a479 | |||
| efc86c1056 | |||
| 39d44d2644 | |||
| 9584a2ce5a | |||
| 95b8ceb87a | |||
| 37b99b9cb8 | |||
| 3116c1a622 | |||
| 86354e9fc0 | |||
| b49f135e31 | |||
| c26f3ad7d1 | |||
| 40f645a864 | |||
| fff266f50d | |||
| 7cfea7c22c | |||
| 6141e5a8ce | |||
| ed58949d24 | |||
| c1d85bd3d9 | |||
| 8d3324465e | |||
| 8c72746edb | |||
| ea3509d2e7 | |||
| bb3a0cc54f | |||
| d808654d99 | |||
| a6cfdbb403 | |||
| 2f7c6834d0 | |||
| ebdd57a7c4 | |||
| 4ff6d74054 | |||
| 0d8b4aafd5 | |||
| 0cca7e9189 | |||
| a5812578c5 | |||
| a419721dcd | |||
| e731e2591a | |||
| 350b411afe | |||
| 9ca86c6093 | |||
| 01729ae22a | |||
| 9196dc2216 | |||
| b925335bbb | |||
| 59b25edb5c | |||
| 965f939967 | |||
| 00feccbb77 | |||
| b6fc66ba0d | |||
| c40debc0e9 | |||
| 3b31d70865 | |||
| afa8b62de7 | |||
| 70fd15de2d | |||
| c54d330f89 | |||
| 4028560d12 | |||
| 3c28c28623 | |||
| a958fa06e7 | |||
| 4d39e9e15a | |||
| 647bc87600 | |||
| ebf56f6585 | |||
| 1644ee152e | |||
| 069fe18b9d | |||
| acf8dea170 | |||
| 7a87b0476e | |||
| 886bcc7b47 |
@@ -3,6 +3,8 @@ name: Build + Test v3 alpha
|
||||
on:
|
||||
push:
|
||||
branches: [v3-alpha]
|
||||
paths-ignore:
|
||||
- 'mkdocs-website/**/*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@@ -12,7 +14,7 @@ jobs:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
os: [windows-latest, macos-latest]
|
||||
go-version: [1.21]
|
||||
|
||||
steps:
|
||||
@@ -87,7 +89,6 @@ jobs:
|
||||
lit-ts,
|
||||
vanilla,
|
||||
vanilla-ts,
|
||||
plain,
|
||||
]
|
||||
go-version: [1.21]
|
||||
steps:
|
||||
@@ -114,6 +115,6 @@ jobs:
|
||||
go install github.com/go-task/task/v3/cmd/task@latest
|
||||
mkdir -p ./test-${{ matrix.template }}
|
||||
cd ./test-${{ matrix.template }}
|
||||
wails3 init -n ${{ matrix.template }} -t ${{ matrix.template }} -ci
|
||||
wails3 init -n ${{ matrix.template }} -t ${{ matrix.template }}
|
||||
cd ${{ matrix.template }}
|
||||
wails3 build
|
||||
|
||||
@@ -3,11 +3,14 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- v3-alpha
|
||||
paths:
|
||||
- 'mkdocs-website/**/*'
|
||||
permissions:
|
||||
contents: write
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.repository.fork == false
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./mkdocs-website
|
||||
@@ -23,6 +26,10 @@ jobs:
|
||||
path: .cache
|
||||
restore-keys: |
|
||||
mkdocs-material-
|
||||
- run: pip install -r requirements.insiders.txt
|
||||
- run: sudo apt-get install pngquant
|
||||
- run: pip install pillow cairosvg
|
||||
- run: pip install git+https://${GH_TOKEN}@github.com/squidfunk/mkdocs-material-insiders.git
|
||||
- run: mkdocs build --config-file mkdocs.insiders.yml
|
||||
- run: mkdocs gh-deploy --force
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
This is the documentation for Wails v3. It is currently a work in progress.
|
||||
|
||||
If you do not wish to build it locally, it is available online at [https://wailsapp.github.io/wails/](https://wailsapp.github.io/wails/).
|
||||
|
||||
## Recommended Setup Steps
|
||||
|
||||
Install the wails3 CLI if you haven't already:
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
# What's new in v3?
|
||||
|
||||
!!! note
|
||||
The features that will be included in the v3 release may change from this list.
|
||||
|
||||
## Multiple Windows
|
||||
|
||||
It's now possible to create multiple windows and configure each one independently.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"log"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
)
|
||||
|
||||
//go:embed assets/*
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
app := application.New(application.Options{
|
||||
Name: "Multi Window Demo",
|
||||
Assets: application.AssetOptions{
|
||||
FS: assets,
|
||||
},
|
||||
})
|
||||
|
||||
window1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Window 1",
|
||||
})
|
||||
|
||||
window2 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Window 2",
|
||||
})
|
||||
|
||||
// load the embedded html from the embed.FS
|
||||
window1.SetURL("/")
|
||||
window1.Center()
|
||||
|
||||
// Load an external URL
|
||||
window2.SetURL("https://wails.app")
|
||||
|
||||
err := app.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Systrays
|
||||
|
||||
Systrays allow you to add an icon in the system tray area of your desktop and have the following features:
|
||||
|
||||
- Attach window (the window will be centered to the systray icon)
|
||||
- Full menu support
|
||||
- Light/Dark mode icons
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/icons"
|
||||
)
|
||||
|
||||
func main() {
|
||||
app := application.New(application.Options{
|
||||
Name: "Systray Demo",
|
||||
Mac: application.MacOptions{
|
||||
ActivationPolicy: application.ActivationPolicyAccessory,
|
||||
},
|
||||
})
|
||||
|
||||
window := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Width: 500,
|
||||
Height: 800,
|
||||
Frameless: true,
|
||||
AlwaysOnTop: true,
|
||||
Hidden: true,
|
||||
Windows: application.WindowsWindow{
|
||||
HiddenOnTaskbar: true,
|
||||
},
|
||||
})
|
||||
|
||||
systemTray := app.NewSystemTray()
|
||||
|
||||
// Support for template icons on macOS
|
||||
if runtime.GOOS == "darwin" {
|
||||
systemTray.SetTemplateIcon(icons.SystrayMacTemplate)
|
||||
} else {
|
||||
// Support for light/dark mode icons
|
||||
systemTray.SetDarkModeIcon(icons.SystrayDark)
|
||||
systemTray.SetIcon(icons.SystrayLight)
|
||||
}
|
||||
|
||||
// Support for menu
|
||||
myMenu := app.NewMenu()
|
||||
myMenu.Add("Hello World!").OnClick(func(_ *application.Context) {
|
||||
println("Hello World!")
|
||||
})
|
||||
systemTray.SetMenu(myMenu)
|
||||
|
||||
// This will center the window to the systray icon with a 5px offset
|
||||
// It will automatically be shown when the systray icon is clicked
|
||||
// and hidden when the window loses focus
|
||||
systemTray.AttachWindow(window).WindowOffset(5)
|
||||
|
||||
err := app.Run()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Plugins
|
||||
|
||||
Plugins allow you to extend the functionality of the Wails system. Not only can plugin methods be used in Go, but also called from Javascript. Included plugins:
|
||||
|
||||
- kvstore - A key/value store
|
||||
- browser - open links in a browser
|
||||
- log - custom logger
|
||||
- oauth - handles oauth authentication and supports 60 providers
|
||||
- single_instance - only allow one copy of your app to be run
|
||||
- sqlite - add a sqlite db to your app. Uses the modernc pure go library
|
||||
- start_at_login - Register/Unregister your application to start at login
|
||||
|
||||
## Improved bindings generation
|
||||
|
||||
v3 uses a new static analyser to generate bindings. This makes it extremely fast and maintains comments and parameter names in your bindings.
|
||||
By default, bindings are generated with calls using IDs instead of strings. This provides a performance boost and allows
|
||||
for using obfuscation tools such as [garble](https://github.com/burrowers/garble).
|
||||
|
||||
Bindings are generated by simply running `wails3 generate bindings` in the project directory.
|
||||
|
||||
```js
|
||||
// @ts-check
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
|
||||
import {main} from './models';
|
||||
|
||||
window.go = window.go || {};
|
||||
window.go.main = {
|
||||
GreetService: {
|
||||
|
||||
/**
|
||||
* GreetService.Greet
|
||||
* Greet greets a person
|
||||
* @param name {string}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
Greet: function(name) { wails.CallByID(1411160069, ...Array.prototype.slice.call(arguments, 0)); },
|
||||
|
||||
/**
|
||||
* GreetService.GreetPerson
|
||||
* GreetPerson greets a person
|
||||
* @param person {main.Person}
|
||||
* @returns {Promise<string>}
|
||||
**/
|
||||
GreetPerson: function(person) { wails.CallByID(4021313248, ...Array.prototype.slice.call(arguments, 0)); },
|
||||
},
|
||||
};
|
||||
|
||||
```
|
||||
## Improved build system
|
||||
|
||||
In v2, the build system was completely opaque and hard to customise.
|
||||
In v3, it's possible to build everything using standard Go tooling.
|
||||
|
||||
All the heavy lifting that the v2 build system did, such as icon generation, have been added as tool commands in the CLI.
|
||||
We have incorporated [Taskfile](https://taskfile.dev) into the CLI to orchestrate these calls to bring the same developer experience as v2.
|
||||
However, this approach brings the ultimate balance of flexibility and ease of use as you can now customise the build process to your needs.
|
||||
|
||||
You can even use make if that's your thing!
|
||||
|
||||
```yaml title="Snippet from Taskfile.yml"
|
||||
build:darwin:
|
||||
summary: Builds the application
|
||||
platforms:
|
||||
- darwin
|
||||
cmds:
|
||||
- task: pre-build
|
||||
- task: build-frontend
|
||||
- go build -gcflags=all="-N -l" -o bin/{{.APP_NAME}}
|
||||
- task: post-build
|
||||
env:
|
||||
CGO_CFLAGS: "-mmacosx-version-min=10.13"
|
||||
CGO_LDFLAGS: "-mmacosx-version-min=10.13"
|
||||
MACOSX_DEPLOYMENT_TARGET: "10.13"
|
||||
```
|
||||
|
||||
## Improved events
|
||||
|
||||
Events are now emitted for a lot of the runtime operations, allowing you to hook into application/system events. Cross-platform (common) events are also emitted where there are common platform events, allowing you to write the same event handling methods cross platform.
|
||||
|
||||
Event hooks can also be registered. These are like the `On` method but are synchronous and allow you to cancel the event. An example of this would be to show a confirmation dialog before closing a window.
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/events"
|
||||
)
|
||||
|
||||
//go:embed assets
|
||||
var assets embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
app := application.New(application.Options{
|
||||
Name: "Events Demo",
|
||||
Description: "A demo of the Events API",
|
||||
Assets: application.AssetOptions{
|
||||
FS: assets,
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
||||
},
|
||||
})
|
||||
|
||||
// Custom event handling
|
||||
app.Events.On("myevent", func(e *application.WailsEvent) {
|
||||
log.Printf("[Go] WailsEvent received: %+v\n", e)
|
||||
})
|
||||
|
||||
// OS specific application events
|
||||
app.On(events.Mac.ApplicationDidFinishLaunching, func(event *application.Event) {
|
||||
println("events.Mac.ApplicationDidFinishLaunching fired!")
|
||||
})
|
||||
|
||||
// Platform agnostic events
|
||||
app.On(events.Common.ApplicationStarted, func(event *application.Event) {
|
||||
println("events.Common.ApplicationStarted fired!")
|
||||
})
|
||||
|
||||
win1 := app.NewWebviewWindowWithOptions(application.WebviewWindowOptions{
|
||||
Title: "Takes 3 attempts to close me!",
|
||||
})
|
||||
|
||||
var countdown = 3
|
||||
|
||||
// Register a hook to cancel the window closing
|
||||
win1.RegisterHook(events.Common.WindowClosing, func(e *application.WindowEvent) {
|
||||
countdown--
|
||||
if countdown == 0 {
|
||||
println("Closing!")
|
||||
return
|
||||
}
|
||||
println("Nope! Not closing!")
|
||||
e.Cancel()
|
||||
})
|
||||
|
||||
win1.On(events.Common.WindowFocus, func(e *application.WindowEvent) {
|
||||
println("[Event] Window focus!")
|
||||
})
|
||||
|
||||
err := app.Run()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Wails Markup Language (wml)
|
||||
|
||||
An experimental feature to call runtime methods using plain html, similar to [htmx](https://htmx.org).
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Wails ML Demo</title>
|
||||
</head>
|
||||
<body style="margin-top:50px; color: white; background-color: #191919">
|
||||
<h2>Wails ML Demo</h2>
|
||||
<p>This application contains no Javascript!</p>
|
||||
<button data-wml-event="button-pressed">Press me!</button>
|
||||
<button data-wml-event="delete-things" data-wml-confirm="Are you sure?">Delete all the things!</button>
|
||||
<button data-wml-window="Close" data-wml-confirm="Are you sure?">Close the Window?</button>
|
||||
<button data-wml-window="Center">Center</button>
|
||||
<button data-wml-window="Minimise">Minimise</button>
|
||||
<button data-wml-window="Maximise">Maximise</button>
|
||||
<button data-wml-window="UnMaximise">UnMaximise</button>
|
||||
<button data-wml-window="Fullscreen">Fullscreen</button>
|
||||
<button data-wml-window="UnFullscreen">UnFullscreen</button>
|
||||
<button data-wml-window="Restore">Restore</button>
|
||||
<div style="width: 200px; height: 200px; border: 2px solid white;" data-wml-event="hover" data-wml-trigger="mouseover">Hover over me</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
@@ -14,8 +14,11 @@ theme:
|
||||
- navigation.sections
|
||||
- navigation.expand
|
||||
- navigation.instant
|
||||
- navigation.instant.prefetch
|
||||
- navigation.top
|
||||
- navigation.footer
|
||||
- navigation.path
|
||||
- navigation.prune
|
||||
|
||||
- toc.integrate
|
||||
- toc.follow
|
||||
@@ -80,11 +83,13 @@ nav:
|
||||
# - Links: community/links.md
|
||||
- Next Steps: getting-started/next-steps.md
|
||||
- Feedback: getting-started/feedback.md
|
||||
- What's New in v3?: whats-new.md
|
||||
- Development:
|
||||
- Introduction: development/introduction.md
|
||||
- Status: development/status.md
|
||||
- v3 Changes: development/changes.md
|
||||
- Change Log: changelog.md
|
||||
- Sponsor❤️: https://github.com/sponsors/leaanthony
|
||||
|
||||
|
||||
markdown_extensions:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -4,6 +4,7 @@ version: "3"
|
||||
|
||||
tasks:
|
||||
release:
|
||||
summary: Release a new version of Task. Call with `task v2:release -- <version>`
|
||||
dir: tools/release
|
||||
cmds:
|
||||
- go run release.go {{.CLI_ARGS}}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -138,20 +139,6 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error {
|
||||
}
|
||||
}
|
||||
|
||||
// create the project files watcher
|
||||
watcher, err := initialiseWatcher(cwd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer func(watcher *fsnotify.Watcher) {
|
||||
err := watcher.Close()
|
||||
if err != nil {
|
||||
logger.Fatal(err.Error())
|
||||
}
|
||||
}(watcher)
|
||||
|
||||
logutils.LogGreen("Watching (sub)/directory: %s", cwd)
|
||||
logutils.LogGreen("Using DevServer URL: %s", f.DevServerURL())
|
||||
if f.FrontendDevServerURL != "" {
|
||||
logutils.LogGreen("Using Frontend DevServer URL: %s", f.FrontendDevServerURL)
|
||||
@@ -165,7 +152,10 @@ func Application(f *flags.Dev, logger *clilogger.CLILogger) error {
|
||||
}()
|
||||
|
||||
// Watch for changes and trigger restartApp()
|
||||
debugBinaryProcess = doWatcherLoop(buildOptions, debugBinaryProcess, f, watcher, exitCodeChannel, quitChannel, f.DevServerURL(), legacyUseDevServerInsteadofCustomScheme)
|
||||
debugBinaryProcess, err = doWatcherLoop(cwd, buildOptions, debugBinaryProcess, f, exitCodeChannel, quitChannel, f.DevServerURL(), legacyUseDevServerInsteadofCustomScheme)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Kill the current program if running and remove dev binary
|
||||
if err := killProcessAndCleanupBinary(debugBinaryProcess, appBinary); err != nil {
|
||||
@@ -318,9 +308,6 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process
|
||||
os.Setenv("assetdir", f.AssetDir)
|
||||
os.Setenv("devserver", f.DevServer)
|
||||
os.Setenv("frontenddevserverurl", f.FrontendDevServerURL)
|
||||
if legacyUseDevServerInsteadofCustomScheme {
|
||||
os.Setenv("legacyusedevsererinsteadofcustomscheme", "true")
|
||||
}
|
||||
|
||||
// Start up new binary with correct args
|
||||
newProcess := process.NewProcess(appBinary, args...)
|
||||
@@ -340,7 +327,23 @@ func restartApp(buildOptions *build.Options, debugBinaryProcess *process.Process
|
||||
}
|
||||
|
||||
// doWatcherLoop is the main watch loop that runs while dev is active
|
||||
func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, watcher *fsnotify.Watcher, exitCodeChannel chan int, quitChannel chan os.Signal, devServerURL *url.URL, legacyUseDevServerInsteadofCustomScheme bool) *process.Process {
|
||||
func doWatcherLoop(cwd string, buildOptions *build.Options, debugBinaryProcess *process.Process, f *flags.Dev, exitCodeChannel chan int, quitChannel chan os.Signal, devServerURL *url.URL, legacyUseDevServerInsteadofCustomScheme bool) (*process.Process, error) {
|
||||
// create the project files watcher
|
||||
watcher, err := initialiseWatcher(cwd)
|
||||
if err != nil {
|
||||
logutils.LogRed("Unable to create filesystem watcher. Reloads will not occur.")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func(watcher *fsnotify.Watcher) {
|
||||
err := watcher.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}(watcher)
|
||||
|
||||
logutils.LogGreen("Watching (sub)/directory: %s", cwd)
|
||||
|
||||
// Main Loop
|
||||
var extensionsThatTriggerARebuild = sliceToMap(strings.Split(f.Extensions, ","))
|
||||
var dirsThatTriggerAReload []string
|
||||
@@ -354,6 +357,12 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
continue
|
||||
}
|
||||
dirsThatTriggerAReload = append(dirsThatTriggerAReload, thePath)
|
||||
err = watcher.Add(thePath)
|
||||
if err != nil {
|
||||
logutils.LogRed("Unable to watch path: %s due to error %v", thePath, err)
|
||||
} else {
|
||||
logutils.LogGreen("Watching (sub)/directory: %s", thePath)
|
||||
}
|
||||
}
|
||||
|
||||
quit := false
|
||||
@@ -502,7 +511,7 @@ func doWatcherLoop(buildOptions *build.Options, debugBinaryProcess *process.Proc
|
||||
quit = true
|
||||
}
|
||||
}
|
||||
return debugBinaryProcess
|
||||
return debugBinaryProcess, nil
|
||||
}
|
||||
|
||||
func joinPath(url *url.URL, subPath string) string {
|
||||
|
||||
@@ -38,7 +38,6 @@ func initialiseWatcher(cwd string) (*fsnotify.Watcher, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
println("watching: " + dir)
|
||||
}
|
||||
return watcher, nil
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
v2.5.1
|
||||
v2.6.0
|
||||
Binary file not shown.
@@ -1,7 +1,7 @@
|
||||
//go:build devtools
|
||||
|
||||
package app
|
||||
|
||||
func IsDevtoolsEnabled() bool {
|
||||
return true
|
||||
}
|
||||
//go:build devtools
|
||||
|
||||
package app
|
||||
|
||||
func IsDevtoolsEnabled() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
//go:build !devtools
|
||||
|
||||
package app
|
||||
|
||||
func IsDevtoolsEnabled() bool {
|
||||
return false
|
||||
}
|
||||
//go:build !devtools
|
||||
|
||||
package app
|
||||
|
||||
func IsDevtoolsEnabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ void ShowApplication(void* ctx);
|
||||
void SetBackgroundColour(void* ctx, int r, int g, int b, int a);
|
||||
void ExecJS(void* ctx, const char*);
|
||||
void Quit(void*);
|
||||
void WindowPrint(void* ctx);
|
||||
|
||||
const char* GetSize(void *ctx);
|
||||
const char* GetPosition(void *ctx);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#import "WailsContext.h"
|
||||
#import "Application.h"
|
||||
#import "AppDelegate.h"
|
||||
#import "WindowDelegate.h"
|
||||
#import "WailsMenu.h"
|
||||
#import "WailsMenuItem.h"
|
||||
|
||||
@@ -384,3 +385,36 @@ void ReleaseContext(void *inctx) {
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
[ctx release];
|
||||
}
|
||||
|
||||
// Credit: https://stackoverflow.com/q/33319295
|
||||
void WindowPrint(void *inctx) {
|
||||
|
||||
// Check if macOS 11.0 or newer
|
||||
if (@available(macOS 11.0, *)) {
|
||||
ON_MAIN_THREAD(
|
||||
WailsContext *ctx = (__bridge WailsContext*) inctx;
|
||||
WKWebView* webView = ctx.webview;
|
||||
|
||||
// I think this should be exposed as a config
|
||||
// It directly affects the printed output/PDF
|
||||
NSPrintInfo *pInfo = [NSPrintInfo sharedPrintInfo];
|
||||
pInfo.horizontalPagination = NSPrintingPaginationModeAutomatic;
|
||||
pInfo.verticalPagination = NSPrintingPaginationModeAutomatic;
|
||||
pInfo.verticallyCentered = YES;
|
||||
pInfo.horizontallyCentered = YES;
|
||||
pInfo.orientation = NSPaperOrientationLandscape;
|
||||
pInfo.leftMargin = 0;
|
||||
pInfo.rightMargin = 0;
|
||||
pInfo.topMargin = 0;
|
||||
pInfo.bottomMargin = 0;
|
||||
|
||||
NSPrintOperation *po = [webView printOperationWithPrintInfo:pInfo];
|
||||
po.showsPrintPanel = YES;
|
||||
po.showsProgressPanel = YES;
|
||||
|
||||
po.view.frame = webView.bounds;
|
||||
|
||||
[po runOperationModalForWindow:ctx.mainWindow delegate:ctx.mainWindow.delegate didRunSelector:nil contextInfo:nil];
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -286,6 +286,10 @@ func (f *Frontend) Quit() {
|
||||
f.mainWindow.Quit()
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowPrint() {
|
||||
f.mainWindow.Print()
|
||||
}
|
||||
|
||||
type EventNotify struct {
|
||||
Name string `json:"name"`
|
||||
Data []interface{} `json:"data"`
|
||||
|
||||
@@ -263,3 +263,7 @@ func (w *Window) SetApplicationMenu(inMenu *menu.Menu) {
|
||||
func (w *Window) UpdateApplicationMenu() {
|
||||
C.UpdateApplicationMenu(w.context)
|
||||
}
|
||||
|
||||
func (w Window) Print() {
|
||||
C.WindowPrint(w.context)
|
||||
}
|
||||
|
||||
@@ -362,6 +362,10 @@ func (f *Frontend) Quit() {
|
||||
f.mainWindow.Quit()
|
||||
}
|
||||
|
||||
func (f *Frontend) WindowPrint() {
|
||||
f.ExecJS("window.print();")
|
||||
}
|
||||
|
||||
type EventNotify struct {
|
||||
Name string `json:"name"`
|
||||
Data []interface{} `json:"data"`
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <locale.h>
|
||||
#include "window.h"
|
||||
|
||||
// These are the x,y,time & button of the last mouse down event
|
||||
@@ -145,20 +146,39 @@ void SetBackgroundColour(void *data)
|
||||
{
|
||||
// set webview's background color
|
||||
RGBAOptions *options = (RGBAOptions *)data;
|
||||
|
||||
GdkRGBA colour = {options->r / 255.0, options->g / 255.0, options->b / 255.0, options->a / 255.0};
|
||||
if (options->windowIsTranslucent != NULL && options->windowIsTranslucent == TRUE)
|
||||
{
|
||||
colour.alpha = 0.0;
|
||||
}
|
||||
webkit_web_view_set_background_color(WEBKIT_WEB_VIEW(options->webview), &colour);
|
||||
|
||||
// set window's background color
|
||||
GtkWidget *window = GTK_WIDGET(options->window);
|
||||
gchar *str = g_strdup_printf("window {background-color: rgba(%d, %d, %d, %d);}", options->r, options->g, options->b, options->a);
|
||||
// Get the name of the current locale
|
||||
char *old_locale, *saved_locale;
|
||||
old_locale = setlocale(LC_ALL, NULL);
|
||||
|
||||
// Copy the name so it won’t be clobbered by setlocale.
|
||||
saved_locale = strdup(old_locale);
|
||||
if (saved_locale == NULL)
|
||||
return;
|
||||
|
||||
//Now change the locale to english for so printf always converts floats with a dot decimal separator
|
||||
setlocale(LC_ALL, "en_US.UTF-8");
|
||||
gchar *str = g_strdup_printf("#webview-box {background-color: rgba(%d, %d, %d, %1.1f);}", options->r, options->g, options->b, options->a / 255.0);
|
||||
|
||||
//Restore the original locale.
|
||||
setlocale(LC_ALL, saved_locale);
|
||||
free(saved_locale);
|
||||
|
||||
if (windowCssProvider == NULL)
|
||||
{
|
||||
windowCssProvider = gtk_css_provider_new();
|
||||
gtk_style_context_add_provider(
|
||||
gtk_widget_get_style_context(window),
|
||||
gtk_widget_get_style_context(GTK_WIDGET(options->webviewBox)),
|
||||
GTK_STYLE_PROVIDER(windowCssProvider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
GTK_STYLE_PROVIDER_PRIORITY_USER);
|
||||
g_object_unref(windowCssProvider);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user