Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add support for server and hybrid #1652

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
439 changes: 439 additions & 0 deletions v2/cmd/wails/internal/commands/build/build.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion v2/internal/app/app_dev.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build dev
//go:build dev && desktop

package app

Expand Down
128 changes: 128 additions & 0 deletions v2/internal/app/app_hybrid_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//go:build (exp && hybrid) || (exp && server)
// +build exp,hybrid exp,server

package app

import (
"context"
"fmt"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/internal/frontend/desktop"
"github.com/wailsapp/wails/v2/internal/frontend/devserver"
"github.com/wailsapp/wails/v2/internal/frontend/dispatcher"
"github.com/wailsapp/wails/v2/internal/frontend/hybrid"
"github.com/wailsapp/wails/v2/internal/frontend/runtime"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/menumanager"
"github.com/wailsapp/wails/v2/pkg/options"
)

// App defines a Wails application structure
type App struct {
frontend frontend.Frontend
logger *logger.Logger
options *options.App

menuManager *menumanager.Manager

// Indicates if the app is in debug mode
debug bool

// OnStartup/OnShutdown
startupCallback func(ctx context.Context)
shutdownCallback func(ctx context.Context)
ctx context.Context
}

func (a *App) Shutdown() {
a.frontend.Quit()
}

func (a *App) Run() error {
err := a.frontend.Run(a.ctx)
if a.shutdownCallback != nil {
a.shutdownCallback(a.ctx)
}
return err
}

// CreateApp creates the app!
func CreateApp(appoptions *options.App) (*App, error) {
var err error

ctx := context.Background()

host, port := "localhost", int32(3112)
if appoptions.Server != nil {
host = appoptions.Server.Host
port = appoptions.Server.Port
}

serverURI := fmt.Sprintf("%s:%d", host, port)
ctx = context.WithValue(ctx, "starturl", serverURI)
ctx = context.WithValue(ctx, "devserver", fmt.Sprintf("%s:%d", host, port))

// Merge default options
options.MergeDefaults(appoptions)

debug := IsDebug()
ctx = context.WithValue(ctx, "debug", debug)

// Set up logger
myLogger := logger.New(appoptions.Logger)
myLogger.Info("Frontend available at 'http://%s'", serverURI)
if IsDebug() {
myLogger.SetLogLevel(appoptions.LogLevel)
} else {
myLogger.SetLogLevel(appoptions.LogLevelProduction)
}
ctx = context.WithValue(ctx, "logger", myLogger)

// Preflight Checks
err = PreflightChecks(appoptions, myLogger)
if err != nil {
return nil, err
}

// Create the menu manager
menuManager := menumanager.NewManager()

// Process the application menu
if appoptions.Menu != nil {
err = menuManager.SetApplicationMenu(appoptions.Menu)
if err != nil {
return nil, err
}
}

// Create binding exemptions - Ugly hack. There must be a better way
bindingExemptions := []interface{}{appoptions.OnStartup, appoptions.OnShutdown, appoptions.OnDomReady}
appBindings := binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions)
eventHandler := runtime.NewEvents(myLogger)
ctx = context.WithValue(ctx, "events", eventHandler)
// Attach logger to context
if debug {
ctx = context.WithValue(ctx, "buildtype", "debug")
} else {
ctx = context.WithValue(ctx, "buildtype", "production")
}

messageDispatcher := dispatcher.NewDispatcher(ctx, myLogger, appBindings, eventHandler)
appFrontend := hybrid.NewFrontend(ctx, appoptions, myLogger, appBindings, messageDispatcher)
eventHandler.AddFrontend(appFrontend)

result := &App{
ctx: ctx,
frontend: appFrontend,
logger: myLogger,
menuManager: menuManager,
startupCallback: appoptions.OnStartup,
shutdownCallback: appoptions.OnShutdown,
debug: debug,
options: appoptions,
}

return result, nil

}
2 changes: 1 addition & 1 deletion v2/internal/app/app_production.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//go:build production
//go:build production && desktop

package app

Expand Down
5 changes: 5 additions & 0 deletions v2/internal/frontend/desktop/null/browser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package null

// BrowserOpenURL does nothing
func (f *Frontend) BrowserOpenURL(url string) {
}
28 changes: 28 additions & 0 deletions v2/internal/frontend/desktop/null/dialog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package null

import "github.com/wailsapp/wails/v2/internal/frontend"

// OpenFileDialog does nothing
func (f *Frontend) OpenFileDialog(dialogOptions frontend.OpenDialogOptions) (result string, err error) {
return "", nil
}

// OpenMultipleFilesDialog does nothing
func (f *Frontend) OpenMultipleFilesDialog(dialogOptions frontend.OpenDialogOptions) ([]string, error) {
return []string{}, nil
}

// OpenDirectoryDialog does nothing
func (f *Frontend) OpenDirectoryDialog(dialogOptions frontend.OpenDialogOptions) (string, error) {
return "", nil
}

