Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/crabnebula-dev/drag-rs
Draggable for GUI apps
https://github.com/crabnebula-dev/drag-rs
draggable linux macos rust tao tauri windows winit wry
Last synced: 4 months ago
JSON representation
Draggable for GUI apps
- Host: GitHub
- URL: https://github.com/crabnebula-dev/drag-rs
- Owner: crabnebula-dev
- License: apache-2.0
- Created: 2023-11-08T11:30:47.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-04-25T11:30:30.000Z (9 months ago)
- Last Synced: 2024-04-25T12:29:35.608Z (9 months ago)
- Topics: draggable, linux, macos, rust, tao, tauri, windows, winit, wry
- Language: Rust
- Homepage: https://crabnebula.dev
- Size: 10.1 MB
- Stars: 36
- Watchers: 3
- Forks: 6
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE.spdx
- Security: SECURITY.md
Awesome Lists containing this project
README
# drag-rs
Start a drag operation out of a window on macOS, Windows and Linux (via GTK).
Tested for [tao](https://github.com/tauri-apps/tao) (latest), [winit](https://github.com/rust-windowing/winit) (latest), [wry](https://github.com/tauri-apps/wry) (v0.24) and [tauri](https://github.com/tauri-apps/tauri) (v1) windows.
Due to the GTK-based implementation, winit currently cannot leverage this crate on Linux yet.This project also includes a Tauri plugin for simplified usage on Tauri apps.
## Setup
There's two ways to consume this crate API: from Rust code via the `drag` crate or from Tauri's frontend via `tauri-plugin-drag` or `tauri-plugin-drag-as-window`.
### Rust
- Add the `drag` dependency:
`$ cargo add drag`
- Define the drag item and preview icon:
```rust
let item = drag::DragItem::Files(vec![std::fs::canonicalize("./examples/icon.png").unwrap()]);
let preview_icon = drag::Image::Raw(include_bytes!("../../icon.png").to_vec());
```- Use the `drag::start_drag` function. It takes a `&T: raw_window_handle::HasRawWindowHandle` type on macOS and Windows, and a `>k::ApplicationWindow` on Linux:
- tao:
```rust
let event_loop = tao::event_loop::EventLoop::new();
let window = tao::window::WindowBuilder::new().build(&event_loop).unwrap();drag::start_drag(
#[cfg(target_os = "linux")]
{
use tao::platform::unix::WindowExtUnix;
window.gtk_window()
},
#[cfg(not(target_os = "linux"))]
&window,
item,
preview_icon,
);
```- wry:
```rust
let event_loop = wry::application::event_loop::EventLoop::new();
let window = wry::application::window::WindowBuilder::new().build(&event_loop).unwrap();
let webview = wry::webview::WebViewBuilder::new(window).unwrap().build().unwrap();drag::start_drag(
#[cfg(target_os = "linux")]
{
use wry::application::platform::unix::WindowExtUnix;
webview.window().gtk_window()
},
#[cfg(not(target_os = "linux"))]
&webview.window(),
item,
preview_icon,
);
```- winit:
```rust
let event_loop = winit::event_loop::EventLoop::new().unwrap();
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
let _ = drag::start_drag(&window, item, preview_icon);
```- tauri:
```rust
tauri::Builder::default()
.setup(|app| {
let window = app.get_window("main").unwrap();drag::start_drag(
#[cfg(target_os = "linux")]
&window.gtk_window()?,
#[cfg(not(target_os = "linux"))]
&window,
item,
preview_icon
);Ok(())
})
```### Tauri Plugin
#### tauri-plugin-drag
- Add the `tauri-plugin-drag` dependency:
`$ cargo add tauri-plugin-drag`
- Install the `@crabnebula/tauri-plugin-drag` NPM package containing the API bindings:
```sh
pnpm add @crabnebula/tauri-plugin-drag
# or
npm add @crabnebula/tauri-plugin-drag
# or
yarn add @crabnebula/tauri-plugin-drag
```- Register the core plugin with Tauri:
`src-tauri/src/main.rs`
```rust
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_drag::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```- Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
```javascript
import { startDrag } from "@crabnebula/tauri-plugin-drag";
startDrag({ item: ['/path/to/drag/file'], icon: '/path/to/icon/image' })
```#### tauri-plugin-drag-as-window
- Add the `tauri-plugin-drag-as-window` dependency:
`$ cargo add tauri-plugin-drag-as-window`
- Install the `@crabnebula/tauri-plugin-drag-as-window` NPM package containing the API bindings:
```sh
pnpm add @crabnebula/tauri-plugin-drag-as-window
# or
npm add @crabnebula/tauri-plugin-drag-as-window
# or
yarn add @crabnebula/tauri-plugin-drag-as-window
```- Register the core plugin with Tauri:
`src-tauri/src/main.rs`
```rust
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_drag_as_window::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
```- Afterwards all the plugin's APIs are available through the JavaScript guest bindings:
```javascript
import { dragAsWindow, dragBack } from "@crabnebula/tauri-plugin-drag-as-window";
import { appWindow, WebviewWindow } from "@tauri-apps/api/window";
// alternatively you can pass a DOM element instead of its selector
dragAsWindow('#my-drag-element', (payload) => {
console.log('dropped!')
// create the window with the content from the current element (that's is up to you!)
new WebviewWindow('label', {
x: payload.cursorPos.x,
y: payload.cursorPos.y,
})
})const el = document.querySelector('#my-drag-element')
el.ondragstart = (event) => {
event.preventDefault()dragBack(event.target, { data: 'some data' }, (payload) => {
appWindow.close()
})
}
```## Examples
Running the examples:
```sh
cargo run --bin [tauri-app|winit-app|tao-app|wry-app]
```Additional drag as window examples are available for tauri and wry:
```sh
cargo run --bin [tauri-app-dragout|wry-app-dragout]
```## Licenses
MIT or MIT/Apache 2.0 where applicable.