github.com/secoba/wails/v2@v2.6.4/internal/frontend/desktop/linux/single_instance.go (about) 1 //go:build linux 2 // +build linux 3 4 package linux 5 6 import ( 7 "encoding/json" 8 "github.com/godbus/dbus/v5" 9 "github.com/secoba/wails/v2/pkg/options" 10 "os" 11 "strings" 12 ) 13 14 type dbusHandler func(string) 15 16 func (f dbusHandler) SendMessage(message string) *dbus.Error { 17 f(message) 18 return nil 19 } 20 21 func SetupSingleInstance(uniqueID string) { 22 id := "wails_app_" + strings.ReplaceAll(strings.ReplaceAll(uniqueID, "-", "_"), ".", "_") 23 24 dbusName := "org." + id + ".SingleInstance" 25 dbusPath := "/org/" + id + "/SingleInstance" 26 27 conn, err := dbus.ConnectSessionBus() 28 // if we will reach any error during establishing connection or sending message we will just continue. 29 // It should not be the case that such thing will happen actually, but just in case. 30 if err != nil { 31 return 32 } 33 34 f := dbusHandler(func(message string) { 35 var secondInstanceData options.SecondInstanceData 36 37 err := json.Unmarshal([]byte(message), &secondInstanceData) 38 if err == nil { 39 secondInstanceBuffer <- secondInstanceData 40 } 41 }) 42 43 err = conn.Export(f, dbus.ObjectPath(dbusPath), dbusName) 44 if err != nil { 45 return 46 } 47 48 reply, err := conn.RequestName(dbusName, dbus.NameFlagDoNotQueue) 49 if err != nil { 50 return 51 } 52 53 // if name already taken, try to send args to existing instance, if no success just launch new instance 54 if reply == dbus.RequestNameReplyExists { 55 data := options.SecondInstanceData{ 56 Args: os.Args[1:], 57 } 58 serialized, err := json.Marshal(data) 59 if err != nil { 60 return 61 } 62 63 err = conn.Object(dbusName, dbus.ObjectPath(dbusPath)).Call(dbusName+".SendMessage", 0, string(serialized)).Store() 64 if err != nil { 65 return 66 } 67 os.Exit(1) 68 } 69 }