From 67664f517518ffbc6f4c93a21b67cca90efc6bbf Mon Sep 17 00:00:00 2001 From: midagedev Date: Wed, 19 Aug 2026 15:04:28 +0900 Subject: [PATCH 1/2] fix(v3/linux): emit launch URL and file-association events on GTK4 --- v3/UNRELEASED_CHANGELOG.md | 1 + v3/pkg/application/application_linux.go | 41 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 33638e7fc86..796718f9273 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -23,6 +23,7 @@ After processing, the content will be moved to the main changelog and this file ## Fixed +- Fix GTK4 Linux host dropping custom-protocol and file-association launch arguments in [PR](https://github.com/wailsapp/wails/pull/6000) by @midagedev ## Deprecated diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go index db707e9e834..89d8c6a1eb6 100644 --- a/v3/pkg/application/application_linux.go +++ b/v3/pkg/application/application_linux.go @@ -18,6 +18,7 @@ import ( "os" "path/filepath" "regexp" + "slices" "strings" "sync" @@ -87,6 +88,46 @@ func (a *linuxApp) name() string { } func (a *linuxApp) run() error { + // Inspect argv the same way the GTK3 host and the Windows host do. + // g_application_run is invoked with argc=0, so GApplication never sees + // the launch argument; custom-protocol URLs and file associations are + // delivered only through this check. + if len(os.Args) == 2 { // Case: program + 1 argument + arg1 := os.Args[1] + // Check if the argument is likely a URL from a custom protocol invocation + if strings.Contains(arg1, "://") { + a.parent.debug("Application launched with argument, potentially a URL from custom protocol", "url", arg1) + eventContext := newApplicationEventContext() + eventContext.setURL(arg1) + applicationEvents <- &ApplicationEvent{ + Id: uint(events.Common.ApplicationLaunchedWithUrl), + ctx: eventContext, + } + } else { + // Check if the argument matches any file associations + matched := false + if a.parent.options.FileAssociations != nil { + ext := filepath.Ext(arg1) + if slices.Contains(a.parent.options.FileAssociations, ext) { + a.parent.debug("File opened via file association", "file", arg1, "extension", ext) + eventContext := newApplicationEventContext() + eventContext.setOpenedWithFile(arg1) + applicationEvents <- &ApplicationEvent{ + Id: uint(events.Common.ApplicationOpenedWithFile), + ctx: eventContext, + } + matched = true + } + } + if !matched { + a.parent.debug("Application launched with single argument (not a URL), potential file open?", "arg", arg1) + } + } + } else if len(os.Args) > 2 { + // Log if multiple arguments are passed + a.parent.debug("Application launched with multiple arguments", "args", os.Args[1:]) + } + a.parent.Event.OnApplicationEvent(events.Linux.ApplicationStartup, func(evt *ApplicationEvent) { if err := a.processAndCacheScreens(); err != nil { a.parent.handleError(err) From 3b285cb31b3ba83e767e2ad3b71bbab6de8b3c3f Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Wed, 19 Aug 2026 22:00:02 +1000 Subject: [PATCH 2/2] fix(v3/linux): avoid logging launch arguments --- v3/pkg/application/application_linux.go | 36 +++++++------------------ 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/v3/pkg/application/application_linux.go b/v3/pkg/application/application_linux.go index 89d8c6a1eb6..6ecd09c03f4 100644 --- a/v3/pkg/application/application_linux.go +++ b/v3/pkg/application/application_linux.go @@ -88,44 +88,26 @@ func (a *linuxApp) name() string { } func (a *linuxApp) run() error { - // Inspect argv the same way the GTK3 host and the Windows host do. - // g_application_run is invoked with argc=0, so GApplication never sees - // the launch argument; custom-protocol URLs and file associations are - // delivered only through this check. - if len(os.Args) == 2 { // Case: program + 1 argument + if len(os.Args) == 2 { arg1 := os.Args[1] - // Check if the argument is likely a URL from a custom protocol invocation if strings.Contains(arg1, "://") { - a.parent.debug("Application launched with argument, potentially a URL from custom protocol", "url", arg1) eventContext := newApplicationEventContext() eventContext.setURL(arg1) applicationEvents <- &ApplicationEvent{ Id: uint(events.Common.ApplicationLaunchedWithUrl), ctx: eventContext, } - } else { - // Check if the argument matches any file associations - matched := false - if a.parent.options.FileAssociations != nil { - ext := filepath.Ext(arg1) - if slices.Contains(a.parent.options.FileAssociations, ext) { - a.parent.debug("File opened via file association", "file", arg1, "extension", ext) - eventContext := newApplicationEventContext() - eventContext.setOpenedWithFile(arg1) - applicationEvents <- &ApplicationEvent{ - Id: uint(events.Common.ApplicationOpenedWithFile), - ctx: eventContext, - } - matched = true + } else if a.parent.options.FileAssociations != nil { + ext := filepath.Ext(arg1) + if slices.Contains(a.parent.options.FileAssociations, ext) { + eventContext := newApplicationEventContext() + eventContext.setOpenedWithFile(arg1) + applicationEvents <- &ApplicationEvent{ + Id: uint(events.Common.ApplicationOpenedWithFile), + ctx: eventContext, } } - if !matched { - a.parent.debug("Application launched with single argument (not a URL), potential file open?", "arg", arg1) - } } - } else if len(os.Args) > 2 { - // Log if multiple arguments are passed - a.parent.debug("Application launched with multiple arguments", "args", os.Args[1:]) } a.parent.Event.OnApplicationEvent(events.Linux.ApplicationStartup, func(evt *ApplicationEvent) {