Windows must be manually managed through the WaitFor function

Closes #5
This commit is contained in:
Sasha Koshka 2024-08-20 21:00:20 -04:00
parent 35636e9ca3
commit 92deac2d56
2 changed files with 44 additions and 31 deletions

View File

@ -15,9 +15,8 @@ type Application interface {
// Describe returns a description of the application. // Describe returns a description of the application.
Describe () ApplicationDescription Describe () ApplicationDescription
// Init performs the initial setup of the application. This behavior // Init performs the initial setup of the application.
// should return a window if it creates one. Init () (error)
Init () (tomo.Window, error)
// Stop stops the application and does not return until all ongoing // Stop stops the application and does not return until all ongoing
// operations have been completely shut down. // operations have been completely shut down.
@ -34,15 +33,11 @@ type ApplicationURLOpener interface {
// //
// Applications should support the file:// scheme at the very least, and // Applications should support the file:// scheme at the very least, and
// should also support others like http:// and https:// if possible. // should also support others like http:// and https:// if possible.
// OpenURL (*url.URL) error
// This behavior should return a window if it creates one.
OpenURL (*url.URL) (tomo.Window, error)
// OpenNone is called when the application is launched without any URLs // OpenNone is called when the application is launched without any URLs
// to open. The application may create some sort of default starting // to open.
// window, or do nothing. This behavior should return a window if it OpenNone () error
// creates one.
OpenNone () (tomo.Window, error)
} }
// ApplicationFlagAdder is an application that supports reading command line // ApplicationFlagAdder is an application that supports reading command line
@ -156,18 +151,18 @@ func RunApplication (application Application) {
if err != nil { log.Fatalln("nasin: could not set icon set:", err) } if err != nil { log.Fatalln("nasin: could not set icon set:", err) }
err = reg.SetFaceSet() err = reg.SetFaceSet()
if err != nil { log.Fatalln("nasin: could not set face set:", err) } if err != nil { log.Fatalln("nasin: could not set face set:", err) }
window, err := application.Init() err = application.Init()
if err != nil { log.Fatalln("nasin: could not run application:", err) } if err != nil { log.Fatalln("nasin: could not run application:", err) }
manageWindow(window)
// open URLs // open URLs
args := flag.Args() args := flag.Args()
applicationOpenUrls(application, args...) applicationOpenUrls(application, args...)
if windows > 0 { if manager.count > 0 {
err = backend.Run() err = backend.Run()
if err != nil { log.Fatalln("nasin: could not run application:", err) } if err != nil { log.Fatalln("nasin: could not run application:", err) }
} }
application.Stop()
} }
// NewApplicationWindow creates a window for an application. It will // NewApplicationWindow creates a window for an application. It will
@ -185,19 +180,6 @@ func NewApplicationWindow (application Application, bounds image.Rectangle) (tom
return window, nil return window, nil
} }
var windows int
func manageWindow (window tomo.Window) {
if window == nil { return }
windows ++
window.OnClose(func () {
windows --
if windows < 1 {
tomo.Stop()
}
})
}
func errorPopupf (title, format string, v ...any) func (func ()) { func errorPopupf (title, format string, v ...any) func (func ()) {
return func (callback func ()) { return func (callback func ()) {
dialog, err := objects.NewDialogOk ( dialog, err := objects.NewDialogOk (
@ -207,7 +189,7 @@ func errorPopupf (title, format string, v ...any) func (func ()) {
callback) callback)
if err != nil { log.Fatal(err) } if err != nil { log.Fatal(err) }
dialog.SetVisible(true) dialog.SetVisible(true)
manageWindow(dialog) WaitFor(dialog)
} }
} }
@ -221,12 +203,11 @@ func applicationOpenUrls (app Application, args ...string) {
} }
openNone := func () bool { openNone := func () bool {
window, err := application.OpenNone() err := application.OpenNone()
if err != nil { if err != nil {
log.Fatalf("nasin: could not open main window: %v", err) log.Fatalf("nasin: could not open main window: %v", err)
return false return false
} }
manageWindow(window)
return true return true
} }
@ -246,7 +227,7 @@ func applicationOpenUrls (app Application, args ...string) {
if ur.Scheme == "" { if ur.Scheme == "" {
ur.Scheme = "file" ur.Scheme = "file"
} }
window, err := application.OpenURL(ur) err = application.OpenURL(ur)
if err != nil { if err != nil {
errorPopupf( errorPopupf(
"Could Not Open URL", "Could Not Open URL",
@ -258,7 +239,6 @@ func applicationOpenUrls (app Application, args ...string) {
} }
}) })
} }
manageWindow(window)
} }
} }

33
manager.go Normal file
View File

@ -0,0 +1,33 @@
package nasin
import "git.tebibyte.media/tomo/tomo"
import "git.tebibyte.media/tomo/tomo/event"
var manager struct {
count int
}
type funcCookie func ()
func (cookie funcCookie) Close () {
cookie()
}
// WaitFor ensures that the application will stay running while the given window
// is open.
func WaitFor (window tomo.Window) event.Cookie {
manager.count ++
isManaged := true
handleClose := func () {
if !isManaged { return }
isManaged = false
manager.count --
if manager.count < 1 {
tomo.Stop()
}
}
return event.MultiCookie (
window.OnClose(handleClose),
funcCookie(handleClose))
}