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

ILauncher launch events and intercept #15674

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

profix898
Copy link
Sponsor

What does the pull request do?

Introduces new events on ILauncher implementations that triggers when a Uri/file launch occurs. The event arguments provide information about the Uri/file and include a property to cancel the default invocation.

What is the current behavior?

ILauncher invokes the platform handling of Uri/file directly. No event is raised.

What is the updated/expected behavior with this PR?

Desired Enhancements
Notification Event: We want to be notified by an event when a URI/file launch occurs.
Interception and Custom Handling: We aim to intercept the call and handle the URI/file launch in a customizable way.

How was the solution implemented (if it's not obvious)?

The PR adds two events to ILauncher: UriLaunching and FileLaunching. It also adds an abstract base class implementing the event handling. Existing ILauncher implementations are updated to derive from that common base instead.
The PR also turns the PlatformInfoPage in the ControlCatalog into more general Platform page and exposes Uri launcher for testing (opens Avalonia website). Additional platform features (think MAUI essentials) might be added here in the future?!

Fixed issues

See #15673

profix898 and others added 3 commits May 10, 2024 10:22
Provide a common base class and make platform implementation inherit it
Turn PlatformInfoPage in ControlCatalog into more general Platform page and expose Uri launcher for testing
@avaloniaui-bot
Copy link

You can test this PR using the following package version. 11.2.999-cibuild0048304-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@cla-avalonia
Copy link
Collaborator

cla-avalonia commented May 10, 2024

  • All contributors have signed the CLA.

@profix898
Copy link
Sponsor Author

@cla-avalonia agree

@robloo
Copy link
Contributor

robloo commented May 10, 2024

In my opinion this isn't the correct approach. ILauncher is clean and simple as is and works for most apps. If you need to customize a service, then you need to provide your own ILauncher implementation. That's the whole beauty of using services.

Inside your implementation you can do what you want first, raise events, then invoke the system ILauncher.

That said, I'm not sure we have a way of registering service overrides. We probably should support that.

@maxkatz6
Copy link
Member

I agree with @robloo.

Looking at your original issue:

Previously I had a custom Hyperlink(button) and URI launcher implementation. Having the launcher in Avalonia directly means that there will be third-party controls using ILauncher. So it would be great to have some flexibility to intercept, rewrite or handle Uri/file launch calls.

Typically, such scenario could be solved by having a special routed event on a Hyperlink control. Like, UriNavigating. Control would raise this event, while control consumers can handle it. If it wasn't handled - control launch the uri by itself.

@profix898
Copy link
Sponsor Author

profix898 commented May 10, 2024

Thanks for your feedback. If I'm not mistaken, you can't do any such thing. Since V11 the service locator (AvaloniaLocator) is internal. You can't register additional services nor can you override existing ones. For that reason, you also can't modify Avalonia "core" services (by means of providing alternate implementations).

More specifically for this case, the launcher implementations are hardwired for the platform-specific ITopLevelImpl, e.g. AndroidLauncher is directly "embedded" in Avalonia.Android.Platform.SkiaPlatform.TopLevelImpl. It does not go through the service locator at all.

Regarding a custom hyperlink control with a special routed event: Absolutely, that's still doable.
I was just looking for a way to handle all launcher events, regardless of the control (or other source) invoking the action.

If you think this is beyond the scope of Avalonia core, that's fine. Let me know, what direction this should take, if any.

@maxkatz6
Copy link
Member

You can't register additional services nor can you override existing ones

That point was about a service in your application logic, not a replacement for Avalonia service.

@robloo
Copy link
Contributor

robloo commented May 11, 2024

So condensing a few ideas:

  1. It's best to have your own services defined in your application (use Microsoft.Extensions.DependencyInjection). These services would include an ILauncher implementation like this PR where you can intercept and do whatever you want. Inside that service you would call Avalonia's built-in service.
  2. HyperlinkButton can be customized by just handling the Click event and IsVisited properties yourself. This allows you to "intercept" the click and route it to your own launcher service first. Personally, I'm not against adding a cancellable Navigating event to HyperlinkButton in the future though.
  3. It would be great if we could override Avalonia's own services implementation at some point in the future. Not sure when/if that will be supported though.

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.

None yet

5 participants