added troubleshooting
This commit is contained in:
@@ -3,4 +3,4 @@
|
|||||||
Name = "TurtleSilicon"
|
Name = "TurtleSilicon"
|
||||||
ID = "com.tairasu.turtlesilicon"
|
ID = "com.tairasu.turtlesilicon"
|
||||||
Version = "1.2.2"
|
Version = "1.2.2"
|
||||||
Build = 58
|
Build = 65
|
||||||
|
1
go.mod
1
go.mod
@@ -42,4 +42,5 @@ require (
|
|||||||
golang.org/x/sys v0.30.0 // indirect
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
golang.org/x/text v0.22.0 // indirect
|
golang.org/x/text v0.22.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
|
howett.net/plist v1.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
4
go.sum
4
go.sum
@@ -47,6 +47,7 @@ github.com/hack-pad/safejs v0.1.0 h1:qPS6vjreAqh2amUqj4WNG1zIw7qlRQJ9K10eDKMCnE8
|
|||||||
github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
github.com/hack-pad/safejs v0.1.0/go.mod h1:HdS+bKF1NrE72VoXZeWzxFOVQVUSqZJAG0xNCnb+Tio=
|
||||||
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 h1:wMeVzrPO3mfHIWLZtDcSaGAe2I4PW9B/P5nMkRSwCAc=
|
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08 h1:wMeVzrPO3mfHIWLZtDcSaGAe2I4PW9B/P5nMkRSwCAc=
|
||||||
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
github.com/jeandeaual/go-locale v0.0.0-20241217141322-fcc2cadd6f08/go.mod h1:ZDXo8KHryOWSIqnsb/CiDq7hQUYryCgdVnxbj8tDG7o=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
|
||||||
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
@@ -86,5 +87,8 @@ golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
|||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
||||||
|
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||||
|
@@ -142,6 +142,11 @@ func createBottomBar(myWindow fyne.Window) fyne.CanvasObject {
|
|||||||
showOptionsPopup()
|
showOptionsPopup()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Troubleshooting button
|
||||||
|
troubleshootingButton = widget.NewButton("Troubleshooting", func() {
|
||||||
|
showTroubleshootingPopup()
|
||||||
|
})
|
||||||
|
|
||||||
// GitHub button
|
// GitHub button
|
||||||
githubButton := widget.NewButton("GitHub", func() {
|
githubButton := widget.NewButton("GitHub", func() {
|
||||||
githubURL := "https://github.com/tairasu/TurtleSilicon"
|
githubURL := "https://github.com/tairasu/TurtleSilicon"
|
||||||
@@ -168,7 +173,7 @@ func createBottomBar(myWindow fyne.Window) fyne.CanvasObject {
|
|||||||
|
|
||||||
leftButtons := container.NewHBox(
|
leftButtons := container.NewHBox(
|
||||||
optionsButton,
|
optionsButton,
|
||||||
widget.NewSeparator(), // Visual separator
|
troubleshootingButton,
|
||||||
githubButton,
|
githubButton,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
160
pkg/ui/popup.go
160
pkg/ui/popup.go
@@ -1,9 +1,20 @@
|
|||||||
package ui
|
package ui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"fyne.io/fyne/v2"
|
"fyne.io/fyne/v2"
|
||||||
"fyne.io/fyne/v2/container"
|
"fyne.io/fyne/v2/container"
|
||||||
|
"fyne.io/fyne/v2/dialog"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
|
|
||||||
|
"howett.net/plist"
|
||||||
|
|
||||||
|
"turtlesilicon/pkg/paths"
|
||||||
|
"turtlesilicon/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// showOptionsPopup creates and shows an integrated popup window for options
|
// showOptionsPopup creates and shows an integrated popup window for options
|
||||||
@@ -123,3 +134,152 @@ func showRemapWarningPopup() {
|
|||||||
|
|
||||||
warningPopup.Show()
|
warningPopup.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// showTroubleshootingPopup creates and shows a popup window for troubleshooting actions
|
||||||
|
func showTroubleshootingPopup() {
|
||||||
|
if currentWindow == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- CrossOver Version Check ---
|
||||||
|
crossoverVersion := getCrossoverVersion(paths.CrossoverPath)
|
||||||
|
var crossoverStatusShort *widget.Label
|
||||||
|
var crossoverStatusDetail *widget.Label
|
||||||
|
if crossoverVersion == "" {
|
||||||
|
crossoverStatusShort = widget.NewLabel("Not found")
|
||||||
|
crossoverStatusDetail = widget.NewLabel("")
|
||||||
|
} else if isCrossoverVersionRecommended(crossoverVersion) {
|
||||||
|
crossoverStatusShort = widget.NewLabelWithStyle("✔ "+crossoverVersion, fyne.TextAlignTrailing, fyne.TextStyle{Bold: true})
|
||||||
|
crossoverStatusDetail = widget.NewLabelWithStyle("✔ Recommended version of CrossOver installed", fyne.TextAlignLeading, fyne.TextStyle{Italic: true})
|
||||||
|
} else {
|
||||||
|
crossoverStatusShort = widget.NewLabelWithStyle("⚠️ "+crossoverVersion, fyne.TextAlignTrailing, fyne.TextStyle{Italic: true})
|
||||||
|
crossoverStatusDetail = widget.NewLabelWithStyle("⚠️ Please update to CrossOver 25.0.1 or later!", fyne.TextAlignLeading, fyne.TextStyle{Italic: true})
|
||||||
|
}
|
||||||
|
crossoverStatusDetail.Wrapping = fyne.TextWrapWord
|
||||||
|
|
||||||
|
// --- Delete WDB Directory ---
|
||||||
|
wdbDeleteButton = widget.NewButton("Delete", func() {
|
||||||
|
wdbPath := filepath.Join(paths.TurtlewowPath, "WDB")
|
||||||
|
if !utils.DirExists(wdbPath) {
|
||||||
|
dialog.ShowInformation("WDB Not Found", "No WDB directory found in your TurtleWoW folder.", currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dialog.NewConfirm("Delete WDB Directory", "Are you sure you want to delete the WDB directory? This will remove all cached data. No important data will be lost.", func(confirm bool) {
|
||||||
|
if confirm {
|
||||||
|
err := os.RemoveAll(wdbPath)
|
||||||
|
if err != nil {
|
||||||
|
dialog.ShowError(fmt.Errorf("Failed to delete WDB: %v", err), currentWindow)
|
||||||
|
} else {
|
||||||
|
dialog.ShowInformation("WDB Deleted", "WDB directory deleted successfully.", currentWindow)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, currentWindow).Show()
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- Delete Wine Prefixes ---
|
||||||
|
wineDeleteButton = widget.NewButton("Delete", func() {
|
||||||
|
homeDir, _ := os.UserHomeDir()
|
||||||
|
userWine := filepath.Join(homeDir, ".wine")
|
||||||
|
turtleWine := filepath.Join(paths.TurtlewowPath, ".wine")
|
||||||
|
msg := "Are you sure you want to delete the following Wine prefixes?\n\n- " + userWine + "\n- " + turtleWine + "\n\nThis cannot be undone."
|
||||||
|
dialog.NewConfirm("Delete Wine Prefixes", msg, func(confirm bool) {
|
||||||
|
if confirm {
|
||||||
|
err1 := os.RemoveAll(userWine)
|
||||||
|
err2 := os.RemoveAll(turtleWine)
|
||||||
|
if err1 != nil && !os.IsNotExist(err1) {
|
||||||
|
dialog.ShowError(fmt.Errorf("Failed to delete ~/.wine: %v", err1), currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err2 != nil && !os.IsNotExist(err2) {
|
||||||
|
dialog.ShowError(fmt.Errorf("Failed to delete TurtleWoW/.wine: %v", err2), currentWindow)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dialog.ShowInformation("Wine Prefixes Deleted", "Wine prefixes deleted successfully.", currentWindow)
|
||||||
|
}
|
||||||
|
}, currentWindow).Show()
|
||||||
|
})
|
||||||
|
|
||||||
|
troubleshootingTitle := widget.NewLabel("Troubleshooting")
|
||||||
|
troubleshootingTitle.TextStyle = fyne.TextStyle{Bold: true}
|
||||||
|
|
||||||
|
rowCrossover := container.NewBorder(nil, nil, widget.NewLabel("CrossOver version:"), crossoverStatusShort, nil)
|
||||||
|
rowWDB := container.NewBorder(nil, nil, widget.NewLabel("Delete WDB directory (cache):"), wdbDeleteButton, nil)
|
||||||
|
rowWine := container.NewBorder(nil, nil, widget.NewLabel("Delete Wine prefixes (~/.wine & TurtleWoW/.wine):"), wineDeleteButton, nil)
|
||||||
|
appMgmtNote := widget.NewLabel("Please ensure TurtleSilicon is enabled in System Settings > Privacy & Security > App Management.")
|
||||||
|
appMgmtNote.Wrapping = fyne.TextWrapWord
|
||||||
|
appMgmtNote.TextStyle = fyne.TextStyle{Italic: true}
|
||||||
|
|
||||||
|
content := container.NewVBox(
|
||||||
|
troubleshootingTitle,
|
||||||
|
widget.NewSeparator(),
|
||||||
|
rowCrossover,
|
||||||
|
crossoverStatusDetail,
|
||||||
|
rowWDB,
|
||||||
|
rowWine,
|
||||||
|
appMgmtNote,
|
||||||
|
)
|
||||||
|
|
||||||
|
scrollContainer := container.NewScroll(content)
|
||||||
|
|
||||||
|
troubleshootingCloseButton = widget.NewButton("Close", func() {})
|
||||||
|
|
||||||
|
popupContent := container.NewBorder(
|
||||||
|
nil, // top
|
||||||
|
container.NewCenter(troubleshootingCloseButton), // bottom
|
||||||
|
nil, // left
|
||||||
|
nil, // right
|
||||||
|
container.NewPadded(scrollContainer), // center
|
||||||
|
)
|
||||||
|
|
||||||
|
windowSize := currentWindow.Content().Size()
|
||||||
|
popupWidth := windowSize.Width * 5 / 6
|
||||||
|
popupHeight := windowSize.Height * 5 / 6
|
||||||
|
|
||||||
|
popup := widget.NewModalPopUp(popupContent, currentWindow.Canvas())
|
||||||
|
popup.Resize(fyne.NewSize(popupWidth, popupHeight))
|
||||||
|
|
||||||
|
troubleshootingCloseButton.OnTapped = func() {
|
||||||
|
popup.Hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCrossoverVersion reads the Info.plist and returns the version string, or "" if not found
|
||||||
|
func getCrossoverVersion(appPath string) string {
|
||||||
|
if appPath == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
plistPath := filepath.Join(appPath, "Contents", "Info.plist")
|
||||||
|
f, err := os.Open(plistPath)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
var data struct {
|
||||||
|
Version string `plist:"CFBundleShortVersionString"`
|
||||||
|
}
|
||||||
|
decoder := plist.NewDecoder(f)
|
||||||
|
if err := decoder.Decode(&data); err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return data.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
// isCrossoverVersionRecommended returns true if version >= 25.0.1
|
||||||
|
func isCrossoverVersionRecommended(version string) bool {
|
||||||
|
parts := strings.Split(version, ".")
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
major := parts[0]
|
||||||
|
minor := parts[1]
|
||||||
|
patch := parts[2]
|
||||||
|
if major > "25" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if major == "25" && minor >= "0" && patch >= "1" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@@ -53,4 +53,13 @@ var (
|
|||||||
|
|
||||||
// Pulsing effect variables (pulsingActive is in status.go)
|
// Pulsing effect variables (pulsingActive is in status.go)
|
||||||
pulsingTicker *time.Ticker
|
pulsingTicker *time.Ticker
|
||||||
|
|
||||||
|
// Troubleshooting popup and controls
|
||||||
|
troubleshootingButton *widget.Button
|
||||||
|
troubleshootingPopupActive bool
|
||||||
|
crossoverVersionStatusLabel *widget.RichText
|
||||||
|
wdbDeleteButton *widget.Button
|
||||||
|
wineDeleteButton *widget.Button
|
||||||
|
appMgmtPermissionButton *widget.Button
|
||||||
|
troubleshootingCloseButton *widget.Button
|
||||||
)
|
)
|
||||||
|
Reference in New Issue
Block a user