-
Notifications
You must be signed in to change notification settings - Fork 126
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
io,app: add deeplinking support #117
base: main
Are you sure you want to change the base?
Conversation
hey @inkeliz WOW this is a huge amount of work you have done. Thank you. Is there a code base with a basic demo we can use to test against ? I am guessing it is this ? https://github.com/gioui-plugins/gio-plugins/tree/add-deeplink and we also need gogio cmd ? |
I use this code for testing: https://gist.github.com/inkeliz/11c071ec4bf8f922a3cb48fd0cbb3b95. That is based on gio-plugins/deeplink/demo, but modified, since the events comes from |
Hey @inkeliz Ok i will try your gist. thanks. I got your deep link demo compiled off the correct git hashes. I am on mac and added your plist. panic(`deeplink: no schemes defined, you must use -ldflags "-X github.com/gioui-plugins/gio-plugins/deeplink.schemes=yourscheme,anotherscheme"`)
} |
@gedw99 That panic was from gio-plugins, not from gio (this current PR). You should not use gio-plugins/deeplink anymore, since everything was ported to Gio (this patch). I didn't use I park the code here, https://github.com/inkeliz/deeplink-demo. It uses the
That will listen to |
Just to remind me in the future:
|
Hi @inkeliz, thanks a lot for implementing this feature. |
In response to: #117 (comment) @inkeliz Yes your Demo code works on darwin_amd64. Really great work Desktop open ... Browser based open ... |
@mearaj, I don't think it's difficult to implement. However, personally, I don't use Linux, either my target-audience (it's < 1% that uses Linux). But, seems that you need to create a file, say
Then run However, its works similar to Windows: that will open the app passing the URL as the first parameter. So, it will require to create some IPC to send the URL to the active window, and make it a single-instance (either by pipe or d-bus). Currently, |
No worries, I understand. Thank you so much for the reply and providing the helpful info. :) |
HI @gedw99 |
If anyone is interested the Deeplinks, allows to then use Universal links. I made an issue here showing how to do it. |
Hi @ALL, |
I saw the gogio code, it doesn't supports linux as pointed out by @inkeliz. I have decided to create a separate repo for this feature on linux. It will support both gio and non gio apps. Will post the link here. Thanks :) |
looking forward to see it. Maybe later merge it into gio cmd if your want. |
Another alternative is to create some app.Scheme("yourscheme") option. Problems: that only works with Linux/Windows, because macOS/iOS/Android requires some manifest, and can't register it on runtime. So, what happens on iOS/Android?! Notice: My suggestion is NOT an My idea with Another approach, is to read Golang's AST. You use The easiest alternative: create a private-variable and then use Line 27 in d62057a
In this patch, a new one: Lines 1016 to 1018 in fe42c61
It not requires |
Hi @inkeliz , I mostly understood what you meant. I will try to implement it in gio itself by looking at the way you did for Windows. In case if I can't do it, I will share my implementation repo link here and will discuss with all of you guys :) |
Hi @inkeliz,@gedw99 and everyone. Desktop Entry Specs Before Window Creation:
The issue currently I am facing is that I don't know how to proceed further. In the current state whenever app receives any uri, it fires window.Event(transfer.URLEvent{URL: urlPtr}). I have created a PR at your branch.(It's not a final PR, but just for your review) |
discussion at gioui#117 (comment) Signed-off-by: Mearaj Bhagad <mearajbhagad@gmail.com>
On macOS (or iOS) it also receives multiple URLs, that is translated to multiple |
Thanks for asking.
These are the reasons I can currently think of :) |
Can you provide an example of how to open multiple URLs? Honestly, I've tried testing this using On Android, Currently, only macOS (and Linux) provide a list of URLs, and I'm not sure how to test that. Changing to |
0d543a0
to
1686874
Compare
I haven't forgotten this, but I'm waiting for https://todo.sr.ht/~eliasnaur/gio/550 to be resolved. In particular, with #550 I believe you no longer need to retain the first event anywhere. |
Ok, #550 and #555 are now merged. Sorry for the delay and merge conflicts. |
I am trying to get https://github.com/gioui-plugins/gio-plugins/tree/add-signin working as well as a few other plugins at https://github.com/orgs/gioui-plugins/projects/1 I believe this is the original link to the blocker: gioui-plugins/gio-plugins#27 (comment) , so it would be awesome if this Deep linking could be finally merged. |
I don't think we have any "blockers." The only "blocker" is "time." I need to upgrade everything (my app, gio-plugins, gio-cmd, and this change) to the new Gio. The gio-plugins rely on unsafe to modify Gio internals (events). Some plugins also support only Go 1.20, which needs update as well (because Go 1.22 has been released). To make matters worse, I am currently working on my final project at university, which is also why I am not very active on Gio anymore. Additionally, the "sign-in" and "deeplink" features require changes to gio-cmd, along with a bunch of changes that are coupled together (gioui/gio-cmd#9, gioui/gio-cmd#13, and gioui/gio-cmd#14). I also need to rebase those changes due to conflicts, if @eliasnaur can review some of those changes will be great. |
Thanks for the summary and the information on what needs to be done. Definitely prioritise your University - Good luck with it .. |
I'm sorry to hear that you're still waiting for review for so long. If you think I missed a PR, feel free to ping me in a GH comment. As for the 3 PRs:
|
67c77c9
to
46cc311
Compare
I'm porting everything to Gio 0.6 (#136 or #134 still a major blocker). But, far I notice the In general, what should I do in that case? Create a new
PS: Not sure if use |
Hey @inkeliz Yep I just tried it. Almost works too for me # [github.com/gioui-plugins/gio-plugins/plugin/gioplugins](http://github.com/gioui-plugins/gio-plugins/plugin/gioplugins)
../../plugin/gioplugins/gioplugins.go:62:8: undefined:
input.SourceEventProcessor
../../plugin/gioplugins/gioplugins.go:71:8: undefined:
input.SourceExecuteProcessor
../../plugin/gioplugins/gioplugins.go:77:5: r.Execute undefined (type
*input.Router has no field or method Execute)
I am guessing you know about this ?
|
@gedw99, I think you are talking about gioui-plugins/gio-plugins#69, which is unrelated to this PR. In case of the gio-plugin you need to use #136 version of Gio, for now. |
ce5792f
to
9ef4718
Compare
Now, it's possible to launch one Gio app using a custom URI scheme, such as `gio://some/data`. This feature is supported on Android, iOS, macOS and Windows, issuing a new transfer.URLEvent, containing the URL launched. If the program is already open, one transfer.URLEvent will be sent to the current app. Limitations: On Windows, if the program listen to schemes (compiled with `-schemes`), then just a single instance of the app can be open. In other words, just a single `myprogram.exe` can be active. Security: Deeplinking have the same level of security of clipboard. Any other software can send such information and read the content, without any restriction. That should not be used to transfer sensible data, and can't be fully trusted. Setup/Compiling: In order to set the custom scheme, you need to use the new `-schemes` flag in `gogio`, using as `-schemes gio` will listen to `gio://`. If you are not using gogio you need to defined some values, which varies for each OS: macOS/iOS - You need to define the following Properly List: ``` <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>yourCustomScheme</string> </array> </dict> </array> ``` Windows - You need to compiling using -X argument: ``` -ldflags="-X "gioui.org/app.schemesDeeplink=yourCustomScheme" -H=windowsgui" ``` Android - You need to add IntentFilter in GioActivity: ``` <intent-filter> <action android:name="android.intent.action.VIEW"></action> <category android:name="android.intent.category.DEFAULT"></category> <category android:name="android.intent.category.BROWSABLE"></category> <data android:scheme="yourCustomScheme"></data> </intent-filter> ``` That assumes that you still using GioActivity and GioAppDelegate, otherwise more changes are required. Signed-off-by: inkeliz <inkeliz@inkeliz.com>
@eliasnaur I need to squash multiple commits, due to rebase. I test have tested it on macOS, Android, iOS and Windows. I tried to avoid re-introducing the old |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great overall. A few nits and questions in the comments.
io/input/pointer.go
Outdated
@@ -320,6 +329,12 @@ func (p *pointerFilter) Matches(e event.Event) bool { | |||
return true | |||
} | |||
} | |||
case transfer.URLEvent: | |||
for _, t := range p.scheme { | |||
if e.URL != nil && (t == "" || t == e.URL.Scheme) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should assume e.URL != nil
.
case transfer.URLFilter: | ||
t = q // See comment in processEvent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not treat transfer.URLFilter
the same as the tag-less key.Filter
above, instead of inventing a fake tag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because q.key.scratchFilter = append(q.key.scratchFilter, f)
is a specific slice that holds key.Filter. Where the "generic one" (used by anything else) uses "taggedFilter". I don't think is right to add yet another specialised slice.
@@ -464,6 +468,10 @@ func (q *Router) processEvent(e event.Event, system bool) { | |||
cstate, evts := q.cqueue.Push(state.clipboardState, e) | |||
state.clipboardState = cstate | |||
q.changeState(e, state, evts) | |||
case transfer.URLEvent: | |||
var evts []taggedEvent | |||
evts = append(evts, taggedEvent{tag: q, event: e}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like key.Event
above, I would not expect a transfer.URLEvent
to have an associated tag.
// On Windows, launching the app using a URI will start a new instance of the app, | ||
// a new window. That behavior, by default, doesn't align with iOS/Android/macOS, where | ||
// the deeplink sends the event to the running app (if any). We are emulating it. | ||
if hwnd, _ := windows.FindWindow(ID); hwnd != 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if multiple program instances have windows matching the ID?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that is unlikely, and only one instance of the program must run anyway. Previously the executable path was used as identifier, then moved to appid
(#117 (comment)).
Maybe in gogio
it must throw one error if appid
is not provided and schemes
are.
Assuming that appid
is unique only one instance of this app will run.
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Signed-off-by: inkeliz <inkeliz@inkeliz.com>
Now, it's possible to launch one Gio app using a custom URI scheme, such as
gio://some/data
.This feature is supported on Android, iOS, macOS and Windows, issuing a new deeplink.Event,
containing the URL launched. If the program is already opened, one deeplink.Event will be
sent to the current opened app.
Limitations:
On Windows, if the program uses deeplink (compiled with
-deeplink
), then just a singleinstance of the app can be open. In other words, just a single
myprogram.exe
canbe active.
Security:
Deeplinking have the same level of security of clipboard. Any other software can send such
information and read the content, without any restriction. That should not be used to transfer
sensible data, and can't be fully trusted.
Setup/Compiling:
In order to set the custom scheme, you need to use the new
-deeplink
flag ingogio
, usingas
-deeplink gio
will listen togio://
.If you are not using gogio you need to defined some values, which varies for each OS:
macOS/iOS - You need to define the following Properly List:
Windows - You need to compiling using -X argument:
Android - You need to add IntentFilter in GioActivity:
That assumes that you still using GioActivity and GioAppDelegate, otherwise more
changes are required.