mirror of
https://github.com/jahruz67/wisp-open.git
synced 2026-08-08 18:14:08 +00:00
2
This commit is contained in:
@@ -74,6 +74,14 @@ func (a *App) startup(ctx context.Context) {
|
|||||||
// Initialize components
|
// Initialize components
|
||||||
a.startupHeadless()
|
a.startupHeadless()
|
||||||
|
|
||||||
|
// When the user launches the app again while it is already running (tray-only),
|
||||||
|
// the second process signals us here so the settings window becomes visible.
|
||||||
|
go func() {
|
||||||
|
for range secondInstanceWake {
|
||||||
|
wailsruntime.WindowShow(ctx)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
// Start system tray in a goroutine
|
// Start system tray in a goroutine
|
||||||
go tray.Start(a)
|
go tray.Start(a)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,7 +134,5 @@ func getLogPath() (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return filepath.Join(homeDir, ".wis-free-v3", "logs"), nil
|
return filepath.Join(homeDir, ".wis-free-v3", "logs", time.Now().Format("2006-01-02")+".log"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,8 +48,13 @@ func main() {
|
|||||||
|
|
||||||
// Ensure only one instance of the application is running
|
// Ensure only one instance of the application is running
|
||||||
if !acquireInstanceLock() {
|
if !acquireInstanceLock() {
|
||||||
|
// Another copy is already running (often left in the tray). Without this,
|
||||||
|
// we would exit silently and the user sees "nothing happens" when clicking
|
||||||
|
// the launcher again.
|
||||||
|
tryNotifyRunningInstanceToShow()
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
|
runSecondInstanceListener()
|
||||||
|
|
||||||
// Initialize the application
|
// Initialize the application
|
||||||
app := NewApp()
|
app := NewApp()
|
||||||
@@ -64,9 +69,7 @@ func main() {
|
|||||||
OnStartup: app.startup,
|
OnStartup: app.startup,
|
||||||
OnShutdown: app.Shutdown,
|
OnShutdown: app.Shutdown,
|
||||||
OnBeforeClose: app.beforeClose,
|
OnBeforeClose: app.beforeClose,
|
||||||
// On Linux, starting hidden makes it look like "nothing happens" if the tray icon
|
StartHidden: true,
|
||||||
// fails to initialize (missing libayatana-appindicator, etc) or is hidden by the DE.
|
|
||||||
StartHidden: runtime.GOOS == "windows",
|
|
||||||
Bind: []interface{}{app},
|
Bind: []interface{}{app},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -147,6 +150,3 @@ func getLockPath() (string, error) {
|
|||||||
}
|
}
|
||||||
return filepath.Join(homeDir, configDir, lockFile), nil
|
return filepath.Join(homeDir, configDir, lockFile), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
//go:build windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
// secondInstanceWake is unused on Windows (second-instance UX not wired here).
|
||||||
|
var secondInstanceWake = make(chan struct{}, 8)
|
||||||
|
|
||||||
|
func tryNotifyRunningInstanceToShow() {}
|
||||||
|
|
||||||
|
func runSecondInstanceListener() {}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
//go:build unix && !windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const instanceSockName = "instance.sock"
|
||||||
|
|
||||||
|
// secondInstanceWake is closed when a second process asks the running app to show its window.
|
||||||
|
var secondInstanceWake = make(chan struct{}, 8)
|
||||||
|
|
||||||
|
func instanceSocketPath() (string, error) {
|
||||||
|
home, err := os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(home, configDir, instanceSockName), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func tryNotifyRunningInstanceToShow() {
|
||||||
|
path, err := instanceSocketPath()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c, err := net.DialTimeout("unix", path, 500*time.Millisecond)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
_, _ = c.Write([]byte{1})
|
||||||
|
}
|
||||||
|
|
||||||
|
func runSecondInstanceListener() {
|
||||||
|
path, err := instanceSocketPath()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = os.Remove(path)
|
||||||
|
l, err := net.Listen("unix", path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
c, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
_, _ = io.Copy(io.Discard, conn)
|
||||||
|
select {
|
||||||
|
case secondInstanceWake <- struct{}{}:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}(c)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
@@ -150,12 +150,15 @@ if [[ "$INSTALL" == "y" || "$INSTALL" == "Y" ]]; then
|
|||||||
sudo cp "build/appicon.png" "$ICON_PATH"
|
sudo cp "build/appicon.png" "$ICON_PATH"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Absolute Exec path: some desktop environments do not put /usr/local/bin on PATH
|
||||||
|
# for .desktop launches, so "Exec=wis-free-v3" can fail with no visible error.
|
||||||
cat << EOF > /tmp/$APP_NAME.desktop
|
cat << EOF > /tmp/$APP_NAME.desktop
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
Type=Application
|
Type=Application
|
||||||
Name=WIS Free V3
|
Name=WIS Free V3
|
||||||
Comment=Voice Dictation App
|
Comment=Voice Dictation App
|
||||||
Exec=$APP_NAME
|
Exec=/usr/local/bin/$APP_NAME
|
||||||
|
TryExec=/usr/local/bin/$APP_NAME
|
||||||
Icon=$APP_NAME
|
Icon=$APP_NAME
|
||||||
Terminal=false
|
Terminal=false
|
||||||
Categories=Utility;Audio;
|
Categories=Utility;Audio;
|
||||||
|
|||||||
Reference in New Issue
Block a user