-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[FEAT]: Native drap and drop for file and folder with complete filepath #1090
Comments
For Windows, the recommendation is to move to v2. |
@leaanthony On v2, Do we have the native drag and drop functionality. |
No, but HTML dnd should. |
Okay Let me check. I will update here with its status. |
@leaanthony It worked with wails v2 but We are not getting the full path of the drag and dropped file. Which make sense for the browser but the full path for the local machine should be accessible. Do we have any work around in wails? |
Thanks for replying. Not right now but happy to accept a PR if it works on all platforms. Why do you need the path? |
Okay, I will be happy to contribute for this feature. Should I include the complete drag and drop functionality ( HTML implementation) with full path as Native drag and drop? Also, I need the path as I want to create some chunks of the file at the location of where the file is located and that is to be done from the Backend (Go) |
At present, there is no way for the front end to obtain the file content. The current feasible way is to start a service on the back end, and then pass the front end to the back end through the service, just like uploading a file on a web page. Because the current Wails does not provide a good way, this method can only be adopted. accomplish. |
It's natural for modern app developers to bring in drag n drop feature. It makes users comfortable to select files or dirs. @hinupurthakur Could you post a link referring to how the full path is got when it's done? It's definitely an important feature for me to choose the framework. |
@misitebao Currently, yes involvment with the backend is the only work around but a feature for a drag and drop with complete file path would be a really good option for the wails. |
Currently from frontend there isn't any possiblity, The work around I am having is involving backend with frontend to get the fullpath |
I suggest you take a look at https://github.com/splode/optimus which has drag and drop capabilities. |
@leaanthony I have checked the https://github.com/splode/optimus implementation of drag and drop but it is limited to file only. I also need to implement drag and drop for directory (folder). |
I suggest changing the ticket title |
@leaanthony Can you help with how we can proceed with this issue to the feature implementation? |
@leaanthony This wasn't helpful for full filepath. |
I can't help you with this. |
@leaanthony So Can we work towards integrating this feature in wails? Or is it not possible at all? |
Sure, I'd love this feature, if you want to try and make it work. How is it implemented in other frameworks? |
@leaanthony I am a backend developer but will research more on it and will provide more information here. Any help from other community members would be really appreciated as well. |
Electron extends DOM to include path to file: https://www.electronjs.org/docs/latest/api/file-object#file-object
|
Yeah, I wonder how they do that? |
How did you get on? |
@leaanthony I would really like to help here to implement something like what electronjs have but probably I will need some guidance there to understand the project better. Let me know if there is a community call or meeting that I can connect on to contribute to this. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
It's awesome, I've wanted this feature for a long time |
This is only Windows though so far isn't it? I wanted to build a file compression program. I can get the entire file if I use the FileReader API, but really I need the full path of the file to read it in via chunks. |
A little late to the party, but isn't this what webtkit2gtk allow-universal-access-from-file-urls is for? Typically each file is considered a separate web origin, I'm pretty sure enabling this flag gives your the real system file path. (Not tested it myself). |
That looks promising indeed. Electron enables that property: https://github.com/electron/electron/blob/d42a94dddeb86d349c050c2ee59b135bd6c8245c/shell/browser/electron_browser_client.cc#L420 |
I'll see what I can do with this tomorrow! I'd be interested in this as well |
I've looked at this, and it looks like some of the assumptions made above are in fact true. |
I'm also waiting for the Native Drap feature. In the v2 version, I can only use this way to implement it: onImagePasted |
Hi, I need this functionality for one of my projects and I started implementing it on Linux because that is my most used platform. As of now I solved the webview stealing my dnd events from the window and crashing my whole window manager issue, by simply calling Here is my progress: https://github.com/lyimmi/wails/tree/feature/1090_native_drag_and_drop_for_file_and_folder I made two options in the
I have implemented two basic methods in the runtime both JS and GO side. The API is pretty linux specific so far, but I'm sure we can solve this on windows and mac as well. @leaanthony and @stffabi if you have time and take a look at this solution and you think this kind of API could be solved on windows and mac I'm willing to sink some more in time to this and try to solve it on windows. Edit: I'll check out the windows pull request, maybe the two solution could be merged somehow. Below I made some examples of the current implementaion. The GO side: import "github.com/wailsapp/wails/v2/pkg/runtime"
runtime.DragAndDropOnMotion(ctx, func(x, y int) {
log.Println("coords", x, y)
})
runtime.DragAndDropOnDrop(ctx, func(paths ...string) {
log.Println("drop", paths)
}) The JS side: import {DragAndDropOnDrop, DragAndDropOnMotion} from "../wailsjs/runtime/runtime.js";
DragAndDropOnMotion((x,y) => {
console.log("coords", x, y);
});
DragAndDropOnDrop(paths => {
console.log("paths", paths);
}); The JS side (extra): In javascript we could implement something like the code below. (Bit nicer maybe 😅) Something similar to the This could be another option in the import {DragAndDropOnDrop, DragAndDropOnMotion} from "../wailsjs/runtime/runtime.js";
let prevEl = null;
DragAndDropOnMotion((x,y) => {
const el = document.elementFromPoint(x, y);
const elStyle = el.getAttribute("style");
if(elStyle !== null && elStyle.indexOf("--wails-drop-target:drop") < 0){
prevEl = el;
el.classList.add("wails-drop-target-active");
} else if(prevEl !== null) {
prevEl.classList.remove("wails-drop-target-active");
}
});
DragAndDropOnDrop(paths => {
if(prevEl !== null) {
prevEl.value = paths[0];
prevEl.classList.remove("wails-drop-target-active");
}
}); Here is a very basic example with the base application and some "advanced" CSS. Screencast.from.2024-01-13.01-07-58.webm |
I successfully married @ayatkyo's and my solution and it works both on Windows and Linux now. (only tested it on Windows 11 and Ubuntu 23.10 with X) I dropped the movement coordinate events and changed the options.
The
The default runtime handlers can be left out if someone wants to implement a custom handler for the drop events by simply listening to Please try this fork and if its ok I'll make a PR for it. It needs some cleaning up but as a test I think its ok. options: type DragAndDrop struct {
// EnableWails enables wails' drag and drop functionality that returns the dropped in files' absolute paths.
EnableWails bool
// Disable webview's drag and drop functionality.
//
// It can be used to prevent accidental file opening of dragged in files in the webview, when there is no need for drag and drop.
Disable bool
// CSS property to test for drag and drop target elements. Default "--wails-drop-target"
CSSDropProperty string
// The CSS Value that the CSSDropProperty must have to be a valid drop target. Default "drop"
CSSDropValue string
} go runtime method: runtime.HandleDragAndDrop(ctx, func(paths ...string) {
log.Println("drop", paths)
}) javascript runtime method: HandleDragAndDrop(paths => {
console.log(paths);
}); Edit: |
how about dragging files out of the window into something like a file explorer? |
Well that is another can of worms that I think I'm going leave to someone else. :) |
I have some progress on macOS. |
@APshenkin - Check this out: #3203 (comment) - feel free to branch that and provide updates if you like. The more people commenting/looking at this, the better! |
Hi @APshenkin I don't know what stage @pavelbinar (and his team) are at with it, but as @leaanthony said the more eyes looking at it the better. For example on windows there is a small window while the dom loads, that the drag and drop prevention is not loaded yet and your drop can still fall trough the original behavior and blow up the state of the program from than on. I have to look into that. I think we should start the webview with the original D&D blocked and "disable" the wails implementation when the dom is ready. 🤔 |
@leaanthony @lyimmi @pavelbinar macOS is ready to be reviewed 🎉 Screen.Recording.2024-02-11.at.03.01.25.mov |
Using v2.9.1 on Windows 10, I'm not seeing either the Go or Js callback for DragAndDrop: &options.DragAndDrop{
EnableFileDrop: true,
DisableWebViewDrop: true,
},
OnDomReady: func(ctx context.Context) {
runtime.EventsOn(ctx, "wails:file-drop", func(optionalData ...interface{}) {
log.Printf("events on file drop: %v", optionalData) // Doesn't get called
})
runtime.OnFileDrop(ctx, func(x, y int, paths []string) {
log.Printf("Dropped at %v,%v\npaths: %v\n", x, y, paths) // Doesn't get called
})
}, Additionally, |
Hi, I checked it on Win11. Yes the DisableWebViewDrop does not register a javascript listener on windows to prevent the default behavior. This should be added, mac and linux handles this at the window level. As far as I can see the current windows implementation requires the /**
* onDrop is called when the drop event is emitted.
* @param {DragEvent} e
* @returns
*/
function onDrop(e) {
if (!window.wails.flags.enableWailsDragAndDrop) {
return;
}
e.preventDefault();
if (!flags.useDropTarget) { <----- this is the problem
return;
}
// Trigger debounce function to deactivate drop targets
if(flags.nextDeactivate) flags.nextDeactivate();
..... However the go events are working fine for me. |
Hi, the condition was already present before my changes. I did not encouter this problem as it is specific to Windows. However I think we can simply fix by moving the file resolving before the condition. |
I have same issue with v2.9.0 none of the events are being called |
Would it be possible for you to raise a quick PR for this? 🙏 |
I've just opened #3595 👍🏼 |
@FrancescoLuzzi @hemkantSplat - I'm testing this on the master branch and not seeing any issue. Events are being raised in Go and JS... In my main.go: OnDomReady: func(ctx context.Context) {
runtime.EventsOn(ctx, "wails:file-drop", func(optionalData ...interface{}) {
log.Printf("events on file drop: %v", optionalData) // Doesn't get called
})
runtime.OnFileDrop(ctx, func(x, y int, paths []string) {
log.Printf("Dropped at %v,%v\npaths: %v\n", x, y, paths) // Doesn't get called
})
}, Using https://github.com/beam-transfer/wails-drag-and-drop as a sample project except I had to change the react component otherwise it immediately deregisters the listener: useEffect(() => {
OnFileDrop((x, y, paths) => {
console.log(x, y, "Dropped files: ", paths);
}, true);
// return () => OnFileDropOff();
}, []); Output: 2024/07/10 13:37:26 events on file drop: [676 296 [C:\Users\l\Downloads\synergy-win_x64-v3.0.80.1-rc3.msi]]
2024/07/10 13:37:26 Dropped at 676,296
paths: [C:\Users\l\Downloads\synergy-win_x64-v3.0.80.1-rc3.msi] So I'm unclear now what the linked PR is trying to fix 😅 |
@leaanthony My PR covers the case where you pass I can't speak about the GO side of things since i've not used it 😄 |
So I'm able to get the Go callbacks to run now but I'm seeing some inconsistencies I'm not understanding using the current master branch. First, I was under the impression that I could use either the Go or Js Also, if
which doesn't make sense to me since the Js |
Yes it is intended, but only if you pass the This helps you implement the drop behavior without checking that the drop location is inside the bounds of the element that you intend to drop on, which would be something like: useEffect(() => {
OnFileDrop((x, y, paths) => {
// useRef that bad boy
const bb = refDrop.current.getBoundingClientRect();
if ( x >= bb.left && x <= bb.right && y >= bb.bottom && y <= bb.top){
// do something with paths
}
}, false); // we want to handle this manually so set useDropTarget to false
return () => OnFileDropOff();
}, []); tldr pass |
Is your feature request related to a problem? Please describe.
Currently, on Wails v1.16.8 as for windows development it depends on IE11 (as Windows development use the mshtml library which is only compatible with IE11), and On IE11, the drag and drop is not supported for folder. Whereas with Chrome, we can have file or folder drag and drop functionality.
Describe the solution you'd like
Feature that can be suitable would be native drag and drop with absolute path of dropped file/folder and if the dependency to IE11 can be removed.
Describe alternatives you've considered
Currently, We have tried the following approaches but not complete solution was found:
Additional context
The text was updated successfully, but these errors were encountered: