tao icon indicating copy to clipboard operation
tao copied to clipboard

feat: add `OpenURLs` Event for macOS

Open meowtec opened this issue 3 years ago • 13 comments

What kind of change does this PR introduce?

  • [ ] Bugfix
  • [x] Feature
  • [ ] Docs
  • [ ] New Binding issue #___
  • [ ] Code style update
  • [ ] Refactor
  • [ ] Build-related changes
  • [ ] Other, please describe:

Does this PR introduce a breaking change?

  • [ ] Yes, and the changes were approved in issue #___
  • [x] No

Checklist

  • [ ] When resolving issues, they are referenced in the PR's title (e.g fix: remove a typo, closes #___, #___)
  • [x] A change file is added if any packages will require a version bump due to this PR per the instructions in the readme.
  • [ ] I have added a convincing reason for adding this feature, if necessary

Other information

This feature is necessary for the file-association function: open files with tauri-based app. ref: https://github.com/tauri-apps/tauri/pull/4320

meowtec avatar Jun 12 '22 04:06 meowtec

Did you try using https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application?language=objc instead?

I'm asking because that's what we need for "deep linking" support and it conflicts with openFile, and i'm not sure yet how we want to handle this conflict. I guess if we can use one interface for both that would be the easiest/best solution.

Anyway, i wanted to try making deep linking work on macos tomorrow, so i can try it out myself too.

FabianLars avatar Jun 25 '22 09:06 FabianLars

Did you try using https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application?language=objc instead?

I'm asking because that's what we need for "deep linking" support and it conflicts with openFile, and i'm not sure yet how we want to handle this conflict. I guess if we can use one interface for both that would be the easiest/best solution.

Anyway, i wanted to try making deep linking work on macos tomorrow, so i can try it out myself too.

I did not aware of the conflict before, and i will try openURLs and find how to make both situations work.

meowtec avatar Jun 25 '22 11:06 meowtec

Did you try using https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application?language=objc instead?

I'm asking because that's what we need for "deep linking" support and it conflicts with openFile, and i'm not sure yet how we want to handle this conflict. I guess if we can use one interface for both that would be the easiest/best solution.

Anyway, i wanted to try making deep linking work on macos tomorrow, so i can try it out myself too.

I have tried openURLs and it seems that we can use openURLs instead of openFile for handling file. When using openURLs, a NSArray<NSURL> are received, in which files are like file:///path/to/file

meowtec avatar Jun 26 '22 15:06 meowtec

I think OpenFile is the correct way to implement this. Let's implement deep link after this so we can see how to handle it.

Electron has both events btw.

lucasfernog avatar Oct 05 '22 02:10 lucasfernog

Actually I saw it gets weird on multiple files :(

This scares me about openURLs urls argument though:

An array of URLs to open. The list does not include URLs for which your app has a defined document type.

lucasfernog avatar Oct 05 '22 03:10 lucasfernog

maybe we should add both events? OpenFile and OpenUrl? seems like both can be used in different cases and I don't see a harm in adding both

amrbashir avatar Oct 05 '22 10:10 amrbashir

after a quick look at the documentation, it seems like it needs a return value to indicate the sucess/failure so maybe we need to do this in a similar way to this winit PR https://github.com/rust-windowing/winit/pull/1759

amrbashir avatar Oct 05 '22 10:10 amrbashir

maybe we should add both events? OpenFile and OpenUrl? seems like both can be used in different cases and I don't see a harm in adding both

If past-me is any trustworthy, we can't because openfile isn't triggered if an app listens to openurl

FabianLars avatar Oct 05 '22 10:10 FabianLars

is there an resource confirming that? electron seems to have it

amrbashir avatar Oct 05 '22 10:10 amrbashir

The docs i linked above mention this: https://developer.apple.com/documentation/appkit/nsapplicationdelegate/2887193-application?language=objc

But these are apple's docs so it's likely that i'm misunderstanding them (or that they are wrong lol)

FabianLars avatar Oct 05 '22 10:10 FabianLars

electron doesn't mention anything about this in their docs so I wonder how electron behaves if you register for both events, anyways, lets follow the official docs.

And in light of this limitation, we need to use the callback style then like this PR https://github.com/rust-windowing/winit/pull/1759 so it can be opt-in for whichever event you want.

amrbashir avatar Oct 05 '22 10:10 amrbashir

We could also emit OpenFile if the url is file:// and OpenUrl for other urls. I couldn't find it in the electron codebase, maybe it's related to chromium.

lucasfernog avatar Oct 05 '22 12:10 lucasfernog

maybe that's something that could be offloaded to tauri instead and tao just allows registering both and documents that only one should be registered.

amrbashir avatar Oct 06 '22 11:10 amrbashir

What is the progress on this issue?

Toldoven avatar Dec 22 '22 15:12 Toldoven

@wusyong could you check out this PR when you have some time? especially the OpenFile event and see if modifying the mutable reference success has any effect at all.

amrbashir avatar Jan 24 '23 14:01 amrbashir

@amrbashir How do I test this? Is there an example to run?

wusyong avatar Jan 26 '23 06:01 wusyong

@wusyong

use tao::{
  event::{Event, WindowEvent},
  event_loop::{ControlFlow, EventLoop},
  window::WindowBuilder,
};

#[allow(clippy::single_match)]
fn main() {
  let event_loop = EventLoop::new();

  let window = Some(
    WindowBuilder::new()
      .with_title("A fantastic window!")
      .with_inner_size(tao::dpi::LogicalSize::new(128.0, 128.0))
      .build(&event_loop)
      .unwrap(),
  );

  event_loop.run(move |event, _, control_flow| {
    *control_flow = ControlFlow::Wait;
    println!("{:?}", event);

    match event {
      Event::OpenFile { filename, success } => {
        dbg!(filename);
        *success = false; // reject the drop, change to true to accept it
      }
      Event::WindowEvent {
        event: WindowEvent::Destroyed,
        window_id: _,
        ..
      } => {
        *control_flow = ControlFlow::Exit;
      }
      Event::MainEventsCleared => {
        if let Some(w) = &window {
          w.request_redraw();
        }
      }
      _ => (),
    }
  });
}

amrbashir avatar Jan 26 '23 12:01 amrbashir

I tired example above but it couldn't really test if events work. If anyone knows how to test it, please let me know.

wusyong avatar Jan 26 '23 14:01 wusyong

I'm testing it again and seems like openURLs is enough for our use case; The URL scheme is file:// when opening files, and the deeplink scheme otherwise. Did I forget something @FabianLars ? This PR is so old I always forget something, but from my tests it looks enough and we could drop the openFile[s] logic.

lucasfernog avatar Jul 03 '23 22:07 lucasfernog

I honestly forgot most of it too, but yeah, openurls is enough unless we need to respond to the openfile event (tho tbh i've not seen a usecase for that yet) and and could be used to simplify the implementation 🤷

One thing tho, did you test it with multiple files too? we've had issues with that when we tried to abuse my deep link plugin for that. Also testing the behavior of different plist configs, like only urls, only files, and having both. Again using the deep link plugin as an example, some users had to add the file scheme to the plist for some messed up reason.

So if all of that works i personally don't see much of a reason to keep openFile/s around

FabianLars avatar Jul 03 '23 22:07 FabianLars

I did test with multiple files, seems to work fine. I guess we can go with the openURLs approach and wait for community feedback.

lucasfernog avatar Jul 03 '23 23:07 lucasfernog

I'd support openFile but default to openURLs because this will and should be upstreamed to winit and could serve as a reference the en

amrbashir avatar Jul 04 '23 00:07 amrbashir

@amrbashir when we upstream we could always use cfc768f (#422) as a reference. But at least for our own use case it seems like openURLs is enough since it also support file opening.

lucasfernog avatar Jul 12 '23 11:07 lucasfernog

yeah I know it is enough but I never want to restrict tao to an API and if possible allow both ways if it is not much hassle. Just to be safe from a future feature request where someone might request it.

amrbashir avatar Jul 12 '23 11:07 amrbashir