// SaveFileDialog does nothing
func (f *Frontend) SaveFileDialog(dialogOptions frontend.SaveDialogOptions) (string, error) {
return "", nil
}

// MessageDialog does nothing
func (f *Frontend) MessageDialog(dialogOptions frontend.MessageDialogOptions) (string, error) {
return "", nil
}
211 changes: 211 additions & 0 deletions v2/internal/frontend/desktop/null/frontend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
package null

import (
"context"
"time"

"github.com/wailsapp/wails/v2/internal/frontend"
"github.com/wailsapp/wails/v2/pkg/options"
)

// Frontend implements an empty Frontend that simply waits until the context is done.
type Frontend struct {
// Context
ctx context.Context
frontendOptions *options.App

done bool
}

// NewFrontend returns an initialized Frontend
func NewFrontend(ctx context.Context, appoptions *options.App) *Frontend {
return &Frontend{
frontendOptions: appoptions,
ctx: ctx,
}
}

// Show does nothing
func (f *Frontend) Show() {

}

// Hide does nothing
func (f *Frontend) Hide() {

}

// ScreenGetAll returns an empty slice
func (f *Frontend) ScreenGetAll() ([]frontend.Screen, error) {
return []frontend.Screen{}, nil
}

// WindowSetBackgroundColour does nothing
func (f *Frontend) WindowSetBackgroundColour(col *options.RGBA) {

}

// WindowReload does nothing
func (f *Frontend) WindowReload() {

}

// WindowReloadApp does nothing
func (f *Frontend) WindowReloadApp() {

}

// WindowSetAlwaysOnTop does nothing
func (f *Frontend) WindowSetAlwaysOnTop(b bool) {

}

// WindowSetSystemDefaultTheme does nothing
func (f *Frontend) WindowSetSystemDefaultTheme() {

}

// WindowSetLightTheme does nothing
func (f *Frontend) WindowSetLightTheme() {

}

// WindowSetDarkTheme does nothing
func (f *Frontend) WindowSetDarkTheme() {

}

// Run waits until the context is done and then exits
func (f *Frontend) Run(ctx context.Context) (err error) {
err = nil
go func() {
if f.frontendOptions.OnStartup != nil {
f.frontendOptions.OnStartup(f.ctx)
}
}()
for {
select {
case <-ctx.Done():
return
default:
time.Sleep(1 * time.Millisecond)
}
if f.done {
return
}
}

}

// WindowCenter does nothing
func (f *Frontend) WindowCenter() {

}

// WindowSetPosition does nothing
func (f *Frontend) WindowSetPosition(x, y int) {

}

// WindowGetPosition does nothing
func (f *Frontend) WindowGetPosition() (int, int) {
return 0, 0
}

// WindowSetSize does nothing
func (f *Frontend) WindowSetSize(width, height int) {

}

// WindowGetSize does nothing
func (f *Frontend) WindowGetSize() (int, int) {
return 0, 0
}

// WindowSetTitle does nothing
func (f *Frontend) WindowSetTitle(title string) {

}

// WindowFullscreen does nothing
func (f *Frontend) WindowFullscreen() {

}

// WindowUnfullscreen does nothing
func (f *Frontend) WindowUnfullscreen() {

}

// WindowShow does nothing
func (f *Frontend) WindowShow() {

}

// WindowHide does nothing
func (f *Frontend) WindowHide() {

}

// WindowMaximize does nothing
func (f *Frontend) WindowMaximise() {

}

// WindowToggleMaximise does nothing
func (f *Frontend) WindowToggleMaximise() {

}

// WindowUnmaximise does nothing
func (f *Frontend) WindowUnmaximise() {
}

// WindowMinimise does nothing
func (f *Frontend) WindowMinimise() {

}

// WindowUnminimise does nothing
func (f *Frontend) WindowUnminimise() {

}

// WindowSetMinSize does nothing
func (f *Frontend) WindowSetMinSize(width int, height int) {

}

// WindowSetMaxSize does nothing
func (f *Frontend) WindowSetMaxSize(width int, height int) {

}

// WindowSetRGBA does nothing
func (f *Frontend) WindowSetRGBA(col *options.RGBA) {
}

// Quit does nothing
func (f *Frontend) Quit() {
f.done = true
}

// Notify does nothing
func (f *Frontend) Notify(name string, data ...interface{}) {

}

// Callback does nothing
func (f *Frontend) Callback(message string) {

}

// startDrag does nothing
func (f *Frontend) startDrag() {

}

// ExecJS does nothing
func (f *Frontend) ExecJS(js string) {

}
11 changes: 11 additions & 0 deletions v2/internal/frontend/desktop/null/menu.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package null

import "github.com/wailsapp/wails/v2/pkg/menu"

//MenuSetApplicationMenu does nothing
func (f *Frontend) MenuSetApplicationMenu(menu *menu.Menu) {
}

// MenuUpdateApplicationMenu does nothing
func (f *Frontend) MenuUpdateApplicationMenu() {
}
Loading
Loading