github.com/AlpineAIO/wails/v2@v2.0.0-beta.32.0.20240505041856-1047a8fa5fef/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/AlpineAIO/wails/v2/pkg/options" 9 "github.com/godbus/dbus/v5" 10 "log" 11 "os" 12 "strings" 13 ) 14 15 type dbusHandler func(string) 16 17 func (f dbusHandler) SendMessage(message string) *dbus.Error { 18 f(message) 19 return nil 20 } 21 22 func SetupSingleInstance(uniqueID string) { 23 id := "wails_app_" + strings.ReplaceAll(strings.ReplaceAll(uniqueID, "-", "_"), ".", "_") 24 25 dbusName := "org." + id + ".SingleInstance" 26 dbusPath := "/org/" + id + "/SingleInstance" 27 28 conn, err := dbus.ConnectSessionBus() 29 // if we will reach any error during establishing connection or sending message we will just continue. 30 // It should not be the case that such thing will happen actually, but just in case. 31 if err != nil { 32 return 33 } 34 35 f := dbusHandler(func(message string) { 36 var secondInstanceData options.SecondInstanceData 37 38 err := json.Unmarshal([]byte(message), &secondInstanceData) 39 if err == nil { 40 secondInstanceBuffer <- secondInstanceData 41 } 42 }) 43 44 err = conn.Export(f, dbus.ObjectPath(dbusPath), dbusName) 45 if err != nil { 46 return 47 } 48 49 reply, err := conn.RequestName(dbusName, dbus.NameFlagDoNotQueue) 50 if err != nil { 51 return 52 } 53 54 // if name already taken, try to send args to existing instance, if no success just launch new instance 55 if reply == dbus.RequestNameReplyExists { 56 data := options.SecondInstanceData{ 57 Args: os.Args[1:], 58 } 59 data.WorkingDirectory, err = os.Getwd() 60 if err != nil { 61 log.Printf("Failed to get working directory: %v", err) 62 return 63 } 64 65 serialized, err := json.Marshal(data) 66 if err != nil { 67 log.Printf("Failed to marshal data: %v", err) 68 return 69 } 70 71 err = conn.Object(dbusName, dbus.ObjectPath(dbusPath)).Call(dbusName+".SendMessage", 0, string(serialized)).Store() 72 if err != nil { 73 return 74 } 75 os.Exit(1) 76 } 77 }