Compare commits

...

4 Commits

Author SHA1 Message Date
Lea Anthony
4b9786abc9 v2.0.0-alpha.58 2021-03-26 18:13:10 +11:00
Lea Anthony
fd96ebc050 Better verbose output 2021-03-26 18:12:42 +11:00
Lea Anthony
939e0f5975 Use default broken image for invalid images 2021-03-26 17:51:49 +11:00
Lea Anthony
6a7a288a0f Limit StartsAtLogin to app bundles 2021-03-26 16:52:59 +11:00
8 changed files with 64 additions and 25 deletions

View File

@@ -1,3 +1,3 @@
package main package main
var version = "v2.0.0-alpha.57" var version = "v2.0.0-alpha.58"

View File

@@ -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

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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);

View File

@@ -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)
@@ -235,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
} }
@@ -272,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
@@ -393,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
@@ -412,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 {

View File

@@ -130,6 +130,10 @@ func Build(options *Options) (string, error) {
// Build amd64 first // Build amd64 first
options.Arch = "amd64" options.Arch = "amd64"
options.OutputFile = amd64Filename options.OutputFile = amd64Filename
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
@@ -137,11 +141,17 @@ func Build(options *Options) (string, error) {
// Build arm64 // Build arm64
options.Arch = "arm64" options.Arch = "arm64"
options.OutputFile = arm64Filename options.OutputFile = arm64Filename
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)

View File

@@ -1,4 +1,4 @@
// build // Package mac provides MacOS related utility functions for Wails applications
package mac package mac
import ( import (
@@ -12,6 +12,9 @@ import (
"github.com/wailsapp/wails/v2/internal/shell" "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 { func StartAtLogin(enabled bool) error {
exe, err := os.Executable() exe, err := os.Executable()
if err != nil { if err != nil {
@@ -19,7 +22,7 @@ func StartAtLogin(enabled bool) error {
} }
binName := filepath.Base(exe) binName := filepath.Base(exe)
if !strings.HasSuffix(exe, "/Contents/MacOS/"+binName) { if !strings.HasSuffix(exe, "/Contents/MacOS/"+binName) {
return fmt.Errorf("app needs to be running as package.app file to start at startup") return fmt.Errorf("app needs to be running as package.app file to start at login")
} }
appPath := strings.TrimSuffix(exe, "/Contents/MacOS/"+binName) appPath := strings.TrimSuffix(exe, "/Contents/MacOS/"+binName)
var command string var command string
@@ -35,12 +38,18 @@ func StartAtLogin(enabled bool) error {
return nil 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) { func StartsAtLogin() (bool, error) {
exe, err := os.Executable() exe, err := os.Executable()
if err != nil { if err != nil {
return false, err return false, err
} }
binName := filepath.Base(exe) 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`) results, stde, err := shell.RunCommand("/tmp", "osascript", "-e", `tell application "System Events" to get the name of every login item`)
if err != nil { if err != nil {
return false, errors.Wrap(err, stde) return false, errors.Wrap(err, stde)