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

Menu bar initially doesn't respond to mouse input on macOS #505

Closed
richardwilkes opened this issue Oct 28, 2019 · 16 comments
Closed

Menu bar initially doesn't respond to mouse input on macOS #505

richardwilkes opened this issue Oct 28, 2019 · 16 comments
Labels
bug Something isn't working OS:macOS Tickets affecting only macOS

Comments

@richardwilkes
Copy link

Describe the bug
Playing with the demo (commit 98fc45e) on macOS (catalina), the menu bar won’t respond to mouse clicks when launching it from the command line (admittedly not normal for a macOS app) until you switch to another app and come back.

To Reproduce
Steps to reproduce the behavior:

  1. cd cmd/fyne_demo
  2. go run main.go
  3. Try to click on the menu entries the demo app put up... none respond
  4. Switch to another app
  5. Switch back to the demo app
  6. Menu now responds to mouse input

Screenshots
If applicable, add screenshots to help explain your problem.

Device (please complete the following information):

  • OS: macOS
  • Version 10.15 (Catalina)
  • Go version 1.13.3
  • Fyne version 98fc45e
@andydotxyz andydotxyz added bug Something isn't working OS:macOS Tickets affecting only macOS labels Nov 6, 2019
@andydotxyz andydotxyz added the blocker Items that would block a forthcoming release label Mar 13, 2020
@toaster
Copy link
Member

toaster commented Mar 20, 2020

Hi, I'm on Mojave here and cannot reproduce this. Can anyone confirm the steps to reproduce this issue? And if so, on which OS version?

@andydotxyz
Copy link
Member

It only happens on Catalina. If you open a Fyne app it’s menu does not respond. Switch away and back again and it works ok.

@andydotxyz
Copy link
Member

I have since found out that if you package the app up the problem does not occur. So this is really only an issue for us developers. I may consider removing "Blocker" now...

@richardwilkes
Copy link
Author

Yes. I did mention it is only an issue when the executable is launched directly from the command line (i.e. not via the UI nor via the use of open, which ultimately behaves as if you opened the app from the UI). This is true whether packaged or not -- but I agree that no one should consider this a blocker.

@richardwilkes
Copy link
Author

I've found a workaround that you can use to fix this problem. First, you need a way to detect you're being launched without a bundle. The easiest way I could think of to do this is to determine if os.stdout was connected to a terminal. If it is, then issue a hide followed immediately by an unhide.

var termios syscall.Termios
if _, _, errno := syscall.Syscall6(syscall.SYS_IOCTL, os.Stdout.Fd(), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0); errno == 0 {
    hideApp() // needs to do this in native code: [[NSRunningApplication currentApplication] hide];
    unhideApp() // needs to do this in native code: [[NSRunningApplication currentApplication] unhide];
}

I do this right before entering the run loop.

@andydotxyz
Copy link
Member

This is really helpful thanks - let's see if we can find a nice way to work it in

@andydotxyz
Copy link
Member

I have coded something in (though I had to activate after unhide to get the window back on top.
Unfortunately the flicker it produces is noticeable.
Of course a flicker is better than not working... this may have to be extended so that it doesn't flicker on other systems so minimising the impact.

@andydotxyz
Copy link
Member

Calling this before the first window is shown:

void menuFix() {
    if ([[NSBundle mainBundle] bundleIdentifier] != nil) {
        return;
    }

    NSRunningApplication *app = [NSRunningApplication currentApplication];
    [app hide];
    [app unhide];
    [app activateWithOptions:NSApplicationActivateIgnoringOtherApps];
}

Not sure why it flickers as it should happen before shown, possibly needs more investigation.

@richardwilkes
Copy link
Author

I don't think you can do much, if anything, about the flicker, unfortunately. However, it should only be triggered if you are launching from the command-line (and not using open), so really should only affect developers. Much less annoying (for me, anyway), than having to manually switch to another app and back every time I try to debug something.

@andydotxyz
Copy link
Member

Short of a real fix to the underlying issue this is probably the best we can do.
I wish I knew how much more difficult it would be to actually fix the issue with activatyion on Catalina so that the app just worked like it should. As I write this bugfix in it keeps looking uglier :(

@richardwilkes
Copy link
Author

If someone on your team has an actual Apple Developer account, an issue could be raised with them. They clearly made a change here, so they should be able to give specific directions on what needs to be done now that they no longer do whatever it is they did previously.

@richardwilkes
Copy link
Author

I see this is still not functioning correctly... did the change above not get applied? One difference between what @andydotxyz listed and what I've done in my own Go apps is that I do the hide/unhide after doing the activate... although I only do that when launched from a terminal, which I detect like this:

// IsTerminal returns true if the writer's file descriptor is a terminal.
func IsTerminal(f io.Writer) bool {
	var termios syscall.Termios
	switch v := f.(type) {
	case *os.File:
		_, _, errno := syscall.Syscall6(syscall.SYS_IOCTL, v.Fd(), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) //nolint:gosec
		return errno == 0
	default:
		return false
	}
}

and calling it with os.Stdout.

I can make a PR for fixing this if it in fact hasn't been done yet. Please let me know.

@richardwilkes
Copy link
Author

Ah... I guess I gave the code for checking for the terminal before... sorry for repeating it.

@richardwilkes
Copy link
Author

richardwilkes commented Nov 4, 2020

It appears that all you really need to do is something like this right before entering the main run loop:

dispatch_async(dispatch_get_main_queue(), ^{
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
});

I'll see if I can find the relevant place in the Fyne source base to apply this and make a PR.

@andydotxyz
Copy link
Member

It will be some time before the fix you submitted is propagated up to us, so I have made a fork of the go-glfw and applied it just for us. So this is now fixed in the release/v1.4.x branch :)

@andydotxyz
Copy link
Member

Thanks for your help on this one @richardwilkes.

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

No branches or pull requests

3 participants