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

Add Async FontDialog methods and sample #993

Conversation

kashifsoofi
Copy link
Contributor

Added manual binding for FontDialog Async methods.

  • ChooseFaceAsync
  • ChooseFamilyAsync
  • ChooseFontAsync

Added a sample application to use ChooseFontAsync function.

  • I agree that my contribution may be licensed either under MIT or any version of LGPL license.

@badcel
Copy link
Member

badcel commented Jan 6, 2024

Thanks for your contribution. At a first glance the code looks good 👍

Some minor remarks:

If you change your code please Ammend your code, to avoid creating additional commits.

@kashifsoofi
Copy link
Contributor Author

kashifsoofi commented Jan 7, 2024

Thanks for the quick review.
Sorry I missed the new sln file, was added by VSCode :(
No specific reason for using regular Button, I could already use the FontDialogButton, Not a real world scenario, I just wanted to show an alternate way of choosing font in a tutorial.
Commit updated

@kashifsoofi kashifsoofi force-pushed the add-manual-bindings-for-fontdialog-async-functions branch from 6f1e512 to d3eefcd Compare January 7, 2024 00:41
@badcel
Copy link
Member

badcel commented Jan 7, 2024

Can you add your sample to the solution file inside the Samples/Gtk-4.0 virtual folder?

@kashifsoofi kashifsoofi force-pushed the add-manual-bindings-for-fontdialog-async-functions branch from d3eefcd to b351bcc Compare January 7, 2024 11:29
@kashifsoofi
Copy link
Contributor Author

Can you add your sample to the solution file inside the Samples/Gtk-4.0 virtual folder?

Done

@badcel
Copy link
Member

badcel commented Jan 7, 2024

I took a detailed look into your PR and found an issue with ChooseFontAsync: According to the docs the finish method can return Null: https://docs.gtk.org/gtk4/method.FontDialog.choose_font_finish.html

Therefore I think the code must look like:

public Task<Pango.FontDescription?> ChooseFontAsync(Window parent, Pango.FontDescription? fontDescription)
{
    var tcs = new TaskCompletionSource<Pango.FontDescription?>();

    var callbackHandler = new Gio.Internal.AsyncReadyCallbackAsyncHandler((sourceObject, res, data) =>
    {
        if (sourceObject is null)
        {
            tcs.SetException(new Exception("Missing source object"));
            return;
        }

        var fontDescriptionOwnedHandle = Internal.FontDialog.ChooseFontFinish(sourceObject.Handle, res.Handle, out var error);

        if (!error.IsInvalid)
            tcs.SetException(new GLib.GException(error));
        else
        {
            if (fontDescriptionOwnedHandle.IsInvalid)
                tcs.SetResult(null);
            else
            {
                var result = new Pango.FontDescription(fontDescriptionOwnedHandle);
                tcs.SetResult(result);   
            }
        }
    });

    var initialValue = (Pango.Internal.FontDescriptionHandle?) fontDescription?.Handle ?? Pango.Internal.FontDescriptionUnownedHandle.NullHandle;
    Internal.FontDialog.ChooseFont(
        Handle,
        parent.Handle,
        initialValue,
        IntPtr.Zero,
        callbackHandler.NativeCallback,
        IntPtr.Zero
    );

    return tcs.Task;
}

I'm not sure if your sample can be considered complete. If a user presses cancel, it means that a "recoverable error" occurred. Which in C# is an exception. I already asked the gnome devs regarding this behaviour. They argument that "if the user is expected to select a font, not doing so is an error".

So if you press cancel in the font chooser the sample app crashes. I'm not sure if or how you want to attribute to this behaviour or just add some comment?

One possible way to fix this would be:

buttonSelectFont.OnClicked += async (_, _) =>
{
    try
    {
        var fontDialog = Gtk.FontDialog.New();
        var selectedFont = await fontDialog.ChooseFontAsync(window, null);
        labelSelectedFont.SetLabel(selectedFont?.ToString() ?? string.Empty);
    }
    catch (Exception ex)
    {
        //Prints "Dismissed by user" if dialog is cancelled
        Console.WriteLine(ex.Message);
    }
};

Do you have another proposal how to attribute to the possible exception?

If those points are fixed, it is good to go 👍

@kashifsoofi kashifsoofi force-pushed the add-manual-bindings-for-fontdialog-async-functions branch from b351bcc to ca438cf Compare January 7, 2024 16:21
@kashifsoofi
Copy link
Contributor Author

Thanks for the detailed review, I have updated as suggested.

@badcel
Copy link
Member

badcel commented Jan 7, 2024

I think you missed the nullable annotations for the return type and the task completion source in ChooseFontAsync.

There should be a warning in your ide in the line tcs.SetResult(null).

@kashifsoofi kashifsoofi force-pushed the add-manual-bindings-for-fontdialog-async-functions branch from ca438cf to ae84b20 Compare January 7, 2024 20:14
@badcel
Copy link
Member

badcel commented Jan 8, 2024

Sorry to bother you even more. In the sample the nullable handling is missing, too: labelSelectedFont.SetLabel(selectedFont?.ToString() ?? string.Empty);

@kashifsoofi kashifsoofi force-pushed the add-manual-bindings-for-fontdialog-async-functions branch from ae84b20 to 948208f Compare January 8, 2024 11:48
@kashifsoofi
Copy link
Contributor Author

No bother at all, done, Thanks

@badcel badcel merged commit 8446477 into gircore:main Jan 8, 2024
3 checks passed
@kashifsoofi kashifsoofi deleted the add-manual-bindings-for-fontdialog-async-functions branch January 8, 2024 19:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants