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

Context cancellation does not close file selection dialogs immediately on Windows #119

Open
gz-95 opened this issue Sep 11, 2024 · 5 comments
Labels
bug Something isn't working

Comments

@gz-95
Copy link

gz-95 commented Sep 11, 2024

Thanks for this really helpful library! Just having some trouble with closing the dialogs programmatically.

It seems that when the context is canceled, the dialog remains open until the user interacts with it e.g. navigating different directories etc. Here's an example code that reproduces the issue on Windows 10.0.19045 Build 19045

package main

import (
	"context"
	"fmt"

	"github.com/ncruces/zenity"
)

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	stop := context.AfterFunc(ctx, func() {
		fmt.Println("canceled!")
	})

	defer stop()

	file, err := zenity.SelectFile(
		zenity.Context(ctx),
	)

	if err != nil {
		panic(err)
	}

	fmt.Println("select", file)
}

Basically, the call to zenity.SelectFile is blocked with no way of returning even if the context has expired unless the user is actively interacting with the underlying dialog.

@ncruces
Copy link
Owner

ncruces commented Sep 11, 2024

I don't have a windows machine handy.
Do you know which specific windows API is blocked?

@ncruces ncruces added the bug Something isn't working label Sep 11, 2024
@gz-95
Copy link
Author

gz-95 commented Sep 12, 2024

In my testing, it appears that IModalWindow::Show continues to block until active user interaction even though a successful call to IFileDialog::Close has returned.

I'm starting to wonder if this is just the way these Windows functions are implemented?

Also, it looks like dialogHookProc never gets called even with a successful SetWindowsHookEx registration. That explained why I wasn't seeing this line firing.

@ncruces
Copy link
Owner

ncruces commented Sep 16, 2024

Thanks for the detailed report. Yeah, I'm not seeing a way out of this…

@gz-95
Copy link
Author

gz-95 commented Sep 17, 2024

Agreed. I've ditched IFileDialog::Close because I'm convinced that it was only ever intended to be called inside IFileDialogEvents callbacks.

Workaround: if I call CoInitializeEx with COINIT_APARTMENTTHREADED, somehow SetWindowsHookEx seems to work again for the dialogs. So I went with that and just call PostMessage(hwnd, WM_SYSCOMMAND, SC_CLOSE, 0) when the context expires.

@ncruces
Copy link
Owner

ncruces commented Sep 17, 2024

This was put in place because of #89. I'm a bit reluctant to go back on that.

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