5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-20 19:09:29 +08:00

Support startup urls when app not running

This commit is contained in:
Lea Anthony 2021-03-15 06:13:00 +11:00
parent 96d8509da3
commit 6f40e85a6e
No known key found for this signature in database
GPG Key ID: 33DAF7BB90A58405
3 changed files with 66 additions and 21 deletions

View File

@ -128,6 +128,7 @@ struct Application {
int hideToolbarSeparator;
int windowBackgroundIsTranslucent;
int hasURLHandlers;
const char *startupURL;
// Menu
Menu *applicationMenu;
@ -144,6 +145,9 @@ struct Application {
// shutting down flag
bool shuttingDown;
// Running flag
bool running;
};
// Debug works like sprintf but mutes if the global debug flag is true
@ -304,8 +308,19 @@ void messageHandler(id self, SEL cmd, id contentController, id message) {
// TODO: Check this actually does reduce flicker
msg(app->config, s("setValue:forKey:"), msg(c("NSNumber"), s("numberWithBool:"), 0), str("suppressesIncrementalRendering"));
// We are now running!
app->running = true;
// Notify backend we are ready (system startup)
app->sendMessageToBackend("SS");
const char *readyMessage = "SS";
if( app->startupURL == NULL ) {
app->sendMessageToBackend("SS");
return;
}
readyMessage = concat("SS", app->startupURL);
app->sendMessageToBackend(readyMessage);
MEMFREE(readyMessage);
} else if( strcmp(name, "windowDrag") == 0 ) {
// Guard against null events
@ -403,6 +418,11 @@ void ExecJS(struct Application *app, const char *js) {
void willFinishLaunching(id self, SEL cmd, id sender) {
struct Application *app = (struct Application *) objc_getAssociatedObject(self, "application");
// If there are URL Handlers, register a listener for them
if( app->hasURLHandlers ) {
id eventManager = msg(c("NSAppleEventManager"), s("sharedAppleEventManager"));
msg(eventManager, s("setEventHandler:andSelector:forEventClass:andEventID:"), self, s("getUrl:withReplyEvent:"), kInternetEventClass, kAEGetURL);
}
messageFromWindowCallback("Ej{\"name\":\"wails:launched\",\"data\":[]}");
}
@ -427,12 +447,6 @@ void themeChanged(id self, SEL cmd, id sender) {
}
}
// void willFinishLaunching(id self) {
// struct Application *app = (struct Application *) objc_getAssociatedObject(self, "application");
// Debug(app, "willFinishLaunching called!");
// }
int releaseNSObject(void *const context, struct hashmap_element_s *const e) {
msg(e->data, s("release"));
return -1;
@ -465,6 +479,10 @@ void DestroyApplication(struct Application *app) {
Debug(app, "Almost a double free for app->bindings");
}
if( app->startupURL != NULL ) {
MEMFREE(app->startupURL);
}
// Remove mouse monitors
if( app->mouseDownMonitor != NULL ) {
msg( c("NSEvent"), s("removeMonitor:"), app->mouseDownMonitor);
@ -1156,12 +1174,28 @@ void DarkModeEnabled(struct Application *app, const char *callbackID) {
}
void getURL(id self, SEL selector, id event, id replyEvent) {
id desc = msg(event, s("paramDescriptorForKeyword:"), keyDirectObject);
id url = msg(desc, s("stringValue"));
const char* curl = cstr(url);
const char* message = concat("UC", curl);
messageFromWindowCallback(message);
MEMFREE(message);
struct Application *app = (struct Application *)objc_getAssociatedObject(self, "application");
id desc = msg(event, s("paramDescriptorForKeyword:"), keyDirectObject);
id url = msg(desc, s("stringValue"));
const char* curl = cstr(url);
if( curl == NULL ) {
return;
}
// If this was an incoming URL, but we aren't running yet
// save it to return when we complete
if( app->running != true ) {
app->startupURL = STRCOPY(curl);
return;
}
const char* message = concat("UC", curl);
messageFromWindowCallback(message);
MEMFREE(message);
}
void openURLs(id self, SEL selector, id event) {
filelog("\n\nI AM HERE!!!!!\n\n");
}
@ -1190,12 +1224,6 @@ void createDelegate(struct Application *app) {
id delegate = msg((id)appDelegate, s("new"));
objc_setAssociatedObject(delegate, "application", (id)app, OBJC_ASSOCIATION_ASSIGN);
// If there are URL Handlers, register a listener for them
if( app->hasURLHandlers ) {
id eventManager = msg(c("NSAppleEventManager"), s("sharedAppleEventManager"));
msg(eventManager, s("setEventHandler:andSelector:forEventClass:andEventID:"), delegate, s("getUrl:withReplyEvent:"), kInternetEventClass, kAEGetURL);
}
// Theme change listener
class_addMethod(appDelegate, s("themeChanged:"), (IMP) themeChanged, "v@:@@");
@ -1976,6 +2004,10 @@ void* NewApplication(const char *title, int width, int height, int resizable, in
result->hasURLHandlers = 0;
result->startupURL = NULL;
result->running = false;
return (void*) result;
}

View File

@ -40,7 +40,8 @@ func systemMessageParser(message string) (*parsedMessage, error) {
// This is our startup hook - the frontend is now ready
case 'S':
topic := "hooks:startup"
responseMessage = &parsedMessage{Topic: topic, Data: nil}
startupURL := message[1:]
responseMessage = &parsedMessage{Topic: topic, Data: startupURL}
default:
return nil, fmt.Errorf("Invalid message to systemMessageParser()")
}

View File

@ -34,6 +34,9 @@ type Runtime struct {
// Startup Hook
startupOnce sync.Once
// Service bus
bus *servicebus.ServiceBus
}
// NewRuntime creates a new runtime subsystem
@ -58,6 +61,7 @@ func NewRuntime(ctx context.Context, bus *servicebus.ServiceBus, logger *logger.
runtime: runtime.New(bus),
startupCallback: startupCallback,
ctx: ctx,
bus: bus,
}
return result, nil
@ -79,7 +83,15 @@ func (r *Runtime) Start() error {
case "startup":
if r.startupCallback != nil {
r.startupOnce.Do(func() {
go r.startupCallback(r.runtime)
go func() {
r.startupCallback(r.runtime)
// If we got a url, publish it now startup completed
url, ok := hooksMessage.Data().(string)
if ok && len(url) > 0 {
r.bus.Publish("url:handler", url)
}
}()
})
} else {
r.logger.Warning("no startup callback registered!")