github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/pkg/options/options.go (about)

     1  package options
     2  
     3  import (
     4  	"context"
     5  	"html"
     6  	"io/fs"
     7  	"net/http"
     8  	"os"
     9  	"path/filepath"
    10  	"runtime"
    11  
    12  	"github.com/AlpineAIO/wails/v2/pkg/options/assetserver"
    13  	"github.com/AlpineAIO/wails/v2/pkg/options/linux"
    14  	"github.com/AlpineAIO/wails/v2/pkg/options/mac"
    15  	"github.com/AlpineAIO/wails/v2/pkg/options/windows"
    16  
    17  	"github.com/AlpineAIO/wails/v2/pkg/menu"
    18  
    19  	"github.com/AlpineAIO/wails/v2/pkg/logger"
    20  )
    21  
    22  type WindowStartState int
    23  
    24  const (
    25  	Normal     WindowStartState = 0
    26  	Maximised  WindowStartState = 1
    27  	Minimised  WindowStartState = 2
    28  	Fullscreen WindowStartState = 3
    29  )
    30  
    31  type Experimental struct{}
    32  
    33  // App contains options for creating the App
    34  type App struct {
    35  	Title             string
    36  	Width             int
    37  	Height            int
    38  	DisableResize     bool
    39  	Fullscreen        bool
    40  	Frameless         bool
    41  	MinWidth          int
    42  	MinHeight         int
    43  	MaxWidth          int
    44  	MaxHeight         int
    45  	StartHidden       bool
    46  	HideWindowOnClose bool
    47  	AlwaysOnTop       bool
    48  	// BackgroundColour is the background colour of the window
    49  	// You can use the options.NewRGB and options.NewRGBA functions to create a new colour
    50  	BackgroundColour *RGBA
    51  	// Deprecated: Use AssetServer.Assets instead.
    52  	Assets fs.FS
    53  	// Deprecated: Use AssetServer.Handler instead.
    54  	AssetsHandler http.Handler
    55  	// AssetServer configures the Assets for the application
    56  	AssetServer        *assetserver.Options
    57  	Menu               *menu.Menu
    58  	Logger             logger.Logger `json:"-"`
    59  	LogLevel           logger.LogLevel
    60  	LogLevelProduction logger.LogLevel
    61  	OnStartup          func(ctx context.Context)                `json:"-"`
    62  	OnDomReady         func(ctx context.Context)                `json:"-"`
    63  	OnShutdown         func(ctx context.Context)                `json:"-"`
    64  	OnBeforeClose      func(ctx context.Context) (prevent bool) `json:"-"`
    65  	Bind               []interface{}
    66  	EnumBind           []interface{}
    67  	WindowStartState   WindowStartState
    68  
    69  	// ErrorFormatter overrides the formatting of errors returned by backend methods
    70  	ErrorFormatter ErrorFormatter
    71  
    72  	// CSS property to test for draggable elements. Default "--wails-draggable"
    73  	CSSDragProperty string
    74  
    75  	// The CSS Value that the CSSDragProperty must have to be draggable, EG: "drag"
    76  	CSSDragValue string
    77  
    78  	// EnableDefaultContextMenu enables the browser's default context-menu in production
    79  	// This menu is already enabled in development and debug builds
    80  	EnableDefaultContextMenu bool
    81  
    82  	// EnableFraudulentWebsiteDetection enables scan services for fraudulent content, such as malware or phishing attempts.
    83  	// These services might send information from your app like URLs navigated to and possibly other content to cloud
    84  	// services of Apple and Microsoft.
    85  	EnableFraudulentWebsiteDetection bool
    86  
    87  	SingleInstanceLock *SingleInstanceLock
    88  
    89  	Windows *windows.Options
    90  	Mac     *mac.Options
    91  	Linux   *linux.Options
    92  
    93  	// Experimental options
    94  	Experimental *Experimental
    95  
    96  	// Debug options for debug builds. These options will be ignored in a production build.
    97  	Debug Debug
    98  }
    99  
   100  type ErrorFormatter func(error) any
   101  
   102  type RGBA struct {
   103  	R uint8 `json:"r"`
   104  	G uint8 `json:"g"`
   105  	B uint8 `json:"b"`
   106  	A uint8 `json:"a"`
   107  }
   108  
   109  // NewRGBA creates a new RGBA struct with the given values
   110  func NewRGBA(r, g, b, a uint8) *RGBA {
   111  	return &RGBA{
   112  		R: r,
   113  		G: g,
   114  		B: b,
   115  		A: a,
   116  	}
   117  }
   118  
   119  // NewRGB creates a new RGBA struct with the given values and Alpha set to 255
   120  func NewRGB(r, g, b uint8) *RGBA {
   121  	return &RGBA{
   122  		R: r,
   123  		G: g,
   124  		B: b,
   125  		A: 255,
   126  	}
   127  }
   128  
   129  // MergeDefaults will set the minimum default values for an application
   130  func MergeDefaults(appoptions *App) {
   131  	// Do set defaults
   132  	if appoptions.Width <= 0 {
   133  		appoptions.Width = 1024
   134  	}
   135  	if appoptions.Height <= 0 {
   136  		appoptions.Height = 768
   137  	}
   138  	if appoptions.Logger == nil {
   139  		appoptions.Logger = logger.NewDefaultLogger()
   140  	}
   141  	if appoptions.LogLevel == 0 {
   142  		appoptions.LogLevel = logger.INFO
   143  	}
   144  	if appoptions.LogLevelProduction == 0 {
   145  		appoptions.LogLevelProduction = logger.ERROR
   146  	}
   147  	if appoptions.CSSDragProperty == "" {
   148  		appoptions.CSSDragProperty = "--wails-draggable"
   149  	}
   150  	if appoptions.CSSDragValue == "" {
   151  		appoptions.CSSDragValue = "drag"
   152  	}
   153  	if appoptions.BackgroundColour == nil {
   154  		appoptions.BackgroundColour = &RGBA{
   155  			R: 255,
   156  			G: 255,
   157  			B: 255,
   158  			A: 255,
   159  		}
   160  	}
   161  
   162  	// Ensure max and min are valid
   163  	processMinMaxConstraints(appoptions)
   164  
   165  	// Default menus
   166  	processMenus(appoptions)
   167  
   168  	// Process Drag Options
   169  	processDragOptions(appoptions)
   170  }
   171  
   172  type SingleInstanceLock struct {
   173  	// uniqueId that will be used for setting up messaging between instances
   174  	UniqueId               string
   175  	OnSecondInstanceLaunch func(secondInstanceData SecondInstanceData)
   176  }
   177  
   178  type SecondInstanceData struct {
   179  	Args             []string
   180  	WorkingDirectory string
   181  }
   182  
   183  func NewSecondInstanceData() (*SecondInstanceData, error) {
   184  	ex, err := os.Executable()
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  	workingDirectory := filepath.Dir(ex)
   189  
   190  	return &SecondInstanceData{
   191  		Args:             os.Args[1:],
   192  		WorkingDirectory: workingDirectory,
   193  	}, nil
   194  }
   195  
   196  func processMenus(appoptions *App) {
   197  	switch runtime.GOOS {
   198  	case "darwin":
   199  		if appoptions.Menu == nil {
   200  			items := []*menu.MenuItem{
   201  				menu.EditMenu(),
   202  			}
   203  			if !appoptions.Frameless {
   204  				items = append(items, menu.WindowMenu()) // Current options in Window Menu only work if not frameless
   205  			}
   206  
   207  			appoptions.Menu = menu.NewMenuFromItems(menu.AppMenu(), items...)
   208  		}
   209  	}
   210  }
   211  
   212  func processMinMaxConstraints(appoptions *App) {
   213  	if appoptions.MinWidth > 0 && appoptions.MaxWidth > 0 {
   214  		if appoptions.MinWidth > appoptions.MaxWidth {
   215  			appoptions.MinWidth = appoptions.MaxWidth
   216  		}
   217  	}
   218  	if appoptions.MinHeight > 0 && appoptions.MaxHeight > 0 {
   219  		if appoptions.MinHeight > appoptions.MaxHeight {
   220  			appoptions.MinHeight = appoptions.MaxHeight
   221  		}
   222  	}
   223  	// Ensure width and height are limited if max/min is set
   224  	if appoptions.Width < appoptions.MinWidth {
   225  		appoptions.Width = appoptions.MinWidth
   226  	}
   227  	if appoptions.MaxWidth > 0 && appoptions.Width > appoptions.MaxWidth {
   228  		appoptions.Width = appoptions.MaxWidth
   229  	}
   230  	if appoptions.Height < appoptions.MinHeight {
   231  		appoptions.Height = appoptions.MinHeight
   232  	}
   233  	if appoptions.MaxHeight > 0 && appoptions.Height > appoptions.MaxHeight {
   234  		appoptions.Height = appoptions.MaxHeight
   235  	}
   236  }
   237  
   238  func processDragOptions(appoptions *App) {
   239  	appoptions.CSSDragProperty = html.EscapeString(appoptions.CSSDragProperty)
   240  	appoptions.CSSDragValue = html.EscapeString(appoptions.CSSDragValue)
   241  }