Nasin now counts application windows to determine when to shut down
This commit is contained in:
		
							parent
							
								
									bc26e78024
								
							
						
					
					
						commit
						7da00e990e
					
				
							
								
								
									
										126
									
								
								application.go
									
									
									
									
									
								
							
							
						
						
									
										126
									
								
								application.go
									
									
									
									
									
								
							@ -15,8 +15,9 @@ type Application interface {
 | 
			
		||||
	// Describe returns a description of the application.
 | 
			
		||||
	Describe () ApplicationDescription
 | 
			
		||||
 | 
			
		||||
	// Init performs the initial setup of the application.
 | 
			
		||||
	Init () error
 | 
			
		||||
	// Init performs the initial setup of the application. This behavior
 | 
			
		||||
	// should return a window if it creates one.
 | 
			
		||||
	Init () (tomo.Window, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ApplicationURLOpener is an application that can open a URL.
 | 
			
		||||
@ -29,12 +30,15 @@ type ApplicationURLOpener interface {
 | 
			
		||||
	//
 | 
			
		||||
	// Applications should support the file:// scheme at the very least, and
 | 
			
		||||
	// 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
 | 
			
		||||
	// to open. The application may create some sort of default starting
 | 
			
		||||
	// window, or call tomo.Stop().
 | 
			
		||||
	OpenNone ()
 | 
			
		||||
	// window, or do nothing. This behavior should return a window if it
 | 
			
		||||
	// creates one.
 | 
			
		||||
	OpenNone () (tomo.Window, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ApplicationFlagAdder is an application that supports reading command line
 | 
			
		||||
@ -148,14 +152,18 @@ func RunApplication (application Application) {
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not set icon set:", err) }
 | 
			
		||||
	err = reg.SetFaceSet()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not set face set:", err) }
 | 
			
		||||
	err = application.Init()
 | 
			
		||||
	window, err := application.Init()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not run application:", err) }
 | 
			
		||||
	manageWindow(window)
 | 
			
		||||
 | 
			
		||||
	// open URLs
 | 
			
		||||
	args := flag.Args()
 | 
			
		||||
	applicationOpenUrls(application, args...)
 | 
			
		||||
	err = backend.Run()
 | 
			
		||||
	if err != nil { log.Fatalln("nasin: could not run application:", err) }
 | 
			
		||||
 | 
			
		||||
	if windows > 0 {
 | 
			
		||||
		err = backend.Run()
 | 
			
		||||
		if err != nil { log.Fatalln("nasin: could not run application:", err) }
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewApplicationWindow creates a window for an application. It will
 | 
			
		||||
@ -173,44 +181,80 @@ func NewApplicationWindow (application Application, bounds image.Rectangle) (tom
 | 
			
		||||
	return window, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func applicationOpenUrls (application Application, args ...string) {
 | 
			
		||||
	if application, ok := application.(ApplicationURLOpener); ok {
 | 
			
		||||
		if len(args) <= 0 {
 | 
			
		||||
			application.OpenNone()
 | 
			
		||||
		}
 | 
			
		||||
var windows int
 | 
			
		||||
 | 
			
		||||
		openedAny := false
 | 
			
		||||
		for _, arg := range flag.Args() {
 | 
			
		||||
			ur, err := url.Parse(arg)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				log.Fatalf (
 | 
			
		||||
					"nasin: invalid URL %v: %v",
 | 
			
		||||
					arg, err)
 | 
			
		||||
			}
 | 
			
		||||
			if ur.Scheme == "" {
 | 
			
		||||
				ur.Scheme = "file"
 | 
			
		||||
			}
 | 
			
		||||
			err = application.OpenURL(ur)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				dialog, err := objects.NewDialogOk (
 | 
			
		||||
					objects.DialogError, nil,
 | 
			
		||||
					"Could Not Open URL",
 | 
			
		||||
					fmt.Sprintf (
 | 
			
		||||
						"Could not open %v: %v",
 | 
			
		||||
						arg, err),
 | 
			
		||||
					func () {
 | 
			
		||||
						if !openedAny {
 | 
			
		||||
							application.OpenNone()
 | 
			
		||||
						}
 | 
			
		||||
					})
 | 
			
		||||
				if err != nil { log.Fatal(err) }
 | 
			
		||||
				dialog.SetVisible(true)
 | 
			
		||||
			}
 | 
			
		||||
func manageWindow (window tomo.Window) {
 | 
			
		||||
	if window == nil { return }
 | 
			
		||||
	windows ++
 | 
			
		||||
	window.OnClose(func () {
 | 
			
		||||
		windows --
 | 
			
		||||
		if windows < 1 {
 | 
			
		||||
			tomo.Stop()
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func errorPopupf (title, format string, v ...any) func (func ()) {
 | 
			
		||||
	return func (callback func ()) {
 | 
			
		||||
		dialog, err := objects.NewDialogOk (
 | 
			
		||||
			objects.DialogError, nil,
 | 
			
		||||
			title,
 | 
			
		||||
			fmt.Sprintf(format, v...),
 | 
			
		||||
			callback)
 | 
			
		||||
		if err != nil { log.Fatal(err) }
 | 
			
		||||
		dialog.SetVisible(true)
 | 
			
		||||
		manageWindow(dialog)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func applicationOpenUrls (app Application, args ...string) {
 | 
			
		||||
	application, ok := app.(ApplicationURLOpener)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		if len(args) > 0 {
 | 
			
		||||
			log.Fatal("nasin: this application cannot open URLs")
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	openNone := func () bool {
 | 
			
		||||
		window, err := application.OpenNone()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalf("nasin: could not open main window: %v", err)
 | 
			
		||||
			return false
 | 
			
		||||
		}
 | 
			
		||||
		manageWindow(window)
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if len(args) <= 0 {
 | 
			
		||||
		openNone()
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	openedAny := false
 | 
			
		||||
	for _, arg := range flag.Args() {
 | 
			
		||||
		ur, err := url.Parse(arg)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			log.Fatalf (
 | 
			
		||||
				"nasin: invalid URL %v: %v",
 | 
			
		||||
				arg, err)
 | 
			
		||||
		}
 | 
			
		||||
		if ur.Scheme == "" {
 | 
			
		||||
			ur.Scheme = "file"
 | 
			
		||||
		}
 | 
			
		||||
		window, err := application.OpenURL(ur)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			errorPopupf(
 | 
			
		||||
				"Could Not Open URL",
 | 
			
		||||
				"Could not open %v: %v",
 | 
			
		||||
				arg, err,
 | 
			
		||||
			)(func () {
 | 
			
		||||
				if !openedAny {
 | 
			
		||||
					openNone()
 | 
			
		||||
				}
 | 
			
		||||
			})
 | 
			
		||||
		}
 | 
			
		||||
		manageWindow(window)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user