mirror of
https://github.com/taigrr/wails.git
synced 2026-04-17 12:15:02 -07:00
Compare commits
9 Commits
v2.0.0-alp
...
v2.0.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
712ad96d2a | ||
|
|
86b4a4f2f5 | ||
|
|
4b9786abc9 | ||
|
|
fd96ebc050 | ||
|
|
939e0f5975 | ||
|
|
6a7a288a0f | ||
|
|
0564d0aa98 | ||
|
|
3a136a73ca | ||
|
|
50c219307f |
@@ -63,6 +63,10 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
outputFilename := ""
|
outputFilename := ""
|
||||||
command.StringFlag("o", "Output filename", &outputFilename)
|
command.StringFlag("o", "Output filename", &outputFilename)
|
||||||
|
|
||||||
|
// Clean build directory
|
||||||
|
cleanBuildDirectory := false
|
||||||
|
command.BoolFlag("clean", "Clean the build directory before building", &cleanBuildDirectory)
|
||||||
|
|
||||||
appleIdentity := ""
|
appleIdentity := ""
|
||||||
if runtime.GOOS == "darwin" {
|
if runtime.GOOS == "darwin" {
|
||||||
command.StringFlag("sign", "Signs your app with the given identity.", &appleIdentity)
|
command.StringFlag("sign", "Signs your app with the given identity.", &appleIdentity)
|
||||||
@@ -112,16 +116,17 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
|
|
||||||
// Create BuildOptions
|
// Create BuildOptions
|
||||||
buildOptions := &build.Options{
|
buildOptions := &build.Options{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
OutputType: outputType,
|
OutputType: outputType,
|
||||||
OutputFile: outputFilename,
|
OutputFile: outputFilename,
|
||||||
Mode: mode,
|
CleanBuildDirectory: cleanBuildDirectory,
|
||||||
Pack: pack,
|
Mode: mode,
|
||||||
LDFlags: ldflags,
|
Pack: pack,
|
||||||
Compiler: compilerCommand,
|
LDFlags: ldflags,
|
||||||
KeepAssets: keepAssets,
|
Compiler: compilerCommand,
|
||||||
AppleIdentity: appleIdentity,
|
KeepAssets: keepAssets,
|
||||||
Verbosity: verbosity,
|
AppleIdentity: appleIdentity,
|
||||||
|
Verbosity: verbosity,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate platform and arch
|
// Calculate platform and arch
|
||||||
@@ -148,6 +153,7 @@ func AddBuildSubcommand(app *clir.Cli, w io.Writer) {
|
|||||||
fmt.Fprintf(w, "Compiler: \t%s\n", buildOptions.Compiler)
|
fmt.Fprintf(w, "Compiler: \t%s\n", buildOptions.Compiler)
|
||||||
fmt.Fprintf(w, "Build Mode: \t%s\n", buildModeText)
|
fmt.Fprintf(w, "Build Mode: \t%s\n", buildModeText)
|
||||||
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
fmt.Fprintf(w, "Package: \t%t\n", buildOptions.Pack)
|
||||||
|
fmt.Fprintf(w, "Clean Build Dir: \t%t\n", buildOptions.CleanBuildDirectory)
|
||||||
fmt.Fprintf(w, "KeepAssets: \t%t\n", buildOptions.KeepAssets)
|
fmt.Fprintf(w, "KeepAssets: \t%t\n", buildOptions.KeepAssets)
|
||||||
fmt.Fprintf(w, "LDFlags: \t\"%s\"\n", buildOptions.LDFlags)
|
fmt.Fprintf(w, "LDFlags: \t\"%s\"\n", buildOptions.LDFlags)
|
||||||
if len(buildOptions.OutputFile) > 0 {
|
if len(buildOptions.OutputFile) > 0 {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
var version = "v2.0.0-alpha.56"
|
var version = "v2.0.0-alpha.59"
|
||||||
|
|||||||
@@ -1789,7 +1789,7 @@ void Run(struct Application *app, int argc, char **argv) {
|
|||||||
// Disable damn smart quotes
|
// Disable damn smart quotes
|
||||||
// Credit: https://stackoverflow.com/a/31640511
|
// Credit: https://stackoverflow.com/a/31640511
|
||||||
id userDefaults = msg_reg(c("NSUserDefaults"), s("standardUserDefaults"));
|
id userDefaults = msg_reg(c("NSUserDefaults"), s("standardUserDefaults"));
|
||||||
((id(*)(id, SEL, id, id))objc_msgSend)(userDefaults, s("setBool:forKey:"), NO, str("NSAutomaticQuoteSubstitutionEnabled"));
|
((id(*)(id, SEL, BOOL, id))objc_msgSend)(userDefaults, s("setBool:forKey:"), false, str("NSAutomaticQuoteSubstitutionEnabled"));
|
||||||
|
|
||||||
// Setup drag message handler
|
// Setup drag message handler
|
||||||
msg_id_id(manager, s("addScriptMessageHandler:name:"), app->delegate, str("windowDrag"));
|
msg_id_id(manager, s("addScriptMessageHandler:name:"), app->delegate, str("windowDrag"));
|
||||||
@@ -1939,6 +1939,24 @@ void Quit(struct Application *app) {
|
|||||||
Hide(app);
|
Hide(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
id createImageFromBase64Data(const char *data, bool isTemplateImage) {
|
||||||
|
id nsdata = ALLOC("NSData");
|
||||||
|
id imageData = ((id(*)(id, SEL, id, int))objc_msgSend)(nsdata, s("initWithBase64EncodedString:options:"), str(data), 0);
|
||||||
|
|
||||||
|
// If it's not valid base64 data, use the broken image
|
||||||
|
if ( imageData == NULL ) {
|
||||||
|
imageData = ((id(*)(id, SEL, id, int))objc_msgSend)(nsdata, s("initWithBase64EncodedString:options:"), str(BrokenImage), 0);
|
||||||
|
}
|
||||||
|
id result = ALLOC("NSImage");
|
||||||
|
msg_id(result, s("initWithData:"), imageData);
|
||||||
|
|
||||||
|
if( isTemplateImage ) {
|
||||||
|
msg_bool(result, s("setTemplate:"), YES);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void* NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel, int hideWindowOnClose) {
|
void* NewApplication(const char *title, int width, int height, int resizable, int devtools, int fullscreen, int startHidden, int logLevel, int hideWindowOnClose) {
|
||||||
|
|
||||||
// Load the tray icons
|
// Load the tray icons
|
||||||
|
|||||||
@@ -117,6 +117,8 @@
|
|||||||
#define NSAlertSecondButtonReturn 1001
|
#define NSAlertSecondButtonReturn 1001
|
||||||
#define NSAlertThirdButtonReturn 1002
|
#define NSAlertThirdButtonReturn 1002
|
||||||
|
|
||||||
|
#define BrokenImage "iVBORw0KGgoAAAANSUhEUgAAABAAAAASCAMAAABl5a5YAAABj1BMVEWopan///+koqSWk5P9/v3///////////+AgACMiovz8/PB0fG9z+3i4+WysbGBfX1Erh80rACLiYqBxolEsDhHlDEbqQDDx+CNho7W1tj4+/bw+O3P5Mn4/f/W1tbK6sX////b2dn////////////8/Pz6+vro6Ojj4+P////G1PL////EzNydmp2cmZnd3eDF1PHs8v/o8P/Q3vrS3vfE0vCdmpqZkpr19/3N2vXI1vPH1fOgnqDg6frP3PbCytvHx8irqq6HhIZtuGtjnlZetU1Xs0NWskBNsi7w9v/d6P7w9P3S4Pzr8Pvl7PrY5PrU4PjQ3fjD1Ozo6Om30NjGzNi7ubm34K+UxKmbnaWXlJeUjpSPi4tppF1TtjxSsTf2+f7L2PTr7e3H2+3V7+q+0uXg4OPg4eLR1uG7z+Hg4ODGzODV2N7V1trP5dmxzs65vcfFxMWq0cKxxr+/vr+0s7apxbWaxrCv2qao05+dlp2Uuo2Dn4F8vIB6xnyAoHmAym9zqGpctENLryNFsgoblJpnAAAAKnRSTlP+hP7+5ZRmYgL+/f39/f39/f38/Pz8/Pv69+7j083My8GocnBPTTMWEgjxeITOAAABEklEQVQY0y3KZXuCYBiG4ceYuu7u3nyVAaKOMBBQ7O5Yd3f3fvheDnd9u8/jBkGwNxP6sjOWVQvY/ftrzfT6bd3yEhCnYZqiaYoKiwX/gXkFiHySTcUTLJMsZ9v8nQvgssWYOEKedKpcOO6CUXD5IlGEY5hLUbyDAAZ6HRf1bnkoavOsFQibg+Q4nuNYL+ON5PHD5nBaraRVyxnzGf6BJzUi2QQCQgMyk8tleL7dg1owpJ17D5IkvV100EingeOopPyo6vfAuXF+9hbDTknZCIaUoeK4efKwG4iT6xDewd7imGlid7gGwv37b6Oh9jwaTdOf/Tc1qH7UZVmuP6G5qZfBr9cAGNy4KiDd4tXIs7tS+QO9aUKvPAIKuQAAAABJRU5ErkJggg=="
|
||||||
|
|
||||||
struct Application;
|
struct Application;
|
||||||
int releaseNSObject(void *const context, struct hashmap_element_s *const e);
|
int releaseNSObject(void *const context, struct hashmap_element_s *const e);
|
||||||
void TitlebarAppearsTransparent(struct Application* app);
|
void TitlebarAppearsTransparent(struct Application* app);
|
||||||
@@ -139,4 +141,6 @@ void* lookupStringConstant(id constantName);
|
|||||||
|
|
||||||
void HasURLHandlers(struct Application* app);
|
void HasURLHandlers(struct Application* app);
|
||||||
|
|
||||||
|
id createImageFromBase64Data(const char *data, bool isTemplateImage);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -651,13 +651,7 @@ id processTextMenuItem(Menu *menu, id parentMenu, const char *title, const char
|
|||||||
|
|
||||||
// Process image
|
// Process image
|
||||||
if( image != NULL && strlen(image) > 0) {
|
if( image != NULL && strlen(image) > 0) {
|
||||||
id data = ALLOC("NSData");
|
id nsimage = createImageFromBase64Data(image, templateImage);
|
||||||
id imageData = ((id(*)(id, SEL, id, int))objc_msgSend)(data, s("initWithBase64EncodedString:options:"), str(image), 0);
|
|
||||||
id nsimage = ALLOC("NSImage");
|
|
||||||
msg_id(nsimage, s("initWithData:"), imageData);
|
|
||||||
if( templateImage ) {
|
|
||||||
msg_bool(nsimage, s("setTemplate:"), YES);
|
|
||||||
}
|
|
||||||
msg_id(item, s("setImage:"), nsimage);
|
msg_id(item, s("setImage:"), nsimage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,14 +102,7 @@ void UpdateTrayIcon(TrayMenu *trayMenu) {
|
|||||||
|
|
||||||
// If we don't have the image in the icon cache then assume it's base64 encoded image data
|
// If we don't have the image in the icon cache then assume it's base64 encoded image data
|
||||||
if (trayImage == NULL) {
|
if (trayImage == NULL) {
|
||||||
id data = ALLOC("NSData");
|
trayImage = createImageFromBase64Data(trayMenu->icon, trayMenu->templateImage);
|
||||||
id imageData = ((id(*)(id, SEL, id, int))objc_msgSend)(data, s("initWithBase64EncodedString:options:"), str(trayMenu->icon), 0);
|
|
||||||
trayImage = ALLOC("NSImage");
|
|
||||||
msg_id(trayImage, s("initWithData:"), imageData);
|
|
||||||
|
|
||||||
if( trayMenu->templateImage ) {
|
|
||||||
msg_bool(trayImage, s("setTemplate:"), YES);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg_int(statusBarButton, s("setImagePosition:"), trayMenu->trayIconPosition);
|
msg_int(statusBarButton, s("setImagePosition:"), trayMenu->trayIconPosition);
|
||||||
|
|||||||
@@ -157,9 +157,11 @@ func (b *BaseBuilder) OutputFilename(options *Options) string {
|
|||||||
// CompileProject compiles the project
|
// CompileProject compiles the project
|
||||||
func (b *BaseBuilder) CompileProject(options *Options) error {
|
func (b *BaseBuilder) CompileProject(options *Options) error {
|
||||||
|
|
||||||
|
verbose := options.Verbosity == VERBOSE
|
||||||
// Run go mod tidy first
|
// Run go mod tidy first
|
||||||
cmd := exec.Command(options.Compiler, "mod", "tidy")
|
cmd := exec.Command(options.Compiler, "mod", "tidy")
|
||||||
if options.Verbosity == VERBOSE {
|
if verbose {
|
||||||
|
println("")
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
}
|
}
|
||||||
@@ -183,7 +185,6 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
// potentially try and see if the assets have changed but will
|
// potentially try and see if the assets have changed but will
|
||||||
// this take as much time as a `-a` build?
|
// this take as much time as a `-a` build?
|
||||||
commands.Add("-a")
|
commands.Add("-a")
|
||||||
commands.Add("-x")
|
|
||||||
|
|
||||||
var tags slicer.StringSlicer
|
var tags slicer.StringSlicer
|
||||||
tags.Add(options.OutputType)
|
tags.Add(options.OutputType)
|
||||||
@@ -212,10 +213,12 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
|
|
||||||
// Get application build directory
|
// Get application build directory
|
||||||
appDir := options.BuildDirectory
|
appDir := options.BuildDirectory
|
||||||
//err = cleanBuildDirectory(options)
|
if options.CleanBuildDirectory {
|
||||||
//if err != nil {
|
err = cleanBuildDirectory(options)
|
||||||
// return err
|
if err != nil {
|
||||||
//}
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if options.LDFlags != "" {
|
if options.LDFlags != "" {
|
||||||
commands.Add("-ldflags")
|
commands.Add("-ldflags")
|
||||||
@@ -233,7 +236,8 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
|
|
||||||
// Create the command
|
// Create the command
|
||||||
cmd = exec.Command(options.Compiler, commands.AsSlice()...)
|
cmd = exec.Command(options.Compiler, commands.AsSlice()...)
|
||||||
if options.Verbosity == VERBOSE {
|
if verbose {
|
||||||
|
println(" Build command:", commands.Join(" "))
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
}
|
}
|
||||||
@@ -270,12 +274,21 @@ func (b *BaseBuilder) CompileProject(options *Options) error {
|
|||||||
return "1"
|
return "1"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if verbose {
|
||||||
|
println(" Environment:", strings.Join(cmd.Env, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup buffers
|
||||||
|
var stdo, stde bytes.Buffer
|
||||||
|
cmd.Stdout = &stdo
|
||||||
|
cmd.Stderr = &stde
|
||||||
|
|
||||||
// Run command
|
// Run command
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
|
|
||||||
// Format error if we have one
|
// Format error if we have one
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("%s\n%s", err, string(stde.Bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -391,7 +404,7 @@ func (b *BaseBuilder) BuildFrontend(outputLogger *clilogger.CLILogger) error {
|
|||||||
outputLogger.Print("Installing frontend dependencies: ")
|
outputLogger.Print("Installing frontend dependencies: ")
|
||||||
if verbose {
|
if verbose {
|
||||||
outputLogger.Println("")
|
outputLogger.Println("")
|
||||||
outputLogger.Println("\tCommand: " + b.projectData.InstallCommand)
|
outputLogger.Println(" Install command: '" + b.projectData.InstallCommand + "'")
|
||||||
}
|
}
|
||||||
if err := b.NpmInstallUsingCommand(frontendDir, b.projectData.InstallCommand, verbose); err != nil {
|
if err := b.NpmInstallUsingCommand(frontendDir, b.projectData.InstallCommand, verbose); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -410,7 +423,7 @@ func (b *BaseBuilder) BuildFrontend(outputLogger *clilogger.CLILogger) error {
|
|||||||
cmd := strings.Split(b.projectData.BuildCommand, " ")
|
cmd := strings.Split(b.projectData.BuildCommand, " ")
|
||||||
if verbose {
|
if verbose {
|
||||||
outputLogger.Println("")
|
outputLogger.Println("")
|
||||||
outputLogger.Println("\tCommand: '" + strings.Join(cmd, " ") + "'")
|
outputLogger.Println(" Build command: '" + strings.Join(cmd, " ") + "'")
|
||||||
}
|
}
|
||||||
stdout, stderr, err := shell.RunCommand(frontendDir, cmd[0], cmd[1:]...)
|
stdout, stderr, err := shell.RunCommand(frontendDir, cmd[0], cmd[1:]...)
|
||||||
if verbose || err != nil {
|
if verbose || err != nil {
|
||||||
|
|||||||
@@ -28,22 +28,23 @@ var modeMap = []string{"Debug", "Production"}
|
|||||||
|
|
||||||
// Options contains all the build options as well as the project data
|
// Options contains all the build options as well as the project data
|
||||||
type Options struct {
|
type Options struct {
|
||||||
LDFlags string // Optional flags to pass to linker
|
LDFlags string // Optional flags to pass to linker
|
||||||
Logger *clilogger.CLILogger // All output to the logger
|
Logger *clilogger.CLILogger // All output to the logger
|
||||||
OutputType string // EG: desktop, server....
|
OutputType string // EG: desktop, server....
|
||||||
Mode Mode // release or debug
|
Mode Mode // release or debug
|
||||||
ProjectData *project.Project // The project data
|
ProjectData *project.Project // The project data
|
||||||
Pack bool // Create a package for the app after building
|
Pack bool // Create a package for the app after building
|
||||||
Platform string // The platform to build for
|
Platform string // The platform to build for
|
||||||
Arch string // The architecture to build for
|
Arch string // The architecture to build for
|
||||||
Compiler string // The compiler command to use
|
Compiler string // The compiler command to use
|
||||||
IgnoreFrontend bool // Indicates if the frontend does not need building
|
IgnoreFrontend bool // Indicates if the frontend does not need building
|
||||||
OutputFile string // Override the output filename
|
OutputFile string // Override the output filename
|
||||||
BuildDirectory string // Directory to use for building the application
|
BuildDirectory string // Directory to use for building the application
|
||||||
CompiledBinary string // Fully qualified path to the compiled binary
|
CleanBuildDirectory bool // Indicates if the build directory should be cleaned before building
|
||||||
KeepAssets bool // /Keep the generated assets/files
|
CompiledBinary string // Fully qualified path to the compiled binary
|
||||||
Verbosity int // Verbosity level (0 - silent, 1 - default, 2 - verbose)
|
KeepAssets bool // /Keep the generated assets/files
|
||||||
AppleIdentity string
|
Verbosity int // Verbosity level (0 - silent, 1 - default, 2 - verbose)
|
||||||
|
AppleIdentity string
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetModeAsString returns the current mode as a string
|
// GetModeAsString returns the current mode as a string
|
||||||
@@ -129,6 +130,11 @@ func Build(options *Options) (string, error) {
|
|||||||
// Build amd64 first
|
// Build amd64 first
|
||||||
options.Arch = "amd64"
|
options.Arch = "amd64"
|
||||||
options.OutputFile = amd64Filename
|
options.OutputFile = amd64Filename
|
||||||
|
options.CleanBuildDirectory = false
|
||||||
|
if options.Verbosity == VERBOSE {
|
||||||
|
println()
|
||||||
|
println(" Building AMD64 Target:", filepath.Join(options.BuildDirectory, options.OutputFile))
|
||||||
|
}
|
||||||
err = builder.CompileProject(options)
|
err = builder.CompileProject(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@@ -136,11 +142,18 @@ func Build(options *Options) (string, error) {
|
|||||||
// Build arm64
|
// Build arm64
|
||||||
options.Arch = "arm64"
|
options.Arch = "arm64"
|
||||||
options.OutputFile = arm64Filename
|
options.OutputFile = arm64Filename
|
||||||
|
options.CleanBuildDirectory = false
|
||||||
|
if options.Verbosity == VERBOSE {
|
||||||
|
println(" Building ARM64 Target:", filepath.Join(options.BuildDirectory, options.OutputFile))
|
||||||
|
}
|
||||||
err = builder.CompileProject(options)
|
err = builder.CompileProject(options)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
// Run lipo
|
// Run lipo
|
||||||
|
if options.Verbosity == VERBOSE {
|
||||||
|
println(" Running lipo: ", "lipo", "-create", "-output", outputFile, amd64Filename, arm64Filename)
|
||||||
|
}
|
||||||
_, stderr, err := shell.RunCommand(options.BuildDirectory, "lipo", "-create", "-output", outputFile, amd64Filename, arm64Filename)
|
_, stderr, err := shell.RunCommand(options.BuildDirectory, "lipo", "-create", "-output", outputFile, amd64Filename, arm64Filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("%s - %s", err.Error(), stderr)
|
return "", fmt.Errorf("%s - %s", err.Error(), stderr)
|
||||||
|
|||||||
60
v2/pkg/mac/mac_darwin.go
Normal file
60
v2/pkg/mac/mac_darwin.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
// Package mac provides MacOS related utility functions for Wails applications
|
||||||
|
package mac
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/leaanthony/slicer"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/wailsapp/wails/v2/internal/shell"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StartAtLogin will either add or remove this application to/from the login
|
||||||
|
// items, depending on the given boolean flag. The limitation is that the
|
||||||
|
// currently running app must be in an app bundle.
|
||||||
|
func StartAtLogin(enabled bool) error {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Error running os.Executable:")
|
||||||
|
}
|
||||||
|
binName := filepath.Base(exe)
|
||||||
|
if !strings.HasSuffix(exe, "/Contents/MacOS/"+binName) {
|
||||||
|
return fmt.Errorf("app needs to be running as package.app file to start at login")
|
||||||
|
}
|
||||||
|
appPath := strings.TrimSuffix(exe, "/Contents/MacOS/"+binName)
|
||||||
|
var command string
|
||||||
|
if enabled {
|
||||||
|
command = fmt.Sprintf("tell application \"System Events\" to make login item at end with properties {name: \"%s\",path:\"%s\", hidden:false}", binName, appPath)
|
||||||
|
} else {
|
||||||
|
command = fmt.Sprintf("tell application \"System Events\" to delete login item \"%s\"", binName)
|
||||||
|
}
|
||||||
|
_, stde, err := shell.RunCommand("/tmp", "osascript", "-e", command)
|
||||||
|
if err != nil {
|
||||||
|
errors.Wrap(err, stde)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StartsAtLogin will indicate if this application is in the login
|
||||||
|
// items. The limitation is that the currently running app must be
|
||||||
|
// in an app bundle.
|
||||||
|
func StartsAtLogin() (bool, error) {
|
||||||
|
exe, err := os.Executable()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
binName := filepath.Base(exe)
|
||||||
|
if !strings.HasSuffix(exe, "/Contents/MacOS/"+binName) {
|
||||||
|
return false, fmt.Errorf("app needs to be running as package.app file to start at login")
|
||||||
|
}
|
||||||
|
results, stde, err := shell.RunCommand("/tmp", "osascript", "-e", `tell application "System Events" to get the name of every login item`)
|
||||||
|
if err != nil {
|
||||||
|
return false, errors.Wrap(err, stde)
|
||||||
|
}
|
||||||
|
results = strings.TrimSpace(results)
|
||||||
|
startupApps := slicer.String(strings.Split(results, ", "))
|
||||||
|
return startupApps.Contains(binName), nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user