Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When last visible window is closed, hidden window is set visible #3059

Closed
d1ss0nanz opened this issue Jun 10, 2022 · 12 comments
Closed

When last visible window is closed, hidden window is set visible #3059

d1ss0nanz opened this issue Jun 10, 2022 · 12 comments
Labels
bug Something isn't working

Comments

@d1ss0nanz
Copy link
Contributor

Describe the bug:

I'm looking for a reliable way to have a systray app that has no visible window.
When there is no hidden window, the app closes after the last visible window is closed.
If there is a hidden window left, the hidden window is set visible when the last visible window is closed.

To Reproduce:

Steps to reproduce the behaviour:

  1. Click "Hide Top Window..." in the systray menu
  2. Click "Show Info..." in the systray menu
  3. Close the info dialog window
  4. The Top Window is made visible (why?)

Please: Either don't make the top window visible or add an option to not close the app when a systray is running.

Example code:

package main

import (
	"fmt"
	"image/color"
	"log"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/canvas"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/driver/desktop"
	"fyne.io/fyne/v2/theme"
)

var topWindow fyne.Window

func main() {
	a := app.NewWithID("io.fyne.demo")
	a.SetIcon(theme.FyneLogo())
	makeTray(a)
	topWindow = a.NewWindow("Top Window")
	topWindow.SetContent(canvas.NewText("Test", color.Gray{}))
	topWindow.Show()
	a.Run()
}

func makeTray(a fyne.App) {
	if desk, ok := a.(desktop.App); ok {
		hideTopWindowMenuItem := fyne.NewMenuItem("Hide Top Window...", func() {})
		hideTopWindowMenuItem.Action = func() {
			log.Println("Hide Top Window systray menu tapped")
			topWindow.Hide()
		}
		showInfoMenuItem := fyne.NewMenuItem("Show Info...", func() {})
		showInfoMenuItem.Action = func() {
			log.Println("Show Info systray menu tapped")
			showInfo("Info", "test")
		}

		items := []*fyne.MenuItem{hideTopWindowMenuItem, showInfoMenuItem}
		menu := fyne.NewMenu("Hello World", items...)
		desk.SetSystemTrayMenu(menu)
	}
}

var windowCounter = 0

func showInfo(title, msg string) {
	count := windowCounter
	windowCounter++
	fmt.Printf("creating window: %d\n", count)
	infoWindow := fyne.CurrentApp().NewWindow("XplicitTrust Network Access")
	d := dialog.NewInformation(title, msg, infoWindow)
	d.SetOnClosed(func() {
		fmt.Printf("closing window: %d\n", count)
		infoWindow.Close()
	})
	infoWindow.Resize(d.MinSize())
	infoWindow.Show()
	d.Show()
}

Device (please complete the following information):

  • OS: MacOS
  • Version: 12.4
  • Go version: 1.17
  • Fyne version: fyne.io/fyne/v2@d0d3ce25
@d1ss0nanz d1ss0nanz added the unverified A bug that has been reported but not verified label Jun 10, 2022
@andydotxyz andydotxyz added bug Something isn't working and removed unverified A bug that has been reported but not verified labels Jun 15, 2022
@andydotxyz andydotxyz added this to the Fixes (v2.2.x) milestone Jun 15, 2022
@andydotxyz
Copy link
Member

Wow this is super weird. Thanks for the clear steps to replicate.

@andydotxyz
Copy link
Member

Interestingly the following code has no effect as the handler is attached to d instead of infoWindow but fixing that makes no diffference:

	d.SetOnClosed(func() {
		fmt.Printf("closing window: %d\n", count)
		infoWindow.Close()
	})

@d1ss0nanz
Copy link
Contributor Author

The SetOnClosed is is intentionally set on d, to close the window when the dialog closes.

@andydotxyz
Copy link
Member

Ah thanks, I misunderstood because of the Printf placement, but that makes sense.

@andydotxyz
Copy link
Member

I notice also that the window which returns is not "alive" so it is not being shown with any purpose, Fyne seems to not be aware that the content is visible again. I wonder if we may have uncovered something relating to GLFW...

@d1ss0nanz
Copy link
Contributor Author

And maybe that behavior is correct? I mean a systray app is conceptually having the systray icon as main window.
Normal apps should have a active window that has content.

@andydotxyz
Copy link
Member

Nope there is certainly something wrong. The window that appears is not alive.
Fyne thinks that it is hidden.
Somehow something underneath Fyne is re-showing it...

@andydotxyz
Copy link
Member

I have made this minimal example... tap the button will show window 2, close the first one to hide it then close the new one and we see a zombee window...

package main

import (
	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
)

var topWindow fyne.Window

func main() {
	a := app.NewWithID("io.fyne.demo")
	a.SetIcon(theme.FyneLogo())
	topWindow = a.NewWindow("Top Window")
	topWindow.SetContent(widget.NewButton("Open info", showInfo))
	topWindow.SetCloseIntercept(func() {
		topWindow.Hide()
	})
	topWindow.Show()
	a.Run()
}

func showInfo() {
	infoWindow := fyne.CurrentApp().NewWindow("Another")
	infoWindow.SetContent(widget.NewLabel("Second"))
	infoWindow.Show()
}

@d1ss0nanz
Copy link
Contributor Author

d1ss0nanz commented Jun 22, 2022

Could the issue be, that focusPreviousWindow is called, that calls RequestFocus on darwin, without checking if the chosen window is visible?

@andydotxyz
Copy link
Member

Oh goodness you are right thanks @d1ss0nanz.
Probably the focusPreviousWindow should know that a window has been hidden and ignore it like those that were closed...

@d1ss0nanz
Copy link
Contributor Author

d1ss0nanz commented Jun 22, 2022

#3093

@andydotxyz
Copy link
Member

Rolling out on v2.2.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants